ConcurrentHashMap.java revision adc854b798c1cfe3bfd4c27d68d5cee38ca617da
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://creativecommons.org/licenses/publicdomain 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent; 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.concurrent.locks.*; 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.*; 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable; 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectInputStream; 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectOutputStream; 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-note 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// removed link to collections framework docs 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// removed cloneable interface from ConcurrentMap interface 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-note 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A hash table supporting full concurrency of retrievals and 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * adjustable expected concurrency for updates. This class obeys the 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * same functional specification as {@link java.util.Hashtable}, and 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * includes versions of methods corresponding to each method of 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>Hashtable</tt>. However, even though all operations are 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thread-safe, retrieval operations do <em>not</em> entail locking, 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and there is <em>not</em> any support for locking the entire table 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in a way that prevents all access. This class is fully 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interoperable with <tt>Hashtable</tt> in programs that rely on its 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thread safety but not on its synchronization details. 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> Retrieval operations (including <tt>get</tt>) generally do not 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * block, so may overlap with update operations (including 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the most recently <em>completed</em> update operations holding 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * upon their onset. For aggregate operations such as <tt>putAll</tt> 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and <tt>clear</tt>, concurrent retrievals may reflect insertion or 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removal of only some entries. Similarly, Iterators and 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Enumerations return elements reflecting the state of the hash table 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * at some point at or since the creation of the iterator/enumeration. 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * They do <em>not</em> throw 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link ConcurrentModificationException}. However, iterators are 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * designed to be used by only one thread at a time. 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> The allowed concurrency among update operations is guided by 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the optional <tt>concurrencyLevel</tt> constructor argument 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (default 16), which is used as a hint for internal sizing. The 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * table is internally partitioned to try to permit the indicated 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * number of concurrent updates without contention. Because placement 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in hash tables is essentially random, the actual concurrency will 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * vary. Ideally, you should choose a value to accommodate as many 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * threads as will ever concurrently modify the table. Using a 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * significantly higher value than you need can waste space and time, 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and a significantly lower value can lead to thread contention. But 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * overestimates and underestimates within an order of magnitude do 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not usually have much noticeable impact. A value of one is 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * appropriate when it is known that only one thread will modify 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and all others will only read. 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>This class implements all of the <em>optional</em> methods 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the {@link Map} and {@link Iterator} interfaces. 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> Like {@link java.util.Hashtable} but unlike {@link 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * java.util.HashMap}, this class does NOT allow <tt>null</tt> to be 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * used as a key or value. 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <K> the type of keys maintained by this map 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <V> the type of mapped values 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class ConcurrentHashMap<K, V> extends AbstractMap<K, V> 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project implements ConcurrentMap<K, V>, Serializable { 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 7249069246763182397L; 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The basic strategy is to subdivide the table among Segments, 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * each of which itself is a concurrently readable hash table. 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* ---------------- Constants -------------- */ 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The default initial number of table slots for this table. 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Used when not otherwise specified in constructor. 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static int DEFAULT_INITIAL_CAPACITY = 16; 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The maximum capacity, used if a higher value is implicitly 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified by either of the constructors with arguments. MUST 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be a power of two <= 1<<30 to ensure that entries are indexible 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * using ints. 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final int MAXIMUM_CAPACITY = 1 << 30; 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The default load factor for this table. Used when not 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise specified in constructor. 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final float DEFAULT_LOAD_FACTOR = 0.75f; 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The default number of concurrency control segments. 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project **/ 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final int DEFAULT_SEGMENTS = 16; 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The maximum number of segments to allow; used to bound 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * constructor arguments. 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final int MAX_SEGMENTS = 1 << 16; // slightly conservative 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* ---------------- Fields -------------- */ 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Mask value for indexing into segments. The upper bits of a 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * key's hash code are used to choose the segment. 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project **/ 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final int segmentMask; 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Shift value for indexing within segments. 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project **/ 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final int segmentShift; 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The segments, each of which is a specialized hash table 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final Segment[] segments; 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project transient Set<K> keySet; 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project transient Set<Map.Entry<K,V>> entrySet; 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project transient Collection<V> values; 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* ---------------- Small Utilities -------------- */ 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a hash code for non-null Object x. 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Uses the same hash code spreader as most other java.util hash tables. 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param x the object serving as a key 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the hash code 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static int hash(Object x) { 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int h = x.hashCode(); 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project h += ~(h << 9); 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project h ^= (h >>> 14); 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project h += (h << 4); 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project h ^= (h >>> 10); 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return h; 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the segment that should be used for key with given hash 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param hash the hash code for the key 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the segment 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final Segment<K,V> segmentFor(int hash) { 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (Segment<K,V>) segments[(hash >>> segmentShift) & segmentMask]; 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* ---------------- Inner Classes -------------- */ 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Segments are specialized versions of hash tables. This 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * subclasses from ReentrantLock opportunistically, just to 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * simplify some locking and avoid separate construction. 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project **/ 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final class Segment<K,V> extends ReentrantLock implements Serializable { 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Segments maintain a table of entry lists that are ALWAYS 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * kept in a consistent state, so can be read without locking. 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Next fields of nodes are immutable (final). All list 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * additions are performed at the front of each bin. This 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * makes it easy to check changes, and also fast to traverse. 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When nodes would otherwise be changed, new nodes are 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * created to replace them. This works well for hash tables 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * since the bin lists tend to be short. (The average length 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is less than two for the default load factor threshold.) 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Read operations can thus proceed without locking, but rely 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * on a memory barrier to ensure that completed write 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * operations performed by other threads are 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * noticed. Conveniently, the "count" field, tracking the 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * number of elements, can also serve as the volatile variable 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * providing proper read/write barriers. This is convenient 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * because this field needs to be read in many read operations 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * anyway. 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implementors note. The basic rules for all this are: 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * - All unsynchronized read operations must first read the 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * "count" field, and should not look at table entries if 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it is 0. 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * - All synchronized write operations should write to 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the "count" field after updating. The operations must not 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * take any action that could even momentarily cause 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a concurrent read operation to see inconsistent 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * data. This is made easier by the nature of the read 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * operations in Map. For example, no operation 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * can reveal that the table has grown but the threshold 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has not yet been updated, so there are no atomicity 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * requirements for this with respect to reads. 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * As a guide, all critical volatile reads and writes are marked 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in code comments. 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 2249069246763182397L; 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The number of elements in this segment's region. 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project **/ 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project transient volatile int count; 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Number of updates; used for checking lack of modifications 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in bulk-read methods. 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project transient int modCount; 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The table is rehashed when its size exceeds this threshold. 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (The value of this field is always (int)(capacity * 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * loadFactor).) 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project transient int threshold; 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The per-segment table 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project transient HashEntry[] table; 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The load factor for the hash table. Even though this value 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is same for all segments, it is replicated to avoid needing 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * links to outer object. 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @serial 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final float loadFactor; 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Segment(int initialCapacity, float lf) { 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loadFactor = lf; 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project setTable(new HashEntry[initialCapacity]); 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set table to new HashEntry array. 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Call only while holding lock or in constructor. 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project **/ 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setTable(HashEntry[] newTable) { 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project table = newTable; 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project threshold = (int)(newTable.length * loadFactor); 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count = count; // write-volatile 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Specialized implementations of map methods */ 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V get(Object key, int hash) { 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (count != 0) { // read-volatile 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] tab = table; 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = hash & (tab.length - 1); 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> e = (HashEntry<K,V>) tab[index]; 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (e != null) { 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e.hash == hash && key.equals(e.key)) 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return e.value; 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e = e.next; 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean containsKey(Object key, int hash) { 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (count != 0) { // read-volatile 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] tab = table; 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = hash & (tab.length - 1); 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> e = (HashEntry<K,V>) tab[index]; 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (e != null) { 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e.hash == hash && key.equals(e.key)) 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e = e.next; 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean containsValue(Object value) { 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (count != 0) { // read-volatile 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] tab = table; 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int len = tab.length; 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0 ; i < len; i++) 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (HashEntry<K,V> e = (HashEntry<K,V>)tab[i] ; e != null ; e = e.next) 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value.equals(e.value)) 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean replace(K key, int hash, V oldValue, V newValue) { 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock(); 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int c = count; 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] tab = table; 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = hash & (tab.length - 1); 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> first = (HashEntry<K,V>) tab[index]; 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> e = first; 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e == null) 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e.hash == hash && key.equals(e.key)) 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e = e.next; 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V v = e.value; 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (v == null || !oldValue.equals(v)) 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e.value = newValue; 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count = c; // write-volatile 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unlock(); 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V replace(K key, int hash, V newValue) { 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock(); 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int c = count; 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] tab = table; 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = hash & (tab.length - 1); 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> first = (HashEntry<K,V>) tab[index]; 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> e = first; 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e == null) 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e.hash == hash && key.equals(e.key)) 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e = e.next; 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V v = e.value; 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e.value = newValue; 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count = c; // write-volatile 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return v; 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unlock(); 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V put(K key, int hash, V value, boolean onlyIfAbsent) { 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock(); 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int c = count; 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] tab = table; 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = hash & (tab.length - 1); 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> first = (HashEntry<K,V>) tab[index]; 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (HashEntry<K,V> e = first; e != null; e = (HashEntry<K,V>) e.next) { 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e.hash == hash && key.equals(e.key)) { 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V oldValue = e.value; 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!onlyIfAbsent) 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e.value = value; 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++modCount; 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count = c; // write-volatile 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return oldValue; 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project tab[index] = new HashEntry<K,V>(hash, key, value, first); 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++modCount; 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++c; 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count = c; // write-volatile 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c > threshold) 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project setTable(rehash(tab)); 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unlock(); 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] rehash(HashEntry[] oldTable) { 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int oldCapacity = oldTable.length; 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (oldCapacity >= MAXIMUM_CAPACITY) 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return oldTable; 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reclassify nodes in each list to new Map. Because we are 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * using power-of-two expansion, the elements from each bin 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * must either stay at same index, or move with a power of two 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * offset. We eliminate unnecessary node creation by catching 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cases where old nodes can be reused because their next 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * fields won't change. Statistically, at the default 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * threshold, only about one-sixth of them need cloning when 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a table doubles. The nodes they replace will be garbage 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * collectable as soon as they are no longer referenced by any 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reader thread that may be in the midst of traversing table 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * right now. 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] newTable = new HashEntry[oldCapacity << 1]; 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int sizeMask = newTable.length - 1; 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < oldCapacity ; i++) { 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We need to guarantee that any existing reads of old Map can 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // proceed. So we cannot yet null out each bin. 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> e = (HashEntry<K,V>)oldTable[i]; 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e != null) { 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> next = e.next; 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int idx = e.hash & sizeMask; 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Single node on list 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (next == null) 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newTable[idx] = e; 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else { 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Reuse trailing consecutive sequence at same slot 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> lastRun = e; 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int lastIdx = idx; 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (HashEntry<K,V> last = next; 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project last != null; 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project last = last.next) { 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int k = last.hash & sizeMask; 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (k != lastIdx) { 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastIdx = k; 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastRun = last; 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newTable[lastIdx] = lastRun; 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Clone all remaining nodes 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (HashEntry<K,V> p = e; p != lastRun; p = p.next) { 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int k = p.hash & sizeMask; 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newTable[k] = new HashEntry<K,V>(p.hash, 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project p.key, 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project p.value, 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (HashEntry<K,V>) newTable[k]); 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return newTable; 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Remove; match on key only if value null, else match both. 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V remove(Object key, int hash, Object value) { 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock(); 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int c = count; 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] tab = table; 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = hash & (tab.length - 1); 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> first = (HashEntry<K,V>)tab[index]; 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> e = first; 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e == null) 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e.hash == hash && key.equals(e.key)) 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e = e.next; 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V oldValue = e.value; 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value != null && !value.equals(oldValue)) 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // All entries following removed node can stay in list, but 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // all preceding ones need to be cloned. 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> newFirst = e.next; 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (HashEntry<K,V> p = first; p != e; p = p.next) 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newFirst = new HashEntry<K,V>(p.hash, p.key, 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project p.value, newFirst); 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project tab[index] = newFirst; 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++modCount; 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count = c-1; // write-volatile 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return oldValue; 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unlock(); 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void clear() { 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock(); 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] tab = table; 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < tab.length ; i++) 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project tab[i] = null; 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++modCount; 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project count = 0; // write-volatile 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unlock(); 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ConcurrentHashMap list entry. Note that this is never exported 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * out as a user-visible Map.Entry 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final class HashEntry<K,V> { 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final K key; 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V value; 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final int hash; 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final HashEntry<K,V> next; 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry(int hash, K key, V value, HashEntry<K,V> next) { 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.value = value; 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.hash = hash; 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.key = key; 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.next = next; 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* ---------------- Public operations -------------- */ 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new, empty map with the specified initial 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * capacity and the specified load factor. 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param initialCapacity the initial capacity. The implementation 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * performs internal sizing to accommodate this many elements. 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param loadFactor the load factor threshold, used to control resizing. 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param concurrencyLevel the estimated number of concurrently 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * updating threads. The implementation performs internal sizing 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to try to accommodate this many threads. 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException if the initial capacity is 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * negative or the load factor or concurrencyLevel are 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * nonpositive. 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ConcurrentHashMap(int initialCapacity, 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project float loadFactor, int concurrencyLevel) { 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (concurrencyLevel > MAX_SEGMENTS) 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project concurrencyLevel = MAX_SEGMENTS; 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Find power-of-two sizes best matching arguments 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int sshift = 0; 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int ssize = 1; 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (ssize < concurrencyLevel) { 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++sshift; 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ssize <<= 1; 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project segmentShift = 32 - sshift; 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project segmentMask = ssize - 1; 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.segments = new Segment[ssize]; 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (initialCapacity > MAXIMUM_CAPACITY) 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project initialCapacity = MAXIMUM_CAPACITY; 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int c = initialCapacity / ssize; 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c * ssize < initialCapacity) 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++c; 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int cap = 1; 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (cap < c) 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cap <<= 1; 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < this.segments.length; ++i) 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.segments[i] = new Segment<K,V>(cap, loadFactor); 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new, empty map with the specified initial 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * capacity, and with default load factor and concurrencyLevel. 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param initialCapacity The implementation performs internal 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sizing to accommodate this many elements. 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException if the initial capacity of 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * elements is negative. 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ConcurrentHashMap(int initialCapacity) { 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS); 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new, empty map with a default initial capacity, 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * load factor, and concurrencyLevel. 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ConcurrentHashMap() { 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS); 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new map with the same mappings as the given map. The 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * map is created with a capacity of twice the number of mappings in 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given map or 11 (whichever is greater), and a default load factor. 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param t the map 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ConcurrentHashMap(Map<? extends K, ? extends V> t) { 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1, 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 11), 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS); 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project putAll(t); 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // inherit Map javadoc 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isEmpty() { 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final Segment[] segments = this.segments; 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * We need to keep track of per-segment modCounts to avoid ABA 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * problems in which an element in one segment was added and 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in another removed during traversal, in which case the 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * table was never actually empty at any point. Note the 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * similar use of modCounts in the size() and containsValue() 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * methods, which are the only other methods also susceptible 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to ABA problems. 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int[] mc = new int[segments.length]; 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int mcsum = 0; 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < segments.length; ++i) { 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (segments[i].count != 0) 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mcsum += mc[i] = segments[i].modCount; 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If mcsum happens to be zero, then we know we got a snapshot 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // before any modifications at all were made. This is 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // probably common enough to bother tracking. 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mcsum != 0) { 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < segments.length; ++i) { 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (segments[i].count != 0 || 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mc[i] != segments[i].modCount) 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // inherit Map javadoc 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int size() { 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final Segment[] segments = this.segments; 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int[] mc = new int[segments.length]; 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long sum = 0; 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int mcsum = 0; 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < segments.length; ++i) { 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sum += segments[i].count; 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mcsum += mc[i] = segments[i].modCount; 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int check = 0; 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mcsum != 0) { 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < segments.length; ++i) { 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project check += segments[i].count; 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mc[i] != segments[i].modCount) { 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project check = -1; // force retry 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (check == sum) { 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (sum > Integer.MAX_VALUE) 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Integer.MAX_VALUE; 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (int)sum; 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the value to which the specified key is mapped in this table. 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key a key in the table. 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value to which the key is mapped in this table; 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>null</tt> if the key is not mapped to any value in 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this table. 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if the key is 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>null</tt>. 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V get(Object key) { 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int hash = hash(key); // throws NullPointerException if key null 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return segmentFor(hash).get(key, hash); 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Tests if the specified object is a key in this table. 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key possible key. 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return <tt>true</tt> if and only if the specified object 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is a key in this table, as determined by the 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>equals</tt> method; <tt>false</tt> otherwise. 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if the key is 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>null</tt>. 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean containsKey(Object key) { 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int hash = hash(key); // throws NullPointerException if key null 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return segmentFor(hash).containsKey(key, hash); 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns <tt>true</tt> if this map maps one or more keys to the 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified value. Note: This method requires a full internal 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * traversal of the hash table, and so is much slower than 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method <tt>containsKey</tt>. 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value value whose presence in this map is to be tested. 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return <tt>true</tt> if this map maps one or more keys to the 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified value. 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if the value is <tt>null</tt>. 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean containsValue(Object value) { 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value == null) 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final Segment[] segments = this.segments; 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int[] mc = new int[segments.length]; 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int sum = 0; 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int mcsum = 0; 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < segments.length; ++i) { 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int c = segments[i].count; 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mcsum += mc[i] = segments[i].modCount; 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (segments[i].containsValue(value)) 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean cleanSweep = true; 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mcsum != 0) { 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < segments.length; ++i) { 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int c = segments[i].count; 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mc[i] != segments[i].modCount) { 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cleanSweep = false; 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cleanSweep) 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Legacy method testing if some key maps into the specified value 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in this table. This method is identical in functionality to 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #containsValue}, and exists solely to ensure 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * full compatibility with class {@link java.util.Hashtable}, 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * which supported this method prior to introduction of the 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Java Collections framework. 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value a value to search for. 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return <tt>true</tt> if and only if some key maps to the 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>value</tt> argument in this table as 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * determined by the <tt>equals</tt> method; 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>false</tt> otherwise. 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if the value is <tt>null</tt>. 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean contains(Object value) { 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return containsValue(value); 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Maps the specified <tt>key</tt> to the specified 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>value</tt> in this table. Neither the key nor the 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value can be <tt>null</tt>. 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> The value can be retrieved by calling the <tt>get</tt> method 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with a key that is equal to the original key. 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key the table key. 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value the value. 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the previous value of the specified key in this table, 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * or <tt>null</tt> if it did not have one. 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if the key or value is 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>null</tt>. 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V put(K key, V value) { 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value == null) 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int hash = hash(key); 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return segmentFor(hash).put(key, hash, value, false); 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the specified key is not already associated 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with a value, associate it with the given value. 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is equivalent to 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre> 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if (!map.containsKey(key)) 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * return map.put(key, value); 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * else 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * return map.get(key); 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre> 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Except that the action is performed atomically. 791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key key with which the specified value is to be associated. 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value value to be associated with the specified key. 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return previous value associated with specified key, or <tt>null</tt> 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if there was no mapping for key. A <tt>null</tt> return can 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * also indicate that the map previously associated <tt>null</tt> 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the specified key, if the implementation supports 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>null</tt> values. 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnsupportedOperationException if the <tt>put</tt> operation is 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not supported by this map. 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassCastException if the class of the specified key or value 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * prevents it from being stored in this map. 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if the specified key or value is 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>null</tt>. 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project **/ 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V putIfAbsent(K key, V value) { 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value == null) 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int hash = hash(key); 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return segmentFor(hash).put(key, hash, value, true); 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copies all of the mappings from the specified map to this one. 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * These mappings replace any mappings that this map had for any of the 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * keys currently in the specified Map. 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param t Mappings to be stored in this map. 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putAll(Map<? extends K, ? extends V> t) { 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (Iterator<? extends Map.Entry<? extends K, ? extends V>> it = (Iterator<? extends Map.Entry<? extends K, ? extends V>>) t.entrySet().iterator(); it.hasNext(); ) { 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Entry<? extends K, ? extends V> e = it.next(); 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(e.getKey(), e.getValue()); 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes the key (and its corresponding value) from this 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * table. This method does nothing if the key is not in the table. 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key the key that needs to be removed. 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value to which the key had been mapped in this table, 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * or <tt>null</tt> if the key did not have a mapping. 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if the key is 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>null</tt>. 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V remove(Object key) { 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int hash = hash(key); 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return segmentFor(hash).remove(key, hash, null); 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Remove entry for key only if currently mapped to given value. 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Acts as 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre> 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if (map.get(key).equals(value)) { 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * map.remove(key); 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * return true; 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } else return false; 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre> 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * except that the action is performed atomically. 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key key with which the specified value is associated. 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value value associated with the specified key. 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the value was removed 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if the specified key is 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>null</tt>. 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean remove(Object key, Object value) { 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int hash = hash(key); 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return segmentFor(hash).remove(key, hash, value) != null; 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Replace entry for key only if currently mapped to given value. 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Acts as 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre> 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if (map.get(key).equals(oldValue)) { 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * map.put(key, newValue); 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * return true; 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } else return false; 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre> 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * except that the action is performed atomically. 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key key with which the specified value is associated. 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param oldValue value expected to be associated with the specified key. 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newValue value to be associated with the specified key. 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the value was replaced 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if the specified key or values are 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>null</tt>. 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean replace(K key, V oldValue, V newValue) { 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (oldValue == null || newValue == null) 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int hash = hash(key); 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return segmentFor(hash).replace(key, hash, oldValue, newValue); 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Replace entry for key only if currently mapped to some value. 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Acts as 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre> 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if ((map.containsKey(key)) { 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * return map.put(key, value); 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } else return null; 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre> 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * except that the action is performed atomically. 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key key with which the specified value is associated. 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value value to be associated with the specified key. 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return previous value associated with specified key, or <tt>null</tt> 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if there was no mapping for key. 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if the specified key or value is 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>null</tt>. 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V replace(K key, V value) { 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value == null) 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int hash = hash(key); 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return segmentFor(hash).replace(key, hash, value); 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes all mappings from this map. 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() { 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < segments.length; ++i) 920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project segments[i].clear(); 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-removed 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // /** 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // * Returns a shallow copy of this 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // * <tt>ConcurrentHashMap</tt> instance: the keys and 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // * values themselves are not cloned. 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // * 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // * @return a shallow copy of this map. 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // */ 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // public Object clone() { 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // // We cannot call super.clone, since it would share final 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // // segments array, and there's no way to reassign finals. 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // float lf = segments[0].loadFactor; 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // int segs = segments.length; 938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // int cap = (int)(size() / lf); 939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if (cap < segs) cap = segs; 940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ConcurrentHashMap<K,V> t = new ConcurrentHashMap<K,V>(cap, lf, segs); 941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // t.putAll(this); 942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // return t; 943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // } 944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a set view of the keys contained in this map. The set is 948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * backed by the map, so changes to the map are reflected in the set, and 949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * vice-versa. The set supports element removal, which removes the 950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * corresponding mapping from this map, via the <tt>Iterator.remove</tt>, 951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and 952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>clear</tt> operations. It does not support the <tt>add</tt> or 953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>addAll</tt> operations. 954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The returned <tt>iterator</tt> is a "weakly consistent" iterator that 955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will never throw {@link java.util.ConcurrentModificationException}, 956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and guarantees to traverse elements as they existed upon 957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * construction of the iterator, and may (but is not guaranteed to) 958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reflect any modifications subsequent to construction. 959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a set view of the keys contained in this map. 961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<K> keySet() { 963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Set<K> ks = keySet; 964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (ks != null) ? ks : (keySet = new KeySet()); 965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a collection view of the values contained in this map. The 970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * collection is backed by the map, so changes to the map are reflected in 971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the collection, and vice-versa. The collection supports element 972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removal, which removes the corresponding mapping from this map, via the 973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>, 974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations. 975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * It does not support the <tt>add</tt> or <tt>addAll</tt> operations. 976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The returned <tt>iterator</tt> is a "weakly consistent" iterator that 977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will never throw {@link java.util.ConcurrentModificationException}, 978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and guarantees to traverse elements as they existed upon 979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * construction of the iterator, and may (but is not guaranteed to) 980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reflect any modifications subsequent to construction. 981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a collection view of the values contained in this map. 983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Collection<V> values() { 985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Collection<V> vs = values; 986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (vs != null) ? vs : (values = new Values()); 987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a collection view of the mappings contained in this map. Each 992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * element in the returned collection is a <tt>Map.Entry</tt>. The 993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * collection is backed by the map, so changes to the map are reflected in 994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the collection, and vice-versa. The collection supports element 995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removal, which removes the corresponding mapping from the map, via the 996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>, 997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations. 998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * It does not support the <tt>add</tt> or <tt>addAll</tt> operations. 999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The returned <tt>iterator</tt> is a "weakly consistent" iterator that 1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will never throw {@link java.util.ConcurrentModificationException}, 1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and guarantees to traverse elements as they existed upon 1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * construction of the iterator, and may (but is not guaranteed to) 1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reflect any modifications subsequent to construction. 1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a collection view of the mappings contained in this map. 1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<Map.Entry<K,V>> entrySet() { 1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Set<Map.Entry<K,V>> es = entrySet; 1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (es != null) ? es : (entrySet = (Set<Map.Entry<K,V>>) (Set) new EntrySet()); 1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an enumeration of the keys in this table. 1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an enumeration of the keys in this table. 1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #keySet 1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Enumeration<K> keys() { 1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new KeyIterator(); 1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an enumeration of the values in this table. 1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an enumeration of the values in this table. 1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #values 1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Enumeration<V> elements() { 1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new ValueIterator(); 1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* ---------------- Iterator Support -------------- */ 1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project abstract class HashIterator { 1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int nextSegmentIndex; 1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int nextTableIndex; 1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] currentTable; 1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K, V> nextEntry; 1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K, V> lastReturned; 1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashIterator() { 1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nextSegmentIndex = segments.length - 1; 1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nextTableIndex = -1; 1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project advance(); 1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasMoreElements() { return hasNext(); } 1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final void advance() { 1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nextEntry != null && (nextEntry = nextEntry.next) != null) 1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (nextTableIndex >= 0) { 1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ( (nextEntry = (HashEntry<K,V>)currentTable[nextTableIndex--]) != null) 1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (nextSegmentIndex >= 0) { 1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Segment<K,V> seg = (Segment<K,V>)segments[nextSegmentIndex--]; 1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (seg.count != 0) { 1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentTable = seg.table; 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int j = currentTable.length - 1; j >= 0; --j) { 1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ( (nextEntry = (HashEntry<K,V>)currentTable[j]) != null) { 1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nextTableIndex = j - 1; 1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasNext() { return nextEntry != null; } 1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry<K,V> nextEntry() { 1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nextEntry == null) 1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NoSuchElementException(); 1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastReturned = nextEntry; 1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project advance(); 1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return lastReturned; 1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void remove() { 1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lastReturned == null) 1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException(); 1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ConcurrentHashMap.this.remove(lastReturned.key); 1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastReturned = null; 1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> { 1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public K next() { return super.nextEntry().key; } 1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public K nextElement() { return super.nextEntry().key; } 1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> { 1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V next() { return super.nextEntry().value; } 1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V nextElement() { return super.nextEntry().value; } 1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Entry iterator. Exported Entry objects must write-through 1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * changes in setValue, even if the nodes have been cloned. So we 1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cannot return internal HashEntry objects. Instead, the iterator 1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * itself acts as a forwarding pseudo-entry. 1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final class EntryIterator extends HashIterator implements Map.Entry<K,V>, Iterator<Entry<K,V>> { 1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Map.Entry<K,V> next() { 1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nextEntry(); 1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 1113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public K getKey() { 1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lastReturned == null) 1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException("Entry was removed"); 1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return lastReturned.key; 1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V getValue() { 1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lastReturned == null) 1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException("Entry was removed"); 1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ConcurrentHashMap.this.get(lastReturned.key); 1125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V setValue(V value) { 1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lastReturned == null) 1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException("Entry was removed"); 1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ConcurrentHashMap.this.put(lastReturned.key, value); 1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Object o) { 1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If not acting as entry, just use default. 1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lastReturned == null) 1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.equals(o); 1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(o instanceof Map.Entry)) 1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map.Entry e = (Map.Entry)o; 1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue()); 1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int hashCode() { 1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If not acting as entry, just use default. 1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lastReturned == null) 1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.hashCode(); 1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object k = getKey(); 1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object v = getValue(); 1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ((k == null) ? 0 : k.hashCode()) ^ 1151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ((v == null) ? 0 : v.hashCode()); 1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If not acting as entry, just use default. 1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lastReturned == null) 1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.toString(); 1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else 1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getKey() + "=" + getValue(); 1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean eq(Object o1, Object o2) { 1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (o1 == null ? o2 == null : o1.equals(o2)); 1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final class KeySet extends AbstractSet<K> { 1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Iterator<K> iterator() { 1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new KeyIterator(); 1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int size() { 1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ConcurrentHashMap.this.size(); 1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean contains(Object o) { 1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ConcurrentHashMap.this.containsKey(o); 1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean remove(Object o) { 1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ConcurrentHashMap.this.remove(o) != null; 1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() { 1182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ConcurrentHashMap.this.clear(); 1183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final class Values extends AbstractCollection<V> { 1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Iterator<V> iterator() { 1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new ValueIterator(); 1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int size() { 1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ConcurrentHashMap.this.size(); 1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean contains(Object o) { 1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ConcurrentHashMap.this.containsValue(o); 1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() { 1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ConcurrentHashMap.this.clear(); 1198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final class EntrySet extends AbstractSet<Map.Entry<K,V>> { 1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Iterator<Map.Entry<K,V>> iterator() { 1203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new EntryIterator(); 1204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean contains(Object o) { 1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(o instanceof Map.Entry)) 1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map.Entry<K,V> e = (Map.Entry<K,V>)o; 1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V v = ConcurrentHashMap.this.get(e.getKey()); 1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return v != null && v.equals(e.getValue()); 1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean remove(Object o) { 1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(o instanceof Map.Entry)) 1214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map.Entry<K,V> e = (Map.Entry<K,V>)o; 1216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ConcurrentHashMap.this.remove(e.getKey(), e.getValue()); 1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int size() { 1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ConcurrentHashMap.this.size(); 1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() { 1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ConcurrentHashMap.this.clear(); 1223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object[] toArray() { 1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Since we don't ordinarily have distinct Entry objects, we 1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // must pack elements using exportable SimpleEntry 1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size()); 1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); ) 1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project c.add(new SimpleEntry<K,V>(i.next())); 1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return c.toArray(); 1231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public <T> T[] toArray(T[] a) { 1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size()); 1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); ) 1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project c.add(new SimpleEntry<K,V>(i.next())); 1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return c.toArray(a); 1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This duplicates java.util.AbstractMap.SimpleEntry until this class 1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is made accessible. 1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final class SimpleEntry<K,V> implements Entry<K,V> { 1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project K key; 1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V value; 1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SimpleEntry(K key, V value) { 1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.key = key; 1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.value = value; 1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SimpleEntry(Entry<K,V> e) { 1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.key = e.getKey(); 1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.value = e.getValue(); 1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public K getKey() { 1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return key; 1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V getValue() { 1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return value; 1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public V setValue(V value) { 1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V oldValue = this.value; 1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.value = value; 1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return oldValue; 1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Object o) { 1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(o instanceof Map.Entry)) 1275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map.Entry e = (Map.Entry)o; 1277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return eq(key, e.getKey()) && eq(value, e.getValue()); 1278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int hashCode() { 1281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ((key == null) ? 0 : key.hashCode()) ^ 1282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ((value == null) ? 0 : value.hashCode()); 1283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 1286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return key + "=" + value; 1287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static boolean eq(Object o1, Object o2) { 1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (o1 == null ? o2 == null : o1.equals(o2)); 1291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* ---------------- Serialization Support -------------- */ 1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Save the state of the <tt>ConcurrentHashMap</tt> 1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * instance to a stream (i.e., 1299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * serialize it). 1300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param s the stream 1301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @serialData 1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key (Object) and value (Object) 1303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for each key-value mapping, followed by a null pair. 1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The key-value mappings are emitted in no particular order. 1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void writeObject(java.io.ObjectOutputStream s) throws IOException { 1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.defaultWriteObject(); 1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int k = 0; k < segments.length; ++k) { 1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Segment<K,V> seg = (Segment<K,V>)segments[k]; 1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project seg.lock(); 1312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HashEntry[] tab = seg.table; 1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < tab.length; ++i) { 1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (HashEntry<K,V> e = (HashEntry<K,V>)tab[i]; e != null; e = e.next) { 1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.writeObject(e.key); 1317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.writeObject(e.value); 1318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 1321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project seg.unlock(); 1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.writeObject(null); 1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.writeObject(null); 1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reconstitute the <tt>ConcurrentHashMap</tt> 1330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * instance from a stream (i.e., 1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * deserialize it). 1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param s the stream 1333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void readObject(java.io.ObjectInputStream s) 1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException, ClassNotFoundException { 1336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.defaultReadObject(); 1337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Initialize each segment to be minimally sized, and let grow. 1339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < segments.length; ++i) { 1340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project segments[i].setTable(new HashEntry[1]); 1341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Read the keys and values, and put the mappings in the table 1344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 1345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project K key = (K) s.readObject(); 1346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V value = (V) s.readObject(); 1347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key == null) 1348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 1349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, value); 1350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1354