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