Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get
and set
.
get(key)
- Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value)
- Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
typedef std::unordered_map<int, std::list<struct CacheNode>::iterator>::iterator Map_Iterator;
typedef std::unordered_map<int, std::list<struct CacheNode>::iterator> Map_Type;
struct CacheNode {
int key;
int value;
CacheNode(int x, int y): key(x), value(y) {};
};
class LRUCache{
public:
LRUCache(int capacity) {
m_size = capacity;
}
int get(int key) {
Map_Iterator map_it = m_map.find(key);
if (map_it == m_map.end()) {
// could not get the value
return -1;
} else {
std::list<struct CacheNode>::iterator list_it = map_it->second;
struct CacheNode node_tmp(list_it->key, list_it->value);
m_list.erase(list_it);
m_list.push_front(node_tmp);
m_map[key] = m_list.begin();
return node_tmp.value;
}
}
void set(int key, int value) {
Map_Iterator map_it = m_map.find(key);
if (map_it != m_map.end()) {
m_list.erase(map_it->second);
} else {
if (m_list.size() == m_size) {
//the cache is full,so delete the last node, and insert the new node into the head of m_list
struct CacheNode node_delete = m_list.back();
m_map.erase(m_map.find(node_delete.key));
m_list.pop_back();
}
}
struct CacheNode node_new(key, value);
m_list.push_front(node_new);
m_map[key] = m_list.begin();
}
private:
int m_size;
std::list<struct CacheNode> m_list;
Map_Type m_map;
};