一个强大易用的缓存库,还在完善中。
通过结合 FIFO 队列和 LRU 列表,Mnemosyne 能够有效地管理缓存的大小和成本,同时确保经常访问的数据能够快速被检索。使用不公平锁提高了并发访问的效率,避免了锁的竞争开销。
- 配置 (
Config
): 允许定制缓存的不同参数,如最大内存成本、单个条目的成本限制、最大条目数量、条目的生命周期和清理间隔等。 - 数据结构
cacheMap
: 一个字典,用于快速查找缓存节点。fifoQueue
: 先入先出队列,用于管理新加入的缓存节点。lruList
: 最近最少使用(Least Recently Used, LRU)列表,用于跟踪和管理缓存中频繁使用的数据。
- 锁 (
lock
): 使用不公平锁 (os_unfair_lock
) 来保证多线程访问缓存时的线程安全。
- 设置值 (
setValue
):- 在缓存中插入或更新一个值时,首先检查该值的成本是否超过配置的限制。
- 如果键已存在于缓存中,更新其数据和过期时间,并根据需要将其移动到 LRU 列表的尾部。
- 如果是新键,创建新的缓存节点,并根据成本限制调整缓存,必要时从缓存中删除旧的数据。
- 获取值 (
value(forKey:)
):- 访问特定键的值时,如果键存在并且节点处于活动状态,更新其在 LRU 列表中的位置,延长其过期时间。
- 删除操作:
- 支持删除特定键的值或清空整个缓存。
- 过期数据的自动清理是通过定时器和内存压力监控触发的,这有助于在资源受限的环境中自动释放内存。
ElysiumEntryFormat
: 定义缓存条目的格式,具有一个可选的expandedName
属性,该属性为 nil,除非被具体类型实现。ElysiumEntry
: 表示可缓存的条目,要求实现转换为数据和从数据恢复的功能。还需指定一个Format
类型,该类型必须遵循ElysiumEntryFormat
协议。String
和Data
实现:String
类型扩展为一个ElysiumEntryFormat
,而Data
类型实现了ElysiumEntry
,使其可直接用于缓存操作。
- 配置 (
Config
): 定义缓存操作的配置,包括文件大小限制、条目保留比例、过期时间、基础路径、目录名等。 - 实现细节:
- 缓存路径: 根据配置的基础路径和目录名构建完整的缓存目录路径。
- 同步和异步存储: 提供方法以同步或异步方式存储条目。
- 检索: 支持同步和异步从缓存中检索条目。
- 删除操作: 支持同步和异步删除特定键的条目或所有条目。
- 过期条目处理: 定期检查并删除过期条目。
- 存储 (
store
): 将条目存储到硬盘上,如果需要,会创建中间目录。存储时将更新条目的修改日期,用作过期判断的依据。 - 检索 (
retrieveEntry
): 从硬盘读取条目,如果条目已过期,根据配置决定是否还提供给调用者。 - 删除 (
removeEntry
): 删除特定键的条目。如果条目属于某个目录,可能还会触发对空目录的清理。
- 并发访问: 使用
DispatchQueue
来处理并发访问和修改操作,保证了操作的线程安全。 - 异步 API: 利用 Swift 的并发特性提供异步 API,使得缓存操作可以在不阻塞主线程的情况下执行。
ElysiumKey
协议: 定义一个缓存键的基本属性,如子目录路径、文件名等。提供了默认和自定义实现。- 错误处理: 定义了一系列错误类型
AkashicError
,用于处理各种可能的异常情况,如数据转换失败、文件写入失败等。