Ery Lee 11 年 前
コミット
c83d6d0e01

+ 10 - 1
apps/emqtt/src/emqtt_oldtopic.erl

@@ -1,6 +1,6 @@
 -module(emqtt_oldtopic).
 -module(emqtt_oldtopic).
 
 
--export([triples/1]).
+-export([triples/1, test/0]).
 
 
 triples(B) when is_binary(B) ->
 triples(B) when is_binary(B) ->
 	triples(binary_to_list(B), []).
 	triples(binary_to_list(B), []).
@@ -17,3 +17,12 @@ triples(I, S, Acc) ->
 	triples(S1, [{l2b(S1), l2b(S2), l2b(S)}|Acc]).
 	triples(S1, [{l2b(S1), l2b(S2), l2b(S)}|Acc]).
 
 
 l2b(L) -> list_to_binary(L).
 l2b(L) -> list_to_binary(L).
+
+test() ->
+    N = 100000,
+    Topic = <<"/abkc/19383/192939/akakdkkdkak/xxxyyuya/akakak">>,
+    {Time, _} = timer:tc(fun() -> 
+                [triples(Topic) || _I <- lists:seq(1, N)]
+        end),
+    io:format("Time for triples: ~p(micro)", [Time/N]),
+    ok.

+ 6 - 0
apps/emqtt/src/emqtt_topic.erl

@@ -100,12 +100,18 @@ match([], []) ->
 	true;
 	true;
 match([H|T1], [H|T2]) ->
 match([H|T1], [H|T2]) ->
 	match(T1, T2);
 	match(T1, T2);
+match([<<$$, _/binary>>|_], ['+'|_]) ->
+    false;
 match([_H|T1], ['+'|T2]) ->
 match([_H|T1], ['+'|T2]) ->
 	match(T1, T2);
 	match(T1, T2);
+match([<<$$, _/binary>>|_], ['#']) ->
+    false;
 match(_, ['#']) ->
 match(_, ['#']) ->
 	true;
 	true;
 match([_H1|_], [_H2|_]) ->
 match([_H1|_], [_H2|_]) ->
 	false;
 	false;
+match([_H1|_], []) ->
+	false;
 match([], [_H|_T2]) ->
 match([], [_H|_T2]) ->
 	false.
 	false.
 
 

+ 39 - 3
apps/emqtt/test/emqtt_topic_tests.erl

@@ -33,18 +33,51 @@
 -define(N, 100000).
 -define(N, 100000).
 
 
 validate_test() ->
 validate_test() ->
+	?assert( validate({filter, <<"sport/tennis/#">>}) ),
 	?assert( validate({filter, <<"a/b/c">>}) ),
 	?assert( validate({filter, <<"a/b/c">>}) ),
 	?assert( validate({filter, <<"/a/b">>}) ),
 	?assert( validate({filter, <<"/a/b">>}) ),
 	?assert( validate({filter, <<"/+/x">>}) ),
 	?assert( validate({filter, <<"/+/x">>}) ),
 	?assert( validate({filter, <<"/a/b/c/#">>}) ),
 	?assert( validate({filter, <<"/a/b/c/#">>}) ),
-	?assertNot( validate({filter, <<"a/#/c">>}) ).
+	?assertNot( validate({filter, <<"a/#/c">>}) ),
+	?assertNot( validate({filter, <<"sport/tennis#">>}) ),
+	?assertNot( validate({filter, <<"sport/tennis/#/ranking">>}) ).
+
+sigle_level_validate_test() ->
+    ?assert( validate({filter, <<"+">>}) ),
+    ?assert( validate({filter, <<"+/tennis/#">>}) ),
+    ?assertNot( validate({filter, <<"sport+">>}) ),
+    ?assert( validate({filter, <<"sport/+/player1">>}) ).
 
 
 match_test() ->
 match_test() ->
+    ?assert( match(<<"sport/tennis/player1">>, <<"sport/tennis/player1/#">>) ),
+    ?assert( match(<<"sport/tennis/player1/ranking">>, <<"sport/tennis/player1/#">>) ),
+    ?assert( match(<<"sport/tennis/player1/score/wimbledon">>, <<"sport/tennis/player1/#">>) ),
+
+    ?assert( match(<<"sport">>, <<"sport/#">>) ),
+    ?assert( match(<<"sport">>, <<"#">>) ),
+    ?assert( match(<<"/sport/football/score/1">>, <<"#">>) ).
+
+sigle_level_match_test() ->
+    ?assert( match(<<"sport/tennis/player1">>, <<"sport/tennis/+">>) ),
+    ?assertNot( match(<<"sport/tennis/player1/ranking">>, <<"sport/tennis/+">>) ),
+    ?assertNot( match(<<"sport">>, <<"sport/+">>) ),
+    ?assert( match(<<"sport/">>, <<"sport/+">>) ),
+    ?assert( match(<<"/finance">>, <<"+/+">>) ),
+    ?assert( match(<<"/finance">>, <<"/+">>) ),
+    ?assertNot( match(<<"/finance">>, <<"+">>) ).
+
+sys_match_test() ->
+    ?assert( match(<<"$SYS/borker/clients/testclient">>, <<"$SYS/#">>) ),
+    ?assert( match(<<"$SYS/borker">>, <<"$SYS/+">>) ),
+    ?assertNot( match(<<"$SYS/borker">>, <<"+/+">>) ),
+    ?assertNot( match(<<"$SYS/borker">>, <<"#">>) ).
+
+match_perf_test() ->
     ?assert( match(<<"a/b/ccc">>, <<"a/#">>) ),
     ?assert( match(<<"a/b/ccc">>, <<"a/#">>) ),
     Name = <<"/abkc/19383/192939/akakdkkdkak/xxxyyuya/akakak">>,
     Name = <<"/abkc/19383/192939/akakdkkdkak/xxxyyuya/akakak">>,
     Filter = <<"/abkc/19383/+/akakdkkdkak/#">>,
     Filter = <<"/abkc/19383/+/akakdkkdkak/#">>,
     ?assert( match(Name, Filter) ),
     ?assert( match(Name, Filter) ),
-    ?debugFmt("Match ~p with ~p", [Name, Filter]),
+    %?debugFmt("Match ~p with ~p", [Name, Filter]),
     {Time, _} = timer:tc(fun() -> 
     {Time, _} = timer:tc(fun() -> 
                 [match(Name, Filter) || _I <- lists:seq(1, ?N)]
                 [match(Name, Filter) || _I <- lists:seq(1, ?N)]
         end),
         end),
@@ -52,6 +85,10 @@ match_test() ->
     ok.
     ok.
 
 
 triples_test() ->
 triples_test() ->
+    Triples = [{root, <<"a">>, <<"a">>}, {<<"a">>, <<"b">>, <<"a/b">>}],
+    ?assertMatch(Triples, triples(<<"a/b">>) ). 
+
+triples_perf_test() ->
     Topic = <<"/abkc/19383/192939/akakdkkdkak/xxxyyuya/akakak">>,
     Topic = <<"/abkc/19383/192939/akakdkkdkak/xxxyyuya/akakak">>,
     {Time, _} = timer:tc(fun() -> 
     {Time, _} = timer:tc(fun() -> 
                 [triples(Topic) || _I <- lists:seq(1, ?N)]
                 [triples(Topic) || _I <- lists:seq(1, ?N)]
@@ -65,7 +102,6 @@ type_test() ->
 	?assertEqual(wildcard, type(#topic{name = <<"/a/b/#">>})).
 	?assertEqual(wildcard, type(#topic{name = <<"/a/b/#">>})).
 
 
 words_test() ->
 words_test() ->
-    ?debugFmt("Words: ~p", [words(<<"/abkc/19383/+/akakdkkdkak/#">>)]),
     ?assertMatch(['', <<"abkc">>, <<"19383">>, '+', <<"akakdkkdkak">>, '#'],  words(<<"/abkc/19383/+/akakdkkdkak/#">>)),
     ?assertMatch(['', <<"abkc">>, <<"19383">>, '+', <<"akakdkkdkak">>, '#'],  words(<<"/abkc/19383/+/akakdkkdkak/#">>)),
     {Time, _} = timer:tc(fun() -> 
     {Time, _} = timer:tc(fun() -> 
                 [words(<<"/abkc/19383/+/akakdkkdkak/#">>) || _I <- lists:seq(1, ?N)]
                 [words(<<"/abkc/19383/+/akakdkkdkak/#">>) || _I <- lists:seq(1, ?N)]