javassist.scopedpool.SoftValueHashMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package javassist.scopedpool;
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;
/**
* This Map will remove entries when the value in the map has been cleaned from
* garbage collection
*
* @version $Revision: 1.4 $
* @author Bill Burke
*/
public class SoftValueHashMap extends AbstractMap implements Map {
private static class SoftValueRef extends SoftReference {
public Object key;
private SoftValueRef(Object key, Object val, ReferenceQueue q) {
super(val, q);
this.key = key;
}
private static SoftValueRef create(Object key, Object val,
ReferenceQueue q) {
if (val == null)
return null;
else
return new SoftValueRef(key, val, q);
}
}
/**
* Returns a set of the mappings contained in this hash table.
*/
public Set entrySet() {
processQueue();
return hash.entrySet();
}
/* Hash table mapping WeakKeys to values */
private Map hash;
/* Reference queue for cleared WeakKeys */
private ReferenceQueue queue = new ReferenceQueue();
/*
* Remove all invalidated entries from the map, that is, remove all entries
* whose values have been discarded.
*/
private void processQueue() {
SoftValueRef ref;
while ((ref = (SoftValueRef)queue.poll()) != null) {
if (ref == (SoftValueRef)hash.get(ref.key)) {
// only remove if it is the *exact* same WeakValueRef
//
hash.remove(ref.key);
}
}
}
/* -- Constructors -- */
/**
* Constructs a new, empty WeakHashMap
with the given initial
* capacity and the given load factor.
*
* @param initialCapacity
* The initial capacity of the WeakHashMap
*
* @param loadFactor
* The load factor of the WeakHashMap
*
* @throws IllegalArgumentException
* If the initial capacity is less than zero, or if the load
* factor is nonpositive
*/
public SoftValueHashMap(int initialCapacity, float loadFactor) {
hash = new HashMap(initialCapacity, loadFactor);
}
/**
* Constructs a new, empty WeakHashMap
with the given initial
* capacity and the default load factor, which is 0.75
.
*
* @param initialCapacity
* The initial capacity of the WeakHashMap
*
* @throws IllegalArgumentException
* If the initial capacity is less than zero
*/
public SoftValueHashMap(int initialCapacity) {
hash = new HashMap(initialCapacity);
}
/**
* Constructs a new, empty WeakHashMap
with the default
* initial capacity and the default load factor, which is 0.75
.
*/
public SoftValueHashMap() {
hash = new HashMap();
}
/**
* Constructs a new WeakHashMap
with the same mappings as the
* specified Map. The WeakHashMap
is created with
* an initial capacity of twice the number of mappings in the specified map
* or 11 (whichever is greater), and a default load factor, which is
* 0.75.
*
* @param t the map whose mappings are to be placed in this map.
*/
public SoftValueHashMap(Map t) {
this(Math.max(2 * t.size(), 11), 0.75f);
putAll(t);
}
/* -- Simple queries -- */
/**
* Returns the number of key-value mappings in this map. Note:
* In contrast with most implementations of the
* Map
interface, the time required by this operation is
* linear in the size of the map.
*/
public int size() {
processQueue();
return hash.size();
}
/**
* Returns true
if this map contains no key-value mappings.
*/
public boolean isEmpty() {
processQueue();
return hash.isEmpty();
}
/**
* Returns true
if this map contains a mapping for the
* specified key.
*
* @param key
* The key whose presence in this map is to be tested.
*/
public boolean containsKey(Object key) {
processQueue();
return hash.containsKey(key);
}
/* -- Lookup and modification operations -- */
/**
* Returns the value to which this map maps the specified key
.
* If this map does not contain a value for this key, then return
* null
.
*
* @param key
* The key whose associated value, if any, is to be returned.
*/
public Object get(Object key) {
processQueue();
SoftReference ref = (SoftReference)hash.get(key);
if (ref != null)
return ref.get();
return null;
}
/**
* Updates this map so that the given key
maps to the given
* value
. If the map previously contained a mapping for
* key
then that mapping is replaced and the previous value
* is returned.
*
* @param key
* The key that is to be mapped to the given value
* @param value
* The value to which the given key
is to be
* mapped
*
* @return The previous value to which this key was mapped, or
* null
if if there was no mapping for the key
*/
public Object put(Object key, Object value) {
processQueue();
Object rtn = hash.put(key, SoftValueRef.create(key, value, queue));
if (rtn != null)
rtn = ((SoftReference)rtn).get();
return rtn;
}
/**
* Removes the mapping for the given key
from this map, if
* present.
*
* @param key
* The key whose mapping is to be removed.
*
* @return The value to which this key was mapped, or null
if
* there was no mapping for the key.
*/
public Object remove(Object key) {
processQueue();
return hash.remove(key);
}
/**
* Removes all mappings from this map.
*/
public void clear() {
processQueue();
hash.clear();
}
}