Split out hashtree implementation
Split out hashtree implementation functions in leveled_cdb to make it easier to swap this out. Currently using an array of skiplists - may be better with an ets ordered_set
This commit is contained in:
parent
c4e4cf67fe
commit
06c58bf84b
1 changed files with 49 additions and 25 deletions
|
@ -860,30 +860,14 @@ close_file(Handle, HashTree, BasePos) ->
|
||||||
get_hashtree(Key, HashTree) ->
|
get_hashtree(Key, HashTree) ->
|
||||||
Hash = hash(Key),
|
Hash = hash(Key),
|
||||||
Index = hash_to_index(Hash),
|
Index = hash_to_index(Hash),
|
||||||
Tree = array:get(Index, HashTree),
|
lookup_positions(HashTree, Index, Hash).
|
||||||
case leveled_skiplist:lookup(Hash, Tree) of
|
|
||||||
{value, List} ->
|
|
||||||
List;
|
|
||||||
_ ->
|
|
||||||
[]
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% Add to hash tree - this is an array of 256 skiplists that contains the Hash
|
%% Add to hash tree - this is an array of 256 skiplists that contains the Hash
|
||||||
%% and position of objects which have been added to an open CDB file
|
%% and position of objects which have been added to an open CDB file
|
||||||
put_hashtree(Key, Position, HashTree) ->
|
put_hashtree(Key, Position, HashTree) ->
|
||||||
Hash = hash(Key),
|
Hash = hash(Key),
|
||||||
Index = hash_to_index(Hash),
|
Index = hash_to_index(Hash),
|
||||||
Tree = array:get(Index, HashTree),
|
add_position_tohashtree(HashTree, Index, Hash, Position).
|
||||||
case leveled_skiplist:lookup(Hash, Tree) of
|
|
||||||
none ->
|
|
||||||
array:set(Index,
|
|
||||||
leveled_skiplist:enter(Hash, [Position], Tree),
|
|
||||||
HashTree);
|
|
||||||
{value, L} ->
|
|
||||||
array:set(Index,
|
|
||||||
leveled_skiplist:enter(Hash, [Position|L], Tree),
|
|
||||||
HashTree)
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% Function to extract a Key-Value pair given a file handle and a position
|
%% Function to extract a Key-Value pair given a file handle and a position
|
||||||
%% Will confirm that the key matches and do a CRC check
|
%% Will confirm that the key matches and do a CRC check
|
||||||
|
@ -924,7 +908,7 @@ extract_key_value_check(Handle, Position) ->
|
||||||
%% Scan through the file until there is a failure to crc check an input, and
|
%% Scan through the file until there is a failure to crc check an input, and
|
||||||
%% at that point return the position and the key dictionary scanned so far
|
%% at that point return the position and the key dictionary scanned so far
|
||||||
startup_scan_over_file(Handle, Position) ->
|
startup_scan_over_file(Handle, Position) ->
|
||||||
HashTree = array:new(256, {default, leveled_skiplist:empty()}),
|
HashTree = new_hashtree(),
|
||||||
scan_over_file(Handle,
|
scan_over_file(Handle,
|
||||||
Position,
|
Position,
|
||||||
fun startup_filter/5,
|
fun startup_filter/5,
|
||||||
|
@ -1152,7 +1136,7 @@ search_hash_table(Handle, [Entry|RestOfEntries], Hash, Key, QuickCheck) ->
|
||||||
% key/value binary in the file.
|
% key/value binary in the file.
|
||||||
write_key_value_pairs(Handle, KeyValueList) ->
|
write_key_value_pairs(Handle, KeyValueList) ->
|
||||||
{ok, Position} = file:position(Handle, cur),
|
{ok, Position} = file:position(Handle, cur),
|
||||||
HashTree = array:new(256, {default, leveled_skiplist:empty()}),
|
HashTree = new_hashtree(),
|
||||||
write_key_value_pairs(Handle, KeyValueList, {Position, HashTree}).
|
write_key_value_pairs(Handle, KeyValueList, {Position, HashTree}).
|
||||||
|
|
||||||
write_key_value_pairs(_, [], Acc) ->
|
write_key_value_pairs(_, [], Acc) ->
|
||||||
|
@ -1184,12 +1168,11 @@ perform_write_hash_tables(Handle, HashTreeBin, StartPos) ->
|
||||||
write_hash_tables([], _HashTree, _CurrPos, IndexList, HashTreeBin) ->
|
write_hash_tables([], _HashTree, _CurrPos, IndexList, HashTreeBin) ->
|
||||||
{IndexList, HashTreeBin};
|
{IndexList, HashTreeBin};
|
||||||
write_hash_tables([Index|Rest], HashTree, CurrPos, IndexList, HashTreeBin) ->
|
write_hash_tables([Index|Rest], HashTree, CurrPos, IndexList, HashTreeBin) ->
|
||||||
Tree = array:get(Index, HashTree),
|
case is_empty(HashTree, Index) of
|
||||||
case leveled_skiplist:size(Tree) of
|
true ->
|
||||||
0 ->
|
|
||||||
write_hash_tables(Rest, HashTree, CurrPos, IndexList, HashTreeBin);
|
write_hash_tables(Rest, HashTree, CurrPos, IndexList, HashTreeBin);
|
||||||
_ ->
|
false ->
|
||||||
HashList = leveled_skiplist:to_list(Tree),
|
HashList = to_list(HashTree, Index),
|
||||||
BinList = build_binaryhashlist(HashList, []),
|
BinList = build_binaryhashlist(HashList, []),
|
||||||
IndexLength = length(BinList) * 2,
|
IndexLength = length(BinList) * 2,
|
||||||
SlotList = lists:duplicate(IndexLength, <<0:32, 0:32>>),
|
SlotList = lists:duplicate(IndexLength, <<0:32, 0:32>>),
|
||||||
|
@ -1345,6 +1328,47 @@ multi_key_value_to_record(KVList, BinaryMode, LastPosition) ->
|
||||||
{[], <<>>, empty},
|
{[], <<>>, empty},
|
||||||
KVList).
|
KVList).
|
||||||
|
|
||||||
|
%%%============================================================================
|
||||||
|
%%% HashTree Implementation
|
||||||
|
%%%============================================================================
|
||||||
|
|
||||||
|
lookup_positions(HashTree, Index, Hash) ->
|
||||||
|
Tree = array:get(Index, HashTree),
|
||||||
|
case leveled_skiplist:lookup(Hash, Tree) of
|
||||||
|
{value, List} ->
|
||||||
|
List;
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
add_position_tohashtree(HashTree, Index, Hash, Position) ->
|
||||||
|
Tree = array:get(Index, HashTree),
|
||||||
|
case leveled_skiplist:lookup(Hash, Tree) of
|
||||||
|
none ->
|
||||||
|
array:set(Index,
|
||||||
|
leveled_skiplist:enter(Hash, [Position], Tree),
|
||||||
|
HashTree);
|
||||||
|
{value, L} ->
|
||||||
|
array:set(Index,
|
||||||
|
leveled_skiplist:enter(Hash, [Position|L], Tree),
|
||||||
|
HashTree)
|
||||||
|
end.
|
||||||
|
|
||||||
|
new_hashtree() ->
|
||||||
|
array:new(256, {default, leveled_skiplist:empty()}).
|
||||||
|
|
||||||
|
is_empty(HashTree, Index) ->
|
||||||
|
Tree = array:get(Index, HashTree),
|
||||||
|
case leveled_skiplist:size(Tree) of
|
||||||
|
0 ->
|
||||||
|
true;
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end.
|
||||||
|
|
||||||
|
to_list(HashTree, Index) ->
|
||||||
|
Tree = array:get(Index, HashTree),
|
||||||
|
leveled_skiplist:to_list(Tree).
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%
|
||||||
% T E S T
|
% T E S T
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue