refactor(topic): move triples/1 func into emqx_trie module

This commit is contained in:
JianBo He 2020-06-18 12:36:25 +08:00 committed by JianBo He
parent 1700a7a98a
commit 9a8859a44c
5 changed files with 33 additions and 36 deletions

View File

@ -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"}}}

View File

@ -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('') -> <<>>;

View File

@ -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}) ->

View File

@ -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">>)),

View File

@ -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).