04 / DATA
collection
A cache with a size limit and an optional expiry over a doubly linked recency list, so a hit is constant work, and a fixed-size ring that keeps the newest samples.
WHERE IT SITS
INTERFACE
struct Cache[K, V]structA cache with a size limit and an optional expiry: reads move an entry to the front, and the least recently used entry is the one evicted when the limit is reached. The recency order is a doubly linked list threaded through links, so a hit costs a constant number of map operations whatever the cache holds. An entry whose time is up is dropped on the next read rather than by a background sweep — a cache here is a performance device, not a store, so there is nothing to reclaim on a timer.
fn[K : Hash + Eq, V] Cache::new( limit~ : Int32 = 1024, ttl_ms~ : Int64 = 0L, clock~ : @clock.Clock = @clock.Clock::system()) -> Cache[K, V]itemA cache holding at most limit entries, each valid for ttl_ms milliseconds (0 for no expiry), reading time from clock. # Parameters - limit : entries kept before the least recently used is evicted - ttl_ms : how long an entry stays valid, 0 for forever - clock : the time source an expiry is measured against
fn[K, V] Cache::len(self : Cache[K, V]) -> Int32itemHow many entries are held, expired ones included until they are read.
fn[K, V] Cache::limit(self : Cache[K, V]) -> Int32itemThe configured limit.
fn[K : Hash + Eq, V] Cache::remove(self : Cache[K, V], key : K) -> UnititemRemove key from both the entries and the recency list.
fn[K : Hash + Eq, V] Cache::set( self : Cache[K, V], key : K, value : V) -> UnititemStore value under key, evicting the least recently used entry when the cache is full. Storing an existing key refreshes its value, its expiry and its place in the recency list.
fn[K : Hash + Eq, V] Cache::set_until( self : Cache[K, V], key : K, value : V, ttl_ms : Int64) -> UnititemStore value under key with its own lifetime in milliseconds; 0 means it never expires.
fn[K : Hash + Eq, V] Cache::get(self : Cache[K, V], key : K) -> V?itemThe value under key if it is there and still valid. Reading moves the entry to the front of the recency list; an expired one is dropped.
fn[K : Hash + Eq, V] Cache::contains(self : Cache[K, V], key : K) -> BoolitemWhether a valid value is under key, without changing the recency order.
fn[K : Hash + Eq, V] Cache::keys(self : Cache[K, V]) -> Array[K]itemThe keys in recency order, most recent first, expired ones excluded.
struct Ring[T]structA fixed-size circular buffer: pushing past the capacity overwrites the oldest sample. What a service keeps its last N events, timings or failures in.
fn[T] Ring::new(capacity : Int32) -> Ring[T]itemA ring holding at most capacity items. # Parameters - capacity : how many items it keeps; 0 is raised to 1, because a ring of nothing could never hold a sample
fn[T] Ring::push(self : Ring[T], item : T) -> UnititemAppend a sample, overwriting the oldest one when the ring is full.
fn[T] Ring::get(self : Ring[T], i : Int32) -> T?itemThe sample i places from the oldest, or None past the end.
fn[T] Ring::last(self : Ring[T]) -> T?itemThe newest sample.
fn[T] Ring::len(self : Ring[T]) -> Int32itemHow many samples are held.
fn[T] Ring::capacity(self : Ring[T]) -> Int32itemThe capacity it was built with.
fn[T] Ring::to_array(self : Ring[T]) -> Array[T]itemThe samples, oldest first.