实用辅助方法 [blog/lrualgorithm/auxiliary-other]

我们已经实现了 LRU 缓存的核心功能,包括基本数据结构、构造函数、核心操作 get/put 以及链表操作的辅助方法。为了让我们的 LRU 缓存更加完整和易用,现在我们来添加一些实用的辅助方法。

获取缓存大小

首先,我们实现一个方法来获取当前缓存中的元素数量:

fn size[K, V](self : LRUCache[K, V]) -> Int {
  self.key_to_node.size()
}

这个方法非常简单,直接返回哈希表的大小,因为哈希表中的每一项都对应缓存中的一个元素。

检查缓存是否为空

接下来,我们添加一个方法来检查缓存是否为空:

fn is_empty[K, V](self : LRUCache[K, V]) -> Bool {
  self.key_to_node.size() == 0
}

这个方法检查哈希表是否为空,从而判断整个缓存是否为空。

检查键是否存在

最后,我们实现一个方法来检查缓存中是否存在某个键:

fn contains[K : Hash + Eq, V](self : LRUCache[K, V], key : K) -> Bool {
  self.key_to_node.contains(key)
}

这个方法直接利用哈希表的 contains 方法,快速判断一个键是否在缓存中。

这些辅助方法的意义

虽然这些方法看起来很简单,但它们对于实际使用 LRU 缓存非常有价值:

  • 提高可读性:使用 is_empty()size() == 0 更直观
  • 封装实现细节:用户不需要知道内部使用了 key_to_node 哈希表
  • 接口完整性:提供了一套完整的接口,满足各种使用场景

这些辅助方法体现了良好的 API 设计原则 —— 简单、一致且易于使用。通过提供这些方法,我们的 LRU 缓存实现更加健壮和用户友好。

实际应用示例

这些辅助方法在实际应用中非常有用,例如:

// 检查键是否存在,而不获取值(避免改变使用顺序)
if contains(cache, "key") {
  // 键存在,可以进行一些操作
}

// 缓存为空时执行特定逻辑
if is_empty(cache) {
  // 缓存为空,可以执行初始化或其他操作
}

// 获取缓存使用情况
let usage_percentage = size(cache) * 100 / cache.capacity

这些方法虽然简单,但它们大大增强了 LRU 缓存的实用性。通过这些辅助方法,我们的 LRU 缓存实现已经相当完整和实用。