/*
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package java.util;
import java.lang.ref.WeakReference;
import java.lang.ref.ReferenceQueue;
/**
* Hash table based implementation of the Map interface, with
* weak keys.
* An entry in a WeakHashMap will automatically be removed when
* its key is no longer in ordinary use. More precisely, the presence of a
* mapping for a given key will not prevent the key from being discarded by the
* garbage collector, that is, made finalizable, finalized, and then reclaimed.
* When a key has been discarded its entry is effectively removed from the map,
* so this class behaves somewhat differently from other Map
* implementations.
*
*
Both null values and the null key are supported. This class has
* performance characteristics similar to those of the HashMap
* class, and has the same efficiency parameters of initial capacity
* and load factor.
*
*
Like most collection classes, this class is not synchronized.
* A synchronized WeakHashMap may be constructed using the
* {@link Collections#synchronizedMap Collections.synchronizedMap}
* method.
*
*
This class is intended primarily for use with key objects whose
* equals methods test for object identity using the
* == operator. Once such a key is discarded it can never be
* recreated, so it is impossible to do a lookup of that key in a
* WeakHashMap at some later time and be surprised that its entry
* has been removed. This class will work perfectly well with key objects
* whose equals methods are not based upon object identity, such
* as String instances. With such recreatable key objects,
* however, the automatic removal of WeakHashMap entries whose
* keys have been discarded may prove to be confusing.
*
*
The behavior of the WeakHashMap class depends in part upon
* the actions of the garbage collector, so several familiar (though not
* required) Map invariants do not hold for this class. Because
* the garbage collector may discard keys at any time, a
* WeakHashMap may behave as though an unknown thread is silently
* removing entries. In particular, even if you synchronize on a
* WeakHashMap instance and invoke none of its mutator methods, it
* is possible for the size method to return smaller values over
* time, for the isEmpty method to return false and
* then true, for the containsKey method to return
* true and later false for a given key, for the
* get method to return a value for a given key but later return
* null, for the put method to return
* null and the remove method to return
* false for a key that previously appeared to be in the map, and
* for successive examinations of the key set, the value collection, and
* the entry set to yield successively smaller numbers of elements.
*
*
Each key object in a WeakHashMap is stored indirectly as
* the referent of a weak reference. Therefore a key will automatically be
* removed only after the weak references to it, both inside and outside of the
* map, have been cleared by the garbage collector.
*
*
Implementation note: The value objects in a
* WeakHashMap are held by ordinary strong references. Thus care
* should be taken to ensure that value objects do not strongly refer to their
* own keys, either directly or indirectly, since that will prevent the keys
* from being discarded. Note that a value object may refer indirectly to its
* key via the WeakHashMap itself; that is, a value object may
* strongly refer to some other key object whose associated value object, in
* turn, strongly refers to the key of the first value object. One way
* to deal with this is to wrap values themselves within
* WeakReferences before
* inserting, as in: m.put(key, new WeakReference(value)),
* and then unwrapping upon each get.
*
*
The iterators returned by the iterator method of the collections
* returned by all of this class's "collection view methods" are
* fail-fast: if the map is structurally modified at any time after the
* iterator is created, in any way except through the iterator's own
* remove method, the iterator will throw a {@link
* ConcurrentModificationException}. Thus, in the face of concurrent
* modification, the iterator fails quickly and cleanly, rather than risking
* arbitrary, non-deterministic behavior at an undetermined time in the future.
*
*
Note that the fail-fast behavior of an iterator cannot be guaranteed
* as it is, generally speaking, impossible to make any hard guarantees in the
* presence of unsynchronized concurrent modification. Fail-fast iterators
* throw ConcurrentModificationException on a best-effort basis.
* Therefore, it would be wrong to write a program that depended on this
* exception for its correctness: the fail-fast behavior of iterators
* should be used only to detect bugs.
*
*
This class is a member of the
*
* Java Collections Framework.
*
* @param the type of keys maintained by this map
* @param the type of mapped values
*
* @author Doug Lea
* @author Josh Bloch
* @author Mark Reinhold
* @since 1.2
* @see java.util.HashMap
* @see java.lang.ref.WeakReference
*/
public class WeakHashMap
extends AbstractMap
implements Map {
/**
* The default initial capacity -- MUST be a power of two.
*/
private static final int DEFAULT_INITIAL_CAPACITY = 16;
/**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
private static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* The load factor used when none specified in constructor.
*/
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
Entry[] table;
/**
* The number of key-value mappings contained in this weak hash map.
*/
private int size;
/**
* The next size value at which to resize (capacity * load factor).
*/
private int threshold;
/**
* The load factor for the hash table.
*/
private final float loadFactor;
/**
* Reference queue for cleared WeakEntries
*/
private final ReferenceQueue