Current section
Files
Jump to
Current section
Files
src/immutable_lru.erl
-module(immutable_lru).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([new/1, get/2, get_exn/2, set/3, has/2, clear/1]).
-export_type([lru_cache/2]).
-opaque lru_cache(FWG, FWH) :: {lru_cache,
gleam@dict:dict(FWG, FWH),
gleam@dict:dict(FWG, FWH),
integer(),
integer()}.
-spec new(integer()) -> lru_cache(any(), any()).
new(Max) ->
Active = gleam@dict:new(),
Stale = gleam@dict:new(),
{lru_cache, Active, Stale, Max, 0}.
-spec keep(lru_cache(FXA, FXB), FXA, FXB) -> lru_cache(FXA, FXB).
keep(Cache, Key, Value) ->
Key_count = erlang:element(5, Cache) + 1,
{Active, Stale, Key_count@1} = case Key_count > erlang:element(4, Cache) of
true ->
{gleam@dict:new(), erlang:element(2, Cache), 1};
false ->
{erlang:element(2, Cache), erlang:element(3, Cache), Key_count}
end,
Active@1 = gleam@dict:insert(Active, Key, Value),
erlang:setelement(
5,
erlang:setelement(3, erlang:setelement(2, Cache, Active@1), Stale),
Key_count@1
).
-spec get(lru_cache(FWM, FWN), FWM) -> {ok, {lru_cache(FWM, FWN), FWN}} |
{error, nil}.
get(Cache, Key) ->
_pipe = erlang:element(2, Cache),
_pipe@1 = gleam@dict:get(_pipe, Key),
_pipe@2 = gleam@result:map(_pipe@1, fun(Val) -> {Cache, Val} end),
gleam@result:lazy_or(_pipe@2, fun() -> _pipe@3 = erlang:element(3, Cache),
_pipe@4 = gleam@dict:get(_pipe@3, Key),
gleam@result:map(
_pipe@4,
fun(Val@1) -> {keep(Cache, Key, Val@1), Val@1} end
) end).
-spec get_exn(lru_cache(FWU, FWV), FWU) -> {lru_cache(FWU, FWV), FWV}.
get_exn(C, Key) ->
case get(C, Key) of
{ok, Pair} ->
Pair;
_ ->
erlang:error(#{gleam_error => panic,
message => <<"key not found in cache"/utf8>>,
module => <<"immutable_lru"/utf8>>,
function => <<"get_exn"/utf8>>,
line => 103})
end.
-spec set(lru_cache(FXG, FXH), FXG, FXH) -> lru_cache(FXG, FXH).
set(Cache, Key, Value) ->
case gleam@dict:has_key(erlang:element(2, Cache), Key) of
true ->
Active = gleam@dict:insert(erlang:element(2, Cache), Key, Value),
erlang:setelement(2, Cache, Active);
false ->
keep(Cache, Key, Value)
end.
-spec has(lru_cache(FXM, any()), FXM) -> boolean().
has(Cache, Key) ->
_pipe = erlang:element(2, Cache),
_pipe@1 = gleam@dict:get(_pipe, Key),
_pipe@3 = gleam@result:lazy_or(
_pipe@1,
fun() -> _pipe@2 = erlang:element(3, Cache),
gleam@dict:get(_pipe@2, Key) end
),
gleam@result:is_ok(_pipe@3).
-spec clear(lru_cache(FXQ, FXR)) -> lru_cache(FXQ, FXR).
clear(Cache) ->
new(erlang:element(4, Cache)).