Added skiplist to datatypes
This commit is contained in:
parent
efec232e71
commit
6d2eb1d57c
1 changed files with 98 additions and 25 deletions
|
@ -82,17 +82,7 @@ match(Key, {idxt, _L, {TLI, IDX}}) ->
|
||||||
lookup_match(Key, element(ListID, TLI))
|
lookup_match(Key, element(ListID, TLI))
|
||||||
end;
|
end;
|
||||||
match(Key, {skpl, _L, SkipList}) ->
|
match(Key, {skpl, _L, SkipList}) ->
|
||||||
FoldFun =
|
SL0 = skpl_getsublist(Key, SkipList),
|
||||||
fun({Mark, SL}, Acc) ->
|
|
||||||
case {Acc, Mark} of
|
|
||||||
{[], Mark} when Mark >= Key ->
|
|
||||||
SL;
|
|
||||||
_ ->
|
|
||||||
Acc
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
SL1 = lists:foldl(FoldFun, [], SkipList),
|
|
||||||
SL0 = lists:foldl(FoldFun, [], SL1),
|
|
||||||
lookup_match(Key, SL0).
|
lookup_match(Key, SL0).
|
||||||
|
|
||||||
search(Key, {tree, _L, Tree}, StartKeyFun) ->
|
search(Key, {tree, _L, Tree}, StartKeyFun) ->
|
||||||
|
@ -124,17 +114,7 @@ search(Key, {idxt, _L, {TLI, IDX}}, StartKeyFun) ->
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
search(Key, {skpl, _L, SkipList}, StartKeyFun) ->
|
search(Key, {skpl, _L, SkipList}, StartKeyFun) ->
|
||||||
FoldFun =
|
SL0 = skpl_getsublist(Key, SkipList),
|
||||||
fun({Mark, SL}, Acc) ->
|
|
||||||
case {Acc, Mark} of
|
|
||||||
{[], Mark} when Mark >= Key ->
|
|
||||||
SL;
|
|
||||||
_ ->
|
|
||||||
Acc
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
SL1 = lists:foldl(FoldFun, [], SkipList),
|
|
||||||
SL0 = lists:foldl(FoldFun, [], SL1),
|
|
||||||
{K, V} = lookup_best(Key, SL0),
|
{K, V} = lookup_best(Key, SL0),
|
||||||
case K < StartKeyFun(V) of
|
case K < StartKeyFun(V) of
|
||||||
true ->
|
true ->
|
||||||
|
@ -154,7 +134,9 @@ match_range(StartRange, EndRange, Tree) ->
|
||||||
match_range(StartRange, EndRange, {tree, _L, Tree}, EndRangeFun) ->
|
match_range(StartRange, EndRange, {tree, _L, Tree}, EndRangeFun) ->
|
||||||
treelookup_range_start(StartRange, EndRange, Tree, EndRangeFun);
|
treelookup_range_start(StartRange, EndRange, Tree, EndRangeFun);
|
||||||
match_range(StartRange, EndRange, {idxt, _L, Tree}, EndRangeFun) ->
|
match_range(StartRange, EndRange, {idxt, _L, Tree}, EndRangeFun) ->
|
||||||
idxtlookup_range_start(StartRange, EndRange, Tree, EndRangeFun).
|
idxtlookup_range_start(StartRange, EndRange, Tree, EndRangeFun);
|
||||||
|
match_range(StartRange, EndRange, {skpl, _L, SkipList}, EndRangeFun) ->
|
||||||
|
skpllookup_to_range(StartRange, EndRange, SkipList, EndRangeFun).
|
||||||
|
|
||||||
|
|
||||||
search_range(StartRange, EndRange, Tree, StartKeyFun) ->
|
search_range(StartRange, EndRange, Tree, StartKeyFun) ->
|
||||||
|
@ -167,7 +149,9 @@ search_range(StartRange, EndRange, Tree, StartKeyFun) ->
|
||||||
{tree, _L, T} ->
|
{tree, _L, T} ->
|
||||||
treelookup_range_start(StartRange, EndRange, T, EndRangeFun);
|
treelookup_range_start(StartRange, EndRange, T, EndRangeFun);
|
||||||
{idxt, _L, T} ->
|
{idxt, _L, T} ->
|
||||||
idxtlookup_range_start(StartRange, EndRange, T, EndRangeFun)
|
idxtlookup_range_start(StartRange, EndRange, T, EndRangeFun);
|
||||||
|
{skpl, _L, SL} ->
|
||||||
|
skpllookup_to_range(StartRange, EndRange, SL, EndRangeFun)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
@ -340,6 +324,88 @@ idxtlookup_range_end(EndRange, {TLI, NK0, SL0}, Iter0, Output, EndRangeFun) ->
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
skpllookup_to_range(StartRange, EndRange, SkipList, EndRangeFun) ->
|
||||||
|
FoldFun =
|
||||||
|
fun({K, SL}, {PassedStart, PassedEnd, Acc}) ->
|
||||||
|
case {PassedStart, PassedEnd} of
|
||||||
|
{false, false} ->
|
||||||
|
case StartRange > K of
|
||||||
|
true ->
|
||||||
|
{PassedStart, PassedEnd, Acc};
|
||||||
|
false ->
|
||||||
|
case leveled_codec:endkey_passed(EndRange, K) of
|
||||||
|
true ->
|
||||||
|
{true, true, [SL|Acc]};
|
||||||
|
false ->
|
||||||
|
{true, false, [SL|Acc]}
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
{true, false} ->
|
||||||
|
case leveled_codec:endkey_passed(EndRange, K) of
|
||||||
|
true ->
|
||||||
|
{true, true, [SL|Acc]};
|
||||||
|
false ->
|
||||||
|
{true, false, [SL|Acc]}
|
||||||
|
end;
|
||||||
|
{true, true} ->
|
||||||
|
{PassedStart, PassedEnd, Acc}
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
Lv1List = lists:reverse(element(3,
|
||||||
|
lists:foldl(FoldFun,
|
||||||
|
{false, false, []},
|
||||||
|
SkipList))),
|
||||||
|
Lv0List = lists:reverse(element(3,
|
||||||
|
lists:foldl(FoldFun,
|
||||||
|
{false, false, []},
|
||||||
|
lists:append(Lv1List)))),
|
||||||
|
BeforeFun =
|
||||||
|
fun({K, _V}) ->
|
||||||
|
K < StartRange
|
||||||
|
end,
|
||||||
|
AfterFun =
|
||||||
|
fun({K, V}) ->
|
||||||
|
case leveled_codec:endkey_passed(EndRange, K) of
|
||||||
|
false ->
|
||||||
|
true;
|
||||||
|
true ->
|
||||||
|
EndRangeFun(EndRange, K, V)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
case length(Lv0List) of
|
||||||
|
0 ->
|
||||||
|
[];
|
||||||
|
1 ->
|
||||||
|
RHS = lists:dropwhile(BeforeFun, lists:nth(1, Lv0List)),
|
||||||
|
lists:takewhile(AfterFun, RHS);
|
||||||
|
2 ->
|
||||||
|
RHSofLHL = lists:dropwhile(BeforeFun, lists:nth(1, Lv0List)),
|
||||||
|
LHSofRHL = lists:takewhile(AfterFun, lists:last(Lv0List)),
|
||||||
|
RHSofLHL ++ LHSofRHL;
|
||||||
|
L ->
|
||||||
|
RHSofLHL = lists:dropwhile(BeforeFun, lists:nth(1, Lv0List)),
|
||||||
|
LHSofRHL = lists:takewhile(AfterFun, lists:last(Lv0List)),
|
||||||
|
MidLists = lists:sublist(Lv0List, 2, L - 2),
|
||||||
|
lists:append([RHSofLHL] ++ MidLists ++ [LHSofRHL])
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
skpl_getsublist(Key, SkipList) ->
|
||||||
|
FoldFun =
|
||||||
|
fun({Mark, SL}, Acc) ->
|
||||||
|
case {Acc, Mark} of
|
||||||
|
{none, Mark} when Mark >= Key ->
|
||||||
|
SL;
|
||||||
|
_ ->
|
||||||
|
Acc
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
SL1 = lists:foldl(FoldFun, none, SkipList),
|
||||||
|
lists:foldl(FoldFun, none, SL1).
|
||||||
|
|
||||||
|
|
||||||
%%%============================================================================
|
%%%============================================================================
|
||||||
%%% Balance tree implementation
|
%%% Balance tree implementation
|
||||||
%%%============================================================================
|
%%%============================================================================
|
||||||
|
@ -429,6 +495,9 @@ tree_search_test() ->
|
||||||
idxt_search_test() ->
|
idxt_search_test() ->
|
||||||
search_test_by_type(idxt).
|
search_test_by_type(idxt).
|
||||||
|
|
||||||
|
skpl_search_test() ->
|
||||||
|
search_test_by_type(skpl).
|
||||||
|
|
||||||
search_test_by_type(Type) ->
|
search_test_by_type(Type) ->
|
||||||
MapFun =
|
MapFun =
|
||||||
fun(N) ->
|
fun(N) ->
|
||||||
|
@ -517,13 +586,16 @@ tree_test_by_(Width, Type, N) ->
|
||||||
[timer:now_diff(os:timestamp(), SWaSRCH2)]).
|
[timer:now_diff(os:timestamp(), SWaSRCH2)]).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tree_matchrange_test() ->
|
tree_matchrange_test() ->
|
||||||
matchrange_test_by_type(tree).
|
matchrange_test_by_type(tree).
|
||||||
|
|
||||||
idxt_matchrange_test() ->
|
idxt_matchrange_test() ->
|
||||||
matchrange_test_by_type(idxt).
|
matchrange_test_by_type(idxt).
|
||||||
|
|
||||||
|
skpl_matchrange_test() ->
|
||||||
|
matchrange_test_by_type(skpl).
|
||||||
|
|
||||||
|
|
||||||
matchrange_test_by_type(Type) ->
|
matchrange_test_by_type(Type) ->
|
||||||
N = 4000,
|
N = 4000,
|
||||||
KL = lists:ukeysort(1, generate_randomkeys(1, N, 1, N div 5)),
|
KL = lists:ukeysort(1, generate_randomkeys(1, N, 1, N div 5)),
|
||||||
|
@ -543,6 +615,7 @@ matchrange_test_by_type(Type) ->
|
||||||
end,
|
end,
|
||||||
|
|
||||||
KL_Length = length(KL),
|
KL_Length = length(KL),
|
||||||
|
io:format("KL_Length ~w~n", [KL_Length]),
|
||||||
?assertMatch(KL_Length, LengthR(FirstKey, FinalKey, Tree0)),
|
?assertMatch(KL_Length, LengthR(FirstKey, FinalKey, Tree0)),
|
||||||
?assertMatch(KL_Length, LengthR(FirstKey, PenultimateKey, Tree0) + 1),
|
?assertMatch(KL_Length, LengthR(FirstKey, PenultimateKey, Tree0) + 1),
|
||||||
?assertMatch(1, LengthR(all, FirstKey, Tree0)),
|
?assertMatch(1, LengthR(all, FirstKey, Tree0)),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue