perf(topicidx): preserve next key on the stack to reuse later
This should further optimize the number of `ets:next/2` calls required for a single match query.
This commit is contained in:
parent
e39bbf4c49
commit
5d79823891
|
@ -127,6 +127,17 @@ matches(Words, RPrefix, Acc, Tab) ->
|
||||||
Prefix = lists:reverse(RPrefix),
|
Prefix = lists:reverse(RPrefix),
|
||||||
matches(ets:next(Tab, {Prefix, {}}), Prefix, Words, RPrefix, Acc, Tab).
|
matches(ets:next(Tab, {Prefix, {}}), Prefix, Words, RPrefix, Acc, Tab).
|
||||||
|
|
||||||
|
matches(Words, RPrefix, K = {Filter, _}, Acc, Tab) ->
|
||||||
|
Prefix = lists:reverse(RPrefix),
|
||||||
|
case Prefix > Filter of
|
||||||
|
true ->
|
||||||
|
% NOTE: Prefix already greater than the last key seen, need to `ets:next/2`.
|
||||||
|
matches(ets:next(Tab, {Prefix, {}}), Prefix, Words, RPrefix, Acc, Tab);
|
||||||
|
false ->
|
||||||
|
% NOTE: Prefix is still less than or equal to the last key seen, reuse it.
|
||||||
|
matches(K, Prefix, Words, RPrefix, Acc, Tab)
|
||||||
|
end.
|
||||||
|
|
||||||
matches(K, Prefix, Words, RPrefix, Acc, Tab) ->
|
matches(K, Prefix, Words, RPrefix, Acc, Tab) ->
|
||||||
case match_next(Prefix, K, Words) of
|
case match_next(Prefix, K, Words) of
|
||||||
true ->
|
true ->
|
||||||
|
@ -136,26 +147,27 @@ matches(K, Prefix, Words, RPrefix, Acc, Tab) ->
|
||||||
stop ->
|
stop ->
|
||||||
Acc;
|
Acc;
|
||||||
Matched ->
|
Matched ->
|
||||||
matches_rest(Matched, Words, RPrefix, Acc, Tab)
|
% NOTE: Prserve next key on the stack to save on `ets:next/2` calls.
|
||||||
|
matches_rest(Matched, Words, RPrefix, K, Acc, Tab)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
matches_rest([W1 | [W2 | _] = SLast], [W1 | [W2 | _] = Rest], RPrefix, Acc, Tab) ->
|
matches_rest([W1 | [W2 | _] = SLast], [W1 | [W2 | _] = Rest], RPrefix, K, Acc, Tab) ->
|
||||||
% NOTE
|
% NOTE
|
||||||
% Fast-forward through identical words in the topic and the last key suffixes.
|
% Fast-forward through identical words in the topic and the last key suffixes.
|
||||||
% This should save us a few redundant `ets:next` calls at the cost of slightly
|
% This should save us a few redundant `ets:next` calls at the cost of slightly
|
||||||
% more complex match patterns.
|
% more complex match patterns.
|
||||||
matches_rest(SLast, Rest, [W1 | RPrefix], Acc, Tab);
|
matches_rest(SLast, Rest, [W1 | RPrefix], K, Acc, Tab);
|
||||||
matches_rest(SLast, [W | Rest], RPrefix, Acc, Tab) when is_list(SLast) ->
|
matches_rest(SLast, [W | Rest], RPrefix, K, Acc, Tab) when is_list(SLast) ->
|
||||||
matches(Rest, [W | RPrefix], Acc, Tab);
|
matches(Rest, [W | RPrefix], K, Acc, Tab);
|
||||||
matches_rest(plus, [W | Rest], RPrefix, Acc, Tab) ->
|
matches_rest(plus, [W | Rest], RPrefix, K, Acc, Tab) ->
|
||||||
% NOTE
|
% NOTE
|
||||||
% There's '+' in the key suffix, meaning we should accumulate all matches from
|
% There's '+' in the key suffix, meaning we should accumulate all matches from
|
||||||
% each of 2 branches:
|
% each of 2 branches:
|
||||||
% 1. Match the rest of the topic as if there was '+' in the current position.
|
% 1. Match the rest of the topic as if there was '+' in the current position.
|
||||||
% 2. Skip this key and try to match the topic as it is.
|
% 2. Skip this key and try to match the topic as it is.
|
||||||
NAcc = matches(Rest, ['+' | RPrefix], Acc, Tab),
|
NAcc = matches(Rest, ['+' | RPrefix], K, Acc, Tab),
|
||||||
matches(Rest, [W | RPrefix], NAcc, Tab);
|
matches(Rest, [W | RPrefix], K, NAcc, Tab);
|
||||||
matches_rest(_, [], _RPrefix, Acc, _Tab) ->
|
matches_rest(_, [], _RPrefix, _K, Acc, _Tab) ->
|
||||||
Acc.
|
Acc.
|
||||||
|
|
||||||
match_add(K = {_Filter, ID}, Acc = #{}) ->
|
match_add(K = {_Filter, ID}, Acc = #{}) ->
|
||||||
|
|
Loading…
Reference in New Issue