Initialise empty trees
When new trees are initialised they are started with 1 byte binaries at Level2 - and become full-size following a merge or add event. The idea is that when trees are distributed before they are added to, or when over-sized trees are used - the output may be smaller on the network.
This commit is contained in:
parent
4d6f816ab2
commit
5e6534fb49
1 changed files with 16 additions and 8 deletions
|
@ -79,6 +79,7 @@
|
||||||
-define(MEDIUM, {9, 512, 512 * 512}).
|
-define(MEDIUM, {9, 512, 512 * 512}).
|
||||||
-define(LARGE, {10, 1024, 1024 * 1024}).
|
-define(LARGE, {10, 1024, 1024 * 1024}).
|
||||||
-define(XLARGE, {11, 2048, 2048 * 2048}).
|
-define(XLARGE, {11, 2048, 2048 * 2048}).
|
||||||
|
-define(EMPTY, <<0:8/integer>>).
|
||||||
|
|
||||||
-record(tictactree, {treeID :: any(),
|
-record(tictactree, {treeID :: any(),
|
||||||
size :: xxsmall|xsmall|small|medium|large|xlarge,
|
size :: xxsmall|xsmall|small|medium|large|xlarge,
|
||||||
|
@ -105,9 +106,7 @@ new_tree(TreeID, Size) ->
|
||||||
{BitWidth, Width, SegmentCount} = get_size(Size),
|
{BitWidth, Width, SegmentCount} = get_size(Size),
|
||||||
Lv1Width = Width * ?HASH_SIZE * 8,
|
Lv1Width = Width * ?HASH_SIZE * 8,
|
||||||
Lv1Init = <<0:Lv1Width/integer>>,
|
Lv1Init = <<0:Lv1Width/integer>>,
|
||||||
Lv2SegBinSize = Width * ?HASH_SIZE * 8,
|
Lv2Init = array:new([{size, Width}, {default, ?EMPTY}]),
|
||||||
Lv2SegBinInit = <<0:Lv2SegBinSize/integer>>,
|
|
||||||
Lv2Init = array:new([{size, Width}, {default, Lv2SegBinInit}]),
|
|
||||||
#tictactree{treeID = TreeID,
|
#tictactree{treeID = TreeID,
|
||||||
size = Size,
|
size = Size,
|
||||||
width = Width,
|
width = Width,
|
||||||
|
@ -190,7 +189,7 @@ add_kv(TicTacTree, Key, Value, BinExtractFun, Exportable) ->
|
||||||
Level2BytePos = ?HASH_SIZE * Level2Pos,
|
Level2BytePos = ?HASH_SIZE * Level2Pos,
|
||||||
Level1BytePos = ?HASH_SIZE * Level1Pos,
|
Level1BytePos = ?HASH_SIZE * Level1Pos,
|
||||||
|
|
||||||
Level2 = array:get(Level1Pos, TicTacTree#tictactree.level2),
|
Level2 = get_level2(TicTacTree, Level1Pos),
|
||||||
|
|
||||||
HashIntLength = ?HASH_SIZE * 8,
|
HashIntLength = ?HASH_SIZE * 8,
|
||||||
<<PreL2:Level2BytePos/binary,
|
<<PreL2:Level2BytePos/binary,
|
||||||
|
@ -256,7 +255,7 @@ fetch_root(TicTacTree) ->
|
||||||
fetch_leaves(TicTacTree, BranchList) ->
|
fetch_leaves(TicTacTree, BranchList) ->
|
||||||
MapFun =
|
MapFun =
|
||||||
fun(Idx) ->
|
fun(Idx) ->
|
||||||
{Idx, array:get(Idx, TicTacTree#tictactree.level2)}
|
{Idx, get_level2(TicTacTree, Idx)}
|
||||||
end,
|
end,
|
||||||
lists:map(MapFun, BranchList).
|
lists:map(MapFun, BranchList).
|
||||||
|
|
||||||
|
@ -277,8 +276,8 @@ merge_trees(TreeA, TreeB) ->
|
||||||
|
|
||||||
MergeFun =
|
MergeFun =
|
||||||
fun(SQN, MergeL2) ->
|
fun(SQN, MergeL2) ->
|
||||||
L2A = array:get(SQN, TreeA#tictactree.level2),
|
L2A = get_level2(TreeA, SQN),
|
||||||
L2B = array:get(SQN, TreeB#tictactree.level2),
|
L2B = get_level2(TreeB, SQN),
|
||||||
NewLevel2 = merge_binaries(L2A, L2B),
|
NewLevel2 = merge_binaries(L2A, L2B),
|
||||||
array:set(SQN, NewLevel2, MergeL2)
|
array:set(SQN, NewLevel2, MergeL2)
|
||||||
end,
|
end,
|
||||||
|
@ -322,6 +321,15 @@ tictac_hash(BinKey, BinVal, false) ->
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%============================================================================
|
%%%============================================================================
|
||||||
|
|
||||||
|
get_level2(TicTacTree, L1Pos) ->
|
||||||
|
case array:get(L1Pos, TicTacTree#tictactree.level2) of
|
||||||
|
?EMPTY ->
|
||||||
|
Lv2SegBinSize = TicTacTree#tictactree.width * ?HASH_SIZE * 8,
|
||||||
|
<<0:Lv2SegBinSize/integer>>;
|
||||||
|
SrcL2 ->
|
||||||
|
SrcL2
|
||||||
|
end.
|
||||||
|
|
||||||
get_size(Size) ->
|
get_size(Size) ->
|
||||||
case Size of
|
case Size of
|
||||||
xxsmall ->
|
xxsmall ->
|
||||||
|
@ -361,7 +369,7 @@ checktree(<<>>, TicTacTree, Counter) ->
|
||||||
checktree(Level1Bin, TicTacTree, Counter) ->
|
checktree(Level1Bin, TicTacTree, Counter) ->
|
||||||
BitSize = ?HASH_SIZE * 8,
|
BitSize = ?HASH_SIZE * 8,
|
||||||
<<TopHash:BitSize/integer, Tail/binary>> = Level1Bin,
|
<<TopHash:BitSize/integer, Tail/binary>> = Level1Bin,
|
||||||
L2Bin = array:get(Counter, TicTacTree#tictactree.level2),
|
L2Bin = get_level2(TicTacTree, Counter),
|
||||||
true = TopHash == segmentsummarise(L2Bin, 0),
|
true = TopHash == segmentsummarise(L2Bin, 0),
|
||||||
checktree(Tail, TicTacTree, Counter + 1).
|
checktree(Tail, TicTacTree, Counter + 1).
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue