Current section
Files
Jump to
Current section
Files
src/glimit@memory_store.erl
-module(glimit@memory_store).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/glimit/memory_store.gleam").
-export([pid/1, new/2, make_store/1, get_count/1, remove/2, sweep/3]).
-export_type([memory_store/0, state/0, msg/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-opaque memory_store() :: {memory_store, gleam@erlang@process:subject(msg())}.
-type state() :: {state,
gleam@dict:dict(binary(), glimit@bucket:bucket_state()),
gleam@option:option(integer()),
integer(),
gleam@erlang@process:subject(msg())}.
-type msg() :: {get,
binary(),
gleam@erlang@process:subject(gleam@option:option(glimit@bucket:bucket_state()))} |
{set,
binary(),
glimit@bucket:bucket_state(),
gleam@erlang@process:subject(nil)} |
{sweep,
integer(),
gleam@option:option(integer()),
gleam@erlang@process:subject(nil)} |
sweep_timer |
{get_count, gleam@erlang@process:subject(integer())} |
{remove, binary(), gleam@erlang@process:subject(nil)}.
-file("src/glimit/memory_store.gleam", 141).
?DOC(false).
-spec is_idle(
glimit@bucket:bucket_state(),
integer(),
gleam@option:option(integer())
) -> boolean().
is_idle(B, Now, Max_idle_ms) ->
case Max_idle_ms of
none ->
false;
{some, Threshold} ->
case erlang:element(5, B) of
none ->
true;
{some, Last_update} ->
(Now - Last_update) > Threshold
end
end.
-file("src/glimit/memory_store.gleam", 130).
?DOC(false).
-spec do_sweep(
gleam@dict:dict(binary(), glimit@bucket:bucket_state()),
integer(),
gleam@option:option(integer())
) -> gleam@dict:dict(binary(), glimit@bucket:bucket_state()).
do_sweep(Data, Now, Max_idle_ms) ->
_pipe = Data,
gleam@dict:filter(
_pipe,
fun(_, B) ->
not glimit@bucket:is_full(B, Now) andalso not is_idle(
B,
Now,
Max_idle_ms
)
end
).
-file("src/glimit/memory_store.gleam", 152).
?DOC(false).
-spec schedule_sweep(state()) -> nil.
schedule_sweep(State) ->
_ = gleam@erlang@process:send_after(
erlang:element(5, State),
erlang:element(4, State),
sweep_timer
),
nil.
-file("src/glimit/memory_store.gleam", 91).
?DOC(false).
-spec handle_message(state(), msg()) -> gleam@otp@actor:next(state(), msg()).
handle_message(State, Msg) ->
case Msg of
{get, Key, Reply} ->
gleam@otp@actor:send(
Reply,
begin
_pipe = gleam_stdlib:map_get(erlang:element(2, State), Key),
gleam@option:from_result(_pipe)
end
),
gleam@otp@actor:continue(State);
{set, Key@1, Bucket_state, Reply@1} ->
Data = gleam@dict:insert(
erlang:element(2, State),
Key@1,
Bucket_state
),
gleam@otp@actor:send(Reply@1, nil),
gleam@otp@actor:continue(
{state,
Data,
erlang:element(3, State),
erlang:element(4, State),
erlang:element(5, State)}
);
{sweep, Now, Max_idle_ms, Reply@2} ->
Data@1 = do_sweep(erlang:element(2, State), Now, Max_idle_ms),
gleam@otp@actor:send(Reply@2, nil),
gleam@otp@actor:continue(
{state,
Data@1,
erlang:element(3, State),
erlang:element(4, State),
erlang:element(5, State)}
);
sweep_timer ->
Now@1 = glimit@utils:now(),
Data@2 = do_sweep(
erlang:element(2, State),
Now@1,
erlang:element(3, State)
),
schedule_sweep(State),
gleam@otp@actor:continue(
{state,
Data@2,
erlang:element(3, State),
erlang:element(4, State),
erlang:element(5, State)}
);
{get_count, Reply@3} ->
gleam@otp@actor:send(Reply@3, maps:size(erlang:element(2, State))),
gleam@otp@actor:continue(State);
{remove, Key@2, Reply@4} ->
Data@3 = gleam@dict:delete(erlang:element(2, State), Key@2),
gleam@otp@actor:send(Reply@4, nil),
gleam@otp@actor:continue(
{state,
Data@3,
erlang:element(3, State),
erlang:element(4, State),
erlang:element(5, State)}
)
end.
-file("src/glimit/memory_store.gleam", 160).
?DOC(false).
-spec pid(memory_store()) -> {ok, gleam@erlang@process:pid_()} | {error, nil}.
pid(Store) ->
gleam@erlang@process:subject_owner(erlang:element(2, Store)).
-file("src/glimit/memory_store.gleam", 45).
?DOC(false).
-spec new(gleam@option:option(integer()), integer()) -> {ok, memory_store()} |
{error, nil}.
new(Max_idle_ms, Sweep_interval_ms) ->
Start_result = begin
_pipe@1 = gleam@otp@actor:new_with_initialiser(
1000,
fun(Self_subject) ->
State = {state,
maps:new(),
Max_idle_ms,
Sweep_interval_ms,
Self_subject},
schedule_sweep(State),
{ok,
begin
_pipe = gleam@otp@actor:initialised(State),
gleam@otp@actor:returning(_pipe, Self_subject)
end}
end
),
_pipe@2 = gleam@otp@actor:on_message(_pipe@1, fun handle_message/2),
gleam@otp@actor:start(_pipe@2)
end,
case Start_result of
{ok, Started} ->
{ok, {memory_store, erlang:element(3, Started)}};
{error, _} ->
{error, nil}
end.
-file("src/glimit/memory_store.gleam", 79).
?DOC(false).
-spec make_store(memory_store()) -> glimit@bucket:store().
make_store(Store) ->
{store,
fun(Key) ->
glimit@utils:safe_call(
erlang:element(2, Store),
fun(_capture) -> {get, Key, _capture} end,
1000
)
end,
fun(Key@1, State, _) ->
glimit@utils:safe_call(
erlang:element(2, Store),
fun(_capture@1) -> {set, Key@1, State, _capture@1} end,
1000
)
end,
fun(_) -> {ok, nil} end}.
-file("src/glimit/memory_store.gleam", 166).
?DOC(false).
-spec get_count(memory_store()) -> integer().
get_count(Store) ->
_pipe = glimit@utils:safe_call(
erlang:element(2, Store),
fun(Field@0) -> {get_count, Field@0} end,
1000
),
gleam@result:unwrap(_pipe, 0).
-file("src/glimit/memory_store.gleam", 173).
?DOC(false).
-spec remove(memory_store(), binary()) -> {ok, nil} | {error, nil}.
remove(Store, Key) ->
glimit@utils:safe_call(
erlang:element(2, Store),
fun(_capture) -> {remove, Key, _capture} end,
1000
).
-file("src/glimit/memory_store.gleam", 179).
?DOC(false).
-spec sweep(memory_store(), integer(), gleam@option:option(integer())) -> {ok,
nil} |
{error, nil}.
sweep(Store, Now, Max_idle_ms) ->
glimit@utils:safe_call(
erlang:element(2, Store),
fun(_capture) -> {sweep, Now, Max_idle_ms, _capture} end,
1000
).