Procházet zdrojové kódy

Add inflight module and test suite

Feng Lee před 9 roky
rodič
revize
08100525a5
4 změnil soubory, kde provedl 144 přidání a 35 odebrání
  1. 0 0
      src/emqttd_hooks.erl
  2. 94 0
      src/emqttd_inflight.erl
  3. 0 35
      src/emqttd_opts.erl
  4. 50 0
      test/emqttd_inflight_SUITE.erl

src/emqttd_hook.erl → src/emqttd_hooks.erl


+ 94 - 0
src/emqttd_inflight.erl

@@ -0,0 +1,94 @@
+%%--------------------------------------------------------------------
+%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io)
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%%     http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%--------------------------------------------------------------------
+
+%% @doc Inflight Window that wraps the gb_trees.
+
+-module(emqttd_inflight).
+
+-author("Feng Lee <feng@emqtt.io>").
+
+-export([new/1, contain/2, lookup/2, insert/3, update/3, delete/2, values/1,
+         to_list/1, size/1, max_size/1, is_full/1, is_empty/1, window/1]).
+
+-type(inflight() :: {?MODULE, list()}).
+
+-export_type([inflight/0]).
+
+-spec(new(non_neg_integer()) -> inflight()).
+new(MaxSize) when MaxSize >= 0 ->
+    {?MODULE, [MaxSize, gb_trees:empty()]}.
+
+-spec(contain(Key :: any(), inflight()) -> boolean()).
+contain(Key, {?MODULE, [_MaxSize, Tree]}) ->
+    gb_trees:is_defined(Key, Tree).
+
+-spec(lookup(Key :: any(), inflight()) -> any()).
+lookup(Key, {?MODULE, [_MaxSize, Tree]}) ->
+    gb_trees:get(Key, Tree).
+
+-spec(insert(Key :: any(), Value :: any(), inflight()) -> inflight()).
+insert(Key, Value, {?MODULE, [MaxSize, Tree]}) ->
+    {?MODULE, [MaxSize, gb_trees:insert(Key, Value, Tree)]}.
+
+-spec(delete(Key :: any(), inflight()) -> inflight()).
+delete(Key, {?MODULE, [MaxSize, Tree]}) ->
+    {?MODULE, [MaxSize, gb_trees:delete(Key, Tree)]}.
+
+-spec(update(Key :: any(), Val :: any(), inflight()) -> inflight()).
+update(Key, Val, {?MODULE, [MaxSize, Tree]}) ->
+    {?MODULE, [MaxSize, gb_trees:update(Key, Val, Tree)]}.
+
+-spec(is_full(inflight()) -> boolean()).
+is_full({?MODULE, [0, _Tree]}) ->
+    false;
+is_full({?MODULE, [MaxSize, Tree]}) ->
+    MaxSize =< gb_trees:size(Tree).
+
+-spec(is_empty(inflight()) -> boolean()).
+is_empty({?MODULE, [_MaxSize, Tree]}) ->
+    gb_trees:is_empty(Tree).
+
+-spec(smallest(inflight()) -> {K :: any(), V :: any()}).
+smallest({?MODULE, [_MaxSize, Tree]}) ->
+    gb_trees:smallest(Tree).
+
+-spec(largest(inflight()) -> {K :: any(), V :: any()}).
+largest({?MODULE, [_MaxSize, Tree]}) ->
+    gb_trees:largest(Tree).
+
+-spec(values(inflight()) -> list()).
+values({?MODULE, [_MaxSize, Tree]}) ->
+    gb_trees:values(Tree).
+
+-spec(to_list(inflight()) -> list({K :: any(), V :: any()})).
+to_list({?MODULE, [_MaxSize, Tree]}) ->
+    gb_trees:to_list(Tree).
+
+-spec(window(inflight()) -> list()).
+window(Inflight = {?MODULE, [_MaxSize, Tree]}) ->
+    case gb_trees:is_empty(Tree) of
+        true  -> [];
+        false -> [Key || {Key, _Val} <- [smallest(Inflight), largest(Inflight)]]
+    end.
+
+-spec(size(inflight()) -> non_neg_integer()).
+size({?MODULE, [_MaxSize, Tree]}) ->
+    gb_trees:size(Tree).
+
+-spec(max_size(inflight()) -> non_neg_integer()).
+max_size({?MODULE, [MaxSize, _Tree]}) ->
+    MaxSize.
+

+ 0 - 35
src/emqttd_opts.erl

@@ -1,35 +0,0 @@
-%%--------------------------------------------------------------------
-%% Copyright (c) 2012-2017 Feng Lee <feng@emqtt.io>.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%--------------------------------------------------------------------
-
--module(emqttd_opts).
-
--export([merge/2]).
-
-%% @doc Merge Options
-merge(Defaults, Options) ->
-    lists:foldl(
-        fun({Opt, Val}, Acc) ->
-                case lists:keymember(Opt, 1, Acc) of
-                    true  -> lists:keyreplace(Opt, 1, Acc, {Opt, Val});
-                    false -> [{Opt, Val}|Acc]
-                end;
-            (Opt, Acc) ->
-                case lists:member(Opt, Acc) of
-                    true  -> Acc;
-                    false -> [Opt | Acc]
-                end
-        end, Defaults, Options).
-

+ 50 - 0
test/emqttd_inflight_SUITE.erl

@@ -0,0 +1,50 @@
+%%
+%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io)
+%%
+
+-module(emqttd_inflight_SUITE).
+
+-author("Feng Lee <feng@emqtt.io>").
+
+-include_lib("eunit/include/eunit.hrl").
+
+%% CT
+-compile(export_all).
+
+all() -> [t_contain, t_lookup, t_insert, t_update, t_delete, t_window,
+          t_is_full, t_is_empty].
+
+t_contain(_) ->
+    Inflight = emqttd_inflight:new(0),
+    ?assertNot(Inflight:contain(k)),
+    Inflight1 = Inflight:insert(k, v),
+    ?assert(Inflight1:contain(k)).
+
+t_lookup(_) ->
+    Inflight = (emqttd_inflight:new(0)):insert(k, v),
+    ?assertEqual(v, Inflight:lookup(k)).
+
+t_insert(_) ->
+    Inflight = ((emqttd_inflight:new(0)):insert(k1, v1)):insert(k2, v2),
+    ?assertEqual(v2, Inflight:lookup(k2)).
+
+t_update(_) ->
+    Inflight = ((emqttd_inflight:new(0)):insert(k, v1)):update(k, v2),
+    ?assertEqual(v2, Inflight:lookup(k)).
+
+t_delete(_) ->
+    Inflight = ((emqttd_inflight:new(0)):insert(k, v1)):delete(k),
+    ?assert(Inflight:is_empty()).
+
+t_window(_) ->
+    ?assertEqual([], (emqttd_inflight:new(10)):window()),
+    Inflight = ((emqttd_inflight:new(0)):insert(1, 1)):insert(2, 2),
+    ?assertEqual([1, 2], Inflight:window()).
+
+t_is_full(_) ->
+    Inflight = ((emqttd_inflight:new(1)):insert(k, v1)),
+    ?assert(Inflight:is_full()).
+
+t_is_empty(_) ->
+    Inflight = ((emqttd_inflight:new(1)):insert(k, v1)),
+    ?assertNot(Inflight:is_empty()).