Current section
Files
Jump to
Current section
Files
src/rememo@otp@memo.erl
-module(rememo@otp@memo).
-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(HWA, HWB) :: shutdown |
{get, HWA, gleam@erlang@process:subject({ok, HWB} | {error, nil})} |
{set, HWA, HWB}.
-opaque cache(HWC, HWD) :: {cache,
gleam@erlang@process:subject(message(HWC, HWD))}.
-spec handle_message(message(HWJ, HWK), gleam@dict:dict(HWJ, HWK)) -> gleam@otp@actor:next(message(HWJ, HWK), gleam@dict:dict(HWJ, HWK)).
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())) -> HWZ)) -> HWZ.
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/otp/memo"/utf8>>,
function => <<"create"/utf8>>,
line => 47})
end,
Result = Fun({cache, Server}),
gleam@erlang@process:send(Server, shutdown),
Result.
-spec set(cache(HXA, HXB), HXA, HXB) -> nil.
set(Cache, Key, Value) ->
gleam@erlang@process:send(erlang:element(2, Cache), {set, Key, Value}).
-spec get(cache(HXE, HXF), HXE) -> {ok, HXF} | {error, nil}.
get(Cache, Key) ->
gleam@erlang@process:call(
erlang:element(2, Cache),
fun(C) -> {get, Key, C} end,
1000
).
-spec memoize(cache(HXK, HXL), HXK, fun(() -> HXL)) -> HXL.
memoize(Cache, Key, Fun) ->
Result = case get(Cache, Key) of
{ok, Value} ->
Value;
{error, nil} ->
Fun()
end,
set(Cache, Key, Result),
Result.