You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2009/05/20 03:27:05 UTC

svn commit: r776514 - in /couchdb/branches/tail_header/src/couchdb: couch_db.erl couch_db_updater.erl couch_file.erl

Author: damien
Date: Wed May 20 01:27:04 2009
New Revision: 776514

URL: http://svn.apache.org/viewvc?rev=776514&view=rev
Log:
Optimization to avoid conversion of iolist_binary call.

Modified:
    couchdb/branches/tail_header/src/couchdb/couch_db.erl
    couchdb/branches/tail_header/src/couchdb/couch_db_updater.erl
    couchdb/branches/tail_header/src/couchdb/couch_file.erl

Modified: couchdb/branches/tail_header/src/couchdb/couch_db.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/tail_header/src/couchdb/couch_db.erl?rev=776514&r1=776513&r2=776514&view=diff
==============================================================================
--- couchdb/branches/tail_header/src/couchdb/couch_db.erl (original)
+++ couchdb/branches/tail_header/src/couchdb/couch_db.erl Wed May 20 01:27:04 2009
@@ -50,6 +50,7 @@
         {ok, Fd} ->
             ?LOG_INFO("Found ~s~s compaction file, using as primary storage.", [Filepath, ".compact"]),
             ok = file:rename(Filepath ++ ".compact", Filepath),
+            ok = couch_file:sync(Fd),
             {ok, Fd};
         {error, enoent} ->
             {not_found, no_db_file}

Modified: couchdb/branches/tail_header/src/couchdb/couch_db_updater.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/tail_header/src/couchdb/couch_db_updater.erl?rev=776514&r1=776513&r2=776514&view=diff
==============================================================================
--- couchdb/branches/tail_header/src/couchdb/couch_db_updater.erl (original)
+++ couchdb/branches/tail_header/src/couchdb/couch_db_updater.erl Wed May 20 01:27:04 2009
@@ -29,6 +29,12 @@
         % delete any old compaction files that might be hanging around
         file:delete(Filepath ++ ".compact");
     false ->
+        case couch_config:get("couchdb", "sync_on_open", "true") of
+        "true" ->
+            ok = couch_file:sync(Fd);
+        _ ->
+            ok
+        end,
         {ok, Header} = couch_file:read_header(Fd)
     end,
     

Modified: couchdb/branches/tail_header/src/couchdb/couch_file.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/tail_header/src/couchdb/couch_file.erl?rev=776514&r1=776513&r2=776514&view=diff
==============================================================================
--- couchdb/branches/tail_header/src/couchdb/couch_file.erl (original)
+++ couchdb/branches/tail_header/src/couchdb/couch_file.erl Wed May 20 01:27:04 2009
@@ -74,8 +74,7 @@
     
 append_binary(Fd, Bin) ->
     Size = iolist_size(Bin),
-    SizePrependedBin = iolist_to_binary([<<Size:32/integer>>, Bin]),
-    gen_server:call(Fd, {append_bin, SizePrependedBin}, infinity).
+    gen_server:call(Fd, {append_bin, [<<Size:32/integer>>, Bin]}, infinity).
 
 
 %%----------------------------------------------------------------------
@@ -192,6 +191,7 @@
                 true ->
                     {ok, 0} = file:position(Fd, 0),
                     ok = file:truncate(Fd),
+                    ok = file:sync(Fd),
                     couch_stats_collector:track_process_count(
                             {couchdb, open_os_files}),
                     {ok, Fd};
@@ -252,7 +252,7 @@
     BlockOffset ->
         Padding = <<0:(8*(?SIZE_BLOCK-BlockOffset))>>
     end,
-    FinalBin = [Padding, <<1, BinSize:32/integer>> | make_blocks(1, Bin)],
+    FinalBin = [Padding, <<1, BinSize:32/integer>> | make_blocks(1, [Bin])],
     {reply, file:pwrite(Fd, Pos, FinalBin), Fd};
 handle_call(find_header, _From, Fd) ->
     {ok, Pos} = file:position(Fd, eof),
@@ -317,14 +317,33 @@
         [Bin]
     end.
 
-make_blocks(_BlockOffset, <<>>) ->
+make_blocks(_BlockOffset, []) ->
     [];
-make_blocks(0, Bin) ->
-    [<<0>> | make_blocks(1, Bin)];
-make_blocks(BlockOffset, Bin) when size(Bin) =< (?SIZE_BLOCK - BlockOffset) ->
-    [Bin];
-make_blocks(BlockOffset, Bin) ->
-    BlockBytes = (?SIZE_BLOCK - BlockOffset),
-    <<BlockBin:BlockBytes/binary, Rest/binary>> = Bin,
-    [BlockBin | make_blocks(0, Rest)].
+make_blocks(0, IoList) ->
+    [<<0>> | make_blocks(1, IoList)];
+make_blocks(BlockOffset, IoList) ->
+    case split_iolist(IoList, (?SIZE_BLOCK - BlockOffset), []) of
+    {Begin, End} ->
+        [Begin | make_blocks(0, End)];
+    _Size ->
+        IoList
+    end.
 
+split_iolist(List, 0, BeginAcc) ->
+    {lists:reverse(BeginAcc), List};
+split_iolist([], SplitAt, _BeginAcc) ->
+    SplitAt;
+split_iolist([<<Bin/binary>> | Rest], SplitAt, BeginAcc)  when SplitAt > size(Bin) ->
+    split_iolist(Rest, SplitAt - size(Bin), [Bin | BeginAcc]);
+split_iolist([<<Bin/binary>> | Rest], SplitAt, BeginAcc) ->
+    <<Begin:SplitAt/binary,End/binary>> = Bin,
+    split_iolist([End | Rest], 0, [Begin | BeginAcc]);
+split_iolist([Sublist| Rest], SplitAt, BeginAcc) when is_list(Sublist) ->
+    case split_iolist(Sublist, SplitAt, BeginAcc) of
+    {Begin, End} ->
+        {Begin, [End | Rest]};
+    Len ->
+        split_iolist(Rest, SplitAt - Len, [Sublist | BeginAcc])
+    end;
+split_iolist([Byte | Rest], SplitAt, BeginAcc) when is_integer(Byte) ->
+    split_iolist(Rest, SplitAt - 1, [Byte | BeginAcc]).