fix(ds): LTS trie handles empty topic levels

This commit is contained in:
ieQu1 2023-11-23 20:29:13 +01:00
parent a158f25a40
commit 449bafc27e
1 changed files with 12 additions and 6 deletions

View File

@ -119,7 +119,7 @@ trie_restore(Options, Dump) ->
Trie. Trie.
%% @doc Lookup the topic key. Create a new one, if not found. %% @doc Lookup the topic key. Create a new one, if not found.
-spec topic_key(trie(), threshold_fun(), [binary()]) -> msg_storage_key(). -spec topic_key(trie(), threshold_fun(), [binary() | '']) -> msg_storage_key().
topic_key(Trie, ThresholdFun, Tokens) -> topic_key(Trie, ThresholdFun, Tokens) ->
do_topic_key(Trie, ThresholdFun, 0, ?PREFIX, Tokens, []). do_topic_key(Trie, ThresholdFun, 0, ?PREFIX, Tokens, []).
@ -363,12 +363,12 @@ emanating(#trie{trie = Tab}, State, ?EOT) ->
[#trans{next = Next}] -> [{?EOT, Next}]; [#trans{next = Next}] -> [{?EOT, Next}];
[] -> [] [] -> []
end; end;
emanating(#trie{trie = Tab}, State, Bin) when is_binary(Bin) -> emanating(#trie{trie = Tab}, State, Token) when is_binary(Token); Token =:= '' ->
[ [
{Edge, Next} {Edge, Next}
|| #trans{key = {_, Edge}, next = Next} <- || #trans{key = {_, Edge}, next = Next} <-
ets:lookup(Tab, {State, ?PLUS}) ++ ets:lookup(Tab, {State, ?PLUS}) ++
ets:lookup(Tab, {State, Bin}) ets:lookup(Tab, {State, Token})
]. ].
%%================================================================================ %%================================================================================
@ -533,6 +533,7 @@ topic_match_test() ->
{S11, []} = test_key(T, ThresholdFun, [1, 1]), {S11, []} = test_key(T, ThresholdFun, [1, 1]),
{S12, []} = test_key(T, ThresholdFun, [1, 2]), {S12, []} = test_key(T, ThresholdFun, [1, 2]),
{S111, []} = test_key(T, ThresholdFun, [1, 1, 1]), {S111, []} = test_key(T, ThresholdFun, [1, 1, 1]),
{S11e, []} = test_key(T, ThresholdFun, [1, 1, '']),
%% Match concrete topics: %% Match concrete topics:
assert_match_topics(T, [1], [{S1, []}]), assert_match_topics(T, [1], [{S1, []}]),
assert_match_topics(T, [1, 1], [{S11, []}]), assert_match_topics(T, [1, 1], [{S11, []}]),
@ -540,14 +541,16 @@ topic_match_test() ->
%% Match topics with +: %% Match topics with +:
assert_match_topics(T, [1, '+'], [{S11, []}, {S12, []}]), assert_match_topics(T, [1, '+'], [{S11, []}, {S12, []}]),
assert_match_topics(T, [1, '+', 1], [{S111, []}]), assert_match_topics(T, [1, '+', 1], [{S111, []}]),
assert_match_topics(T, [1, '+', ''], [{S11e, []}]),
%% Match topics with #: %% Match topics with #:
assert_match_topics(T, [1, '#'], assert_match_topics(T, [1, '#'],
[{S1, []}, [{S1, []},
{S11, []}, {S12, []}, {S11, []}, {S12, []},
{S111, []}]), {S111, []}, {S11e, []}]),
assert_match_topics(T, [1, 1, '#'], assert_match_topics(T, [1, 1, '#'],
[{S11, []}, [{S11, []},
{S111, []}]), {S111, []},
{S11e, []}]),
%% Now add learned wildcards: %% Now add learned wildcards:
{S21, []} = test_key(T, ThresholdFun, [2, 1]), {S21, []} = test_key(T, ThresholdFun, [2, 1]),
{S22, []} = test_key(T, ThresholdFun, [2, 2]), {S22, []} = test_key(T, ThresholdFun, [2, 2]),
@ -587,7 +590,10 @@ assert_match_topics(Trie, Filter0, Expected) ->
%% erlfmt-ignore %% erlfmt-ignore
test_key(Trie, Threshold, Topic0) -> test_key(Trie, Threshold, Topic0) ->
Topic = [integer_to_binary(I) || I <- Topic0], Topic = lists:map(fun('') -> '';
(I) -> integer_to_binary(I)
end,
Topic0),
Ret = topic_key(Trie, Threshold, Topic), Ret = topic_key(Trie, Threshold, Topic),
%% Test idempotency: %% Test idempotency:
Ret1 = topic_key(Trie, Threshold, Topic), Ret1 = topic_key(Trie, Threshold, Topic),