LRU
核心思想:优先淘汰最不被使用的元素,保留最经常被访问的k个元素,使得o(1)时间内高效完成对数据的查询操作,又兼顾了空间问题
常用于操作系统页面置换,数据库缓存,web缓存等场景
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
| #include<bits/stdc++.h>
using namespace std;
class LRU { public: LRU() {} LRU(int capacity_) : capacity(capacity_) {}
int get(int key) { auto it = mp.find(key); if (it != mp.end()) { cache.splice(cache.begin(), cache, it->second); } else { return -1; } }
void set(int key, int value) { auto it = mp.find(key); if (it == mp.end()) { if (cache.size() == capacity) { auto del = cache.back(); mp.erase(del.first); cache.pop_back(); } cache.emplace_front(key, value); mp[key] = cache.begin(); } else { it->second->second = value; cache.splice(cache.begin(), cache, it->second); } } private: int capacity; list<pair<int, int>> cache; unordered_map<int, list<pair<int, int>>::iterator> mp; };
|
LFU
是LRU的适用范围更大版本,LRU可以看作是频率为1的LFU
LFU 的核心思想是:当缓存空间满时,优先淘汰访问频率最低的数据。
LFU 适合“热点”比较明显且长期稳定的场景,比如某些数据库缓存或网页缓存。
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
| #include<bits/stdc++.h>
using namespace std;
class LFU { public: int get(int key) { if (!cache.count(key)) return -1; auto [val, cnt, lst] = cache[key];
cntlist[cnt].erase(lst); if (cntlist.empty() && cnt == mincnt) { cache.erase(cnt); mincnt++; }
cnt++; cntlist[cnt].push_front(key); cache[key] = { val, cnt, cntlist[cnt].begin() }; return val; }
void put(int key, int value) { if (cap == 0) return; if (cache.contains(key)) { cache[key].value = value; get(key); return; }
if (siz == cap) { int minuse = cntlist[mincnt].back(); cntlist[mincnt].pop_back(); cache.erase(minuse); siz--; } cntlist[1].push_front(key); cache[key] = { value, 1, cntlist[1].begin() }; mincnt = 1; siz++; } private: struct node { int value; int cnt; list<int>::iterator it; }; int cap, siz, mincnt; unordered_map<int, node> cache; unordered_map<int, list<int>> cntlist; };
|