Skip to content

Instantly share code, notes, and snippets.

@leonardb
Created December 31, 2021 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leonardb/47eee18b21f420e5ce62461be2bb3090 to your computer and use it in GitHub Desktop.
Save leonardb/47eee18b21f420e5ce62461be2bb3090 to your computer and use it in GitHub Desktop.
shq_atomics
-module(shq_atomics).
-export([init/1,
in/2,
in_r/2,
out/1,
out_r/1,
size/1,
test_in_out/1]).
-define(FRONT, 1).
-define(REAR, 2).
init(Tab) ->
Ref = ets:new(Tab, [public, set]),
ARef = atomics:new(2,[]), %% front is index 1, rear is index 2
{ok, {Ref, ARef}}.
in({Ref, ARef}, Value) ->
true = ets:insert(Ref, {atomics:add_get(ARef, ?REAR, 1) - 1, Value}),
ok.
in_r({Ref, ARef}, Value) ->
true = ets:insert(Ref, {atomics:add_get(ARef, ?FRONT, -1), Value}),
ok.
out({Ref, ARef}) ->
KF = atomics:add_get(ARef, ?FRONT, 1) - 1,
case ets:take(Ref, KF) of
[{_, V}] ->
{ok, V};
[] ->
%% reset counter
atomics:add_get(ARef, ?FRONT, -1),
empty
end.
out_r({Ref, ARef}) ->
KR1 = atomics:add_get(ARef, ?REAR, -1),
case ets:take(Ref, KR1) of
[{_, V}] ->
{ok, V};
[] ->
%% reset counter
atomics:add_get(ARef, ?REAR, 1),
empty
end.
size({_Ref, ARef}) ->
atomic:get(ARef, ?REAR) - atomics:get(ARef, ?FRONT).
test_in_out(Ref) ->
in(Ref, 0),
out(Ref).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment