View Source ExKits.Cache.LRU (ex_kits v0.2.7)

This modules implements a simple LRU cache, using 2 ets tables for it.

For using it, you need to start it:

iex> LRU.start_link(:my_cache, 1000)

Or add it to your supervisor tree, like: worker(LRU, [:my_cache, 1000])

Using

iex> LRU.start_link(:my_cache, 1000)
{:ok, #PID<0.60.0>}

iex> LRU.put(:my_cache, "id", "value")
:ok

iex> LRU.get(:my_cache, "id", touch = false)
"value"

To take some action when old keys are evicted from the cache when it is full, you can pass an :evict_fn option to LRU.start_link/3. This is helpful for cleaning up processes that depend on values in the cache, or logging, or instrumentation of cache evictions etc.

iex> evict = fn(key,value) -> IO.inspect("#{key}=#{value} evicted") end
iex> LRU.start_link(:my_cache, 10, evict_fn: evict)
{:ok, #PID<0.60.0>}

Design

First ets table save the key values pairs, the second save order of inserted elements.

Summary

Functions

Removes the entry stored under the given key from cache.

Returns the value associated with key in cache. If cache does not contain key, returns nil. touch defines, if the order in LRU should be actualized.

Stores the given value under key in cache. If cache already has key, the stored value is replaced by the new one. This updates the order of LRU cache.

Selects and returns the first value in the cache that matches the given condition.

Creates an LRU of the given size as part of a supervision tree with a registered name

Updates a value in cache. If key is not present in cache then nothing is done. touch defines, if the order in LRU should be actualized. The function assumes, that the element exists in a cache.

Types

@type t() :: %ExKits.Cache.LRU{
  evict_fn: nil | (atom(), atom() -> any()),
  size: non_neg_integer(),
  table: atom(),
  ttl_table: atom()
}

Functions

Link to this function

delete(name, key, timeout \\ 5000)

View Source
@spec delete(atom(), any(), non_neg_integer()) :: :ok

Removes the entry stored under the given key from cache.

Link to this function

get(name, key, touch \\ true, timeout \\ 5000)

View Source
@spec get(atom(), any(), boolean(), non_neg_integer()) :: any()

Returns the value associated with key in cache. If cache does not contain key, returns nil. touch defines, if the order in LRU should be actualized.

Link to this function

put(name, key, value, timeout \\ 5000)

View Source
@spec put(atom(), any(), any(), non_neg_integer()) :: :ok

Stores the given value under key in cache. If cache already has key, the stored value is replaced by the new one. This updates the order of LRU cache.

Link to this function

select(name, match_fun, timeout \\ 5000)

View Source
@spec select(atom(), (any() -> boolean()), non_neg_integer()) :: any()

Selects and returns the first value in the cache that matches the given condition.

Examples

iex> LRU.select(:my_cache, fn value -> value > 10 end)
15

Parameters

  • name - The name of the cache.
  • match_fun - A function that takes a value and returns a boolean indicating whether it matches the condition.
  • timeout (optional) - The timeout value in milliseconds for the operation. Defaults to 5000.

Returns

The first value in the cache that matches the given condition, or nil if no match is found.

Link to this function

start_link(name, size, opts \\ [])

View Source
@spec start_link(atom(), non_neg_integer(), Keyword.t()) :: Agent.on_start()

Creates an LRU of the given size as part of a supervision tree with a registered name

Options

  • :evict_fn - function that accepts (key, value) and takes some action when keys are evicted when the cache is full.
Link to this function

update(name, key, value, touch \\ true, timeout \\ 5000)

View Source
@spec update(atom(), any(), any(), boolean(), non_neg_integer()) :: :ok

Updates a value in cache. If key is not present in cache then nothing is done. touch defines, if the order in LRU should be actualized. The function assumes, that the element exists in a cache.