Don't bother writing out the bloom filter when a level is empty, instead just write 0 for the bloom size and before that record the level's filter size so as to re-create a properly sized filter later when reading this file.

This commit is contained in:
Gregory Burd 2012-06-25 11:54:38 +05:30
parent 59282eaf2a
commit db243b9794
2 changed files with 25 additions and 14 deletions

View file

@ -79,12 +79,25 @@ open(Name, Config) ->
%% read root position %% read root position
{ok, <<RootPos:64/unsigned>>} = file:pread(File, FileInfo#file_info.size - 8, 8), {ok, <<RootPos:64/unsigned>>} = file:pread(File, FileInfo#file_info.size - 8, 8),
{ok, <<BloomSize:32/unsigned>>} = file:pread(File, FileInfo#file_info.size - 12, 4), {ok, <<BloomSize:32/unsigned>>} = file:pread(File, FileInfo#file_info.size - 12, 4),
{ok, BloomData} = file:pread(File, (FileInfo#file_info.size - 12 - BloomSize), BloomSize),
Bloom = hanoidb_util:decode_bloom(BloomData), Bloom =
case BloomSize of
0 ->
{ok, <<FilterSize:32/unsigned>>} = file:pread(File, (FileInfo#file_info.size - 16), 4),
bloom:new(FilterSize, 0.001);
_ ->
{ok, BloomData} = file:pread(File, (FileInfo#file_info.size - 12 - BloomSize), BloomSize),
hanoidb_util:decode_bloom(BloomData)
end,
%% suck in the root %% read in the root node
{ok, Root} = read_node(File, RootPos), Root =
case read_node(File, RootPos) of
{ok, Node} ->
Node;
eof ->
none
end,
{ok, #index{file=File, root=Root, bloom=Bloom, name=Name, config=Config}} {ok, #index{file=File, root=Root, bloom=Bloom, name=Name, config=Config}}
end. end.

View file

@ -186,27 +186,25 @@ do_open(Name, Options, OpenOpts) ->
%% @doc flush pending nodes and write trailer %% @doc flush pending nodes and write trailer
flush_nodes(#state{ nodes=[], last_node_pos=LastNodePos, last_node_size=_LastNodeSize, bloom=Bloom }=State) -> flush_nodes(#state{ nodes=[], last_node_pos=LastNodePos, last_node_size=_LastNodeSize, bloom=Bloom, index_file=IdxFile }=State) ->
IdxFile = State#state.index_file,
RootPos = {BloomBin, BloomSize, RootPos} =
case LastNodePos =:= undefined of case LastNodePos of
true -> undefined ->
%% store contains no entries %% store contains no entries
ok = file:write(IdxFile, <<0:32,0:16>>), ok = file:write(IdxFile, <<0:32,0:16>>),
?FIRST_BLOCK_POS; FilterSize = bloom:filter_size(Bloom),
{<<FilterSize:32/unsigned>>, 0, ?FIRST_BLOCK_POS};
_ -> _ ->
LastNodePos EncodedBloom = hanoidb_util:encode_bloom(Bloom),
{EncodedBloom, byte_size(EncodedBloom), LastNodePos}
end, end,
BloomBin = hanoidb_util:encode_bloom(Bloom),
BloomSize = byte_size(BloomBin),
Trailer = << 0:32, BloomBin/binary, BloomSize:32/unsigned, RootPos:64/unsigned >>, Trailer = << 0:32, BloomBin/binary, BloomSize:32/unsigned, RootPos:64/unsigned >>,
ok = file:write(IdxFile, Trailer), ok = file:write(IdxFile, Trailer),
ok = file:datasync(IdxFile), ok = file:datasync(IdxFile),
ok = file:close(IdxFile), ok = file:close(IdxFile),
{ok, State#state{ index_file=undefined, index_file_pos=undefined }}; {ok, State#state{ index_file=undefined, index_file_pos=undefined }};
flush_nodes(State=#state{ nodes=[#node{level=N, members=[{_,{Pos,_Len}}]}], last_node_pos=Pos }) flush_nodes(State=#state{ nodes=[#node{level=N, members=[{_,{Pos,_Len}}]}], last_node_pos=Pos })