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(FJS, FJT) :: {lru_cache,
gleam@dict:dict(FJS, FJT),
gleam@dict:dict(FJS, FJT),
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(FKM, FKN), FKM, FKN) -> lru_cache(FKM, FKN).
keep(C, Key, Value) ->
case C of
{lru_cache, Active, Stale, Max, Key_count} ->
Key_count@1 = Key_count + 1,
Parts = case Key_count@1 > Max of
true ->
{gleam@dict:new(), Active, 1};
false ->
{Active, Stale, Key_count@1}
end,
Active@1 = gleam@dict:insert(erlang:element(1, Parts), Key, Value),
{lru_cache,
Active@1,
erlang:element(2, Parts),
Max,
erlang:element(3, Parts)}
end.
-spec get(lru_cache(FJY, FJZ), FJY) -> {ok, {lru_cache(FJY, FJZ), FJZ}} |
{error, nil}.
get(C, Key) ->
case C of
{lru_cache, Active, Stale, _, _} ->
Value_from_active = begin
_pipe = Active,
_pipe@1 = gleam@dict:get(_pipe, Key),
gleam@result:map(_pipe@1, fun(Val) -> {C, Val} end)
end,
Value_from_stale = begin
_pipe@2 = Stale,
_pipe@3 = gleam@dict:get(_pipe@2, Key),
gleam@result:map(
_pipe@3,
fun(Val@1) -> {keep(C, Key, Val@1), Val@1} end
)
end,
gleam@result:'or'(Value_from_active, Value_from_stale)
end.
-spec get_exn(lru_cache(FKG, FKH), FKG) -> {lru_cache(FKG, FKH), FKH}.
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 => 109})
end.
-spec set(lru_cache(FKR, FKS), FKR, FKS) -> lru_cache(FKR, FKS).
set(C, Key, Value) ->
case C of
{lru_cache, Active, Stale, Max, Key_count} ->
case gleam@dict:has_key(Active, Key) of
true ->
Next_active = gleam@dict:insert(Active, Key, Value),
{lru_cache, Next_active, Stale, Max, Key_count};
false ->
keep(C, Key, Value)
end
end.
-spec has(lru_cache(FKX, any()), FKX) -> boolean().
has(C, Key) ->
case C of
{lru_cache, Active, Stale, _, _} ->
_pipe@2 = gleam@result:'or'(
begin
_pipe = Active,
gleam@dict:get(_pipe, Key)
end,
begin
_pipe@1 = Stale,
gleam@dict:get(_pipe@1, Key)
end
),
gleam@result:is_ok(_pipe@2)
end.
-spec clear(lru_cache(FLB, FLC)) -> lru_cache(FLB, FLC).
clear(C) ->
case C of
{lru_cache, _, _, Max, _} ->
new(Max)
end.