You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2026/05/26 11:47:53 UTC
(couchdb) branch no-eof created (now c897c245b)
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a change to branch no-eof
in repository https://gitbox.apache.org/repos/asf/couchdb.git
at c897c245b eliminate internal tracking of EOF
This branch includes the following new commits:
new c897c245b eliminate internal tracking of EOF
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(couchdb) 01/01: eliminate internal tracking of EOF
Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a commit to branch no-eof
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit c897c245bcf6c70260b3d122eb041355c3c354b9
Author: Robert Newson <rn...@apache.org>
AuthorDate: Tue May 26 12:44:59 2026 +0100
eliminate internal tracking of EOF
---
src/couch/src/couch_file.erl | 46 +++++++++++++------------------
src/couch/test/eunit/couch_file_tests.erl | 6 ++--
2 files changed, 22 insertions(+), 30 deletions(-)
diff --git a/src/couch/src/couch_file.erl b/src/couch/src/couch_file.erl
index 2d0920f7e..03b342988 100644
--- a/src/couch/src/couch_file.erl
+++ b/src/couch/src/couch_file.erl
@@ -34,7 +34,6 @@
-record(file, {
fd,
is_sys,
- eof = 0,
db_monitor,
filepath
}).
@@ -497,9 +496,8 @@ init({Filepath, Options, ReturnPid, Ref}) ->
put(couch_file_fd, {Fd, Filepath}),
ok = file:close(Fd_Read),
maybe_track_open_os_files(Options),
- {ok, Eof} = file:position(Fd, eof),
erlang:send_after(?INITIAL_WAIT, self(), maybe_close),
- {ok, dup(File#file{fd = Fd, eof = Eof})};
+ {ok, dup(File#file{fd = Fd})};
Error ->
init_status_error(ReturnPid, Ref, Error)
end;
@@ -568,7 +566,7 @@ handle_call({truncate, Pos}, _From, #file{fd = Fd} = File) ->
{ok, Pos} = file:position(Fd, Pos),
case file:truncate(Fd) of
ok ->
- {reply, ok, File#file{eof = Pos}};
+ {reply, ok, File};
Error ->
{reply, Error, File}
end;
@@ -601,7 +599,8 @@ handle_call({write_header, Bin, Opts}, _From, #file{} = File) ->
% handle_call(sync, ...) why we're dropping the fd
{stop, {error, Error}, {error, Error}, #file{fd = nil}}
end;
-handle_call(find_header, _From, #file{fd = Fd, eof = Pos} = File) ->
+handle_call(find_header, _From, #file{fd = Fd} = File) ->
+ {ok, Pos} = file:position(Fd, eof),
{reply, find_header(Fd, Pos div ?SIZE_BLOCK), File}.
handle_cast(Msg, #file{} = File) ->
@@ -624,8 +623,9 @@ handle_info({'DOWN', Ref, process, _Pid, _Info}, #file{db_monitor = Ref} = File)
eof(#file{fd = Fd}) ->
file:position(Fd, eof).
-append_bins(#file{fd = Fd, eof = Pos} = File, Bins) ->
- {BlockResps, FinalPos} = lists:mapfoldl(
+append_bins(#file{fd = Fd} = File, Bins) ->
+ {ok, Pos} = file:position(Fd, eof),
+ {BlockResps, _} = lists:mapfoldl(
fun(Bin, PosAcc) ->
Blocks = make_blocks(PosAcc rem ?SIZE_BLOCK, Bin),
Size = iolist_size(Blocks),
@@ -636,8 +636,8 @@ append_bins(#file{fd = Fd, eof = Pos} = File, Bins) ->
),
{AllBlocks, Resps} = lists:unzip(BlockResps),
case file:write(Fd, AllBlocks) of
- ok -> {{ok, Resps}, File#file{eof = FinalPos}};
- Error -> {Error, reset_eof(File)}
+ ok -> {{ok, Resps}, File};
+ Error -> {Error, File}
end.
pread(#file{} = File, PosL) ->
@@ -770,19 +770,18 @@ find_newest_header(Fd, [{Location, Size} | LocationSizes]) ->
find_newest_header(Fd, LocationSizes)
end.
-handle_write_header(Bin, #file{fd = Fd, eof = Pos} = File) ->
+handle_write_header(Bin, #file{fd = Fd} = File) ->
BinSize = byte_size(Bin),
+ {ok, Pos} = file:position(Fd, eof),
case Pos rem ?SIZE_BLOCK of
0 -> Padding = <<>>;
BlockOffset -> Padding = <<0:(8 * (?SIZE_BLOCK - BlockOffset))>>
end,
FinalBin = [Padding, <<1, BinSize:32/integer>> | make_blocks(5, [Bin])],
- case file:write(Fd, FinalBin) of
- ok -> {ok, File#file{eof = Pos + iolist_size(FinalBin)}};
- {error, Error} -> {{error, Error}, reset_eof(File)}
- end.
+ {file:write(Fd, FinalBin), File}.
-read_multi_raw_iolists_int(#file{fd = Fd, eof = Eof} = File, PosLens) ->
+read_multi_raw_iolists_int(#file{fd = Fd} = File, PosLens) ->
+ {ok, Eof} = file:position(Fd, eof),
MapFun = fun({Pos, Len}) -> get_pread_locnum(File, Pos, Len) end,
LocNums = lists:map(MapFun, PosLens),
ZipFun = fun({Pos, TotalBytes}, Bin) ->
@@ -791,9 +790,8 @@ read_multi_raw_iolists_int(#file{fd = Fd, eof = Eof} = File, PosLens) ->
{remove_block_prefixes(Pos rem ?SIZE_BLOCK, Bin), Pos + TotalBytes};
false ->
couch_stats:increment_counter([pread, exceed_eof]),
- {ok, CurEof} = file:position(File#file.fd, eof),
Filepath = File#file.filepath,
- throw_stop({read_beyond_eof, Filepath, Pos, TotalBytes, Eof, CurEof}, File)
+ throw_stop({read_beyond_eof, Filepath, Pos, TotalBytes, Eof}, File)
end
end,
case file:pread(Fd, LocNums) of
@@ -804,15 +802,15 @@ read_multi_raw_iolists_int(#file{fd = Fd, eof = Eof} = File, PosLens) ->
throw_stop({pread, Filepath, Error, hd(LocNums)}, File)
end.
-get_pread_locnum(#file{eof = Eof} = File, Pos, Len) ->
+get_pread_locnum(#file{} = File, Pos, Len) ->
+ {ok, Eof} = file:position(File#file.fd, eof),
BlockOffset = Pos rem ?SIZE_BLOCK,
TotalBytes = calculate_total_read_len(BlockOffset, Len),
case Pos + TotalBytes of
Size when Size > Eof ->
couch_stats:increment_counter([pread, exceed_eof]),
- {ok, CurEof} = file:position(File#file.fd, eof),
Filepath = File#file.filepath,
- throw_stop({read_beyond_eof, Filepath, Pos, TotalBytes, Eof, CurEof}, File);
+ throw_stop({read_beyond_eof, Filepath, Pos, TotalBytes, Eof}, File);
_ ->
{Pos, TotalBytes}
end.
@@ -959,11 +957,6 @@ is_idle(#file{is_sys = false}) ->
process_info(Pid) ->
couch_util:process_dict_get(Pid, couch_file_fd).
-%% in event of a partially successful write.
-reset_eof(#file{} = File) ->
- {ok, Eof} = file:position(File#file.fd, eof),
- File#file{eof = Eof}.
-
-spec generate_checksum(binary()) -> <<_:128>>.
generate_checksum(Bin) when is_binary(Bin) ->
case generate_xxhash_checksums() of
@@ -1016,8 +1009,7 @@ dup(#file{fd = Fd} = File) ->
ok = file:close(Fd),
CFile = File#file{fd = CFd},
put(couch_file_fd, {CFd, CFile#file.filepath}),
- % Use an effective infinity for eof max limit for now
- put(?CFILE_HANDLE, CFile#file{eof = 1 bsl 60}),
+ put(?CFILE_HANDLE, CFile),
CFile;
{error, _Error} ->
File
diff --git a/src/couch/test/eunit/couch_file_tests.erl b/src/couch/test/eunit/couch_file_tests.erl
index c138a9c0a..5efe211bd 100644
--- a/src/couch/test/eunit/couch_file_tests.erl
+++ b/src/couch/test/eunit/couch_file_tests.erl
@@ -236,7 +236,7 @@ should_not_read_beyond_eof(_) ->
file:close(Io),
unlink(Fd),
?assertMatch(
- {error, {read_beyond_eof, Filepath, _, _, _, _}}, couch_file:pread_binary(Fd, Pos)
+ {error, {read_beyond_eof, Filepath, _, _, _}}, couch_file:pread_binary(Fd, Pos)
),
catch file:close(Fd).
@@ -253,7 +253,7 @@ should_not_read_beyond_eof_when_externally_truncated(_) ->
file:close(Io),
unlink(Fd),
?assertMatch(
- {error, {read_beyond_eof, Filepath, _, _, _, _}}, couch_file:pread_binary(Fd, Pos)
+ {error, {read_beyond_eof, Filepath, _, _, _}}, couch_file:pread_binary(Fd, Pos)
),
catch file:close(Fd).
@@ -319,7 +319,7 @@ should_apply_overwrite_create_option(Fd) ->
{ok, Fd1} = couch_file:open(Path, [create, overwrite]),
unlink(Fd1),
?assertMatch(
- {error, {read_beyond_eof, Path, Pos, _, _, _}},
+ {error, {read_beyond_eof, Path, Pos, _, _}},
couch_file:pread_term(Fd1, Pos)
).