跳到主要内容

Cacher

重要 注意 提醒

Coding Style wiki


CacherUtilities容量控制缓存容器,提供三种淘汰策略的泛型缓存:ARCCache<TKey, TValue> (自适应替换)、LRUCache<TKey, TValue> (最近最少使用)、LRUKCache<TKey, TValue> (LRU-K 扫描防护),所有操作皆有线程锁 (Thread Lock),并支持自定义移除处理器 IRemoveCacheHandler<TKey, TValue> 于淘汰或移除时对缓存值进行特殊处理。

命名空间OxGKit.Utilities.Cacher
类型public class ARCCache<TKey, TValue>public class LRUCache<TKey, TValue>public class LRUKCache<TKey, TValue>
源码ARCCache.csLRUCache.csLRUKCache.cs
using OxGKit.Utilities.Cacher;

重要 三种缓存的默认移除处理器皆为 UnityObjectRemoveCacheHandler<TKey, TValue>,当缓存值为 UnityEngine.Object 时,淘汰或移除会自动 Destroy 该对象;若缓存值仍会被外部持有使用,请自定义 IRemoveCacheHandler<TKey, TValue> 更换处理行为。

快速上手

using OxGKit.Utilities.Cacher;
using UnityEngine;

// 创建容量 60 的 LRU 缓存
var cache = new LRUCache<string, Texture2D>(60);

// 加入缓存
cache.Add("key", texture);

// 获取缓存 (未命中返回 default)
Texture2D t2d = cache.Get("key");

// 检查是否存在
bool contains = cache.Contains("key");

// 移除缓存 (默认处理器会自动 Destroy Unity 对象)
cache.Remove("key");

// 清空缓存
cache.Clear();

// 自定义移除处理器 (取代默认的 UnityObjectRemoveCacheHandler)
public class MyRemoveCacheHandler : IRemoveCacheHandler<string, Texture2D>
{
public void RemoveCache(string key, Texture2D value)
{
// 自行决定淘汰时的处理 (例如不进行 Destroy)
}
}

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

通用规则

策略选择

缓存策略适用场景
ARCCache<TKey, TValue>Adaptive Replacement Cache兼顾新近性与频率的混合访问模式。
LRUCache<TKey, TValue>Least Recently Used单纯以新近性淘汰 (最久未使用先淘汰)。
LRUKCache<TKey, TValue>LRU-K扫描防护,需累积 K 次访问才视为热门,淘汰时优先移除最久未使用且人气最低的项目。

淘汰处理器

  • 淘汰 (容量满) 与 RemoveClear 时,会调用 IRemoveCacheHandler<TKey, TValue>.RemoveCache(key, value) 对移除的缓存值进行处理。
  • 未指定时,默认为 UnityObjectRemoveCacheHandler (自动 Destroy Unity 对象)。

线程安全

  • 三种缓存的 GetKeysContainsGetAddRemoveClearCount 操作皆有 lock 保护,可于多线程环境下操作。

注意 ARCCacheLRUCache 的构造函数在 capacity 小于等于 0 时会抛出 ArgumentExceptionLRUKCache 则无此检查,请自行传入合理的容量与 K 值。


ARCCache

构造函数

public ARCCache(int capacity)

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

创建指定容量的 ARC 缓存,可额外指定移除处理器。

  • 行为说明:内部以 T1 (新近)T2 (频率) 双链表管理,新加入的 Key 进入 T1,再次命中 (Get) 或更新 (Add) 会提升至 T2;容量满时优先淘汰 T1 尾部,其次 T2 尾部。
var arc = new ARCCache<string, Texture2D>(60);

LRUCache

构造函数

public LRUCache(int capacity)

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

创建指定容量的 LRU 缓存,可额外指定移除处理器。

  • 行为说明GetAdd (更新) 会将节点移至列表最前面;容量满时淘汰最久未使用 (列表尾部) 的项目。
var lru = new LRUCache<string, Texture2D>(60);

LRUKCache

构造函数

public LRUKCache(int capacity, int k)

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

创建指定容量的 LRU-K 缓存k 为访问次数阈值,可额外指定移除处理器。

  • 行为说明:每次 Get / Add 会累加该 Key 的计数器 (上限为 K) 并移至列表尾部 (最新使用);淘汰时从最久未使用端开始,移除计数最低的项目,并对其余项目进行计数衰减
var lruk = new LRUKCache<string, Texture2D>(60, 3);

共用成员与方法

以下成员与方法于 ARCCache<TKey, TValue>LRUCache<TKey, TValue>LRUKCache<TKey, TValue> 皆相同

成员

成员说明
public int Count当前缓存数量。

方法总览

方法说明
GetKeys获取当前所有缓存的 Key 数组。
Contains检查指定 Key 是否存在于缓存中。
Get获取指定 Key 的缓存值 (会更新使用状态)。
Add加入或更新缓存 (容量满时触发淘汰)。
Remove移除指定 Key 的缓存 (会触发移除处理器)。
Clear清空所有缓存 (逐一触发移除处理器)。

GetKeys

public TKey[] GetKeys()

获取当前所有缓存的 Key 数组

Contains

public bool Contains(TKey key)

检查指定 Key 是否存在于缓存中。

Get

public TValue Get(TKey key)

获取指定 Key 的缓存值,未命中返回 default;命中时会依策略更新使用状态 (ARC 提升至 T2 / LRU 移至最前面 / LRU-K 计数累加并移至尾部)。

Add

public void Add(TKey key, TValue value)

加入或更新缓存;容量满时会先淘汰再加入,淘汰的缓存值会交由移除处理器处理。

Remove

public bool Remove(TKey key)

移除指定 Key 的缓存,移除成功返回 true;移除的缓存值会交由移除处理器处理 (默认会 Destroy Unity 对象)。

Clear

public void Clear()

清空所有缓存,逐一触发移除处理器后重置内部结构。


IRemoveCacheHandler

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

移除处理器接口 (IRemoveCacheHandler.cs),当缓存项目被淘汰或移除时调用,可实现此接口自定义处理行为 (例如归还对象池、释放资源或不做任何处理)。

UnityObjectRemoveCacheHandler

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

默认的移除处理器 (UnityObjectRemoveCacheHandler.cs),当缓存值为 UnityEngine.Object 时,直接调用 UnityEngine.Object.Destroy 销毁。

提醒 若缓存值非 Unity 对象 (例如 string、自定义类),默认处理器不会有任何动作,仅移出缓存交由 GC 回收。