Merge pull request #12092 from keynslug/fix/EMQX-11520/ds-empty-levels
fix(ds): pass topics to emqx_topic:words/1 before feeding LTS tree
This commit is contained in:
commit
6a1db5db4a
|
@ -91,13 +91,11 @@ match([H | T1], [H | T2]) ->
|
||||||
match(T1, T2);
|
match(T1, T2);
|
||||||
match([_H | T1], ['+' | T2]) ->
|
match([_H | T1], ['+' | T2]) ->
|
||||||
match(T1, T2);
|
match(T1, T2);
|
||||||
|
match([<<>> | T1], ['' | T2]) ->
|
||||||
|
match(T1, T2);
|
||||||
match(_, ['#']) ->
|
match(_, ['#']) ->
|
||||||
true;
|
true;
|
||||||
match([_H1 | _], [_H2 | _]) ->
|
match(_, _) ->
|
||||||
false;
|
|
||||||
match([_H1 | _], []) ->
|
|
||||||
false;
|
|
||||||
match([], [_H | _T2]) ->
|
|
||||||
false.
|
false.
|
||||||
|
|
||||||
-spec match_share(Name, Filter) -> boolean() when
|
-spec match_share(Name, Filter) -> boolean() when
|
||||||
|
|
|
@ -282,6 +282,34 @@ t_publish_as_persistent(_Config) ->
|
||||||
emqtt:stop(Pub)
|
emqtt:stop(Pub)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
t_publish_empty_topic_levels(_Config) ->
|
||||||
|
Sub = connect(<<?MODULE_STRING "1">>, true, 30),
|
||||||
|
Pub = connect(<<?MODULE_STRING "2">>, true, 30),
|
||||||
|
try
|
||||||
|
{ok, _, [?RC_GRANTED_QOS_1]} = emqtt:subscribe(Sub, <<"t//+//#">>, qos1),
|
||||||
|
Messages = [
|
||||||
|
{<<"t//1">>, <<"1">>},
|
||||||
|
{<<"t//1/">>, <<"2">>},
|
||||||
|
{<<"t//2//">>, <<"3">>},
|
||||||
|
{<<"t//2//foo">>, <<"4">>},
|
||||||
|
{<<"t//2/foo">>, <<"5">>},
|
||||||
|
{<<"t/3/bar">>, <<"6">>}
|
||||||
|
],
|
||||||
|
[emqtt:publish(Pub, Topic, Payload, ?QOS_1) || {Topic, Payload} <- Messages],
|
||||||
|
Received = receive_messages(length(Messages), 1_500),
|
||||||
|
?assertMatch(
|
||||||
|
[
|
||||||
|
#{topic := <<"t//1/">>, payload := <<"2">>},
|
||||||
|
#{topic := <<"t//2//">>, payload := <<"3">>},
|
||||||
|
#{topic := <<"t//2//foo">>, payload := <<"4">>}
|
||||||
|
],
|
||||||
|
lists:sort(emqx_utils_maps:key_comparer(payload), Received)
|
||||||
|
)
|
||||||
|
after
|
||||||
|
emqtt:stop(Sub),
|
||||||
|
emqtt:stop(Pub)
|
||||||
|
end.
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
connect(ClientId, CleanStart, EI) ->
|
connect(ClientId, CleanStart, EI) ->
|
||||||
|
@ -322,15 +350,18 @@ consume(It) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
receive_messages(Count) ->
|
receive_messages(Count) ->
|
||||||
lists:reverse(receive_messages(Count, [])).
|
receive_messages(Count, 5_000).
|
||||||
|
|
||||||
receive_messages(0, Msgs) ->
|
receive_messages(Count, Timeout) ->
|
||||||
|
lists:reverse(receive_messages(Count, [], Timeout)).
|
||||||
|
|
||||||
|
receive_messages(0, Msgs, _Timeout) ->
|
||||||
Msgs;
|
Msgs;
|
||||||
receive_messages(Count, Msgs) ->
|
receive_messages(Count, Msgs, Timeout) ->
|
||||||
receive
|
receive
|
||||||
{publish, Msg} ->
|
{publish, Msg} ->
|
||||||
receive_messages(Count - 1, [Msg | Msgs])
|
receive_messages(Count - 1, [Msg | Msgs], Timeout)
|
||||||
after 5_000 ->
|
after Timeout ->
|
||||||
Msgs
|
Msgs
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,12 @@ t_sys_match(_) ->
|
||||||
true = match(<<"a/b/$c">>, <<"a/b/#">>),
|
true = match(<<"a/b/$c">>, <<"a/b/#">>),
|
||||||
true = match(<<"a/b/$c">>, <<"a/#">>).
|
true = match(<<"a/b/$c">>, <<"a/#">>).
|
||||||
|
|
||||||
|
t_match_tokens(_) ->
|
||||||
|
true = match(emqx_topic:tokens(<<"a/b/c">>), words(<<"a/+/c">>)),
|
||||||
|
true = match(emqx_topic:tokens(<<"a//c">>), words(<<"a/+/c">>)),
|
||||||
|
false = match(emqx_topic:tokens(<<"a//c/">>), words(<<"a/+/c">>)),
|
||||||
|
true = match(emqx_topic:tokens(<<"a//c/">>), words(<<"a/+/c/#">>)).
|
||||||
|
|
||||||
t_match_perf(_) ->
|
t_match_perf(_) ->
|
||||||
true = match(<<"a/b/ccc">>, <<"a/#">>),
|
true = match(<<"a/b/ccc">>, <<"a/#">>),
|
||||||
Name = <<"/abkc/19383/192939/akakdkkdkak/xxxyyuya/akakak">>,
|
Name = <<"/abkc/19383/192939/akakdkkdkak/xxxyyuya/akakak">>,
|
||||||
|
|
|
@ -368,7 +368,7 @@ check_message(
|
||||||
#{?tag := ?IT, ?start_time := StartTime, ?topic_filter := TopicFilter},
|
#{?tag := ?IT, ?start_time := StartTime, ?topic_filter := TopicFilter},
|
||||||
#message{timestamp = Timestamp, topic = Topic}
|
#message{timestamp = Timestamp, topic = Topic}
|
||||||
) when Timestamp >= StartTime ->
|
) when Timestamp >= StartTime ->
|
||||||
emqx_topic:match(emqx_topic:words(Topic), TopicFilter);
|
emqx_topic:match(emqx_topic:tokens(Topic), TopicFilter);
|
||||||
check_message(_Cutoff, _It, _Msg) ->
|
check_message(_Cutoff, _It, _Msg) ->
|
||||||
false.
|
false.
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ format_key(KeyMapper, Key) ->
|
||||||
|
|
||||||
-spec make_key(s(), emqx_types:message()) -> {binary(), [binary()]}.
|
-spec make_key(s(), emqx_types:message()) -> {binary(), [binary()]}.
|
||||||
make_key(#s{keymappers = KeyMappers, trie = Trie}, #message{timestamp = Timestamp, topic = TopicBin}) ->
|
make_key(#s{keymappers = KeyMappers, trie = Trie}, #message{timestamp = Timestamp, topic = TopicBin}) ->
|
||||||
Tokens = emqx_topic:tokens(TopicBin),
|
Tokens = emqx_topic:words(TopicBin),
|
||||||
{TopicIndex, Varying} = emqx_ds_lts:topic_key(Trie, fun threshold_fun/1, Tokens),
|
{TopicIndex, Varying} = emqx_ds_lts:topic_key(Trie, fun threshold_fun/1, Tokens),
|
||||||
VaryingHashes = [hash_topic_level(I) || I <- Varying],
|
VaryingHashes = [hash_topic_level(I) || I <- Varying],
|
||||||
KeyMapper = array:get(length(Varying), KeyMappers),
|
KeyMapper = array:get(length(Varying), KeyMappers),
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
if_only_to_toggle_enable/2,
|
if_only_to_toggle_enable/2,
|
||||||
update_if_present/3,
|
update_if_present/3,
|
||||||
put_if/4,
|
put_if/4,
|
||||||
rename/3
|
rename/3,
|
||||||
|
key_comparer/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export_type([config_key/0, config_key_path/0]).
|
-export_type([config_key/0, config_key_path/0]).
|
||||||
|
@ -318,3 +319,16 @@ rename(OldKey, NewKey, Map) ->
|
||||||
error ->
|
error ->
|
||||||
Map
|
Map
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec key_comparer(K) -> fun((M, M) -> boolean()) when M :: #{K => _V}.
|
||||||
|
key_comparer(K) ->
|
||||||
|
fun
|
||||||
|
(#{K := V1}, #{K := V2}) ->
|
||||||
|
V1 < V2;
|
||||||
|
(#{K := _}, _) ->
|
||||||
|
false;
|
||||||
|
(_, #{K := _}) ->
|
||||||
|
true;
|
||||||
|
(M1, M2) ->
|
||||||
|
M1 < M2
|
||||||
|
end.
|
||||||
|
|
|
@ -110,3 +110,22 @@ best_effort_recursive_sum_test_() ->
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
].
|
].
|
||||||
|
|
||||||
|
key_comparer_test() ->
|
||||||
|
Comp = emqx_utils_maps:key_comparer(foo),
|
||||||
|
?assertEqual(
|
||||||
|
[
|
||||||
|
#{},
|
||||||
|
#{baz => 42},
|
||||||
|
#{foo => 1},
|
||||||
|
#{foo => 42},
|
||||||
|
#{foo => bar, baz => 42}
|
||||||
|
],
|
||||||
|
lists:sort(Comp, [
|
||||||
|
#{foo => 42},
|
||||||
|
#{baz => 42},
|
||||||
|
#{foo => bar, baz => 42},
|
||||||
|
#{foo => 1},
|
||||||
|
#{}
|
||||||
|
])
|
||||||
|
).
|
||||||
|
|
Loading…
Reference in New Issue