package com.justwayward.reader.view.chmview;
import java.util.Map;
import java.util.TreeMap;
public class LRUCache<K extends Comparable<K>, V> {
Map<K, Item> cacheMap = new TreeMap<K, Item>();
private int capacity;
public LRUCache(int capacity) {
if (capacity < 1)
throw new IllegalArgumentException("capacity must be positive integer");
this.capacity = capacity;
}
public synchronized V get(K key) {
Item item = cacheMap.get(key);
if (item == null)
return null;
for(Item i: cacheMap.values()) {
i.hits --;
}
item.hits += 2;
return item.value;
}
public synchronized V prune() {
if (cacheMap.size() >= capacity) {
Item kick = null;
for (Item item: cacheMap.values()) {
if (kick == null || kick.hits > item.hits) {
kick = item;
}
}
cacheMap.remove(kick.key);
return kick.value;
}
return null;
}
public synchronized void put(K key, V val) {
if (cacheMap.containsKey(key)) { // just refresh the value
cacheMap.put(key, new Item(key, val));
return;
}
prune();
cacheMap.put(key, new Item(key, val));
}
public synchronized void clear() {
cacheMap.clear();
}
public int size() {
return cacheMap.size();
}
public String toString() {
return "LRUCache " + size() + "/" + capacity + ": " + cacheMap.toString();
}
class Item {
K key;
V value;
int hits;
public Item(K key, V value) {
this.key = key;
this.value = value;
this.hits = 1;
}
public String toString() {
return "(" + hits + ")";
}
}
}