LRU C++ 算法
#ifndef _LRU_H
#define _LRU_H
#include <unordered_map>
#include
namespace tools {
template <class KEY, class VALUE>
class Lru
{
public:
class Node
{
public:
Node(const KEY& key, const VALUE& value) : key(key), value(value) {}
KEY key;
VALUE value;
};
Lru(int capacity) : _capacity(capacity), _count(0)
{
}
void AddNode(const KEY& key, const VALUE& value)
{
_PutValue(key, value);
}
bool GetValue(const KEY& key, VALUE& value)
{
auto iter = _keyValues.find(key);
if (iter == _keyValues.end()) {
return false;
}
Node node = *iter->second;
value = node.value;
// 如果元素已经在头部,不需要移动位置
if (iter->second == _dataList.begin())
{
return true;
}
// 增加了一次拷贝
_dataList.erase(iter->second);
_dataList.push_front(node);
_keyValues[key] = _dataList.begin();
_PrintDebug(__FUNCTION__);
return true;
}
private:
void _PutValue(const KEY& key, const VALUE& value)
{
_RemoveKey(key);
if (_count < _capacity)
{
_dataList.push_front(Node(key, value));
auto iter = _dataList.begin();
_keyValues[key] = iter;
++_count;
}
else
{
auto reverseIt = _dataList.rbegin();
auto lastIter = --(reverseIt.base());
_keyValues.erase(lastIter->key);
_dataList.erase(lastIter);
_dataList.push_front(Node(key, value));
auto iter = _dataList.begin();
_keyValues[key] = iter;
}
_PrintDebug(__FUNCTION__);
}
void _RemoveKey(const KEY& key)
{
if (_count == 0)
{
return ;
}
auto iter = _keyValues.find(key);
if (iter == _keyValues.end())
{
return ;
}
auto dataIter = iter->second;
_dataList.erase(dataIter);
_keyValues.erase(iter);
--_count;
_PrintDebug(__FUNCTION__);
}
void _PrintDebug(std::string action="")
{
#if 0
std::cout<<"-------------BEGIN-"<<action<<"-----------"<<std::endl;
std::cout<<“count:”<<_count<<" capacity:"<<_capacity<<std::endl;
std::cout<<“Map-Data:”<<std::endl;
for (auto& it : _keyValues)
{
std::cout<<it.first<< " “<< “key:”<<(it.second)->key <<” value:"<<(it.second)->value<<std::endl;
}
std::cout<<“List-Data”<<std::endl;
for (auto it = _dataList.begin(); it != _dataList.end(); ++it)
{
std::cout<<&it <<" value:"<value<<" key:"<key<<std::endl;
}
std::cout<<“END*”<<std::endl;
#endif
}
private:
int _capacity;
int _count;
std::list<Node> _dataList;
typedef typename std::list<Node>::iterator NODE_ITER;
std::unordered_map<KEY, NODE_ITER> _keyValues;
};
}
#endif
#include
#include “Lru.h”
using namespace tools;
int main() {
std::cout << “Hello, World!” << std::endl;
Lru<int, std::string> lru(3);
lru.AddNode(1, "1");
lru.AddNode(2, "2");
lru.AddNode(3, "3");
lru.AddNode(4, "4");
lru.AddNode(5, "5");
lru.AddNode(3, "3");
lru.AddNode(3, "3");
lru.AddNode(4, "4");
lru.AddNode(5, "5");
std::string value;
lru.GetValue(3, value);
std::cout<<"3:"<<value<<std::endl;
lru.GetValue(4, value);
std::cout<<"4:"<<value<<std::endl;
lru.GetValue(7, value);
std::cout<<"7:"<<value<<std::endl;
// lru.AddNode(3, “3”);
return 0;
}