Skip to main content

Cacher

Important Attention Reminder

Coding Style wiki


Cacher is the capacity-bounded cache container family of Utilities, providing generic caches with three eviction strategies: ARCCache<TKey, TValue> (Adaptive Replacement), LRUCache<TKey, TValue> (Least Recently Used), and LRUKCache<TKey, TValue> (LRU-K, scan-resistant). All operations are protected by thread locks, and a custom removal handler IRemoveCacheHandler<TKey, TValue> can process values on eviction or removal.

NamespaceOxGKit.Utilities.Cacher
Typepublic class ARCCache<TKey, TValue>, public class LRUCache<TKey, TValue>, public class LRUKCache<TKey, TValue>
SourceARCCache.cs, LRUCache.cs, LRUKCache.cs
using OxGKit.Utilities.Cacher;

Important The default removal handler of all three caches is UnityObjectRemoveCacheHandler<TKey, TValue>: when the cached value is a UnityEngine.Object, eviction or removal automatically destroys the object. If cached values are still held and used externally, provide a custom IRemoveCacheHandler<TKey, TValue> to change this behavior.

Quick Start

using OxGKit.Utilities.Cacher;
using UnityEngine;

// Create an LRU cache with capacity 60
var cache = new LRUCache<string, Texture2D>(60);

// Add to the cache
cache.Add("key", texture);

// Get from the cache (returns default on miss)
Texture2D t2d = cache.Get("key");

// Check existence
bool contains = cache.Contains("key");

// Remove from the cache (the default handler destroys Unity objects)
cache.Remove("key");

// Clear the cache
cache.Clear();

// Custom removal handler (replaces the default UnityObjectRemoveCacheHandler)
public class MyRemoveCacheHandler : IRemoveCacheHandler<string, Texture2D>
{
public void RemoveCache(string key, Texture2D value)
{
// Decide what happens on eviction (e.g. do not Destroy)
}
}

var customCache = new LRUCache<string, Texture2D>(60, new MyRemoveCacheHandler());

General Rules

Choosing a Strategy

CacheStrategyBest for
ARCCache<TKey, TValue>Adaptive Replacement CacheMixed access patterns balancing recency and frequency.
LRUCache<TKey, TValue>Least Recently UsedPlain recency-based eviction (least recently used goes first).
LRUKCache<TKey, TValue>LRU-KScan resistance: an entry becomes "hot" only after K accesses; eviction removes the least recently used entry with the lowest popularity first.

Removal Handler

  • On eviction (capacity reached), Remove, and Clear, the cache calls IRemoveCacheHandler<TKey, TValue>.RemoveCache(key, value) for each removed value.
  • When not specified, the default is UnityObjectRemoveCacheHandler (automatically destroys Unity objects).

Thread Safety

  • GetKeys, Contains, Get, Add, Remove, Clear, and Count are all protected by lock in all three caches, so they can be used from multiple threads.

Attention The constructors of ARCCache and LRUCache throw ArgumentException when capacity is less than or equal to 0; LRUKCache performs no such check, so pass a sensible capacity and K value yourself.


ARCCache

Constructors

public ARCCache(int capacity)

public ARCCache(int capacity, IRemoveCacheHandler<TKey, TValue> removeCacheHandler)

Creates an ARC cache with the given capacity and an optional removal handler.

  • Behavior: internally managed by two linked lists, T1 (recency) and T2 (frequency). New keys enter T1; another hit (Get) or update (Add) promotes them to T2. When full, the tail of T1 is evicted first, then the tail of T2.
var arc = new ARCCache<string, Texture2D>(60);

LRUCache

Constructors

public LRUCache(int capacity)

public LRUCache(int capacity, IRemoveCacheHandler<TKey, TValue> removeCacheHandler)

Creates an LRU cache with the given capacity and an optional removal handler.

  • Behavior: Get and Add (update) move the node to the front of the list; when full, the least recently used entry (list tail) is evicted.
var lru = new LRUCache<string, Texture2D>(60);

LRUKCache

Constructors

public LRUKCache(int capacity, int k)

public LRUKCache(int capacity, int k, IRemoveCacheHandler<TKey, TValue> removeCacheHandler)

Creates an LRU-K cache with the given capacity, where k is the access-count threshold, and an optional removal handler.

  • Behavior: every Get / Add increments the key's counter (capped at K) and moves it to the list tail (most recently used); eviction starts from the least recently used end, removes the entry with the lowest counter, and decays the counters of the remaining entries.
var lruk = new LRUKCache<string, Texture2D>(60, 3);

Shared Members and Methods

The following members and methods are identical across ARCCache<TKey, TValue>, LRUCache<TKey, TValue>, and LRUKCache<TKey, TValue>.

Members

MemberDescription
public int CountCurrent number of cached entries.

Method Overview

MethodDescription
GetKeysGets an array of all cached keys.
ContainsChecks whether the given key exists in the cache.
GetGets the cached value for a key (updates its usage state).
AddAdds or updates a cache entry (triggers eviction when full).
RemoveRemoves the entry for a key (invokes the removal handler).
ClearClears all entries (invokes the removal handler for each).

GetKeys

public TKey[] GetKeys()

Gets an array of all cached keys.

Contains

public bool Contains(TKey key)

Checks whether the given key exists in the cache.

Get

public TValue Get(TKey key)

Gets the cached value for a key; returns default on a miss. On a hit, the usage state is updated per strategy (ARC promotes to T2 / LRU moves to the front / LRU-K increments the counter and moves to the tail).

Add

public void Add(TKey key, TValue value)

Adds or updates a cache entry; when the cache is full, an entry is evicted first, and the evicted value is passed to the removal handler.

Remove

public bool Remove(TKey key)

Removes the entry for a key; returns true on success. The removed value is passed to the removal handler (which destroys Unity objects by default).

Clear

public void Clear()

Clears all entries, invoking the removal handler for each one, then resets the internal structures.


IRemoveCacheHandler

public interface IRemoveCacheHandler<TKey, TValue>
{
void RemoveCache(TKey key, TValue value);
}

The removal handler interface (IRemoveCacheHandler.cs), invoked when a cache entry is evicted or removed. Implement it to customize behavior (e.g. return objects to a pool, release resources, or do nothing).

UnityObjectRemoveCacheHandler

public class UnityObjectRemoveCacheHandler<TKey, TValue> : IRemoveCacheHandler<TKey, TValue>

The default removal handler (UnityObjectRemoveCacheHandler.cs): when the cached value is a UnityEngine.Object, it calls UnityEngine.Object.Destroy on it.

Reminder If the cached value is not a Unity object (e.g. string or a custom class), the default handler does nothing; the entry is simply removed from the cache and left to the GC.