package ca.uwaterloo.ece.qhanam.practice.lrucombined; import java.util.Hashtable; public class LRUCache { Hashtable<Integer, Node> hash; LRUList list; int capacity; int currentLoad; public LRUCache(int capacity) { hash = new Hashtable<Integer, Node>(capacity); list = new LRUList(); this.capacity = capacity; this.currentLoad = 0; } public int get(int key) { /* Get the node from the hash table. */ Node n = hash.get(new Integer(key)); if(n == null) return -1; /* Set the node as most recently used. */ list.access(n); return n.value; } public void set(int key, int value) { Integer k = new Integer(key); Node n; /* Might allready be in the list. */ n = hash.get(new Integer(key)); if(n != null){ n.value = value; /* Set the node as most recently used. */ list.access(n); } else{ n = new Node(k, value); /* We might need to make room. */ if(currentLoad == capacity + 1/* Bug Here */){ Node lru = list.remove(); hash.remove(lru.key); } else{ currentLoad++; } /* Set the node as the most recently used. */ hash.put(k, n); list.insert(n); } } public class LRUList{ private Node mru; private Node lru; /* Inserts a node into the list as the MRU node. */ public void insert(Node node){ if(this.mru == null){ this.mru = node; this.lru = node; } else{ node.next = mru; mru.previous = node; this.mru = node; } } /* Removes the LRU node. */ public Node remove(){ Node removed = this.lru; if(this.mru == this.lru){ this.mru = null; this.lru = null; } else{ this.lru.previous.next = null; this.lru = this.lru.previous; } return removed; } /* Make the given node the MRU node. */ public void access(Node node){ if(this.mru == node) { } // Do nothing else{ if(node != lru){ node.previous.next = node.next; node.next.previous = node.previous; } else{ node.previous.next = null; this.lru = node.previous; } node.next = this.mru; node.previous = null; this.mru.previous = node; this.mru = node; } } } public class Node{ Integer key; int value; Node previous; Node next; public Node(Integer key, int value){ this.key = key; this.value = value; } } }