LRU Cache(Least Recently Used):即最近最少使用,它是一种Cache的替换算法。
- 是一种常见的缓存淘汰算法
- 用于在有限的缓存空间中管理数据对象
- LRU Cache 的核心思想是基于时间局部性原理,即最近被访问的数据在未来可能会被再次访问
草图:

实现
使用list和unordered_map(hash表)实现$O(1)$的get和put
- 上面草图是
list头部作为最久未使用的缓存,最尾部的座位最近使用的缓存
- 其实大部分都是反过来的,头部作为最近使用的,最尾部作为最久未使用的缓存,思路都一样
- 当在
hash表里面找到对应key的键值对
- 存在就代表缓存命中,把对应
key的键值对移动到队尾,代表最近使用,返回数据
- 不存在就代表未命中
- 缓存长度到
max就把最久未使用(头部)的缓存删除,把新读取到的硬盘数据读到缓存里面(list的尾部),同时hash表也会把对应的key的键值对删掉,新增对应的键值对
- 缓存长度没有到
max,直接把硬盘上的数据读到缓存(list的尾部),同时hash表新增对应的键值对
- 处理完后返回数据
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
std::shared_ptr<const ChunkData> FileCacheManager::readChunk(uint64_t chunk_id){ auto map_it = lru_map.find(chunk_id);
if(map_it != lru_map.end()){ auto currentChunk = find(lru_list.begin(),lru_list.end(),chunk_id);
if (currentChunk != lru_list.end()){ uint64_t id = *currentChunk; lru_list.erase(currentChunk); lru_list.push_back(id); }
_hitCount++;
return map_it->second;
}
_missCount++; std::shared_ptr<const ChunkData> newChunkData = loadFromDisk(chunk_id);
if (!newChunkData){ return nullptr; }
if (lru_list.size() >= _max_chunks){ uint64_t minimumUsage_id = lru_list.front(); lru_list.pop_front(); lru_map.erase(minimumUsage_id); }
lru_map[chunk_id] = newChunkData; lru_list.push_back(chunk_id);
return newChunkData;
}
|