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?