least recently used(最近最少使用算法),是一种内存数据淘汰策略,使用常见是当内存不足时,需要淘汰最近最少使用的数据。
概括来讲,即,“不断访问,不断缓存,放不下了,得删一个。”
实现方法:hash+双向链表
hash以键找指针,链表节点存键与值
1)读一条数据,hash知道已经在不在,在,挪到链表最后(双向链表才能O(1)),不在,插到链表最后。
2)满了,试图删一条数据,删头元素,更新hash(链表里存键、值二者)
typedef int KEYTYPE;
typedef int VALUETYPE;
class CDoubleListNode {
public:
KEYTYPE key;
VALUETYPE value;
CDoubleListNode * pre;
CDoubleListNode * nxt;
};
class CLRUpool {
int capacity;
int current;
std::map<KEYTYPE, CDoubleListNode *> hashtable;
CDoubleListNode * pheadNode;
CDoubleListNode * ptailNode;
public:
CLRUpool(int _c):capacity(_c), current(0)
{
pheadNode = new CDoubleListNode;
ptailNode = new CDoubleListNode;
pheadNode->pre = ptailNode->nxt = NULL;
pheadNode->nxt = ptailNode;
ptailNode->pre = pheadNode;
}
void find(KEYTYPE key)
{
std::map<KEYTYPE, CDoubleListNode *>::iterator it; //第二个双冒号啥意思
it = hashtable.find(key);
if (it == hashtable.end())
{
std::cout << "**未查到信息" << key << ",请输入其value:**" << std::endl;
int value;
std::cin >> value;
add(key, value);
}
else
{
std::cout << "**查到" << key << "的value是" << (it->second)->value << "**" << std::endl;
// *it指向的节点移到最后
CDoubleListNode * tmp = it->second;
tmp->pre->nxt = tmp->nxt;
tmp->nxt = tmp->pre;
tmp->pre = ptailNode->pre;
tmp->nxt = ptailNode;
ptailNode->pre->nxt = tmp;
ptailNode->pre = tmp;
}
return;
}
void add(KEYTYPE key, VALUETYPE value)
{
if (current == capacity)
{
// 删头
std::cout << "**缓存已满,删除" << pheadNode->nxt->key << std::endl;
CDoubleListNode * tmp = pheadNode->nxt;
hashtable.erase(tmp->key);
pheadNode->nxt = tmp->nxt;
tmp->nxt->pre = pheadNode;
delete tmp;
}
// 添加
std::cout << "**已添加" << key << '-' << value << "**" << std::endl;
CDoubleListNode * tmp = new CDoubleListNode;
tmp->pre = ptailNode->pre;
tmp->nxt = ptailNode;
tmp->key = key;
tmp->value = value;
ptailNode->pre->nxt = tmp;
ptailNode->pre = tmp;
hashtable[key] = tmp;
current++;
}
~CLRUpool() {
CDoubleListNode * p = pheadNode->nxt;
for (; p != NULL; p = p->nxt)
{
delete p->pre;
}
delete ptailNode;
}
};
测试
int main(void)
{
CLRUpool mypool(3);
mypool.find(1106);
mypool.find(1102);
mypool.find(1106);
mypool.find(1101);
mypool.find(1104);
return 0;
}
结果