Adds LRW cache

master
Abhinav Sarkar 2019-06-28 10:41:30 +05:30
parent ba1023bca1
commit d84f4bad8d
2 changed files with 139 additions and 5 deletions

View File

@ -0,0 +1,80 @@
package net.abhinavsarkar.algorist;
import java.util.Iterator;
import java.util.Optional;
public class LRWCache<K, V> implements Iterable<K>
{
private final int capacity;
private final OpenAddressingHashTable<K, V> store;
public LRWCache(int capacity) {
this.capacity = capacity;
this.store = new OpenAddressingHashTable<>(capacity+1);
}
public Optional<V> get(K key) {
return store.get(key);
}
public void remove(K key) {
store.remove(key);
}
public void put(K key, V val) {
store.put(key, val);
if (store.size() > capacity) {
store.remove(store.iterator().next().key());
}
}
public int size()
{
return store.size();
}
public Iterator<K> iterator()
{
return new Iterator<K>()
{
private final Iterator<OpenAddressingHashTable.Entry<K,V>> it = store.iterator();
@Override
public boolean hasNext()
{
return it.hasNext();
}
@Override
public K next()
{
return it.next().key();
}
};
}
public String toString() {
return store.toString();
}
public static void main(String[] args)
{
LRWCache<String, String> cache = new LRWCache<>(4);
cache.put("a", "abhinav");
cache.put("b", "batman");
cache.put("c", "carol");
cache.put("z", "zellman");
System.out.println(cache);
cache.put("w", "walker");
System.out.println(cache);
cache.put("c", "carly");
System.out.println(cache);
cache.put("x", "xander");
System.out.println(cache);
}
}

View File

@ -9,15 +9,21 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
private static final Entry REMOVED = new Entry(0,0); private static final Entry REMOVED = new Entry(0,0);
private Object[] store; private Object[] store;
private ProbingStrategy probingStrategy; private final ProbingStrategy probingStrategy;
private Entry<K, V> head; private Entry<K, V> head;
private Entry<K, V> tail; private Entry<K, V> tail;
private int size;
public OpenAddressingHashTable(int initialCapacity, ProbingStrategy probingStrategy) { public OpenAddressingHashTable(int initialCapacity, ProbingStrategy probingStrategy) {
this.store = new Object[initialCapacity]; this.store = new Object[initialCapacity];
this.probingStrategy = probingStrategy; this.probingStrategy = probingStrategy;
} }
public OpenAddressingHashTable(int initialCapacity)
{
this(initialCapacity, new LinearProbing());
}
public Optional<V> get(K key) { public Optional<V> get(K key) {
int trial = 0; int trial = 0;
int baseIndex = calcIndex(key, store.length); int baseIndex = calcIndex(key, store.length);
@ -75,7 +81,8 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
{ {
if (!resize) if (!resize)
{ {
addLink(nEntry); linkNewEntry(nEntry);
size++;
} }
store[index] = nEntry; store[index] = nEntry;
@ -83,6 +90,9 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
} }
else if (entry.key.equals(nEntry.key)) else if (entry.key.equals(nEntry.key))
{ {
if (!resize) {
linkUpdatedEntry(entry);
}
entry.val = nEntry.val; entry.val = nEntry.val;
return true; return true;
} }
@ -91,7 +101,7 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
return false; return false;
} }
private void addLink(Entry<K, V> nEntry) private void linkNewEntry(Entry<K, V> nEntry)
{ {
if (head == null) if (head == null)
{ {
@ -105,6 +115,28 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
tail = nEntry; tail = nEntry;
} }
private void linkUpdatedEntry(Entry<K, V> entry)
{
if (head == null)
{
head = entry;
} else if (entry == head) {
if (entry.next != null) {
head = entry.next;
tail.next = entry;
entry.prev = tail;
tail = entry;
}
} else if (entry != tail) {
entry.prev.next = entry.next;
entry.next.prev = entry.prev;
tail.next = entry;
entry.prev = tail;
entry.next = null;
tail = entry;
}
}
public void remove(K key) { public void remove(K key) {
int trial = 0; int trial = 0;
int baseIndex = calcIndex(key, store.length); int baseIndex = calcIndex(key, store.length);
@ -118,15 +150,16 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
} }
else if (entry.key.equals(key)) else if (entry.key.equals(key))
{ {
removeLink(entry); unlinkEntry(entry);
store[index] = REMOVED; store[index] = REMOVED;
size--;
return; return;
} }
trial++; trial++;
} }
} }
private void removeLink(Entry<K, V> entry) private void unlinkEntry(Entry<K, V> entry)
{ {
if (head == entry) { if (head == entry) {
head = entry.next; head = entry.next;
@ -142,6 +175,10 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
} }
} }
public int size() {
return size;
}
private int calcIndex(K key, int size) { private int calcIndex(K key, int size) {
return key.hashCode() % size; return key.hashCode() % size;
} }
@ -183,10 +220,20 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
private V val; private V val;
private Entry<K, V> prev; private Entry<K, V> prev;
private Entry<K, V> next; private Entry<K, V> next;
public Entry(K key, V val) { public Entry(K key, V val) {
this.key = key; this.key = key;
this.val = val; this.val = val;
} }
public K key()
{
return key;
}
public V val()
{
return val;
}
public String toString() { public String toString() {
return "<" + key + "," + val + ">"; return "<" + key + "," + val + ">";
} }
@ -239,9 +286,11 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
table.put("z", "zellman"); table.put("z", "zellman");
table.put("w", "walker"); table.put("w", "walker");
System.out.println(table); System.out.println(table);
System.out.println(table.size());
table.remove("x"); table.remove("x");
table.remove("z"); table.remove("z");
System.out.println(table.size());
System.out.println(table.get("a")); System.out.println(table.get("a"));
System.out.println(table.get("b")); System.out.println(table.get("b"));
@ -252,6 +301,11 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
table.put("z", "zebra"); table.put("z", "zebra");
System.out.println(table.get("z")); System.out.println(table.get("z"));
System.out.println(table); System.out.println(table);
System.out.println(table.size());
table.put("w", "wanted");
System.out.println(table);
System.out.println(table.size());
System.out.println(table.get("A")); System.out.println(table.get("A"));
System.out.println(table.get("B")); System.out.println(table.get("B"));