This is an automated email from the ASF dual-hosted git repository.

iilyak pushed a commit to branch introduce-commit_header
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit e70a995db2d5dca277c04d72152503bfa51b19c1
Author: ILYA Khlopotov <[email protected]>
AuthorDate: Mon Jun 23 07:02:27 2025 -0700

    Introduce couch_file:commit_header/2
    
    This PR is an optimization to reduce number of messages to couch_file 
proccess,
    in casses when we need to call sync. The couch_file:commit_header/2 is more
    efficient equivalent of:
    
    ```
    couch_file:sync(Fd),
    ok = couch_file:write_header(Fd, NewHeader),
    couch_file:sync(Fd),
    ```
---
 src/couch/src/couch_bt_engine.erl           |  4 +---
 src/couch/src/couch_bt_engine_compactor.erl |  3 +--
 src/couch/src/couch_file.erl                | 17 +++++++++++++++--
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/src/couch/src/couch_bt_engine.erl 
b/src/couch/src/couch_bt_engine.erl
index ad84e0db8..422b2c775 100644
--- a/src/couch/src/couch_bt_engine.erl
+++ b/src/couch/src/couch_bt_engine.erl
@@ -562,9 +562,7 @@ commit_data(St) ->
 
     case NewHeader /= OldHeader orelse NeedsCommit of
         true ->
-            couch_file:sync(Fd),
-            ok = couch_file:write_header(Fd, NewHeader),
-            couch_file:sync(Fd),
+            ok = couch_file:commit_header(Fd, NewHeader),
             couch_stats:increment_counter([couchdb, commits]),
             {ok, St#st{
                 header = NewHeader,
diff --git a/src/couch/src/couch_bt_engine_compactor.erl 
b/src/couch/src/couch_bt_engine_compactor.erl
index 8ed55b5c3..f879725e9 100644
--- a/src/couch/src/couch_bt_engine_compactor.erl
+++ b/src/couch/src/couch_bt_engine_compactor.erl
@@ -660,8 +660,7 @@ commit_compaction_data(#st{header = OldHeader} = St0, Fd) ->
         db_header = Header,
         meta_st = MetaState
     },
-    ok = couch_file:sync(Fd),
-    ok = couch_file:write_header(Fd, CompHeader),
+    ok = couch_file:commit_header(Fd, CompHeader),
     St2 = St1#st{
         header = Header
     },
diff --git a/src/couch/src/couch_file.erl b/src/couch/src/couch_file.erl
index 24c910302..714ac9a7e 100644
--- a/src/couch/src/couch_file.erl
+++ b/src/couch/src/couch_file.erl
@@ -47,7 +47,7 @@
 -export([append_term/2, append_term/3]).
 -export([pread_terms/2]).
 -export([append_terms/2, append_terms/3]).
--export([write_header/2, read_header/1]).
+-export([write_header/2, read_header/1, commit_header/2]).
 -export([delete/2, delete/3, nuke_dir/2, init_delete_dir/1]).
 
 % gen_server callbacks
@@ -439,6 +439,14 @@ write_header(Fd, Data) ->
     FinalBin = <<Checksum/binary, Bin/binary>>,
     ioq:call(Fd, {write_header, FinalBin}, erlang:get(io_priority)).
 
+% Same as write_header/2, but ensure durable write.
+commit_header(Fd, Data) ->
+    Bin = ?term_to_bin(Data),
+    Checksum = generate_checksum(Bin),
+    % now we assemble the final header binary and write to disk
+    FinalBin = <<Checksum/binary, Bin/binary>>,
+    ioq:call(Fd, {commit_header, FinalBin}, erlang:get(io_priority)).
+
 init_status_error(ReturnPid, Ref, Error) ->
     ReturnPid ! {Ref, self(), Error},
     ignore.
@@ -596,7 +604,12 @@ handle_call({write_header, Bin}, _From, #file{fd = Fd, eof 
= Pos} = File) ->
             {reply, Error, reset_eof(File)}
     end;
 handle_call(find_header, _From, #file{fd = Fd, eof = Pos} = File) ->
-    {reply, find_header(Fd, Pos div ?SIZE_BLOCK), File}.
+    {reply, find_header(Fd, Pos div ?SIZE_BLOCK), File};
+handle_call({write_header, Bin}, From, #file{fd = Fd} = File) ->
+    sync(Fd),
+    Result = handle_call({write_header, Bin}, From, File),
+    sync(Fd),
+    Result.
 
 handle_cast(Msg, #file{} = File) ->
     {stop, {invalid_cast, Msg}, File}.

Reply via email to