Author: fdmanana
Date: Thu Nov 11 00:59:40 2010
New Revision: 1033790

URL: http://svn.apache.org/viewvc?rev=1033790&view=rev
Log:
Micro optimization: when reading an iolist, read up to 8Kbs instead of the 4 
bytes length prefix only in the first file read operation.
For reads of small terms/iolist (up to 8Kbs), this speeds up the whole 
operation. No impact on larger terms/iolists.

Modified:
    couchdb/trunk/src/couchdb/couch_file.erl
    couchdb/trunk/test/etap/010-file-basics.t

Modified: couchdb/trunk/src/couchdb/couch_file.erl
URL: 
http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_file.erl?rev=1033790&r1=1033789&r2=1033790&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_file.erl (original)
+++ couchdb/trunk/src/couchdb/couch_file.erl Thu Nov 11 00:59:40 2010
@@ -283,20 +283,28 @@ terminate(_Reason, #file{fd = Fd}) ->
 
 
 handle_call({pread_iolist, Pos}, _From, File) ->
-    {LenIolist, NextPos} = read_raw_iolist_int(File, Pos, 4),
-    case iolist_to_binary(LenIolist) of
-    <<1:1/integer,Len:31/integer>> -> % an MD5-prefixed term
-        {Md5AndIoList, _} = read_raw_iolist_int(File, NextPos, Len+16),
-        {Md5, IoList} = extract_md5(Md5AndIoList),
+    {RawData, NextPos} = try
+        % up to 8Kbs of read ahead
+        read_raw_iolist_int(File, Pos, 2 * ?SIZE_BLOCK - (Pos rem ?SIZE_BLOCK))
+    catch
+    _:_ ->
+        read_raw_iolist_int(File, Pos, 4)
+    end,
+    <<Prefix:1/integer, Len:31/integer, RestRawData/binary>> =
+        iolist_to_binary(RawData),
+    case Prefix of
+    1 ->
+        {Md5, IoList} = extract_md5(
+            maybe_read_more_iolist(RestRawData, 16 + Len, NextPos, File)),
         case couch_util:md5(IoList) of
         Md5 ->
             {reply, {ok, IoList}, File};
         _ ->
             {stop, file_corruption, {error,file_corruption}, File}
         end;
-    <<0:1/integer,Len:31/integer>> ->
-        {Iolist, _} = read_raw_iolist_int(File, NextPos, Len),
-        {reply, {ok, Iolist}, File}
+    0 ->
+        IoList = maybe_read_more_iolist(RestRawData, Len, NextPos, File),
+        {reply, {ok, IoList}, File}
     end;
 handle_call({pread, Pos, Bytes}, _From, 
#file{fd=Fd,tail_append_begin=TailAppendBegin}=File) ->
     {ok, Bin} = file:pread(Fd, Pos, Bytes),
@@ -503,6 +511,15 @@ load_header(Fd, Block) ->
     Md5Sig = couch_util:md5(HeaderBin),
     {ok, HeaderBin}.
 
+maybe_read_more_iolist(Buffer, DataSize, _, _)
+    when DataSize =< byte_size(Buffer) ->
+    <<Data:DataSize/binary, _/binary>> = Buffer,
+    [Data];
+maybe_read_more_iolist(Buffer, DataSize, NextPos, File) ->
+    {Missing, _} =
+        read_raw_iolist_int(File, NextPos, DataSize - byte_size(Buffer)),
+    [Buffer, Missing].
+
 -spec read_raw_iolist_int(#file{}, Pos::non_neg_integer(), 
Len::non_neg_integer()) ->
     {Data::iolist(), CurPos::non_neg_integer()}.
 read_raw_iolist_int(Fd, {Pos, _Size}, Len) -> % 0110 UPGRADE CODE

Modified: couchdb/trunk/test/etap/010-file-basics.t
URL: 
http://svn.apache.org/viewvc/couchdb/trunk/test/etap/010-file-basics.t?rev=1033790&r1=1033789&r2=1033790&view=diff
==============================================================================
--- couchdb/trunk/test/etap/010-file-basics.t (original)
+++ couchdb/trunk/test/etap/010-file-basics.t Thu Nov 11 00:59:40 2010
@@ -84,7 +84,8 @@ test() ->
     % append_binary == append_iolist?
     % Possible bug in pread_iolist or iolist() -> append_binary
     {ok, IOLPos} = couch_file:append_binary(Fd, ["foo", $m, <<"bam">>]),
-    etap:is({ok, [<<"foombam">>]}, couch_file:pread_iolist(Fd, IOLPos),
+    {ok, IoList} = couch_file:pread_iolist(Fd, IOLPos),
+    etap:is(<<"foombam">>, iolist_to_binary(IoList),
         "Reading an results in a binary form of the written iolist()"),
 
     % XXX: How does on test fsync?


Reply via email to