Skip to content

Instantly share code, notes, and snippets.

@rxmichael
Last active September 24, 2016 18:40
Show Gist options
  • Save rxmichael/ccb61471fd0d1441ba013b1322c99302 to your computer and use it in GitHub Desktop.
Save rxmichael/ccb61471fd0d1441ba013b1322c99302 to your computer and use it in GitHub Desktop.
Java implementation of a cache
import java.util.HashMap;
import java.util.Iterator;
public class LRUCache<K,V>
{
// generic node class used to store key/value
class Node <K,V> {
K key;
V value;
Node next;
Node prev;
public Node(K newkey, V newvalue) {
this.key = newkey;
this.value = newvalue;
}
}
private int size;
private final int maxSize;
private HashMap<K, Node<K,V>> map;
private Node<K,V> first;
private Node<K,V> last;
/* create an LRU cache with a mxaimum capacitiy size
*/
public LRUCache(int maxSize) {
this.maxSize = maxSize;
this.size = 0;
map = new HashMap<K,Node<K,V>>();
}
/* retreive cache size */
public int size() {
return size;
}
/* insert node in hashmap:
1. If node is already exisitng => move to the top of the list, (most recently used), and set new value
2. If node isn't exisitng => insert at top of the list.
*/
public void put(K key, V value) {
System.out.println("Trying to add "+key+" : "+value);
if(!map.containsKey(key)) {
Node<K,V> newNode = new Node<K,V>(key, value);
if(this.size < maxSize) {
addFirst(newNode);
this.size = this.size+1;
}
else {
System.out.println("Cache full, removing least recently used entry");
removeLast();
addFirst(newNode);
}
}
else {
Node<K,V> current = map.get(key);
current.value = value;
moveToFirst(current);
}
}
/* Retreive node in hashmap:
1. If node is already exisitng => move to the top of the list, (most recently used) and return value
2. If node isn't exisitng => return null.
*/
public V get(K key) {
if(!map.containsKey(key)) {
Node<K,V> current = map.get(key);
moveToFirst(current);
return current.value;
}
else {
return null;
}
}
/*
Insert node at top of our linked list
*/
public void addFirst(Node<K,V> used) {
used.next = first;
used.prev = null;
if (first!= null)
first.prev = used;
first = used;
if (last == null)
last = used;
map.put(used.key, used);
}
public void removeLast() {
Node<K,V> toRemove = map.remove(last.key);
System.out.println("Removing node with key : "+toRemove.key+" , value: "+toRemove.value);
last = last.prev;
if (last!= null)
last.next = null;
}
/*
mode node to the top of the list
*/
public void moveToFirst(Node<K,V> used) {
Node<K,V> temp1 = used.prev;
Node<K,V> temp2 = used.next;
if (temp1!= null)
temp1.next = temp2;
else
first = temp2;
if (temp2!= null)
temp2.prev = temp1;
else
last = temp1;
addFirst(used);
}
/* print method used a linked list travesal
*/
public void print() {
Node<K,V> current = first;
while (current != null) {
System.out.print("key " + current.key + " value "
+ current.value + "\n");
current = current.next;
}
}
/* print method using a hashmap iterator
*/
public void print2() {
Iterator<K> keyIterator = map.keySet().iterator();
while (keyIterator.hasNext()) {
K key = keyIterator.next();
Node<K,V> node = map.get(key);
System.out.println("key = " + key + "; value = " + node.value);
}
}
public static void main(String[] args) {
LRUCache<Integer, String> cache = new LRUCache(3);
cache.put(1, "HWYWRW");
cache.put(2, "Boston");
cache.put(1, "NEw York");
cache.put(3, "SEattle");
cache.put(4, "SEattle1212");
cache.put(5, "SEattle");
cache.print2();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment