Adds LRW cache

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