|
@@ -34,8 +34,8 @@
|
|
|
-export([empty/0]).
|
|
-export([empty/0]).
|
|
|
|
|
|
|
|
%% Mnesia tables
|
|
%% Mnesia tables
|
|
|
--define(TRIE, emqx_trie).
|
|
|
|
|
--define(TRIE_NODE, emqx_trie_node).
|
|
|
|
|
|
|
+-define(TRIE_TAB, emqx_trie).
|
|
|
|
|
+-define(TRIE_NODE_TAB, emqx_trie_node).
|
|
|
|
|
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
%% Mnesia bootstrap
|
|
%% Mnesia bootstrap
|
|
@@ -48,13 +48,13 @@ mnesia(boot) ->
|
|
|
StoreProps = [{ets, [{read_concurrency, true},
|
|
StoreProps = [{ets, [{read_concurrency, true},
|
|
|
{write_concurrency, true}]}],
|
|
{write_concurrency, true}]}],
|
|
|
%% Trie table
|
|
%% Trie table
|
|
|
- ok = ekka_mnesia:create_table(?TRIE, [
|
|
|
|
|
|
|
+ ok = ekka_mnesia:create_table(?TRIE_TAB, [
|
|
|
{ram_copies, [node()]},
|
|
{ram_copies, [node()]},
|
|
|
{record_name, trie},
|
|
{record_name, trie},
|
|
|
{attributes, record_info(fields, trie)},
|
|
{attributes, record_info(fields, trie)},
|
|
|
{storage_properties, StoreProps}]),
|
|
{storage_properties, StoreProps}]),
|
|
|
%% Trie node table
|
|
%% Trie node table
|
|
|
- ok = ekka_mnesia:create_table(?TRIE_NODE, [
|
|
|
|
|
|
|
+ ok = ekka_mnesia:create_table(?TRIE_NODE_TAB, [
|
|
|
{ram_copies, [node()]},
|
|
{ram_copies, [node()]},
|
|
|
{record_name, trie_node},
|
|
{record_name, trie_node},
|
|
|
{attributes, record_info(fields, trie_node)},
|
|
{attributes, record_info(fields, trie_node)},
|
|
@@ -62,9 +62,9 @@ mnesia(boot) ->
|
|
|
|
|
|
|
|
mnesia(copy) ->
|
|
mnesia(copy) ->
|
|
|
%% Copy trie table
|
|
%% Copy trie table
|
|
|
- ok = ekka_mnesia:copy_table(?TRIE),
|
|
|
|
|
|
|
+ ok = ekka_mnesia:copy_table(?TRIE_TAB),
|
|
|
%% Copy trie_node table
|
|
%% Copy trie_node table
|
|
|
- ok = ekka_mnesia:copy_table(?TRIE_NODE).
|
|
|
|
|
|
|
+ ok = ekka_mnesia:copy_table(?TRIE_NODE_TAB).
|
|
|
|
|
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
%% Trie APIs
|
|
%% Trie APIs
|
|
@@ -73,7 +73,7 @@ mnesia(copy) ->
|
|
|
%% @doc Insert a topic filter into the trie.
|
|
%% @doc Insert a topic filter into the trie.
|
|
|
-spec(insert(emqx_topic:topic()) -> ok).
|
|
-spec(insert(emqx_topic:topic()) -> ok).
|
|
|
insert(Topic) when is_binary(Topic) ->
|
|
insert(Topic) when is_binary(Topic) ->
|
|
|
- case mnesia:wread({?TRIE_NODE, Topic}) of
|
|
|
|
|
|
|
+ case mnesia:wread({?TRIE_NODE_TAB, Topic}) of
|
|
|
[#trie_node{topic = Topic}] ->
|
|
[#trie_node{topic = Topic}] ->
|
|
|
ok;
|
|
ok;
|
|
|
[TrieNode = #trie_node{topic = undefined}] ->
|
|
[TrieNode = #trie_node{topic = undefined}] ->
|
|
@@ -94,14 +94,14 @@ match(Topic) when is_binary(Topic) ->
|
|
|
%% @doc Lookup a trie node.
|
|
%% @doc Lookup a trie node.
|
|
|
-spec(lookup(NodeId :: binary()) -> [#trie_node{}]).
|
|
-spec(lookup(NodeId :: binary()) -> [#trie_node{}]).
|
|
|
lookup(NodeId) ->
|
|
lookup(NodeId) ->
|
|
|
- mnesia:read(?TRIE_NODE, NodeId).
|
|
|
|
|
|
|
+ mnesia:read(?TRIE_NODE_TAB, NodeId).
|
|
|
|
|
|
|
|
%% @doc Delete a topic filter from the trie.
|
|
%% @doc Delete a topic filter from the trie.
|
|
|
-spec(delete(emqx_topic:topic()) -> ok).
|
|
-spec(delete(emqx_topic:topic()) -> ok).
|
|
|
delete(Topic) when is_binary(Topic) ->
|
|
delete(Topic) when is_binary(Topic) ->
|
|
|
- case mnesia:wread({?TRIE_NODE, Topic}) of
|
|
|
|
|
|
|
+ case mnesia:wread({?TRIE_NODE_TAB, Topic}) of
|
|
|
[#trie_node{edge_count = 0}] ->
|
|
[#trie_node{edge_count = 0}] ->
|
|
|
- ok = mnesia:delete({?TRIE_NODE, Topic}),
|
|
|
|
|
|
|
+ ok = mnesia:delete({?TRIE_NODE_TAB, Topic}),
|
|
|
delete_path(lists:reverse(emqx_topic:triples(Topic)));
|
|
delete_path(lists:reverse(emqx_topic:triples(Topic)));
|
|
|
[TrieNode] ->
|
|
[TrieNode] ->
|
|
|
write_trie_node(TrieNode#trie_node{topic = undefined});
|
|
write_trie_node(TrieNode#trie_node{topic = undefined});
|
|
@@ -111,7 +111,7 @@ delete(Topic) when is_binary(Topic) ->
|
|
|
%% @doc Is the trie empty?
|
|
%% @doc Is the trie empty?
|
|
|
-spec(empty() -> boolean()).
|
|
-spec(empty() -> boolean()).
|
|
|
empty() ->
|
|
empty() ->
|
|
|
- ets:info(?TRIE, size) == 0.
|
|
|
|
|
|
|
+ ets:info(?TRIE_TAB, size) == 0.
|
|
|
|
|
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
%% Internal functions
|
|
%% Internal functions
|
|
@@ -121,9 +121,9 @@ empty() ->
|
|
|
%% @doc Add a path to the trie.
|
|
%% @doc Add a path to the trie.
|
|
|
add_path({Node, Word, Child}) ->
|
|
add_path({Node, Word, Child}) ->
|
|
|
Edge = #trie_edge{node_id = Node, word = Word},
|
|
Edge = #trie_edge{node_id = Node, word = Word},
|
|
|
- case mnesia:wread({?TRIE_NODE, Node}) of
|
|
|
|
|
|
|
+ case mnesia:wread({?TRIE_NODE_TAB, Node}) of
|
|
|
[TrieNode = #trie_node{edge_count = Count}] ->
|
|
[TrieNode = #trie_node{edge_count = Count}] ->
|
|
|
- case mnesia:wread({?TRIE, Edge}) of
|
|
|
|
|
|
|
+ case mnesia:wread({?TRIE_TAB, Edge}) of
|
|
|
[] ->
|
|
[] ->
|
|
|
ok = write_trie_node(TrieNode#trie_node{edge_count = Count + 1}),
|
|
ok = write_trie_node(TrieNode#trie_node{edge_count = Count + 1}),
|
|
|
write_trie(#trie{edge = Edge, node_id = Child});
|
|
write_trie(#trie{edge = Edge, node_id = Child});
|
|
@@ -143,11 +143,11 @@ match_node(NodeId, Words) ->
|
|
|
match_node(NodeId, Words, []).
|
|
match_node(NodeId, Words, []).
|
|
|
|
|
|
|
|
match_node(NodeId, [], ResAcc) ->
|
|
match_node(NodeId, [], ResAcc) ->
|
|
|
- mnesia:read(?TRIE_NODE, NodeId) ++ 'match_#'(NodeId, ResAcc);
|
|
|
|
|
|
|
+ mnesia:read(?TRIE_NODE_TAB, NodeId) ++ 'match_#'(NodeId, ResAcc);
|
|
|
|
|
|
|
|
match_node(NodeId, [W|Words], ResAcc) ->
|
|
match_node(NodeId, [W|Words], ResAcc) ->
|
|
|
lists:foldl(fun(WArg, Acc) ->
|
|
lists:foldl(fun(WArg, Acc) ->
|
|
|
- case mnesia:read(?TRIE, #trie_edge{node_id = NodeId, word = WArg}) of
|
|
|
|
|
|
|
+ case mnesia:read(?TRIE_TAB, #trie_edge{node_id = NodeId, word = WArg}) of
|
|
|
[#trie{node_id = ChildId}] -> match_node(ChildId, Words, Acc);
|
|
[#trie{node_id = ChildId}] -> match_node(ChildId, Words, Acc);
|
|
|
[] -> Acc
|
|
[] -> Acc
|
|
|
end
|
|
end
|
|
@@ -156,9 +156,9 @@ match_node(NodeId, [W|Words], ResAcc) ->
|
|
|
%% @private
|
|
%% @private
|
|
|
%% @doc Match node with '#'.
|
|
%% @doc Match node with '#'.
|
|
|
'match_#'(NodeId, ResAcc) ->
|
|
'match_#'(NodeId, ResAcc) ->
|
|
|
- case mnesia:read(?TRIE, #trie_edge{node_id = NodeId, word = '#'}) of
|
|
|
|
|
|
|
+ case mnesia:read(?TRIE_TAB, #trie_edge{node_id = NodeId, word = '#'}) of
|
|
|
[#trie{node_id = ChildId}] ->
|
|
[#trie{node_id = ChildId}] ->
|
|
|
- mnesia:read(?TRIE_NODE, ChildId) ++ ResAcc;
|
|
|
|
|
|
|
+ mnesia:read(?TRIE_NODE_TAB, ChildId) ++ ResAcc;
|
|
|
[] -> ResAcc
|
|
[] -> ResAcc
|
|
|
end.
|
|
end.
|
|
|
|
|
|
|
@@ -167,10 +167,10 @@ match_node(NodeId, [W|Words], ResAcc) ->
|
|
|
delete_path([]) ->
|
|
delete_path([]) ->
|
|
|
ok;
|
|
ok;
|
|
|
delete_path([{NodeId, Word, _} | RestPath]) ->
|
|
delete_path([{NodeId, Word, _} | RestPath]) ->
|
|
|
- ok = mnesia:delete({?TRIE, #trie_edge{node_id = NodeId, word = Word}}),
|
|
|
|
|
- case mnesia:wread({?TRIE_NODE, NodeId}) of
|
|
|
|
|
|
|
+ ok = mnesia:delete({?TRIE_TAB, #trie_edge{node_id = NodeId, word = Word}}),
|
|
|
|
|
+ case mnesia:wread({?TRIE_NODE_TAB, NodeId}) of
|
|
|
[#trie_node{edge_count = 1, topic = undefined}] ->
|
|
[#trie_node{edge_count = 1, topic = undefined}] ->
|
|
|
- ok = mnesia:delete({?TRIE_NODE, NodeId}),
|
|
|
|
|
|
|
+ ok = mnesia:delete({?TRIE_NODE_TAB, NodeId}),
|
|
|
delete_path(RestPath);
|
|
delete_path(RestPath);
|
|
|
[TrieNode = #trie_node{edge_count = 1, topic = _}] ->
|
|
[TrieNode = #trie_node{edge_count = 1, topic = _}] ->
|
|
|
write_trie_node(TrieNode#trie_node{edge_count = 0});
|
|
write_trie_node(TrieNode#trie_node{edge_count = 0});
|
|
@@ -182,9 +182,9 @@ delete_path([{NodeId, Word, _} | RestPath]) ->
|
|
|
|
|
|
|
|
%% @private
|
|
%% @private
|
|
|
write_trie(Trie) ->
|
|
write_trie(Trie) ->
|
|
|
- mnesia:write(?TRIE, Trie, write).
|
|
|
|
|
|
|
+ mnesia:write(?TRIE_TAB, Trie, write).
|
|
|
|
|
|
|
|
%% @private
|
|
%% @private
|
|
|
write_trie_node(TrieNode) ->
|
|
write_trie_node(TrieNode) ->
|
|
|
- mnesia:write(?TRIE_NODE, TrieNode, write).
|
|
|
|
|
|
|
+ mnesia:write(?TRIE_NODE_TAB, TrieNode, write).
|
|
|
|
|
|