cache
Advanced caching strategies - LRU (least-recently-used), LFU (least-frequently-used), TTL (time-to-live), distributed consistent-hash cache, memoising function decorator, and a named cache manager. All with hit-rate stats tracking.
Load with: use cache
What this module does
cache provides four cache eviction strategies and two higher-level
abstractions on top of them. Every cache tracks hits, misses, sets, deletes, and
evictions in a stats object, readable via cchst.
- LRU: evicts the least-recently-accessed key when full. Access order is maintained via an explicit list.
- LFU: evicts the least-frequently-accessed key. Maintains per-key frequency counts and frequency-group buckets, advancing the minimum-frequency pointer on eviction.
- TTL: evicts entries whose expiry time has passed. A sorted heap (by expiry) provides efficient expired-entry sweeping before each set. Evicts the soonest-expiring entry when the cache is full.
- Distributed: consistent-hash ring across named nodes with 150 virtual nodes each. Checks a local LRU cache first, then routes to the responsible node.
The decorator wraps any function so that its results are cached by argument value. The manager holds multiple named caches and provides a unified get/set interface.
Quick example
use cache
# LRU cache - max 100 entries
lru = cchxa("my-lru", 100)
cchna(lru, "user:1", {name: "Alice"}, 0)
prn(cchma(lru, "user:1")) # {name: "Alice"}
# TTL cache - 5-minute expiry
ttl = cchza("my-ttl", 500)
cchsa(ttl, "session:abc", {uid: 42}, 300) # 300s TTL
prn(cchra(ttl, "session:abc"))
# Polymorphic get/set/delete (works on any cache type)
cache = cchxa("x", 50)
cch2a(cache, "k", "v", nil)
prn(cchgt(cache, "k")) # "v"
cchdl(cache, "k")
# Memoize a slow function
dec = cchta("lru", 1000, 60)
cached_fn = cchua(dec, slow_fn, nil)
prn(cached_fn(42))
Functions
LRU cache
cchxa(name, capacity)
Creates an LRU cache. capacity defaults to 1000. Type field is "lru".
cchma(cache, key)
Gets a value. If the entry exists and is not TTL-expired, moves the key to the end of the access order (most recently used) and increments hits. Returns nil on miss or expiry.
cchna(cache, key, value, ttl)
Sets a value. If the cache is full and the key is new, evicts the LRU entry first. Updates the access order. ttl of 0 means no expiry.
cchlr(cache, key)
Deletes a key from the LRU cache. Returns tru if found and deleted, fls if not present.
cchda(cache)
Evicts the LRU entry (the first key in access order).
cchea(cache)
Returns stats: name, capacity, current size, hits, misses, hit rate %, sets, deletes, evictions.
LFU cache
cchwa(name, capacity)
Creates an LFU cache. Maintains frequencies (key → count), frequency_groups (count → [keys]), and min_frequency.
cchka(cache, key)
Gets a value. Increments the key's frequency, moves it to the correct frequency group, updates min_frequency if the old group is now empty.
cchla(cache, key, value, ttl)
Sets a value with initial frequency 1. Evicts the least-frequent key first if at capacity.
cchlf(cache, key)
Deletes a key from the LFU cache, cleaning up frequency group membership.
cchca(cache)
Evicts the first key from the minimum-frequency group. Advances min_frequency if that group is now empty.
TTL cache
cchza(name, max_size)
Creates a TTL cache. Uses a heap sorted by expiry time to efficiently find expired entries.
cchra(cache, key)
Gets a value, checking expires_at against tim.now(). Returns nil and deletes the entry if expired.
cchsa(cache, key, value, ttl)
Sets a value with expiry at now + ttl seconds (default 3600). Sweeps expired entries first, then evicts the soonest-expiring entry if full. Adds entry to the sorted heap.
cchaa(cache, key)
Deletes a key from the TTL cache.
cchtt(cache)
Sweeps expired entries by scanning the front of the heap until a non-expired entry is found. Removes expired keys from both the heap and entries map.
cchga(cache)
Evicts the soonest-expiring entry (heap front).
Distributed cache (consistent hashing)
cchia(name, nodes, hash_function)
Creates a distributed cache across a list of node addresses. Builds a consistent-hash ring with 150 virtual nodes per address. Each node also gets a local LRU cache (1000 entries). Default hash function: "consistent".
cchja(cache, key)
Gets a value. Checks the local LRU cache first. If not found, routes to the responsible node via cchba and caches the result locally with a 300s TTL.
cchha(cache, key, value, ttl)
Sets a value in the local LRU and routes to the responsible remote node.
cchba(cache, key)
Finds the responsible node for a key by hashing the key and finding the first ring entry with hash >= key_hash. Wraps to the first ring entry if no entry is ≥.
Cache decorator (memoization)
cchta(cache_type, capacity, ttl)
Creates a decorator config backed by an LRU or TTL cache of the given capacity and default TTL.
cchua(decorator, fn, key_func)
Wraps fn with caching. key_func generates the cache key from arguments - defaults to str(args) if nil. Returns a new function that transparently caches results.
Cache manager
cchya()
Creates a new cache manager with an empty caches map and no default cache.
cchoa(manager, name, cache)
Registers a cache. The first registered cache becomes the default.
cchpa(manager, name)
Returns the named cache object.
cchpad(manager)
Returns the default cache object.
cchqa(manager, name, key, value, ttl)
Sets a key in the named cache (type-aware: LRU or TTL).
cchqad(manager, key, value, ttl)
Sets a key in the default cache.
cchmg(manager, name, key)
Gets a key from the named cache.
cchmgd(manager, key)
Gets a key from the default cache.
cchfa(manager)
Returns a stats object for all registered caches, keyed by cache name.
Polymorphic helpers
cchgt(cache, key)
Gets from any cache type - dispatches on cache.type to cchma, cchra, or cchka.
cch2a(cache, key, value, ttl)
Sets in any cache type.
cchdl(cache, key)
Deletes from any cache type. Returns tru on success.
cchst(cache)
Returns stats for any cache type.
Notes
- TTL values are in seconds. Pass
0as TTL to an LRU entry to skip expiry checking. - The distributed cache's "remote get" is a stub that returns a placeholder string - integrate with real remote calls for production use.
- Default instances are available:
deflru,deflfu,defttl,defdistributed,defdecorator,defmanager. - Requires
trl,txt,jsn,tim, andobs.