|
|
@ -1,5 +1,8 @@ |
|
|
|
-module(utLifo). |
|
|
|
|
|
|
|
-compile(inline). |
|
|
|
-compile({inline_size, 128}). |
|
|
|
|
|
|
|
-export([ |
|
|
|
new/1 |
|
|
|
, del/1 |
|
|
@ -11,89 +14,43 @@ |
|
|
|
|
|
|
|
-spec new(Name :: atom()) -> ok | name_used. |
|
|
|
new(Name) -> |
|
|
|
case persistent_term:get(Name, undefined) of |
|
|
|
case ets:info(Name, id) of |
|
|
|
undefined -> |
|
|
|
ARef = atomics:new(1, [{signed, false}]), |
|
|
|
ets:new(Name, [set, named_table, {write_concurrency, true}]), |
|
|
|
persistent_term:put(Name, ARef), |
|
|
|
ok; |
|
|
|
ets:new(Name, [ordered_set, named_table, {write_concurrency, true}]); |
|
|
|
_ -> |
|
|
|
case ets:info(Name, id) of |
|
|
|
undefined -> |
|
|
|
ets:new(Name, [set, named_table, {write_concurrency, true}]); |
|
|
|
_ -> |
|
|
|
name_used |
|
|
|
end |
|
|
|
name_used |
|
|
|
end. |
|
|
|
|
|
|
|
-spec del(Name :: atom()) -> ok | error_lifo. |
|
|
|
del(Name) -> |
|
|
|
case persistent_term:get(Name, undefined) of |
|
|
|
undefined -> |
|
|
|
error_lifo; |
|
|
|
_ -> |
|
|
|
persistent_term:erase(Name), |
|
|
|
ets:delete(Name), |
|
|
|
ok |
|
|
|
end. |
|
|
|
ets:delete(Name). |
|
|
|
|
|
|
|
-spec in(Name :: atom(), Value :: term()) -> true | false | error_lifo. |
|
|
|
-spec in(Name :: atom(), Value :: term()) -> true. |
|
|
|
in(Name, Value) -> |
|
|
|
case persistent_term:get(Name, undefined) of |
|
|
|
undefined -> |
|
|
|
error_lifo; |
|
|
|
ARef -> |
|
|
|
in(ARef, Name, Value) |
|
|
|
end. |
|
|
|
|
|
|
|
in(ARef, Name, Value) -> |
|
|
|
Index = atomics:add_get(ARef, 1, 1), |
|
|
|
case ets:insert_new(Name, {Index, Value}) of |
|
|
|
true -> |
|
|
|
true; |
|
|
|
_ -> |
|
|
|
in(ARef, Name, Value) |
|
|
|
end. |
|
|
|
ets:insert(Name, {erlang:unique_integer(), Value}). |
|
|
|
|
|
|
|
-spec out(Name :: atom()) -> error_lifo | empty | Value :: term(). |
|
|
|
-spec out(Name :: atom()) -> empty | Value :: term(). |
|
|
|
out(Name) -> |
|
|
|
case persistent_term:get(Name, undefined) of |
|
|
|
undefined -> |
|
|
|
error_lifo; |
|
|
|
ARef -> |
|
|
|
out(ARef, Name) |
|
|
|
end. |
|
|
|
|
|
|
|
out(ARef, Name) -> |
|
|
|
Index = atomics:sub_get(ARef, 1, 1), |
|
|
|
case ets:take(Name, Index + 1) of |
|
|
|
[] -> |
|
|
|
case ets:info(Name, size) of |
|
|
|
0 -> |
|
|
|
empty; |
|
|
|
_ -> |
|
|
|
out(ARef, Name) |
|
|
|
end; |
|
|
|
[{_, Value}] -> |
|
|
|
Value |
|
|
|
do_out(Name). |
|
|
|
|
|
|
|
do_out(Name) -> |
|
|
|
case ets:last(Name) of |
|
|
|
'$end_of_table' -> |
|
|
|
empty; |
|
|
|
Key -> |
|
|
|
case ets:take(Name, Key) of |
|
|
|
[] -> |
|
|
|
do_out(Name); |
|
|
|
[{_, Value}] -> |
|
|
|
Value |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
-spec clear(Name :: atom()) -> error_lifo | ok. |
|
|
|
-spec clear(Name :: atom()) -> ok. |
|
|
|
clear(Name) -> |
|
|
|
case persistent_term:get(Name, undefined) of |
|
|
|
undefined -> |
|
|
|
error_lifo; |
|
|
|
_ -> |
|
|
|
ets:delete_all_objects(Name), |
|
|
|
ok |
|
|
|
end. |
|
|
|
ets:delete_all_objects(Name). |
|
|
|
|
|
|
|
-spec size(Name :: atom()) -> Size :: integer() | error_lifo. |
|
|
|
-spec size(Name :: atom()) -> Size :: integer() | undefined. |
|
|
|
size(Name) -> |
|
|
|
case ets:info(Name, size) of |
|
|
|
undefined -> |
|
|
|
error_lifo; |
|
|
|
Size -> |
|
|
|
Size |
|
|
|
end. |
|
|
|
ets:info(Name, size). |
|
|
|
|