Current section
Files
Jump to
Current section
Files
src/rememo.erl
-module(rememo).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([create/1, set/3, get/2, memoize/3]).
-export_type([message/2, cache/2]).
-type message(GYN, GYO) :: shutdown |
{get, GYN, gleam@erlang@process:subject({ok, GYO} | {error, nil})} |
{set, GYN, GYO}.
-opaque cache(GYP, GYQ) :: {cache,
gleam@erlang@process:subject(message(GYP, GYQ))}.
-spec handle_message(message(GYW, GYX), gleam@dict:dict(GYW, GYX)) -> gleam@otp@actor:next(message(GYW, GYX), gleam@dict:dict(GYW, GYX)).
handle_message(Message, Dict) ->
case Message of
shutdown ->
{stop, normal};
{get, Key, Client} ->
gleam@erlang@process:send(Client, gleam@dict:get(Dict, Key)),
{continue, Dict, none};
{set, Key@1, Value} ->
{continue, gleam@dict:insert(Dict, Key@1, Value), none}
end.
-spec create(fun((cache(any(), any())) -> GZM)) -> GZM.
create(Fun) ->
_assert_subject = gleam@otp@actor:start(
gleam@dict:new(),
fun handle_message/2
),
{ok, Server} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"rememo"/utf8>>,
function => <<"create"/utf8>>,
line => 44})
end,
Result = Fun({cache, Server}),
gleam@erlang@process:send(Server, shutdown),
Result.
-spec set(cache(GZN, GZO), GZN, GZO) -> nil.
set(Cache, Key, Value) ->
gleam@erlang@process:send(erlang:element(2, Cache), {set, Key, Value}).
-spec get(cache(GZR, GZS), GZR) -> {ok, GZS} | {error, nil}.
get(Cache, Key) ->
gleam@erlang@process:call(
erlang:element(2, Cache),
fun(C) -> {get, Key, C} end,
1000
).
-spec memoize(cache(GZX, GZY), GZX, fun(() -> GZY)) -> GZY.
memoize(Cache, Key, Fun) ->
Result = case get(Cache, Key) of
{ok, Value} ->
Value;
{error, nil} ->
Fun()
end,
set(Cache, Key, Result),
Result.