Skip to content

Instantly share code, notes, and snippets.

@navyxliu
Created April 25, 2020 23:56
Show Gist options
  • Save navyxliu/df22921e78766a9d673ad598926cea8f to your computer and use it in GitHub Desktop.
Save navyxliu/df22921e78766a9d673ad598926cea8f to your computer and use it in GitHub Desktop.
doubly linkedlist with a dummy node. it can simplify implementation.
void breakpoint() {
exit(-1);
}
struct node {
friend class linkedlist;
int key;
int value;
node* prev, * next;
node(int k, int v) : key(k), value(v), prev(nullptr), next(nullptr) {
}
node() = default;
};
/*doubly linkedlist*/
class linkedlist {
node* head_;
node end_;
public:
linkedlist() : head_(&end_) {
end_.prev = &end_;
end_.next = &end_;
}
void push_front(node* n) {
n->next = head_;
n->prev = head_->prev;
head_->prev = n;
head_ = n;
}
void erase(node* n) {
assert(!empty());
n->prev->next = n->next;
n->next->prev = n->prev;
if (n == head_) {
head_ = n->next;
}
}
node* front() const {
return head_;
}
// return the 1st
node* pop_front() {
node* h = head_;
erase(h);
return h;
}
node* pop_back() {
node* b = end_.prev;
erase(b);
return b;
}
bool empty() const {
return head_ == &end_;
}
};
class LRUCache {
public:
LRUCache(int cap) : capacity_(cap), freelist(), lru(), map_() {
}
int get(int key) {
if (map_.count(key) == 0) {
return -1;
}
node* n = map_[key];
lru.erase(n);
lru.push_front(n);
return n->value;
}
void put(int key, int value) {
node* n;
if (map_.count(key) == 0) {
n = allocate_node();
n->key = key;
n->value = value;
if (map_.size() == capacity_)
evict();
map_[key] = n;
}
else {
n = map_[key];
n->value = value;
lru.erase(n);
}
lru.push_front(n);
}
private:
void evict() {
node* t = lru.pop_back();
freelist.push_front(t);
map_.erase(t->key);
}
node* allocate_node() {
node* n;
if (!freelist.empty()) {
n = freelist.pop_front();
}
else {
n = new node();
}
return n;
}
private:
unordered_map<int, node*> map_;
linkedlist lru;
linkedlist freelist;
const int capacity_;
};
@navyxliu
Copy link
Author

NS: I found the of llvm's libcxx uses this trick.
I hope I can use rope for the freelist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment