Bounded LRU cache with explicit Elixir state
Elixir
defmodule LruCache do
def new(capacity) when is_integer(capacity) and capacity > 0, do: %{capacity: capacity, data: %{}, order: []}
def get(cache, key) do
case Map.fetch(cache.data, key) do
{:ok, value} -> {value, touch(cache, key)}
:error -> {nil, cache}
end
end
def put(cache, key, value) do
data = Map.put(cache.data, key, value)
order = [key | List.delete(cache.order, key)]
{dropped, kept} = Enum.split(order, cache.capacity)
{Enum.reverse(dropped), %{cache | data: Map.drop(data, dropped), order: kept}}
end
defp touch(%{order: order} = cache, key), do: %{cache | order: [key | List.delete(order, key)]}
end