refactor(topic): move triples/1 func into emqx_trie module
This commit is contained in:
parent
1700a7a98a
commit
9a8859a44c
|
@ -6,7 +6,7 @@
|
|||
[{gproc, {git, "https://github.com/uwiger/gproc", {tag, "0.8.0"}}},
|
||||
{jiffy, {git, "https://github.com/emqx/jiffy", {tag, "1.0.4"}}},
|
||||
{cowboy, {git, "https://github.com/emqx/cowboy", {tag, "2.7.1"}}},
|
||||
{esockd, {git, "https://github.com/emqx/esockd", {tag, "5.6.2"}}},
|
||||
{esockd, {git, "https://github.com/emqx/esockd", {tag, "5.7.0"}}},
|
||||
{ekka, {git, "https://github.com/emqx/ekka", {tag, "0.7.3"}}},
|
||||
{gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "2.4.1"}}},
|
||||
{cuttlefish, {git, "https://github.com/emqx/cuttlefish", {tag, "v3.0.0"}}}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
, validate/1
|
||||
, validate/2
|
||||
, levels/1
|
||||
, triples/1
|
||||
, tokens/1
|
||||
, words/1
|
||||
, wildcard/1
|
||||
|
@ -36,14 +35,12 @@
|
|||
-export_type([ group/0
|
||||
, topic/0
|
||||
, word/0
|
||||
, triple/0
|
||||
]).
|
||||
|
||||
-type(group() :: binary()).
|
||||
-type(topic() :: binary()).
|
||||
-type(word() :: '' | '+' | '#' | binary()).
|
||||
-type(words() :: list(word())).
|
||||
-type(triple() :: {root | binary(), word(), binary()}).
|
||||
|
||||
-define(MAX_TOPIC_LEN, 4096).
|
||||
|
||||
|
@ -129,32 +126,15 @@ validate3(<<C/utf8, _Rest/binary>>) when C == $#; C == $+; C == 0 ->
|
|||
validate3(<<_/utf8, Rest/binary>>) ->
|
||||
validate3(Rest).
|
||||
|
||||
%% @doc Topic to triples.
|
||||
-spec(triples(topic()) -> list(triple())).
|
||||
triples(Topic) when is_binary(Topic) ->
|
||||
triples(words(Topic), root, []).
|
||||
|
||||
triples([], _Parent, Acc) ->
|
||||
lists:reverse(Acc);
|
||||
triples([W|Words], Parent, Acc) ->
|
||||
Node = join(Parent, W),
|
||||
triples(Words, Node, [{Parent, W, Node}|Acc]).
|
||||
|
||||
join(root, W) ->
|
||||
bin(W);
|
||||
join(Parent, W) ->
|
||||
<<(bin(Parent))/binary, $/, (bin(W))/binary>>.
|
||||
|
||||
%% @doc Prepend a topic prefix.
|
||||
%% Ensured to have only one / between prefix and suffix.
|
||||
prepend(root, W) -> bin(W);
|
||||
prepend(undefined, W) -> bin(W);
|
||||
prepend(<<>>, W) -> bin(W);
|
||||
prepend(Parent0, W) ->
|
||||
Parent = bin(Parent0),
|
||||
case binary:last(Parent) of
|
||||
$/ -> <<Parent/binary, (bin(W))/binary>>;
|
||||
_ -> join(Parent, W)
|
||||
_ -> <<Parent/binary, $/, (bin(W))/binary>>
|
||||
end.
|
||||
|
||||
bin('') -> <<>>;
|
||||
|
|
|
@ -33,6 +33,13 @@
|
|||
|
||||
-export([empty/0]).
|
||||
|
||||
-ifdef(TEST).
|
||||
-compile(export_all).
|
||||
-compile(nowarn_export_all).
|
||||
-endif.
|
||||
|
||||
-type(triple() :: {root | binary(), emqx_topic:word(), binary()}).
|
||||
|
||||
%% Mnesia tables
|
||||
-define(TRIE_TAB, emqx_trie).
|
||||
-define(TRIE_NODE_TAB, emqx_trie_node).
|
||||
|
@ -80,7 +87,7 @@ insert(Topic) when is_binary(Topic) ->
|
|||
write_trie_node(TrieNode#trie_node{topic = Topic});
|
||||
[] ->
|
||||
%% Add trie path
|
||||
ok = lists:foreach(fun add_path/1, emqx_topic:triples(Topic)),
|
||||
ok = lists:foreach(fun add_path/1, triples(Topic)),
|
||||
%% Add last node
|
||||
write_trie_node(#trie_node{node_id = Topic, topic = Topic})
|
||||
end.
|
||||
|
@ -102,7 +109,7 @@ delete(Topic) when is_binary(Topic) ->
|
|||
case mnesia:wread({?TRIE_NODE_TAB, Topic}) of
|
||||
[#trie_node{edge_count = 0}] ->
|
||||
ok = mnesia:delete({?TRIE_NODE_TAB, Topic}),
|
||||
delete_path(lists:reverse(emqx_topic:triples(Topic)));
|
||||
delete_path(lists:reverse(triples(Topic)));
|
||||
[TrieNode] ->
|
||||
write_trie_node(TrieNode#trie_node{topic = undefined});
|
||||
[] -> ok
|
||||
|
@ -117,6 +124,22 @@ empty() ->
|
|||
%% Internal functions
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% @doc Topic to triples.
|
||||
-spec(triples(emqx_topic:topic()) -> list(triple())).
|
||||
triples(Topic) when is_binary(Topic) ->
|
||||
triples(emqx_topic:words(Topic), root, []).
|
||||
|
||||
triples([], _Parent, Acc) ->
|
||||
lists:reverse(Acc);
|
||||
triples([W|Words], Parent, Acc) ->
|
||||
Node = join(Parent, W),
|
||||
triples(Words, Node, [{Parent, W, Node}|Acc]).
|
||||
|
||||
join(root, W) ->
|
||||
emqx_topic:join([W]);
|
||||
join(Parent, W) ->
|
||||
emqx_topic:join([Parent, W]).
|
||||
|
||||
%% @private
|
||||
%% @doc Add a path to the trie.
|
||||
add_path({Node, Word, Child}) ->
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
[ wildcard/1
|
||||
, match/2
|
||||
, validate/1
|
||||
, triples/1
|
||||
, prepend/2
|
||||
, join/1
|
||||
, words/1
|
||||
|
@ -143,18 +142,7 @@ t_sigle_level_validate(_) ->
|
|||
true = validate({filter, <<"sport/+/player1">>}),
|
||||
ok = ?catch_error(topic_invalid_char, validate({filter, <<"sport+">>})).
|
||||
|
||||
t_triples(_) ->
|
||||
Triples = [{root,<<"a">>,<<"a">>},
|
||||
{<<"a">>,<<"b">>,<<"a/b">>},
|
||||
{<<"a/b">>,<<"c">>,<<"a/b/c">>}],
|
||||
?assertEqual(Triples, triples(<<"a/b/c">>)).
|
||||
|
||||
t_triples_perf(_) ->
|
||||
Topic = <<"/abkc/19383/192939/akakdkkdkak/xxxyyuya/akakak">>,
|
||||
ok = bench('triples/1', fun emqx_topic:triples/1, [Topic]).
|
||||
|
||||
t_prepend(_) ->
|
||||
?assertEqual(<<"a/b/c">>, prepend(root, <<"a/b/c">>)),
|
||||
?assertEqual(<<"ab">>, prepend(undefined, <<"ab">>)),
|
||||
?assertEqual(<<"a/b">>, prepend(<<>>, <<"a/b">>)),
|
||||
?assertEqual(<<"x/a/b">>, prepend("x/", <<"a/b">>)),
|
||||
|
|
|
@ -141,6 +141,12 @@ t_delete3(_) ->
|
|||
end,
|
||||
?assertEqual({atomic, {[], []}}, trans(Fun)).
|
||||
|
||||
t_triples(_) ->
|
||||
Triples = [{root,<<"a">>,<<"a">>},
|
||||
{<<"a">>,<<"b">>,<<"a/b">>},
|
||||
{<<"a/b">>,<<"c">>,<<"a/b/c">>}],
|
||||
?assertEqual(Triples, emqx_trie:triples(<<"a/b/c">>)).
|
||||
|
||||
clear_tables() ->
|
||||
lists:foreach(fun mnesia:clear_table/1, ?TRIE_TABS).
|
||||
|
||||
|
|
Loading…
Reference in New Issue