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.
class LRUCache{
private:
class dlist {
public:
dlist(void) : __prev__(this), __next__(this)
{}
void join(dlist *prev_node, dlist *next_node)
{
next_node->__prev__ = this;
this->__next__ = next_node;
this->__prev__ = prev_node;
prev_node->__next__ = this;
}
void leav(void)
{
dlist *prev_node = this->__prev__;
dlist *next_node = this->__next__;
next_node->__prev__ = prev_node;
prev_node->__next__ = next_node;
}
dlist *__prev__;
dlist *__next__;
};
class data : public dlist
{
public:
explicit data(int key, int val) {
__key__ = key;
__value__ = val;
}
int __key__;
int __value__;
};
public:
LRUCache(int capacity) : __CAPACITY__(capacity)
{
}
int get(int key) {
if (__kv__.end() == __kv__.find(key)) {
return -1;
}
__update_priority__(__kv__[key]);
return __kv__[key]->__value__;
}
void set(int key, int value) {
if (__kv__.end() == __kv__.find(key)) {
int kv_size = __kv__.size();
if (kv_size >= __CAPACITY__) {
data *tail = static_cast<data *>(__lru__.__prev__);
tail->leav();
__kv__.erase(tail->__key__);
}
__kv__.insert(pair<int, data *>(key, new data(key, value)));
} else {
__kv__[key]->__value__ = value;
}
__update_priority__(__kv__[key]);
}
private:
void __update_priority__(data *p)
{
p->leav();
p->join(&__lru__, __lru__.__next__);
}
private:
int const __CAPACITY__;
dlist __lru__;
map<int, data *> __kv__;
};