Skip to content

Commit 47ef5f5

Browse files
committed
'async' and 'sync' modes to the 'clean' interface to accordance with 'PACR' was added
1 parent c0009a3 commit 47ef5f5

File tree

5 files changed

+104
-34
lines changed

5 files changed

+104
-34
lines changed

lfu.app

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{application,lfu,[
22
{description,"Least Frequently Used Algorithm"},
3-
{vsn,"2.2.2"},
3+
{vsn,"2.3.0"},
44
{modules,[
55
lfu_app,lfu_sup,lfu,
66
lfu_score_sups_sup,lfu_protocol,

priv/lfu.rel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
{crypto,"4.8"},
1010
{public_key,"1.9"},
1111
{asn1,"5.0.14"},
12-
{lfu, "2.2.2"}]
12+
{lfu, "2.3.0"}]
1313
}.

priv/lfu.tar.gz

1.42 KB
Binary file not shown.

src/lfu.erl

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,22 @@ score() ->
102102
gen_statem:call(?MODULE,score).
103103
fetch() ->
104104
gen_statem:call(?MODULE,fetch).
105-
clean() ->
106-
gen_statem:call(?MODULE,clean).
107105
fetch(T) ->
108106
gen_statem:call(?MODULE,{fetch,T}).
107+
clean() ->
108+
gen_statem:call(?MODULE,{clean,async}).
109+
clean(async) ->
110+
gen_statem:call(?MODULE,{clean,async});
111+
clean(sync) ->
112+
gen_statem:call(?MODULE,{clean,sync});
109113
clean(T) ->
110-
gen_statem:call(?MODULE,{clean,T}).
114+
gen_statem:call(?MODULE,{clean,{async,T}}).
115+
clean(async,T) ->
116+
gen_statem:call(?MODULE,{clean,{async,T}});
117+
clean(sync,T) ->
118+
gen_statem:call(?MODULE,{clean,{sync,T}});
119+
clean(R,T) ->
120+
gen_statem:cast(?MODULE,{{clean,R},T}).
111121

112122
reset(D) ->
113123
gen_statem:cast(?MODULE,{reset,D}).
@@ -116,8 +126,6 @@ score(R,C) ->
116126
gen_statem:cast(?MODULE,{{score,R},C}).
117127
fetch(R,C) ->
118128
gen_statem:cast(?MODULE,{{fetch,R},C}).
119-
clean(R,T) ->
120-
gen_statem:cast(?MODULE,{{clean,R},T}).
121129

122130

123131
common(cast,{point,K},[O,Q]) ->
@@ -323,13 +331,18 @@ common({call,From},score,[O,Q]) ->
323331
common({call,From},fetch,[O,Q]) ->
324332
T = lfu_utils:ets_create(),
325333
{next_state,offset,[O,Q,#{from => From, tid => T, ets => internal, order => fetch}],[{next_event,internal,{score,{previous,{?SCORE_OFFSET,O}}}}]};
326-
common({call,From},clean,[O,Q]) ->
327-
T = lfu_utils:ets_create(),
328-
{next_state,offset,[O,Q,#{from => From, tid => T, ets => internal, order => clean}],[{next_event,internal,{score,{previous,{?SCORE_OFFSET,O}}}}]};
329334
common({call,From},{fetch,T},[O,Q]) ->
330335
{next_state,offset,[O,Q,#{from => From, tid => T, ets => external, order => fetch}],[{next_event,internal,{score,{previous,{?SCORE_OFFSET,O}}}}]};
331-
common({call,From},{clean,T},[O,Q]) ->
332-
{next_state,offset,[O,Q,#{from => From, tid => T, ets => external, order => clean}],[{next_event,internal,{score,{previous,{?SCORE_OFFSET,O}}}}]};
336+
common({call,From},{clean,async},[O,Q]) ->
337+
T = lfu_utils:ets_create(),
338+
{next_state,offset,[O,Q,#{from => From, tid => T, ets => internal, order => clean, mode => async}],[{next_event,internal,{score,{previous,{?SCORE_OFFSET,O}}}}]};
339+
common({call,From},{clean,sync},[O,Q]) ->
340+
T = lfu_utils:ets_create(),
341+
{next_state,offset,[O,Q,#{from => From, tid => T, ets => internal, order => clean, mode => sync}],[{next_event,internal,{score,{previous,{?SCORE_OFFSET,O}}}}]};
342+
common({call,From},{clean,{async,T}},[O,Q]) ->
343+
{next_state,offset,[O,Q,#{from => From, tid => T, ets => external, order => clean, mode => async}],[{next_event,internal,{score,{previous,{?SCORE_OFFSET,O}}}}]};
344+
common({call,From},{clean,{sync,T}},[O,Q]) ->
345+
{next_state,offset,[O,Q,#{from => From, tid => T, ets => external, order => clean, mode => sync}],[{next_event,internal,{score,{previous,{?SCORE_OFFSET,O}}}}]};
333346
common(cast,{reset,D},[O,Q]) ->
334347
NQ = resetting(D,Q),
335348
{keep_state,[O,NQ]};
@@ -404,7 +417,7 @@ offset(internal,count,[O,Q,#{previous := P, current := C, following := F, from :
404417
{next_state,select,[O,Q,#{from => From, tid => maps:get(tid,MD), ets => maps:get(ets,MD), order => fetch}],[{next_event,internal,fetch}]};
405418
Order =:= clean ->
406419
%% idle iteration but necessary
407-
{next_state,select,[O,Q,#{from => From, tid => maps:get(tid,MD), ets => maps:get(ets,MD), order => clean}],[{next_event,internal,fetch}]}
420+
{next_state,select,[O,Q,#{from => From, tid => maps:get(tid,MD), ets => maps:get(ets,MD), order => clean, mode => maps:get(mode,MD)}],[{next_event,internal,fetch}]}
408421
end;
409422
C / Q * 100 < ?MIN_OFFSET andalso O*10 =< ?MAX_ORDER andalso F / Q * 100 =< ?MAX_OFFSET ->
410423
{keep_state,[O*10,Q,MD#{previous => C, current => F, following => 0}],[{next_event,internal,{score,{following,{O*100,O*1000}}}}]};
@@ -417,7 +430,7 @@ offset(internal,count,[O,Q,#{previous := P, current := C, following := F, from :
417430
Order =:= fetch ->
418431
{next_state,select,[O,Q,#{from => From, tid => maps:get(tid,MD), ets => maps:get(ets,MD), order => fetch}],[{next_event,internal,fetch}]};
419432
Order =:= clean ->
420-
{next_state,select,[O,Q,#{from => From, tid => maps:get(tid,MD), ets => maps:get(ets,MD), order => clean}],[{next_event,internal,fetch}]}
433+
{next_state,select,[O,Q,#{from => From, tid => maps:get(tid,MD), ets => maps:get(ets,MD), order => clean, mode => maps:get(mode,MD)}],[{next_event,internal,fetch}]}
421434
end
422435
end;
423436
offset(cast,{{score,_},_S},_StateData) ->
@@ -440,11 +453,9 @@ offset({call,_From},score,_StateData) ->
440453
{keep_state_and_data,[postpone]};
441454
offset({call,_From},fetch,_StateData) ->
442455
{keep_state_and_data,[postpone]};
443-
offset({call,_From},clean,_StateData) ->
444-
{keep_state_and_data,[postpone]};
445456
offset({call,_From},{fetch,_T},_StateData) ->
446457
{keep_state_and_data,[postpone]};
447-
offset({call,_From},{clean,_T},_StateData) ->
458+
offset({call,_From},{clean,_D},_StateData) -> %% _D = {async,tid()} || {sync,tid()} || async || sync
448459
{keep_state_and_data,[postpone]};
449460
offset(cast,{reset,_T},_StateData) ->
450461
{keep_state_and_data,[postpone]};
@@ -465,24 +476,34 @@ select(internal,fetch,[O,Q,#{tid := T} = MD]) ->
465476
true ->
466477
{keep_state,[O,Q,MD#{number => N, ref => R}],[{state_timeout,0,T}]}
467478
end;
468-
select(state_timeout,T,[O,Q,#{tid := T, from := From, order := Order, ets := internal} = _MD]) ->
479+
select(state_timeout,T,[O,Q,#{tid := T, from := From, order := Order, ets := internal} = MD]) ->
469480
% io:format("TimeoutState:~p~nMD:~p~nO:~p~nQ~p~n~n",[select,MD,O,Q]),
470481
NT = lfu_utils:ets_re_create(),
471482
if
472483
Order =:= fetch ->
473484
{next_state,common,[O,Q],[{reply,From,NT}]};
474485
Order =:= clean ->
475-
R1 = make_ref(),
476-
{next_state,delete,[O,Q,#{tid => NT, ref => R1}],[{reply,From,{NT,R1}},{state_timeout,?TIMEOUT_STATE_DELETE,NT}]}
486+
case maps:get(mode,MD) of
487+
async ->
488+
{next_state,delete,[O,Q,#{tid => NT, from => From}],[{next_event,internal,clean}]};
489+
sync ->
490+
R = make_ref(),
491+
{next_state,delete,[O,Q,#{tid => NT, ref => R}],[{reply,From,{NT,R}},{state_timeout,?TIMEOUT_STATE_DELETE,NT}]}
492+
end
477493
end;
478-
select(state_timeout,T,[O,Q,#{tid := T, from := From, order := Order, ets := external} = _MD]) ->
494+
select(state_timeout,T,[O,Q,#{tid := T, from := From, order := Order, ets := external} = MD]) ->
479495
% io:format("TimeoutState:~p~nMD:~p~nO:~p~nQ~p~n~n",[select,MD,O,Q]),
480496
if
481497
Order =:= fetch ->
482498
{next_state,common,[O,Q],[{reply,From,T}]};
483499
Order =:= clean ->
484-
R1 = make_ref(),
485-
{next_state,delete,[O,Q,#{tid => T, ref => R1}],[{reply,From,{T,R1}},{state_timeout,?TIMEOUT_STATE_DELETE,T}]}
500+
case maps:get(mode,MD) of
501+
async ->
502+
{next_state,delete,[O,Q,#{tid => T, from => From}],[{next_event,internal,clean}]};
503+
sync ->
504+
R = make_ref(),
505+
{next_state,delete,[O,Q,#{tid => T, ref => R}],[{reply,From,{T,R}},{state_timeout,?TIMEOUT_STATE_DELETE,T}]}
506+
end
486507
end;
487508
select(cast,{{fetch,R},ready},[O,Q,#{number := N, tid := T, from := From, order := Order, ref := R} = MD]) ->
488509
if
@@ -493,8 +514,13 @@ select(cast,{{fetch,R},ready},[O,Q,#{number := N, tid := T, from := From, order
493514
Order =:= fetch ->
494515
{next_state,common,[O,Q],[{reply,From,T}]};
495516
Order =:= clean ->
496-
R1 = make_ref(),
497-
{next_state,delete,[O,Q,#{tid => T, ref => R1}],[{reply,From,{T,R1}},{state_timeout,?TIMEOUT_STATE_DELETE,T}]}
517+
case maps:get(mode,MD) of
518+
async ->
519+
{next_state,delete,[O,Q,#{tid => T, from => From}],[{next_event,internal,clean}]};
520+
sync ->
521+
R1 = make_ref(),
522+
{next_state,delete,[O,Q,#{tid => T, ref => R1}],[{reply,From,{T,R1}},{state_timeout,?TIMEOUT_STATE_DELETE,T}]}
523+
end
498524
end
499525
end;
500526
select(cast,{{fetch,_R},ready},_StateData) ->
@@ -517,11 +543,9 @@ select({call,_From},score,_StateData) ->
517543
{keep_state_and_data,[postpone]};
518544
select({call,_From},fetch,_StateData) ->
519545
{keep_state_and_data,[postpone]};
520-
select({call,_From},clean,_StateData) ->
521-
{keep_state_and_data,[postpone]};
522546
select({call,_From},{fetch,_T},_StateData) ->
523547
{keep_state_and_data,[postpone]};
524-
select({call,_From},{clean,_T},_StateData) ->
548+
select({call,_From},{clean,_D},_StateData) -> %% _D = {async,tid()} || {sync,tid()} || async || sync
525549
{keep_state_and_data,[postpone]};
526550
select(cast,{reset,_T},_StateData) ->
527551
{keep_state_and_data,[postpone]};
@@ -532,6 +556,10 @@ select({call,_From},_EventContent,_StateData) ->
532556
select(info,_EventContent,_StateData) ->
533557
keep_state_and_data.
534558

559+
delete(internal,clean,[O,Q,#{tid := T, from := From}]) ->
560+
NQ = resetting(T,Q),
561+
?SUPPORT andalso erlang:apply(?AUXILIARY,reset,[T]),
562+
{next_state,common,[O,NQ],[{reply,From,T}]};
535563
delete(state_timeout,T,[O,Q,#{tid := T, ref := _R}]) ->
536564
% io:format("TimeoutState:~p~nT:~p~nO:~p~nQ~p~n~n",[delete,T,O,Q]),
537565
{next_state,common,[O,Q]};
@@ -559,11 +587,9 @@ delete({call,_From},score,_StateData) ->
559587
{keep_state_and_data,[postpone]};
560588
delete({call,_From},fetch,_StateData) ->
561589
{keep_state_and_data,[postpone]};
562-
delete({call,_From},clean,_StateData) ->
563-
{keep_state_and_data,[postpone]};
564590
delete({call,_From},{fetch,_T},_StateData) ->
565591
{keep_state_and_data,[postpone]};
566-
delete({call,_From},{clean,_T},_StateData) ->
592+
delete({call,_From},{clean,_D},_StateData) -> %% _D = {async,tid()} || {sync,tid()} || async || sync
567593
{keep_state_and_data,[postpone]};
568594
delete(cast,{reset,_T},_StateData) ->
569595
{keep_state_and_data,[postpone]};

src/lfu_protocol.erl

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@ common(info,{tcp,S,<<"FETCH",_/binary>>},[S,T]) ->
136136
T:send(S,<<"{","ERROR",":","UNKNOW_ERROR","}">>)
137137
end,
138138
keep_state_and_data;
139-
common(info,{tcp,S,<<"CLEAN",_/binary>>},[S,T]) ->
139+
common(info,{tcp,S,<<"CLEAN",":","SYNC",_/binary>>},[S,T]) ->
140140
T:setopts(S,[{active,once}]),
141-
case lfu:clean() of
141+
case lfu:clean(sync) of
142142
{TID,R} when is_reference(TID) andalso is_reference(R) ->
143143
BD = ets:foldl(
144144
fun({K,V},BA) ->
@@ -159,18 +159,62 @@ common(info,{tcp,S,<<"CLEAN",_/binary>>},[S,T]) ->
159159
T:send(S,<<"{","ERROR",":","UNKNOW_ERROR","}">>),
160160
keep_state_and_data
161161
end;
162+
common(info,{tcp,S,<<"CLEAN",":","ASYNC",_/binary>>},[S,T]) ->
163+
T:setopts(S,[{active,once}]),
164+
case lfu:clean(async) of
165+
TID when is_reference(TID) ->
166+
BD = ets:foldl(
167+
fun({K,V},BA) ->
168+
BK = integer_to_binary(K),
169+
BV = pack_list_to_binary(V,<<>>),
170+
case BA of
171+
<<>> ->
172+
<<"{",BK/binary,":",BV/binary,"}">>;
173+
BA ->
174+
<<BA/binary,",","{",BK/binary,":",BV/binary,"}">>
175+
end
176+
end,
177+
<<>>,TID),
178+
T:send(S,<<"[",BD/binary,"]">>),
179+
keep_state_and_data;
180+
_ ->
181+
T:send(S,<<"{","ERROR",":","UNKNOW_ERROR","}">>),
182+
keep_state_and_data
183+
end;
162184
common(info,{tcp,S,<<"CLEAN",":",_P/binary>>},[S,T]) ->
163185
T:setopts(S,[{active,once}]),
164186
T:send(S,<<"{","ERROR",":","EXPIRED_REF","}">>),
165187
keep_state_and_data;
188+
common(info,{tcp,S,<<"CLEAN",_/binary>>},[S,T]) ->
189+
T:setopts(S,[{active,once}]),
190+
case lfu:clean(async) of
191+
TID when is_reference(TID) ->
192+
BD = ets:foldl(
193+
fun({K,V},BA) ->
194+
BK = integer_to_binary(K),
195+
BV = pack_list_to_binary(V,<<>>),
196+
case BA of
197+
<<>> ->
198+
<<"{",BK/binary,":",BV/binary,"}">>;
199+
BA ->
200+
<<BA/binary,",","{",BK/binary,":",BV/binary,"}">>
201+
end
202+
end,
203+
<<>>,TID),
204+
T:send(S,<<"[",BD/binary,"]">>),
205+
keep_state_and_data;
206+
_ ->
207+
T:send(S,<<"{","ERROR",":","UNKNOW_ERROR","}">>),
208+
keep_state_and_data
209+
end;
166210
common(info,{tcp,S,_B},[S,T]) ->
167211
T:setopts(S,[{active,once}]),
168212
T:send(S,<<"{","ERROR",":","UNKNOW_COMMAND","}">>),
169213
keep_state_and_data.
170214

171215
delete(state_timeout,BR,[S,T,#{ref := BR, tid := _T}]) ->
172216
{next_state,common,[S,T]};
173-
delete(info,{tcp,S,<<"CLEAN",_:1/binary,P/binary>>},[S,T,#{ref := BR, tid := TID}]) ->
217+
delete(info,{tcp,S,<<"CLEAN",":",P/binary>>},[S,T,#{ref := BR, tid := TID}]) ->
174218
T:setopts(S,[{active,once}]),
175219
case break_binary_string(P) =:= BR of
176220
true ->

0 commit comments

Comments
 (0)