perf(topicidx): implement fast-forwarding prefixes
This should give less `ets:next/2` calls in general and much less when index has relatively small number of long non-wildcard topics.
This commit is contained in:
parent
0c7bdbdab4
commit
fd0986071c
|
@ -73,7 +73,13 @@ match(K, Prefix, Words, RPrefix, Tab) ->
|
|||
match_rest(Matched, Words, RPrefix, Tab)
|
||||
end.
|
||||
|
||||
match_rest(false, [W | Rest], RPrefix, Tab) ->
|
||||
match_rest([W1 | [W2 | _] = SLast], [W1 | [W2 | _] = Rest], RPrefix, Tab) ->
|
||||
% NOTE
|
||||
% 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
|
||||
% more complex match patterns.
|
||||
match_rest(SLast, Rest, [W1 | RPrefix], Tab);
|
||||
match_rest(SLast, [W | Rest], RPrefix, Tab) when is_list(SLast) ->
|
||||
match(Rest, [W | RPrefix], Tab);
|
||||
match_rest(plus, [W | Rest], RPrefix, Tab) ->
|
||||
case match(Rest, ['+' | RPrefix], Tab) of
|
||||
|
@ -115,7 +121,13 @@ matches(K, Prefix, Words, RPrefix, Acc, Tab) ->
|
|||
matches_rest(Matched, Words, RPrefix, Acc, Tab)
|
||||
end.
|
||||
|
||||
matches_rest(false, [W | Rest], RPrefix, Acc, Tab) ->
|
||||
matches_rest([W1 | [W2 | _] = SLast], [W1 | [W2 | _] = Rest], RPrefix, Acc, Tab) ->
|
||||
% NOTE
|
||||
% 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
|
||||
% more complex match patterns.
|
||||
matches_rest(SLast, Rest, [W1 | RPrefix], Acc, Tab);
|
||||
matches_rest(SLast, [W | Rest], RPrefix, Acc, Tab) when is_list(SLast) ->
|
||||
matches(Rest, [W | RPrefix], Acc, Tab);
|
||||
matches_rest(plus, [W | Rest], RPrefix, Acc, Tab) ->
|
||||
NAcc = matches(Rest, ['+' | RPrefix], Acc, Tab),
|
||||
|
@ -143,8 +155,8 @@ match_filter([], ['#'], _Suffix) ->
|
|||
true;
|
||||
match_filter([], ['+' | _], _Suffix) ->
|
||||
plus;
|
||||
match_filter([], [_H | _], _Suffix) ->
|
||||
false;
|
||||
match_filter([], [_H | _] = Rest, _Suffix) ->
|
||||
Rest;
|
||||
match_filter([H | T1], [H | T2], Suffix) ->
|
||||
match_filter(T1, T2, Suffix);
|
||||
match_filter([H1 | _], [H2 | _], _Suffix) when H2 > H1 ->
|
||||
|
|
|
@ -133,6 +133,16 @@ t_match7(_) ->
|
|||
emqx_topic_index:insert(W, t_match7, <<>>, Tab),
|
||||
?assertEqual(W, topic(match(T, Tab))).
|
||||
|
||||
t_match_fast_forward(_) ->
|
||||
Tab = emqx_topic_index:new(),
|
||||
emqx_topic_index:insert(<<"a/b/1/2/3/4/5/6/7/8/9/#">>, id1, <<>>, Tab),
|
||||
emqx_topic_index:insert(<<"z/y/x/+/+">>, id2, <<>>, Tab),
|
||||
emqx_topic_index:insert(<<"a/b/c/+">>, id3, <<>>, Tab),
|
||||
% dbg:tracer(),
|
||||
% dbg:p(all, c),
|
||||
% dbg:tpl({ets, next, '_'}, x),
|
||||
?assertEqual([id1], [id(M) || M <- matches(<<"a/b/1/2/3/4/5/6/7/8/9/0">>, Tab)]).
|
||||
|
||||
t_match_unique(_) ->
|
||||
Tab = emqx_topic_index:new(),
|
||||
emqx_topic_index:insert(<<"a/b/c">>, t_match_id1, <<>>, Tab),
|
||||
|
|
Loading…
Reference in New Issue