Packages

A collection of simple data structures for use in non production settings.

Current section

Files

Jump to
simple_data_structures lib lru_cache.ex
Raw

lib/lru_cache.ex

defmodule SimpleDataStructures.LRUCache do
alias __MODULE__
@enforce_keys [:capacity]
defstruct lru: [], store: %{}, capacity: 2
def new(capacity \\ 2) do
%LRUCache{capacity: capacity}
end
def get(cache = %LRUCache{lru: lru, store: store}, key) do
case Map.get(store, key) do
nil -> {cache, -1}
n -> {%LRUCache{cache | lru: update_lru(lru, key)}, n}
end
end
def put(cache = %LRUCache{store: store, lru: lru}, key, value)
when :erlang.is_map_key(key, store) do
%LRUCache{cache | store: Map.put(store, key, value), lru: update_lru(lru, key)}
end
def put(cache = %LRUCache{capacity: cap, lru: lru}, key, value)
when length(lru) == cap do
cache
|> evict
|> put(key, value)
end
def put(cache = %LRUCache{store: store, lru: lru}, key, value) do
%LRUCache{cache | store: Map.put(store, key, value), lru: [key | lru]}
end
defp update_lru(lru, key) do
[key | List.delete(lru, key)]
end
defp evict(cache = %LRUCache{lru: lru}) when length(lru) == 0, do: cache
defp evict(cache = %LRUCache{lru: lru, store: store}) do
to_evict = List.last(lru)
%LRUCache{
cache
| store: Map.delete(store, to_evict),
lru: List.delete_at(lru, length(lru) - 1)
}
end
end