Map which stores items using SoftReference.
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
//package org.h2.util;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Map which stores items using SoftReference. Items can be garbage collected
* and removed. It is not a general purpose cache, as it doesn't implement some
* methods, and others not according to the map definition, to improve speed.
*
* @param <K> the key type
* @param <V> the value type
*/
public class SoftHashMap<K, V> extends AbstractMap<K, V> {
private Map<K, SoftValue<V>> map;
private ReferenceQueue<V> queue = new ReferenceQueue<V>();
public SoftHashMap() {
map = new HashMap<K, SoftValue<V>>();
}
@SuppressWarnings("unchecked")
private void processQueue() {
while (true) {
Reference<? extends V> o = queue.poll();
if (o == null) {
return;
}
SoftValue<V> k = (SoftValue<V>) o;
Object key = k.key;
map.remove(key);
}
}
public V get(Object key) {
processQueue();
SoftReference<V> o = map.get(key);
if (o == null) {
return null;
}
return o.get();
}
/**
* Store the object. The return value of this method is null or a SoftReference.
*
* @param key the key
* @param value the value
* @return null or the old object.
*/
public V put(K key, V value) {
processQueue();
SoftValue<V> old = map.put(key, new SoftValue<V>(value, queue, key));
return old == null ? null : old.get();
}
/**
* Remove an object.
*
* @param key the key
* @return null or the old object
*/
public V remove(Object key) {
processQueue();
SoftReference<V> ref = map.remove(key);
return ref == null ? null : ref.get();
}
public void clear() {
processQueue();
map.clear();
}
public Set<Entry<K, V>> entrySet() {
throw new UnsupportedOperationException();
}
/**
* A soft reference that has a hard reference to the key.
*/
private static class SoftValue<T> extends SoftReference<T> {
final Object key;
public SoftValue(T ref, ReferenceQueue<T> q, Object key) {
super(ref, q);
this.key = key;
}
}
}
Related examples in the same category