forked from dgiot/dgiot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
emqx_inflight.erl
127 lines (99 loc) · 3.58 KB
/
emqx_inflight.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
%%--------------------------------------------------------------------
%% Copyright (c) 2017-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% 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(emqx_inflight).
-compile(inline).
%% APIs
-export([ new/0
, new/1
, contain/2
, lookup/2
, insert/3
, update/3
, resize/2
, delete/2
, values/1
, to_list/1
, to_list/2
, size/1
, max_size/1
, is_full/1
, is_empty/1
, window/1
]).
-export_type([inflight/0]).
-type(key() :: term()).
-type(max_size() :: pos_integer()).
-opaque(inflight() :: {inflight, max_size(), gb_trees:tree()}).
-define(INFLIGHT(Tree), {inflight, _MaxSize, Tree}).
-define(INFLIGHT(MaxSize, Tree), {inflight, MaxSize, (Tree)}).
-spec(new() -> inflight()).
new() -> new(0).
-spec(new(non_neg_integer()) -> inflight()).
new(MaxSize) when MaxSize >= 0 ->
?INFLIGHT(MaxSize, gb_trees:empty()).
-spec(contain(key(), inflight()) -> boolean()).
contain(Key, ?INFLIGHT(Tree)) ->
gb_trees:is_defined(Key, Tree).
-spec(lookup(key(), inflight()) -> {value, term()} | none).
lookup(Key, ?INFLIGHT(Tree)) ->
gb_trees:lookup(Key, Tree).
-spec(insert(key(), Val :: term(), inflight()) -> inflight()).
insert(Key, Val, ?INFLIGHT(MaxSize, Tree)) ->
?INFLIGHT(MaxSize, gb_trees:insert(Key, Val, Tree)).
-spec(delete(key(), inflight()) -> inflight()).
delete(Key, ?INFLIGHT(MaxSize, Tree)) ->
?INFLIGHT(MaxSize, gb_trees:delete(Key, Tree)).
-spec(update(key(), Val :: term(), inflight()) -> inflight()).
update(Key, Val, ?INFLIGHT(MaxSize, Tree)) ->
?INFLIGHT(MaxSize, gb_trees:update(Key, Val, Tree)).
-spec(resize(integer(), inflight()) -> inflight()).
resize(MaxSize, ?INFLIGHT(Tree)) ->
?INFLIGHT(MaxSize, Tree).
-spec(is_full(inflight()) -> boolean()).
is_full(?INFLIGHT(0, _Tree)) ->
false;
is_full(?INFLIGHT(MaxSize, Tree)) ->
MaxSize =< gb_trees:size(Tree).
-spec(is_empty(inflight()) -> boolean()).
is_empty(?INFLIGHT(Tree)) ->
gb_trees:is_empty(Tree).
-spec(smallest(inflight()) -> {key(), term()}).
smallest(?INFLIGHT(Tree)) ->
gb_trees:smallest(Tree).
-spec(largest(inflight()) -> {key(), term()}).
largest(?INFLIGHT(Tree)) ->
gb_trees:largest(Tree).
-spec(values(inflight()) -> list()).
values(?INFLIGHT(Tree)) ->
gb_trees:values(Tree).
-spec(to_list(inflight()) -> list({key(), term()})).
to_list(?INFLIGHT(Tree)) ->
gb_trees:to_list(Tree).
-spec(to_list(fun(), inflight()) -> list({key(), term()})).
to_list(SortFun, ?INFLIGHT(Tree)) ->
lists:sort(SortFun, gb_trees:to_list(Tree)).
-spec(window(inflight()) -> list()).
window(Inflight = ?INFLIGHT(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(?INFLIGHT(Tree)) ->
gb_trees:size(Tree).
-spec(max_size(inflight()) -> non_neg_integer()).
max_size(?INFLIGHT(MaxSize, _Tree)) ->
MaxSize.