Twm.Cache (Twm v0.1.0)
View SourceLRU (Least Recently Used) cache implementation for Twm.
This module provides caching capabilities for Tailwind class merging operations to improve performance by avoiding redundant operations on the same class combinations. It also stores configuration and class group utilities in ETS tables for efficient access.
This module can be used in two ways:
- As a global cache for the main Twm functionality:
defmodule Twm.Application do
@moduledoc false
use Application
@impl true
def start(_type, _args) do
children = [
# Start the Twm.Cache with default configuration
{Twm.Cache, []}
]
opts = [strategy: :one_for_one, name: Twm.Supervisor]
Supervisor.start_link(children, opts)
end
end
You can also pass a custom cache name and configuration:
defmodule Twm.Application do
@moduledoc false
use Application
@impl true
def start(_type, _args) do
# Custom configuration
custom_config = Twm.Config.extend(cache_size: 1000)
children = [
# Start the Twm.Cache with custom name and configuration
{Twm.Cache, [name: :my_twm_cache, config: custom_config]}
]
opts = [strategy: :one_for_one, name: Twm.Supervisor]
Supervisor.start_link(children, opts)
end
end
- As custom cache instances for custom merge functions:
# Create a custom cache with a specific size
cache_pid = Twm.Cache.ensure_started(20, :cache_23231)
# Use the cache directly
Twm.Cache.put(cache_pid, "key", "value")
Summary
Functions
Returns a specification to start this module under a supervisor.
Clears all entries from the cache.
Ensures a cache server is started with the given size.
Retrieves a value from the cache by key.
Retrieves a value from the cache by key. If it is not present creates one, stores it and returns it.
Stores a key-value pair in the cache.
Changes the maximum capacity of the cache.
Returns the current size of the cache.
Starts the cache server.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor
.
@spec clear(GenServer.server()) :: :ok
Clears all entries from the cache.
Examples
# Start a cache server for doctest
iex> unique_number = Integer.to_string(:erlang.unique_integer([:positive]))
iex> cache_pid = Twm.Cache.ensure_started(10, String.to_atom("cache" <> unique_number))
iex> Twm.Cache.put(cache_pid, "key1", "value1")
:ok
iex> Twm.Cache.clear(cache_pid)
:ok
iex> Twm.Cache.get(cache_pid, "key1")
:error
@spec ensure_started(pos_integer(), atom() | nil) :: pid()
Ensures a cache server is started with the given size.
If a server with the provided name already exists, it returns its pid. Otherwise, it starts a new server with the given cache size.
Examples
iex> unique_number = Integer.to_string(:erlang.unique_integer([:positive]))
iex> cache_pid = Twm.Cache.ensure_started(100, String.to_atom("cache" <> unique_number))
iex> Twm.Cache.put(cache_pid, "key", "value")
:ok
iex> Twm.Cache.get(cache_pid, "key")
{:ok, "value"}
@spec get(GenServer.server(), any()) :: {:ok, any()} | :error
Retrieves a value from the cache by key.
Returns {:ok, value}
if the key exists, or :error
if it doesn't.
Examples
# Start a cache server for doctest
iex> unique_number = Integer.to_string(:erlang.unique_integer([:positive]))
iex> cache_pid = Twm.Cache.ensure_started(10, String.to_atom("cache" <> unique_number))
iex> Twm.Cache.put(cache_pid, "key1", "value1")
:ok
iex> Twm.Cache.get(cache_pid, "key1")
{:ok, "value1"}
iex> Twm.Cache.get(cache_pid, "nonexistent_key")
:error
@spec get_or_create(GenServer.server(), any()) :: {:ok, any()} | :error
Retrieves a value from the cache by key. If it is not present creates one, stores it and returns it.
Returns {:ok, value}
or :error
if the cache doesn't exist.
Examples
# Start a cache server for doctest
iex> unique_number = Integer.to_string(:erlang.unique_integer([:positive]))
iex> cache_pid = Twm.Cache.ensure_started(10, String.to_atom("cache" <> unique_number))
iex> Twm.Cache.put(cache_pid, "key1", "value1")
:ok
iex> Twm.Cache.get(cache_pid, "key1")
{:ok, "value1"}
iex> Twm.Cache.get(cache_pid, "nonexistent_key")
:error
@spec put(GenServer.server(), any(), any()) :: :ok
Stores a key-value pair in the cache.
If the key already exists, its value is updated and it becomes the most recently used. If the cache is full, the least recently used entry is removed.
Examples
# Start a cache server for doctest
iex> unique_number = Integer.to_string(:erlang.unique_integer([:positive]))
iex> cache_pid = Twm.Cache.ensure_started(10, String.to_atom("cache" <> unique_number))
iex> Twm.Cache.put(cache_pid, "key1", "value1")
:ok
iex> Twm.Cache.get(cache_pid, "key1")
{:ok, "value1"}
@spec resize(GenServer.server(), pos_integer()) :: :ok
Changes the maximum capacity of the cache.
If the new size is smaller than the current number of entries, the least recently used entries are removed until the cache fits the new size.
Examples
# Start a cache server for doctest
iex> unique_number = Integer.to_string(:erlang.unique_integer([:positive]))
iex> cache_pid = Twm.Cache.ensure_started(100, String.to_atom("cache" <> unique_number))
iex> # Fill cache with a few entries
iex> Twm.Cache.put(cache_pid, "key1", "value1")
:ok
iex> Twm.Cache.put(cache_pid, "key2", "value2")
:ok
iex> Twm.Cache.resize(cache_pid, 1)
:ok
iex> Twm.Cache.size(cache_pid)
1
@spec size(GenServer.server()) :: non_neg_integer()
Returns the current size of the cache.
Examples
# Start a cache server for doctest
iex> unique_number = Integer.to_string(:erlang.unique_integer([:positive]))
iex> cache_pid = Twm.Cache.ensure_started(10, String.to_atom("cache" <> unique_number))
iex> Twm.Cache.put(cache_pid, "key1", "value1")
:ok
iex> Twm.Cache.put(cache_pid, "key2", "value2")
:ok
iex> Twm.Cache.size(cache_pid)
2
@spec start_link(keyword()) :: GenServer.on_start()
Starts the cache server.
Options
:name
- The name to register the cache process with. Defaults toTwm.Cache
.:cache_size
- The maximum number of entries in the cache. Defaults to 500.