LRU缓存淘汰策略
之前寫(xiě)過(guò)一篇關(guān)于LRU緩存淘汰策略的博客,那時(shí)候還在俄羅斯。在面試深信服的時(shí)候面試官有問(wèn)到,面試官特別的nice,雖然好多問(wèn)題沒(méi)有答上來(lái),但是從面試官那里學(xué)到不少的東西。今天再總結(jié)下LRU
首先是寫(xiě)LRU緩存淘汰策略的邏輯。
LRU緩存淘汰策略分為訪問(wèn)和新建兩個(gè)方面
訪問(wèn):如果最近有訪問(wèn)直接把它提到最前面。
新建:新建的時(shí)候應(yīng)該考慮到兩個(gè)方面
(1)程序是新打開(kāi)的之前沒(méi)有打開(kāi)過(guò)這個(gè)時(shí)候需要判斷存放緩存的容器是否已滿,如果滿了的話就需要把最后一個(gè)緩存刪掉。
。如果沒(méi)有滿的話直接插入就可以
(2)程序之前打開(kāi)過(guò),再次打開(kāi),這個(gè)時(shí)候只需要把這個(gè)程序的緩存調(diào)到最前面即可。
LRU緩存淘汰策略實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)是哈希表加雙向鏈表。
原因:
哈希表的查找速度比較快,雙向鏈表的插入和刪除速度比較快。把兩者結(jié)合起來(lái)使用,時(shí)間復(fù)雜度位o(1)
具體代碼如下
class LRUCache { private:int cap;// 雙鏈表:裝著 (key, value) 元組list<pair<int, int>> cache;// 哈希表:key 映射到 (key, value) 在 cache 中的位置unordered_map<int, list<pair<int, int>>::iterator> map; public:LRUCache(int capacity) {this->cap = capacity; }int get(int key) {auto it = map.find(key);// 訪問(wèn)的 key 不存在if (it == map.end()) return -1;// key 存在,把 (k, v) 換到隊(duì)頭pair<int, int> kv = *map[key];cache.erase(map[key]);cache.push_front(kv);// 更新 (key, value) 在 cache 中的位置map[key] = cache.begin();return kv.second; // value}void put(int key, int value) {/* 要先判斷 key 是否已經(jīng)存在 */ auto it = map.find(key);if (it == map.end()) {/* key 不存在,判斷 cache 是否已滿 */ if (cache.size() == cap) {// cache 已滿,刪除尾部的鍵值對(duì)騰位置// cache 和 map 中的數(shù)據(jù)都要?jiǎng)h除auto lastPair = cache.back();int lastKey = lastPair.first;map.erase(lastKey);cache.pop_back();}// cache 沒(méi)滿,可以直接添加cache.push_front(make_pair(key, value));map[key] = cache.begin();} else {/* key 存在,更改 value 并換到隊(duì)頭 */cache.erase(map[key]);cache.push_front(make_pair(key, value));map[key] = cache.begin();}} };?
總結(jié)
- 上一篇: linux通过yum安装vim,linu
- 下一篇: 深信服一面总结