LRU是Least Recently Used的缩写,即最近最少使用页面置换算法,是为虚拟页式存储管理服务的,是根据页面调入内存后的使用情况进行决策了。由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU算法就是将最近最久未使用的页面予以淘汰。
//LRU缓存机制(least recently used最近最少使用):一般采用链表+hashtable实现
class LRUCache
{
public:
LRUCache(int capacity)
{
m_iMaxCap = capacity;
m_mapLRU.clear();
m_listLRU.clear();
}
int get(int key)
{
unordered_map<int,list<pair<int,int>>::iterator>::iterator iter = m_mapLRU.find(key);
if(iter == m_mapLRU.end())//不存在
return -1;
else //获取值并把当前放在缓存的头部
{
int value = iter->second->second;
m_listLRU.erase(iter->second);//删除当前
pair<int,int> tempPair = make_pair(key,value);
m_listLRU.push_front(tempPair);//重新放置头部
m_mapLRU[key] = m_listLRU.begin();//重新赋值
return value;
}
}
void set(int key,int value)
{
unordered_map<int,list<pair<int,int>>::iterator>::iterator iter = m_mapLRU.find(key);
if(iter == m_mapLRU.end())//不存在(如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间)
{
pair<int,int> newPair = make_pair(key,value);
if(m_listLRU.size() == m_iMaxCap)//超出范围
{
//移除末尾
int deleteKey = m_listLRU.back().first;
m_listLRU.pop_back();
unordered_map<int,list<pair<int,int>>::iterator>::iterator delIter = m_mapLRU.find(deleteKey);
m_mapLRU.erase(delIter);
}
m_listLRU.push_front(newPair);
m_mapLRU[key]=m_listLRU.begin();
}
else//存在,替换值
{
m_listLRU.erase(iter->second);//删除当前
pair<int,int> tempPair = make_pair(key,value);
m_listLRU.push_front(tempPair);//重新放置头部
m_mapLRU[key] = m_listLRU.begin();//重新赋值
}
}
private:
int m_iMaxCap;//最大容量
//使用unordered_map原因:内部实现了一个哈希表(也叫散列表,通过把关键码值映射到Hash表中一个位置来访问记录,查找的时间复杂度可达到O(1)
unordered_map<int,list<pair<int,int>>::iterator> m_mapLRU;
list<pair<int,int>> m_listLRU;//用于判定清除哪一个元素,超过时候每次删除list尾巴
};
参考:https://www.jianshu.com/p/8bf1c8f0eea4
https://blog.csdn.net/luoweifu/article/details/8297084
https://blog.csdn.net/qq_21997625/article/details/84672775