Add cache population for non-yielding range fetches
More likely to require caching at lower levels.
This commit is contained in:
parent
779ccd9c2a
commit
989f23bca6
2 changed files with 83 additions and 57 deletions
|
@ -145,7 +145,8 @@
|
||||||
:: {next,
|
:: {next,
|
||||||
leveled_pmanifest:manifest_entry(),
|
leveled_pmanifest:manifest_entry(),
|
||||||
leveled_codec:ledger_key()|all}.
|
leveled_codec:ledger_key()|all}.
|
||||||
|
-type binaryslot_element()
|
||||||
|
:: {tuple(), tuple()}|{binary(), integer(), tuple(), tuple()}.
|
||||||
|
|
||||||
%% yield_blockquery is used to detemrine if the work necessary to process a
|
%% yield_blockquery is used to detemrine if the work necessary to process a
|
||||||
%% range query beyond the fetching the slot should be managed from within
|
%% range query beyond the fetching the slot should be managed from within
|
||||||
|
@ -375,8 +376,9 @@ sst_getfilteredrange(Pid, StartKey, EndKey, ScanWidth, SegList) ->
|
||||||
ScanWidth, SegList0},
|
ScanWidth, SegList0},
|
||||||
infinity) of
|
infinity) of
|
||||||
{yield, SlotsToFetchBinList, SlotsToPoint, PressMethod} ->
|
{yield, SlotsToFetchBinList, SlotsToPoint, PressMethod} ->
|
||||||
binaryslot_reader(SlotsToFetchBinList, PressMethod, SegList0)
|
{L, _BIC} =
|
||||||
++ SlotsToPoint;
|
binaryslot_reader(SlotsToFetchBinList, PressMethod, SegList0),
|
||||||
|
L ++ SlotsToPoint;
|
||||||
Reply ->
|
Reply ->
|
||||||
Reply
|
Reply
|
||||||
end.
|
end.
|
||||||
|
@ -405,7 +407,8 @@ sst_getfilteredslots(Pid, SlotList, SegList) ->
|
||||||
SegL0 = tune_seglist(SegList),
|
SegL0 = tune_seglist(SegList),
|
||||||
{SlotBins, PressMethod} =
|
{SlotBins, PressMethod} =
|
||||||
gen_fsm:sync_send_event(Pid, {get_slots, SlotList, SegL0}, infinity),
|
gen_fsm:sync_send_event(Pid, {get_slots, SlotList, SegL0}, infinity),
|
||||||
binaryslot_reader(SlotBins, PressMethod, SegL0).
|
{L, _BIC} = binaryslot_reader(SlotBins, PressMethod, SegL0),
|
||||||
|
L.
|
||||||
|
|
||||||
-spec sst_getmaxsequencenumber(pid()) -> integer().
|
-spec sst_getmaxsequencenumber(pid()) -> integer().
|
||||||
%% @doc
|
%% @doc
|
||||||
|
@ -588,11 +591,22 @@ reader({get_kvrange, StartKey, EndKey, ScanWidth, SegList}, _From, State) ->
|
||||||
reader,
|
reader,
|
||||||
State};
|
State};
|
||||||
false ->
|
false ->
|
||||||
{reply,
|
{L, BIC} =
|
||||||
binaryslot_reader(SlotsToFetchBinList, PressMethod, SegList)
|
binaryslot_reader(SlotsToFetchBinList, PressMethod, SegList),
|
||||||
++ SlotsToPoint,
|
FoldFun =
|
||||||
reader,
|
fun(CacheEntry, Cache) ->
|
||||||
State}
|
case CacheEntry of
|
||||||
|
{_ID, none} ->
|
||||||
|
Cache;
|
||||||
|
{ID, Header} ->
|
||||||
|
array:set(ID - 1, Header, Cache)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
BlockIdxC0 = lists:foldl(FoldFun, State#state.blockindex_cache, BIC),
|
||||||
|
{reply,
|
||||||
|
L ++ SlotsToPoint,
|
||||||
|
reader,
|
||||||
|
State#state{blockindex_cache = BlockIdxC0}}
|
||||||
end;
|
end;
|
||||||
reader({get_slots, SlotList, SegList}, _From, State) ->
|
reader({get_slots, SlotList, SegList}, _From, State) ->
|
||||||
SlotBins =
|
SlotBins =
|
||||||
|
@ -1346,15 +1360,16 @@ pointer_mapfun(Pointer) ->
|
||||||
%% Return a function that can pull individual slot binaries from a binary
|
%% Return a function that can pull individual slot binaries from a binary
|
||||||
%% covering multiple slots
|
%% covering multiple slots
|
||||||
binarysplit_mapfun(MultiSlotBin, StartPos) ->
|
binarysplit_mapfun(MultiSlotBin, StartPos) ->
|
||||||
fun({SP, L, _ID, SK, EK}) ->
|
fun({SP, L, ID, SK, EK}) ->
|
||||||
Start = SP - StartPos,
|
Start = SP - StartPos,
|
||||||
<<_Pre:Start/binary, SlotBin:L/binary, _Post/binary>> = MultiSlotBin,
|
<<_Pre:Start/binary, SlotBin:L/binary, _Post/binary>> = MultiSlotBin,
|
||||||
{SlotBin, SK, EK}
|
{SlotBin, ID, SK, EK}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
-spec read_slots(file:io_device(), list(),
|
-spec read_slots(file:io_device(), list(),
|
||||||
{false|list(), any()}, press_methods()) -> list().
|
{false|list(), any()}, press_methods())
|
||||||
|
-> list(binaryslot_element()).
|
||||||
%% @doc
|
%% @doc
|
||||||
%% The reading of sots will return a list of either 2-tuples containing
|
%% The reading of sots will return a list of either 2-tuples containing
|
||||||
%% {K, V} pairs - or 3-tuples containing {Binary, SK, EK}. The 3 tuples
|
%% {K, V} pairs - or 3-tuples containing {Binary, SK, EK}. The 3 tuples
|
||||||
|
@ -1416,28 +1431,33 @@ read_slots(Handle, SlotList, {SegList, BlockIndexCache}, PressMethod) ->
|
||||||
lists:foldl(BinMapFun, [], SlotList).
|
lists:foldl(BinMapFun, [], SlotList).
|
||||||
|
|
||||||
|
|
||||||
-spec binaryslot_reader(list({tuple(), tuple()}|{binary(), tuple(), tuple()}),
|
-spec binaryslot_reader(list(binaryslot_element()),
|
||||||
native|lz4,
|
native|lz4,
|
||||||
leveled_codec:segment_list())
|
leveled_codec:segment_list())
|
||||||
-> list({tuple(), tuple()}).
|
-> {list({tuple(), tuple()}),
|
||||||
|
list({integer(), binary()})}.
|
||||||
%% @doc
|
%% @doc
|
||||||
%% Read the binary slots converting them to {K, V} pairs if they were not
|
%% Read the binary slots converting them to {K, V} pairs if they were not
|
||||||
%% already {K, V} pairs
|
%% already {K, V} pairs
|
||||||
binaryslot_reader(SlotBinsToFetch, PressMethod, SegList) ->
|
binaryslot_reader(SlotBinsToFetch, PressMethod, SegList) ->
|
||||||
binaryslot_reader(SlotBinsToFetch, PressMethod, SegList, []).
|
binaryslot_reader(SlotBinsToFetch, PressMethod, SegList, [], []).
|
||||||
|
|
||||||
binaryslot_reader([], _PressMethod, _SegList, Acc) ->
|
binaryslot_reader([], _PressMethod, _SegList, Acc, BIAcc) ->
|
||||||
Acc;
|
{Acc, BIAcc};
|
||||||
binaryslot_reader([{SlotBin, SK, EK}|Tail], PressMethod, SegList, Acc) ->
|
binaryslot_reader([{SlotBin, ID, SK, EK}|Tail],
|
||||||
|
PressMethod, SegList, Acc, BIAcc) ->
|
||||||
|
{TrimmedL, BICache} =
|
||||||
|
binaryslot_trimmedlist(SlotBin,
|
||||||
|
SK, EK,
|
||||||
|
PressMethod,
|
||||||
|
SegList),
|
||||||
binaryslot_reader(Tail,
|
binaryslot_reader(Tail,
|
||||||
PressMethod,
|
PressMethod,
|
||||||
SegList,
|
SegList,
|
||||||
Acc ++ binaryslot_trimmedlist(SlotBin,
|
Acc ++ TrimmedL,
|
||||||
SK, EK,
|
[{ID, BICache}|BIAcc]);
|
||||||
PressMethod,
|
binaryslot_reader([{K, V}|Tail], PressMethod, SegList, Acc, BIAcc) ->
|
||||||
SegList));
|
binaryslot_reader(Tail, PressMethod, SegList, Acc ++ [{K, V}], BIAcc).
|
||||||
binaryslot_reader([{K, V}|Tail], PressMethod, SegList, Acc) ->
|
|
||||||
binaryslot_reader(Tail, PressMethod, SegList, Acc ++ [{K, V}]).
|
|
||||||
|
|
||||||
|
|
||||||
read_length_list(Handle, LengthList) ->
|
read_length_list(Handle, LengthList) ->
|
||||||
|
@ -1496,7 +1516,7 @@ binaryslot_tolist(FullBin, PressMethod) ->
|
||||||
|
|
||||||
|
|
||||||
binaryslot_trimmedlist(FullBin, all, all, PressMethod, false) ->
|
binaryslot_trimmedlist(FullBin, all, all, PressMethod, false) ->
|
||||||
binaryslot_tolist(FullBin, PressMethod);
|
{binaryslot_tolist(FullBin, PressMethod), none};
|
||||||
binaryslot_trimmedlist(FullBin, StartKey, EndKey, PressMethod, SegList) ->
|
binaryslot_trimmedlist(FullBin, StartKey, EndKey, PressMethod, SegList) ->
|
||||||
LTrimFun = fun({K, _V}) -> K < StartKey end,
|
LTrimFun = fun({K, _V}) -> K < StartKey end,
|
||||||
RTrimFun = fun({K, _V}) -> not leveled_codec:endkey_passed(EndKey, K) end,
|
RTrimFun = fun({K, _V}) -> not leveled_codec:endkey_passed(EndKey, K) end,
|
||||||
|
@ -1519,9 +1539,11 @@ binaryslot_trimmedlist(FullBin, StartKey, EndKey, PressMethod, SegList) ->
|
||||||
{LastKey, _LV} ->
|
{LastKey, _LV} ->
|
||||||
{_LDrop, RKeep} = lists:splitwith(LTrimFun,
|
{_LDrop, RKeep} = lists:splitwith(LTrimFun,
|
||||||
BlockList),
|
BlockList),
|
||||||
case leveled_codec:endkey_passed(EndKey, LastKey) of
|
case leveled_codec:endkey_passed(EndKey,
|
||||||
|
LastKey) of
|
||||||
true ->
|
true ->
|
||||||
{LKeep, _RDrop} = lists:splitwith(RTrimFun, RKeep),
|
{LKeep, _RDrop}
|
||||||
|
= lists:splitwith(RTrimFun, RKeep),
|
||||||
{Acc ++ LKeep, false};
|
{Acc ++ LKeep, false};
|
||||||
false ->
|
false ->
|
||||||
{Acc ++ RKeep, true}
|
{Acc ++ RKeep, true}
|
||||||
|
@ -1584,20 +1606,21 @@ binaryslot_trimmedlist(FullBin, StartKey, EndKey, PressMethod, SegList) ->
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
{Acc, _Continue} = lists:foldl(BlockCheckFun, {[], true}, BlocksToCheck),
|
{Acc, _Continue} = lists:foldl(BlockCheckFun, {[], true}, BlocksToCheck),
|
||||||
Acc;
|
{Acc, none};
|
||||||
{{Header, _Blocks}, SegList} ->
|
{{Header, _Blocks}, SegList} ->
|
||||||
BL = ?BLOCK_LENGTHS_LENGTH,
|
BL = ?BLOCK_LENGTHS_LENGTH,
|
||||||
<<BlockLengths:BL/binary, BlockIdx/binary>> = Header,
|
<<BlockLengths:BL/binary, BlockIdx/binary>> = Header,
|
||||||
PosList = find_pos(BlockIdx, SegList, [], 0),
|
PosList = find_pos(BlockIdx, SegList, [], 0),
|
||||||
check_blocks(PosList,
|
KVL = check_blocks(PosList,
|
||||||
FullBin,
|
FullBin,
|
||||||
BlockLengths,
|
BlockLengths,
|
||||||
byte_size(BlockIdx),
|
byte_size(BlockIdx),
|
||||||
false,
|
false,
|
||||||
PressMethod,
|
PressMethod,
|
||||||
[]);
|
[]),
|
||||||
|
{KVL, Header};
|
||||||
{crc_wonky, _} ->
|
{crc_wonky, _} ->
|
||||||
[]
|
{[], none}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
@ -2293,8 +2316,9 @@ indexed_list_allindexkeys_test() ->
|
||||||
% "Indexed list flattened in ~w microseconds ~n",
|
% "Indexed list flattened in ~w microseconds ~n",
|
||||||
% [timer:now_diff(os:timestamp(), SW)]),
|
% [timer:now_diff(os:timestamp(), SW)]),
|
||||||
?assertMatch(Keys, BinToList),
|
?assertMatch(Keys, BinToList),
|
||||||
?assertMatch(Keys,
|
?assertMatch({Keys, none}, binaryslot_trimmedlist(FullBin,
|
||||||
binaryslot_trimmedlist(FullBin, all, all, native, false)).
|
all, all,
|
||||||
|
native, false)).
|
||||||
|
|
||||||
indexed_list_allindexkeys_nolookup_test() ->
|
indexed_list_allindexkeys_nolookup_test() ->
|
||||||
Keys = lists:sublist(lists:ukeysort(1, generate_indexkeys(1000)),
|
Keys = lists:sublist(lists:ukeysort(1, generate_indexkeys(1000)),
|
||||||
|
@ -2308,8 +2332,9 @@ indexed_list_allindexkeys_nolookup_test() ->
|
||||||
% "Indexed list flattened in ~w microseconds ~n",
|
% "Indexed list flattened in ~w microseconds ~n",
|
||||||
% [timer:now_diff(os:timestamp(), SW)]),
|
% [timer:now_diff(os:timestamp(), SW)]),
|
||||||
?assertMatch(Keys, BinToList),
|
?assertMatch(Keys, BinToList),
|
||||||
?assertMatch(Keys,
|
?assertMatch({Keys, none}, binaryslot_trimmedlist(FullBin,
|
||||||
binaryslot_trimmedlist(FullBin, all, all, native, false)).
|
all, all,
|
||||||
|
native, false)).
|
||||||
|
|
||||||
indexed_list_allindexkeys_trimmed_test() ->
|
indexed_list_allindexkeys_trimmed_test() ->
|
||||||
Keys = lists:sublist(lists:ukeysort(1, generate_indexkeys(150)),
|
Keys = lists:sublist(lists:ukeysort(1, generate_indexkeys(150)),
|
||||||
|
@ -2318,36 +2343,36 @@ indexed_list_allindexkeys_trimmed_test() ->
|
||||||
generate_binary_slot(lookup, Keys, native, no_timing),
|
generate_binary_slot(lookup, Keys, native, no_timing),
|
||||||
EmptySlotSize = ?LOOK_SLOTSIZE - 1,
|
EmptySlotSize = ?LOOK_SLOTSIZE - 1,
|
||||||
?assertMatch(<<_BL:20/binary, EmptySlotSize:8/integer>>, Header),
|
?assertMatch(<<_BL:20/binary, EmptySlotSize:8/integer>>, Header),
|
||||||
?assertMatch(Keys, binaryslot_trimmedlist(FullBin,
|
?assertMatch({Keys, none}, binaryslot_trimmedlist(FullBin,
|
||||||
{i,
|
{i,
|
||||||
"Bucket",
|
"Bucket",
|
||||||
{"t1_int", 0},
|
{"t1_int", 0},
|
||||||
null},
|
null},
|
||||||
{i,
|
{i,
|
||||||
"Bucket",
|
"Bucket",
|
||||||
{"t1_int", 99999},
|
{"t1_int", 99999},
|
||||||
null},
|
null},
|
||||||
native,
|
native,
|
||||||
false)),
|
false)),
|
||||||
|
|
||||||
{SK1, _} = lists:nth(10, Keys),
|
{SK1, _} = lists:nth(10, Keys),
|
||||||
{EK1, _} = lists:nth(100, Keys),
|
{EK1, _} = lists:nth(100, Keys),
|
||||||
R1 = lists:sublist(Keys, 10, 91),
|
R1 = lists:sublist(Keys, 10, 91),
|
||||||
O1 = binaryslot_trimmedlist(FullBin, SK1, EK1, native, false),
|
{O1, none} = binaryslot_trimmedlist(FullBin, SK1, EK1, native, false),
|
||||||
?assertMatch(91, length(O1)),
|
?assertMatch(91, length(O1)),
|
||||||
?assertMatch(R1, O1),
|
?assertMatch(R1, O1),
|
||||||
|
|
||||||
{SK2, _} = lists:nth(10, Keys),
|
{SK2, _} = lists:nth(10, Keys),
|
||||||
{EK2, _} = lists:nth(20, Keys),
|
{EK2, _} = lists:nth(20, Keys),
|
||||||
R2 = lists:sublist(Keys, 10, 11),
|
R2 = lists:sublist(Keys, 10, 11),
|
||||||
O2 = binaryslot_trimmedlist(FullBin, SK2, EK2, native, false),
|
{O2, none} = binaryslot_trimmedlist(FullBin, SK2, EK2, native, false),
|
||||||
?assertMatch(11, length(O2)),
|
?assertMatch(11, length(O2)),
|
||||||
?assertMatch(R2, O2),
|
?assertMatch(R2, O2),
|
||||||
|
|
||||||
{SK3, _} = lists:nth(?LOOK_SLOTSIZE - 1, Keys),
|
{SK3, _} = lists:nth(?LOOK_SLOTSIZE - 1, Keys),
|
||||||
{EK3, _} = lists:nth(?LOOK_SLOTSIZE, Keys),
|
{EK3, _} = lists:nth(?LOOK_SLOTSIZE, Keys),
|
||||||
R3 = lists:sublist(Keys, ?LOOK_SLOTSIZE - 1, 2),
|
R3 = lists:sublist(Keys, ?LOOK_SLOTSIZE - 1, 2),
|
||||||
O3 = binaryslot_trimmedlist(FullBin, SK3, EK3, native, false),
|
{O3, none} = binaryslot_trimmedlist(FullBin, SK3, EK3, native, false),
|
||||||
?assertMatch(2, length(O3)),
|
?assertMatch(2, length(O3)),
|
||||||
?assertMatch(R3, O3).
|
?assertMatch(R3, O3).
|
||||||
|
|
||||||
|
@ -2408,7 +2433,7 @@ indexed_list_mixedkeys_bitflip_test() ->
|
||||||
|
|
||||||
{SK1, _} = lists:nth(10, Keys),
|
{SK1, _} = lists:nth(10, Keys),
|
||||||
{EK1, _} = lists:nth(20, Keys),
|
{EK1, _} = lists:nth(20, Keys),
|
||||||
O1 = binaryslot_trimmedlist(SlotBin3, SK1, EK1, native, false),
|
{O1, none} = binaryslot_trimmedlist(SlotBin3, SK1, EK1, native, false),
|
||||||
?assertMatch([], O1),
|
?assertMatch([], O1),
|
||||||
|
|
||||||
SlotBin4 = flip_byte(SlotBin, 0, 20),
|
SlotBin4 = flip_byte(SlotBin, 0, 20),
|
||||||
|
@ -2420,8 +2445,8 @@ indexed_list_mixedkeys_bitflip_test() ->
|
||||||
ToList5 = binaryslot_tolist(SlotBin5, native),
|
ToList5 = binaryslot_tolist(SlotBin5, native),
|
||||||
?assertMatch([], ToList4),
|
?assertMatch([], ToList4),
|
||||||
?assertMatch([], ToList5),
|
?assertMatch([], ToList5),
|
||||||
O4 = binaryslot_trimmedlist(SlotBin4, SK1, EK1, native, false),
|
{O4, none} = binaryslot_trimmedlist(SlotBin4, SK1, EK1, native, false),
|
||||||
O5 = binaryslot_trimmedlist(SlotBin4, SK1, EK1, native, false),
|
{O5, none} = binaryslot_trimmedlist(SlotBin4, SK1, EK1, native, false),
|
||||||
?assertMatch([], O4),
|
?assertMatch([], O4),
|
||||||
?assertMatch([], O5).
|
?assertMatch([], O5).
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,7 @@ crossbucket_aae(_Config) ->
|
||||||
ok = leveled_bookie:book_close(Bookie2),
|
ok = leveled_bookie:book_close(Bookie2),
|
||||||
{ok, Bookie2A} = leveled_bookie:book_start(StartOpts2),
|
{ok, Bookie2A} = leveled_bookie:book_start(StartOpts2),
|
||||||
|
|
||||||
|
test_segfilter_query(Bookie2A, CLs),
|
||||||
test_segfilter_query(Bookie2A, CLs),
|
test_segfilter_query(Bookie2A, CLs),
|
||||||
|
|
||||||
test_singledelta_stores(Bookie2A, Bookie3, small, {B1, K1}),
|
test_singledelta_stores(Bookie2A, Bookie3, small, {B1, K1}),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue