Current section
Files
Jump to
Current section
Files
src/memhash_data.erl
-module(memhash_data).
-author('manuel@altenwald.com').
-compile([warnings_as_errors, {no_auto_import, [get/1]}]).
-export([start_link/0,
stop/0,
get/1,
get_links/1,
add/1,
set/2,
incr/1,
decr/1]).
-opaque table_id() :: pos_integer().
-export_type([table_id/0]).
start_link() ->
Tid = ets:new(?MODULE, [set, public]),
erlang:put(?MODULE, Tid),
ok.
stop() ->
Tid = erlang:get(?MODULE),
erlang:erase(?MODULE),
ets:delete(Tid),
ok.
-spec seq_id() -> table_id().
seq_id() ->
Tid = erlang:get(?MODULE),
update_counter(Tid, idx, 1, {idx, 0}).
-spec get(table_id()) -> term().
get(ID) ->
Tid = erlang:get(?MODULE),
case ets:lookup(Tid, {data, ID}) of
[] -> undefined;
[{{data, ID}, Data}] -> Data
end.
-spec get_links(table_id()) -> pos_integer().
get_links(ID) ->
Tid = erlang:get(?MODULE),
case ets:lookup(Tid, {links, ID}) of
[] -> undefined;
[{{links, ID}, Data}] -> Data
end.
-spec add(Data :: term()) -> table_id().
add(Data) ->
ID = seq_id(),
Tid = erlang:get(?MODULE),
ets:insert(Tid, [{{data, ID}, Data}, {{links, ID}, 1}]),
ID.
-spec set(table_id(), Data :: term()) -> ok.
set(ID, Data) ->
Tid = erlang:get(?MODULE),
ets:insert(Tid, {{data, ID}, Data}),
ok.
-spec incr(table_id()) -> ok.
incr(ID) ->
Tid = erlang:get(?MODULE),
update_counter(Tid, {links, ID}, 1, {idx, 0}),
ok.
-spec decr(table_id()) -> ok.
decr(ID) ->
Tid = erlang:get(?MODULE),
case update_counter(Tid, {links, ID}, -1, {idx, 0}) of
N when N =< 0 ->
ets:delete(Tid, {links, ID}),
ets:delete(Tid, {data, ID}),
ok;
_ ->
ok
end.
-ifdef(NO_ETS_UPDATE_DEFAULT).
update_counter(Tid, Key, Incr, Default) ->
try
ets:update_counter(Tid, Key, Incr)
catch error:badarg ->
ets:insert(Tid, Default)
end.
-else.
update_counter(Tid, Key, Incr, Default) ->
ets:update_counter(Tid, Key, Incr, Default).
-endif.