Tuesday, November 25, 2014
LRU Cache -- Java
public class LRUCache {
class Node{
int key;
int value;
Node prev;
Node next;
public Node(int k, int v){
key = k;
value = v;
prev = null;
next = null;
}
public void setValue(int v){
value = v;
}
}
int cap;
HashMap<Integer,Node> hmap;
Node head;
Node tail;
public LRUCache(int capacity) {
if(capacity<0){
capacity = 1;
}
cap = capacity;
hmap = new HashMap<Integer, Node>();
head = null;
tail = null;
}
public int get(int key) {
if(hmap.containsKey(key)){
if(hmap.size()>1){
dragKeyNode(hmap.get(key)); //lru
}
return hmap.get(key).value;
}
else return -1;
}
public void set(int key, int value) {
if(hmap.containsKey(key)){
dragKeyNode(hmap.get(key)); //lru
hmap.get(key).setValue(value);
}
else{
//to insert a new Node to the doubly linkedin list.
Node insertNode = new Node(key,value);
if(hmap.size() < cap){ //!important judge.
attachKeyNode(insertNode);
}
else{ // cur size >=cap
detachKeyNode();
attachKeyNode(insertNode);
}
hmap.put(key,insertNode);
}
return;
}
//drag an existed node from original inner pos in doubly linkedlist to the head new pos.
public void dragKeyNode(Node p){
if(p==head)return; //if p==head, nothing needed to do.
Node pprev = p.prev;
Node pnext = p.next;
pprev.next = pnext;
if(pnext!=null){
pnext.prev = pprev;
}
else{ //if p is currently tail node, modify tail!
tail = pprev;
}
p.prev = null;
p.next = null;
attachKeyNode(p);
return;
}
public void attachKeyNode(Node p){
if(head == null && tail == null){
head = p;
tail = p;
}
else{
p.next = head;
head.prev = p;
head = p;
}
return;
}
public void detachKeyNode(){ //cut off tail node.
if(hmap.size() < 1)return;
int key = tail.key;
hmap.remove(key); //!important, also need to delete tail node in hashmap.
if(hmap.size()==0){
head = null;
tail = null;
}
else{
Node pprev = tail.prev;
pprev.next = null;
tail.prev = null;
tail = pprev;
}
return;
}
}
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment