FileDocCategorySizeDatePackage
WeakValueHashMap.javaAPI DocGlassfish v2 API15614Fri May 04 22:35:20 BST 2007com.sun.jdo.spi.persistence.utility

WeakValueHashMap

public class WeakValueHashMap extends HashMap
A WeakValueHashMap is implemented as a HashMap that maps keys to WeakValues. Because we don't have access to the innards of the HashMap, we have to wrap/unwrap value objects with WeakValues on every operation. Fortunately WeakValues are small, short-lived objects, so the added allocation overhead is tolerable. This implementaton directly extends java.util.HashMap.
author
Markus Fuchs
see
java.util.HashMap
see
java.lang.ref.WeakReference

Fields Summary
private ReferenceQueue
queue
private Set
hashEntrySet
private Set
entrySet
private transient Collection
values
Constructors Summary
Methods Summary
public booleancontainsKey(java.lang.Object key)
Returns true if this map contains a mapping for the specified key.

param
key key whose presence in this map is to be tested
return
true if this map contains a mapping for the specified key.

        // need to clean up gc'ed values before invoking super method
        processQueue();
        return super.containsKey(key);
    
public booleancontainsValue(java.lang.Object value)
Returns true if this map maps one or more keys to the specified value.

param
value value whose presence in this map is to be tested
return
true if this map maps one or more keys to this value.

        return super.containsValue(WeakValue.create(value));
    
public java.util.SetentrySet()
Returns a Set view of the mappings in this map.

return
a Set view of the mappings in this map.


                             
       
        if (entrySet == null) {
            hashEntrySet = super.entrySet();
            entrySet = new EntrySet();
        }
        return entrySet;
    
public java.lang.Objectget(java.lang.Object key)
Gets the value for the given key.

param
key key whose associated value, if any, is to be returned
return
the value to which this map maps the specified key.

        // We don't need to remove garbage collected values here;
        // if they are garbage collected, the get() method returns null;
        // the next put() call with the same key removes the old value
        // automatically so that it can be completely garbage collected
        return getReferenceObject((WeakReference) super.get(key));
    
private final java.lang.ObjectgetReferenceObject(java.lang.ref.WeakReference ref)
A convenience method to return the object held by the weak reference or null if it does not exist.

        return (ref == null) ? null : ref.get();
    
public booleanisEmpty()
Returns true if this map contains no key-value mappings.

return
true if this map contains no key-value mappings.

        return size() == 0;
    
private voidprocessQueue()
Removes all garbage collected values with their keys from the map. Since we don't know how much the ReferenceQueue.poll() operation costs, we should not call it every map operation.

        WeakValue wv = null;

        while ((wv = (WeakValue) this.queue.poll()) != null) {
            // "super" is not really necessary but use it
            // to be on the safe side
            super.remove(wv.key);
        }
    
public java.lang.Objectput(java.lang.Object key, java.lang.Object value)
Puts a new (key,value) into the map.

param
key key with which the specified value is to be associated.
param
value value to be associated with the specified key.
return
previous value associated with specified key, or null if there was no mapping for key or the value has been garbage collected by the garbage collector.

        // If the map already contains an equivalent key, the new key
        // of a (key, value) pair is NOT stored in the map but the new
        // value only. But as the key is strongly referenced by the
        // map, it can not be removed from the garbage collector, even
        // if the key becomes weakly reachable due to the old
        // value. So, it isn't necessary to remove all garbage
        // collected values with their keys from the map before the
        // new entry is made. We only clean up here to distribute
        // clean up calls on different operations.
        processQueue();

        WeakValue oldValue = 
            (WeakValue)super.put(key, WeakValue.create(key, value, queue));
        return getReferenceObject(oldValue);
    
public java.lang.Objectremove(java.lang.Object key)
Removes key and value for the given key.

param
key key whose mapping is to be removed from the map.
return
previous value associated with specified key, or null if there was no mapping for key or the value has been garbage collected by the garbage collector.

        return getReferenceObject((WeakReference) super.remove(key));
    
public intsize()
Returns the number of key-value mappings in this map.

return
the number of key-value mappings in this map.


                           
       
        // delegate to entrySet, as super.size() also counts WeakValues
        return entrySet().size();
    
public java.util.Collectionvalues()
Returns a Collection view of the values contained in this map.

return
a Collection view of the values contained in this map.


                               
       
        // delegates to entrySet, because super method returns
        // WeakValues instead of value objects
	if (values == null) {
	    values = new AbstractCollection() {
		public Iterator iterator() {
		    return new Iterator() {
			private Iterator i = entrySet().iterator();

			public boolean hasNext() {
			    return i.hasNext();
			}

			public Object next() {
			    return ((Entry)i.next()).getValue();
			}

			public void remove() {
			    i.remove();
			}
                    };
                }

		public int size() {
		    return WeakValueHashMap.this.size();
		}

		public boolean contains(Object v) {
		    return WeakValueHashMap.this.containsValue(v);
		}
	    };
	}
	return values;