ObjectCache.java
package com.gh.mygreen.xlsmapper.expression;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
public class ObjectCache<K, V> {
private final Map<K, SoftReference<V>> map = new HashMap<K, SoftReference<V>>();
private final LinkedList<V> objectsLastAccessed = new LinkedList<V>();
private final int objectsToKeepCount;
/**
* Creates a new cache keeping all objects.
*/
public ObjectCache() {
this.objectsToKeepCount = -1;
}
/**
* @param maxObjectsToKeep the number of cached objects that should stay in memory when GC
* starts removing SoftReferences to free memory
*/
public ObjectCache(final int maxObjectsToKeep) {
this.objectsToKeepCount = maxObjectsToKeep;
}
public void compact() {
for (final Map.Entry<K, SoftReference<V>> entry : map.entrySet()) {
final SoftReference<V> ref = entry.getValue();
if (ref.get() == null) map.remove(entry.getKey());
}
}
public boolean contains(final K key) {
return map.containsKey(key);
}
public V get(final K key) {
final SoftReference<V> softReference = map.get(key);
if (softReference != null) {
final V value = softReference.get();
if (value == null) {
map.remove(key);
} else if (objectsToKeepCount > 0 && value != objectsLastAccessed.getFirst()) {
objectsLastAccessed.remove(value);
objectsLastAccessed.addFirst(value);
if (objectsLastAccessed.size() > objectsToKeepCount) objectsLastAccessed.removeLast();
}
return softReference.get();
}
return null;
}
public void put(final K key, final V value) {
map.remove(key);
map.put(key, new SoftReference<V>(value));
}
}