From 9a8859a44c5632dfe574f32a1a7237a12cf43061 Mon Sep 17 00:00:00 2001 From: JianBo He Date: Thu, 18 Jun 2020 12:36:25 +0800 Subject: [PATCH] refactor(topic): move triples/1 func into emqx_trie module --- rebar.config | 2 +- src/emqx_topic.erl | 22 +--------------------- src/emqx_trie.erl | 27 +++++++++++++++++++++++++-- test/emqx_topic_SUITE.erl | 12 ------------ test/emqx_trie_SUITE.erl | 6 ++++++ 5 files changed, 33 insertions(+), 36 deletions(-) diff --git a/rebar.config b/rebar.config index a1920304c..4f9c1990e 100644 --- a/rebar.config +++ b/rebar.config @@ -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"}}} diff --git a/src/emqx_topic.erl b/src/emqx_topic.erl index 029a46b61..cda057f06 100644 --- a/src/emqx_topic.erl +++ b/src/emqx_topic.erl @@ -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(<>) 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 $/ -> <>; - _ -> join(Parent, W) + _ -> <> end. bin('') -> <<>>; diff --git a/src/emqx_trie.erl b/src/emqx_trie.erl index adb184aa7..4189c0270 100644 --- a/src/emqx_trie.erl +++ b/src/emqx_trie.erl @@ -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}) -> diff --git a/test/emqx_topic_SUITE.erl b/test/emqx_topic_SUITE.erl index 707e4a6aa..89b3b11af 100644 --- a/test/emqx_topic_SUITE.erl +++ b/test/emqx_topic_SUITE.erl @@ -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">>)), diff --git a/test/emqx_trie_SUITE.erl b/test/emqx_trie_SUITE.erl index 5324829c9..f1db3813c 100644 --- a/test/emqx_trie_SUITE.erl +++ b/test/emqx_trie_SUITE.erl @@ -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).