-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.