From db243b9794a83d238768eb6a60fa0aec88d5a694 Mon Sep 17 00:00:00 2001 From: Gregory Burd Date: Mon, 25 Jun 2012 11:54:38 +0530 Subject: [PATCH] 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. --- src/hanoidb_reader.erl | 21 +++++++++++++++++---- src/hanoidb_writer.erl | 18 ++++++++---------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/hanoidb_reader.erl b/src/hanoidb_reader.erl index 6ac867d..60c7b63 100644 --- a/src/hanoidb_reader.erl +++ b/src/hanoidb_reader.erl @@ -79,12 +79,25 @@ open(Name, Config) -> %% read root position {ok, <>} = file:pread(File, FileInfo#file_info.size - 8, 8), {ok, <>} = 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, <>} = 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 - {ok, Root} = read_node(File, RootPos), + %% read in the root node + 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}} end. diff --git a/src/hanoidb_writer.erl b/src/hanoidb_writer.erl index 12c9720..6345d99 100644 --- a/src/hanoidb_writer.erl +++ b/src/hanoidb_writer.erl @@ -186,27 +186,25 @@ do_open(Name, Options, OpenOpts) -> %% @doc flush pending nodes and write trailer -flush_nodes(#state{ nodes=[], last_node_pos=LastNodePos, last_node_size=_LastNodeSize, bloom=Bloom }=State) -> - IdxFile = State#state.index_file, +flush_nodes(#state{ nodes=[], last_node_pos=LastNodePos, last_node_size=_LastNodeSize, bloom=Bloom, index_file=IdxFile }=State) -> - RootPos = - case LastNodePos =:= undefined of - true -> + {BloomBin, BloomSize, RootPos} = + case LastNodePos of + undefined -> %% store contains no entries ok = file:write(IdxFile, <<0:32,0:16>>), - ?FIRST_BLOCK_POS; + FilterSize = bloom:filter_size(Bloom), + {<>, 0, ?FIRST_BLOCK_POS}; _ -> - LastNodePos + EncodedBloom = hanoidb_util:encode_bloom(Bloom), + {EncodedBloom, byte_size(EncodedBloom), LastNodePos} end, - BloomBin = hanoidb_util:encode_bloom(Bloom), - BloomSize = byte_size(BloomBin), Trailer = << 0:32, BloomBin/binary, BloomSize:32/unsigned, RootPos:64/unsigned >>, ok = file:write(IdxFile, Trailer), ok = file:datasync(IdxFile), ok = file:close(IdxFile), - {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 })