Erlang bounded LRU cache with map and list
Erlang
-module(lru_cache).
-export([new/1, get/2, put/3]).
new(Cap) -> #{cap => Cap, order => [], data => #{}}.
get(Key, C = #{data := D, order := O}) ->
case maps:find(Key, D) of
{ok, V} -> {ok, V, C#{order => [Key | lists:delete(Key, O)]}};
error -> {error, C}
end.
put(Key, Val, C = #{cap := Cap, data := D, order := O0}) ->
O1 = [Key | lists:delete(Key, O0)],
D1 = D#{Key => Val},
case length(O1) > Cap of
true ->
Oldest = lists:last(O1),
Keep = lists:sublist(O1, Cap),
{evicted, Oldest, C#{data => maps:remove(Oldest, D1), order => Keep}};
false ->
{ok, C#{data => D1, order => O1}}
end.