ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/ConcurrentHashMapV8.java
Revision: 1.13
Committed: Wed Aug 31 00:22:11 2011 UTC (12 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.12: +16 -21 lines
Log Message:
standard idiom for code snippets

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/publicdomain/zero/1.0/
5     */
6    
7     package jsr166e;
8     import jsr166e.LongAdder;
9     import java.util.Map;
10     import java.util.Set;
11     import java.util.Collection;
12     import java.util.AbstractMap;
13     import java.util.AbstractSet;
14     import java.util.AbstractCollection;
15     import java.util.Hashtable;
16     import java.util.HashMap;
17     import java.util.Iterator;
18     import java.util.Enumeration;
19     import java.util.ConcurrentModificationException;
20     import java.util.NoSuchElementException;
21     import java.util.concurrent.ConcurrentMap;
22     import java.io.Serializable;
23    
24     /**
25     * A hash table supporting full concurrency of retrievals and
26     * high expected concurrency for updates. This class obeys the
27     * same functional specification as {@link java.util.Hashtable}, and
28     * includes versions of methods corresponding to each method of
29     * {@code Hashtable}. However, even though all operations are
30     * thread-safe, retrieval operations do <em>not</em> entail locking,
31     * and there is <em>not</em> any support for locking the entire table
32     * in a way that prevents all access. This class is fully
33     * interoperable with {@code Hashtable} in programs that rely on its
34     * thread safety but not on its synchronization details.
35     *
36     * <p> Retrieval operations (including {@code get}) generally do not
37     * block, so may overlap with update operations (including {@code put}
38     * and {@code remove}). Retrievals reflect the results of the most
39     * recently <em>completed</em> update operations holding upon their
40     * onset. For aggregate operations such as {@code putAll} and {@code
41     * clear}, concurrent retrievals may reflect insertion or removal of
42     * only some entries. Similarly, Iterators and Enumerations return
43     * elements reflecting the state of the hash table at some point at or
44     * since the creation of the iterator/enumeration. They do
45     * <em>not</em> throw {@link ConcurrentModificationException}.
46     * However, iterators are designed to be used by only one thread at a
47     * time. Bear in mind that the results of aggregate status methods
48     * including {@code size}, {@code isEmpty}, and {@code containsValue}
49     * are typically useful only when a map is not undergoing concurrent
50     * updates in other threads. Otherwise the results of these methods
51     * reflect transient states that may be adequate for monitoring
52     * purposes, but not for program control.
53     *
54     * <p> Resizing this or any other kind of hash table is a relatively
55     * slow operation, so, when possible, it is a good idea to provide
56     * estimates of expected table sizes in constructors. Also, for
57 jsr166 1.7 * compatibility with previous versions of this class, constructors
58 dl 1.1 * may optionally specify an expected {@code concurrencyLevel} as an
59     * additional hint for internal sizing.
60     *
61     * <p>This class and its views and iterators implement all of the
62     * <em>optional</em> methods of the {@link Map} and {@link Iterator}
63     * interfaces.
64     *
65     * <p> Like {@link Hashtable} but unlike {@link HashMap}, this class
66     * does <em>not</em> allow {@code null} to be used as a key or value.
67     *
68     * <p>This class is a member of the
69     * <a href="{@docRoot}/../technotes/guides/collections/index.html">
70     * Java Collections Framework</a>.
71     *
72     * <p><em>jsr166e note: This class is a candidate replacement for
73     * java.util.concurrent.ConcurrentHashMap.<em>
74     *
75     * @since 1.5
76     * @author Doug Lea
77     * @param <K> the type of keys maintained by this map
78     * @param <V> the type of mapped values
79     */
80     public class ConcurrentHashMapV8<K, V>
81     implements ConcurrentMap<K, V>, Serializable {
82     private static final long serialVersionUID = 7249069246763182397L;
83    
84     /**
85     * A function computing a mapping from the given key to a value,
86 jsr166 1.8 * or {@code null} if there is no mapping. This is a place-holder
87     * for an upcoming JDK8 interface.
88 dl 1.1 */
89     public static interface MappingFunction<K, V> {
90     /**
91     * Returns a value for the given key, or null if there is no
92     * mapping. If this function throws an (unchecked) exception,
93     * the exception is rethrown to its caller, and no mapping is
94     * recorded. Because this function is invoked within
95     * atomicity control, the computation should be short and
96     * simple. The most common usage is to construct a new object
97     * serving as an initial mapped value.
98     *
99     * @param key the (non-null) key
100     * @return a value, or null if none
101     */
102     V map(K key);
103     }
104    
105     /*
106     * Overview:
107     *
108     * The primary design goal of this hash table is to maintain
109     * concurrent readability (typically method get(), but also
110     * iterators and related methods) while minimizing update
111     * contention.
112     *
113     * Each key-value mapping is held in a Node. Because Node fields
114     * can contain special values, they are defined using plain Object
115     * types. Similarly in turn, all internal methods that use them
116     * work off Object types. All public generic-typed methods relay
117     * in/out of these internal methods, supplying casts as needed.
118     *
119     * The table is lazily initialized to a power-of-two size upon the
120     * first insertion. Each bin in the table contains a (typically
121     * short) list of Nodes. Table accesses require volatile/atomic
122     * reads, writes, and CASes. Because there is no other way to
123     * arrange this without adding further indirections, we use
124     * intrinsics (sun.misc.Unsafe) operations. The lists of nodes
125     * within bins are always accurately traversable under volatile
126     * reads, so long as lookups check hash code and non-nullness of
127     * key and value before checking key equality. (All valid hash
128 dl 1.2 * codes are nonnegative. Negative values are reserved for special
129     * forwarding nodes; see below.)
130 dl 1.1 *
131     * A bin may be locked during update (insert, delete, and replace)
132     * operations. We do not want to waste the space required to
133     * associate a distinct lock object with each bin, so instead use
134     * the first node of a bin list itself as a lock, using builtin
135     * "synchronized" locks. These save space and we can live with
136     * only plain block-structured lock/unlock operations. Using the
137     * first node of a list as a lock does not by itself suffice
138     * though: When a node is locked, any update must first validate
139     * that it is still the first node, and retry if not. (Because new
140     * nodes are always appended to lists, once a node is first in a
141     * bin, it remains first until deleted or the bin becomes
142 dl 1.10 * invalidated.) However, update operations can and sometimes do
143 dl 1.1 * still traverse the bin until the point of update, which helps
144     * reduce cache misses on retries. This is a converse of sorts to
145     * the lazy locking technique described by Herlihy & Shavit. If
146     * there is no existing node during a put operation, then one can
147     * be CAS'ed in (without need for lock except in computeIfAbsent);
148     * the CAS serves as validation. This is on average the most
149 dl 1.5 * common case for put operations -- under random hash codes, the
150     * distribution of nodes in bins follows a Poisson distribution
151     * (see http://en.wikipedia.org/wiki/Poisson_distribution) with a
152     * parameter of 0.5 on average under the default loadFactor of
153     * 0.75. The expected number of locks covering different elements
154     * (i.e., bins with 2 or more nodes) is approximately 10% at
155     * steady state under default settings. Lock contention
156     * probability for two threads accessing arbitrary distinct
157     * elements is, roughly, 1 / (8 * #elements).
158 dl 1.1 *
159     * The table is resized when occupancy exceeds a threshold. Only
160     * a single thread performs the resize (using field "resizing", to
161     * arrange exclusion), but the table otherwise remains usable for
162     * both reads and updates. Resizing proceeds by transferring bins,
163     * one by one, from the table to the next table. Upon transfer,
164     * the old table bin contains only a special forwarding node (with
165     * negative hash code ("MOVED")) that contains the next table as
166     * its key. On encountering a forwarding node, access and update
167     * operations restart, using the new table. To ensure concurrent
168     * readability of traversals, transfers must proceed from the last
169     * bin (table.length - 1) up towards the first. Any traversal
170     * starting from the first bin can then arrange to move to the new
171     * table for the rest of the traversal without revisiting nodes.
172     * This constrains bin transfers to a particular order, and so can
173     * block indefinitely waiting for the next lock, and other threads
174     * cannot help with the transfer. However, expected stalls are
175     * infrequent enough to not warrant the additional overhead and
176     * complexity of access and iteration schemes that could admit
177     * out-of-order or concurrent bin transfers.
178     *
179 dl 1.2 * A similar traversal scheme (not yet implemented) can apply to
180     * partial traversals during partitioned aggregate operations.
181     * Also, read-only operations give up if ever forwarded to a null
182     * table, which provides support for shutdown-style clearing,
183     * which is also not currently implemented.
184 dl 1.1 *
185     * The element count is maintained using a LongAdder, which avoids
186     * contention on updates but can encounter cache thrashing if read
187     * too frequently during concurrent updates. To avoid reading so
188 dl 1.2 * often, resizing is normally attempted only upon adding to a bin
189     * already holding two or more nodes. Under the default threshold
190     * (0.75), and uniform hash distributions, the probability of this
191 dl 1.1 * occurring at threshold is around 13%, meaning that only about 1
192     * in 8 puts check threshold (and after resizing, many fewer do
193 dl 1.2 * so). But this approximation has high variance for small table
194     * sizes, so we check on any collision for sizes <= 64. Further,
195 jsr166 1.7 * to increase the probability that a resize occurs soon enough, we
196 dl 1.2 * offset the threshold (see THRESHOLD_OFFSET) by the expected
197     * number of puts between checks. This is currently set to 8, in
198     * accord with the default load factor. In practice, this is
199     * rarely overridden, and in any case is close enough to other
200 jsr166 1.7 * plausible values not to waste dynamic probability computation
201 dl 1.1 * for more precision.
202     */
203    
204     /* ---------------- Constants -------------- */
205    
206     /**
207     * The smallest allowed table capacity. Must be a power of 2, at
208     * least 2.
209     */
210     static final int MINIMUM_CAPACITY = 2;
211    
212     /**
213     * The largest allowed table capacity. Must be a power of 2, at
214     * most 1<<30.
215     */
216     static final int MAXIMUM_CAPACITY = 1 << 30;
217    
218     /**
219     * The default initial table capacity. Must be a power of 2, at
220 jsr166 1.9 * least MINIMUM_CAPACITY and at most MAXIMUM_CAPACITY.
221 dl 1.1 */
222     static final int DEFAULT_CAPACITY = 16;
223    
224     /**
225     * The default load factor for this table, used when not otherwise
226     * specified in a constructor.
227     */
228     static final float DEFAULT_LOAD_FACTOR = 0.75f;
229    
230     /**
231     * The default concurrency level for this table. Unused, but
232     * defined for compatibility with previous versions of this class.
233     */
234     static final int DEFAULT_CONCURRENCY_LEVEL = 16;
235    
236     /**
237 jsr166 1.7 * The count value to offset thresholds to compensate for checking
238 dl 1.1 * for resizing only when inserting into bins with two or more
239     * elements. See above for explanation.
240     */
241     static final int THRESHOLD_OFFSET = 8;
242    
243     /**
244     * Special node hash value indicating to use table in node.key
245     * Must be negative.
246     */
247     static final int MOVED = -1;
248    
249     /* ---------------- Fields -------------- */
250    
251     /**
252     * The array of bins. Lazily initialized upon first insertion.
253     * Size is always a power of two. Accessed directly by inner
254     * classes.
255     */
256     transient volatile Node[] table;
257    
258     /** The counter maintaining number of elements. */
259     private transient final LongAdder counter;
260     /** Nonzero when table is being initialized or resized. Updated via CAS. */
261     private transient volatile int resizing;
262     /** The target load factor for the table. */
263     private transient float loadFactor;
264     /** The next element count value upon which to resize the table. */
265     private transient int threshold;
266     /** The initial capacity of the table. */
267     private transient int initCap;
268    
269     // views
270     transient Set<K> keySet;
271     transient Set<Map.Entry<K,V>> entrySet;
272     transient Collection<V> values;
273    
274 jsr166 1.7 /** For serialization compatibility. Null unless serialized; see below */
275 dl 1.1 Segment<K,V>[] segments;
276    
277     /**
278     * Applies a supplemental hash function to a given hashCode, which
279     * defends against poor quality hash functions. The result must
280     * be non-negative, and for reasonable performance must have good
281     * avalanche properties; i.e., that each bit of the argument
282     * affects each bit (except sign bit) of the result.
283     */
284     private static final int spread(int h) {
285     // Apply base step of MurmurHash; see http://code.google.com/p/smhasher/
286     h ^= h >>> 16;
287     h *= 0x85ebca6b;
288     h ^= h >>> 13;
289     h *= 0xc2b2ae35;
290     return (h >>> 16) ^ (h & 0x7fffffff); // mask out sign bit
291     }
292    
293     /**
294     * Key-value entry. Note that this is never exported out as a
295     * user-visible Map.Entry.
296     */
297     static final class Node {
298     final int hash;
299     final Object key;
300     volatile Object val;
301     volatile Node next;
302    
303     Node(int hash, Object key, Object val, Node next) {
304     this.hash = hash;
305     this.key = key;
306     this.val = val;
307     this.next = next;
308     }
309     }
310    
311     /*
312 jsr166 1.7 * Volatile access methods are used for table elements as well as
313 dl 1.1 * elements of in-progress next table while resizing. Uses in
314     * access and update methods are null checked by callers, and
315     * implicitly bounds-checked, relying on the invariants that tab
316     * arrays have non-zero size, and all indices are masked with
317     * (tab.length - 1) which is never negative and always less than
318 dl 1.2 * length. The "relaxed" non-volatile forms are used only during
319     * table initialization. The only other usage is in
320     * HashIterator.advance, which performs explicit checks.
321 dl 1.1 */
322    
323     static final Node tabAt(Node[] tab, int i) { // used in HashIterator
324     return (Node)UNSAFE.getObjectVolatile(tab, ((long)i<<ASHIFT)+ABASE);
325     }
326    
327     private static final boolean casTabAt(Node[] tab, int i, Node c, Node v) {
328     return UNSAFE.compareAndSwapObject(tab, ((long)i<<ASHIFT)+ABASE, c, v);
329     }
330    
331     private static final void setTabAt(Node[] tab, int i, Node v) {
332     UNSAFE.putObjectVolatile(tab, ((long)i<<ASHIFT)+ABASE, v);
333     }
334    
335 dl 1.2 private static final Node relaxedTabAt(Node[] tab, int i) {
336     return (Node)UNSAFE.getObject(tab, ((long)i<<ASHIFT)+ABASE);
337     }
338    
339     private static final void relaxedSetTabAt(Node[] tab, int i, Node v) {
340     UNSAFE.putObject(tab, ((long)i<<ASHIFT)+ABASE, v);
341     }
342    
343 dl 1.1 /* ---------------- Access and update operations -------------- */
344    
345 dl 1.10 /** Implementation for get and containsKey */
346 jsr166 1.4 private final Object internalGet(Object k) {
347 dl 1.1 int h = spread(k.hashCode());
348     Node[] tab = table;
349     retry: while (tab != null) {
350     Node e = tabAt(tab, (tab.length - 1) & h);
351     while (e != null) {
352     int eh = e.hash;
353     if (eh == h) {
354     Object ek = e.key, ev = e.val;
355     if (ev != null && ek != null && (k == ek || k.equals(ek)))
356     return ev;
357     }
358 dl 1.2 else if (eh < 0) { // bin was moved during resize
359 dl 1.1 tab = (Node[])e.key;
360     continue retry;
361     }
362     e = e.next;
363     }
364     break;
365     }
366     return null;
367     }
368    
369 dl 1.10
370     /** Implementation for put and putIfAbsent */
371 dl 1.1 private final Object internalPut(Object k, Object v, boolean replace) {
372     int h = spread(k.hashCode());
373     Object oldVal = null; // the previous value or null if none
374     Node[] tab = table;
375     for (;;) {
376     Node e; int i;
377     if (tab == null)
378     tab = grow(0);
379     else if ((e = tabAt(tab, i = (tab.length - 1) & h)) == null) {
380 dl 1.2 if (casTabAt(tab, i, null, new Node(h, k, v, null)))
381 dl 1.1 break;
382     }
383     else if (e.hash < 0)
384     tab = (Node[])e.key;
385     else {
386     boolean validated = false;
387     boolean checkSize = false;
388 jsr166 1.4 synchronized (e) {
389 dl 1.10 if (tabAt(tab, i) == e) {
390     validated = true;
391     for (Node first = e;;) {
392     Object ek, ev;
393 jsr166 1.11 if (e.hash == h &&
394 dl 1.10 (ek = e.key) != null &&
395     (ev = e.val) != null &&
396     (k == ek || k.equals(ek))) {
397 dl 1.1 oldVal = ev;
398     if (replace)
399     e.val = v;
400 dl 1.10 break;
401 dl 1.1 }
402 dl 1.10 Node last = e;
403     if ((e = e.next) == null) {
404 dl 1.2 last.next = new Node(h, k, v, null);
405     if (last != first || tab.length <= 64)
406 dl 1.1 checkSize = true;
407 dl 1.10 break;
408 dl 1.1 }
409     }
410     }
411     }
412     if (validated) {
413     if (checkSize && tab.length < MAXIMUM_CAPACITY &&
414     resizing == 0 && counter.sum() >= threshold)
415     grow(0);
416     break;
417     }
418     }
419     }
420     if (oldVal == null)
421     counter.increment();
422     return oldVal;
423     }
424    
425     /**
426 dl 1.10 * Implementation for the four public remove/replace methods:
427     * Replaces node value with v, conditional upon match of cv if
428     * non-null. If resulting value is null, delete.
429 dl 1.1 */
430     private final Object internalReplace(Object k, Object v, Object cv) {
431     int h = spread(k.hashCode());
432     Object oldVal = null;
433     Node e; int i;
434     Node[] tab = table;
435     while (tab != null &&
436     (e = tabAt(tab, i = (tab.length - 1) & h)) != null) {
437     if (e.hash < 0)
438     tab = (Node[])e.key;
439     else {
440     boolean validated = false;
441     boolean deleted = false;
442 jsr166 1.4 synchronized (e) {
443 dl 1.10 if (tabAt(tab, i) == e) {
444     validated = true;
445     Node pred = null;
446     do {
447     Object ek, ev;
448     if (e.hash == h &&
449     (ek = e.key) != null &&
450     (ev = e.val) != null &&
451     (k == ek || k.equals(ek))) {
452 dl 1.1 if (cv == null || cv == ev || cv.equals(ev)) {
453     oldVal = ev;
454     if ((e.val = v) == null) {
455     deleted = true;
456     Node en = e.next;
457     if (pred != null)
458     pred.next = en;
459     else
460     setTabAt(tab, i, en);
461     }
462     }
463 dl 1.10 break;
464 dl 1.1 }
465 dl 1.10 pred = e;
466     } while ((e = e.next) != null);
467 dl 1.1 }
468     }
469     if (validated) {
470     if (deleted)
471     counter.decrement();
472     break;
473     }
474     }
475     }
476     return oldVal;
477     }
478    
479 dl 1.2 /** Implementation for computeIfAbsent and compute */
480 dl 1.1 @SuppressWarnings("unchecked")
481 dl 1.2 private final V internalCompute(K k,
482     MappingFunction<? super K, ? extends V> f,
483     boolean replace) {
484 dl 1.1 int h = spread(k.hashCode());
485     V val = null;
486     boolean added = false;
487     Node[] tab = table;
488 jsr166 1.12 for (;;) {
489 dl 1.1 Node e; int i;
490     if (tab == null)
491     tab = grow(0);
492     else if ((e = tabAt(tab, i = (tab.length - 1) & h)) == null) {
493 dl 1.2 Node node = new Node(h, k, null, null);
494 dl 1.10 boolean validated = false;
495 jsr166 1.4 synchronized (node) {
496 dl 1.1 if (casTabAt(tab, i, null, node)) {
497     validated = true;
498     try {
499     val = f.map(k);
500     if (val != null) {
501     node.val = val;
502     added = true;
503     }
504     } finally {
505     if (!added)
506     setTabAt(tab, i, null);
507     }
508     }
509     }
510 dl 1.10 if (validated)
511     break;
512 dl 1.1 }
513     else if (e.hash < 0)
514     tab = (Node[])e.key;
515 dl 1.5 else if (Thread.holdsLock(e))
516     throw new IllegalStateException("Recursive map computation");
517 dl 1.1 else {
518 dl 1.10 boolean validated = false;
519 dl 1.1 boolean checkSize = false;
520 jsr166 1.4 synchronized (e) {
521 dl 1.10 if (tabAt(tab, i) == e) {
522     validated = true;
523     for (Node first = e;;) {
524     Object ek, ev, fv;
525     if (e.hash == h &&
526     (ek = e.key) != null &&
527     (ev = e.val) != null &&
528     (k == ek || k.equals(ek))) {
529     if (replace && (fv = f.map(k)) != null)
530     ev = e.val = fv;
531 dl 1.1 val = (V)ev;
532 dl 1.10 break;
533 dl 1.1 }
534 dl 1.10 Node last = e;
535     if ((e = e.next) == null) {
536 dl 1.1 if ((val = f.map(k)) != null) {
537 dl 1.2 last.next = new Node(h, k, val, null);
538     added = true;
539     if (last != first || tab.length <= 64)
540 dl 1.1 checkSize = true;
541     }
542 dl 1.10 break;
543 dl 1.1 }
544     }
545     }
546     }
547 dl 1.10 if (validated) {
548     if (checkSize && tab.length < MAXIMUM_CAPACITY &&
549     resizing == 0 && counter.sum() >= threshold)
550     grow(0);
551     break;
552     }
553 dl 1.1 }
554 dl 1.10 }
555 dl 1.1 if (added)
556     counter.increment();
557     return val;
558     }
559    
560     /*
561     * Reclassifies nodes in each bin to new table. Because we are
562     * using power-of-two expansion, the elements from each bin must
563     * either stay at same index, or move with a power of two
564     * offset. We eliminate unnecessary node creation by catching
565     * cases where old nodes can be reused because their next fields
566     * won't change. Statistically, at the default threshold, only
567     * about one-sixth of them need cloning when a table doubles. The
568     * nodes they replace will be garbage collectable as soon as they
569     * are no longer referenced by any reader thread that may be in
570     * the midst of concurrently traversing table.
571     *
572     * Transfers are done from the bottom up to preserve iterator
573     * traversability. On each step, the old bin is locked,
574     * moved/copied, and then replaced with a forwarding node.
575     */
576     private static final void transfer(Node[] tab, Node[] nextTab) {
577     int n = tab.length;
578     int mask = nextTab.length - 1;
579     Node fwd = new Node(MOVED, nextTab, null, null);
580     for (int i = n - 1; i >= 0; --i) {
581     for (Node e;;) {
582     if ((e = tabAt(tab, i)) == null) {
583     if (casTabAt(tab, i, e, fwd))
584     break;
585     }
586     else {
587 dl 1.10 int idx = e.hash & mask;
588 dl 1.1 boolean validated = false;
589 jsr166 1.4 synchronized (e) {
590 dl 1.1 if (tabAt(tab, i) == e) {
591     validated = true;
592 dl 1.10 Node lastRun = e;
593     for (Node p = e.next; p != null; p = p.next) {
594     int j = p.hash & mask;
595     if (j != idx) {
596     idx = j;
597     lastRun = p;
598     }
599     }
600 dl 1.2 relaxedSetTabAt(nextTab, idx, lastRun);
601 dl 1.1 for (Node p = e; p != lastRun; p = p.next) {
602     int h = p.hash;
603     int j = h & mask;
604 dl 1.2 Node r = relaxedTabAt(nextTab, j);
605     relaxedSetTabAt(nextTab, j,
606     new Node(h, p.key, p.val, r));
607 dl 1.1 }
608     setTabAt(tab, i, fwd);
609     }
610     }
611     if (validated)
612     break;
613     }
614     }
615     }
616     }
617    
618     /**
619     * If not already resizing, initializes or creates next table and
620     * transfers bins. Rechecks occupancy after a transfer to see if
621     * another resize is already needed because resizings are lagging
622     * additions.
623     *
624     * @param sizeHint overridden capacity target (nonzero only from putAll)
625     * @return current table
626     */
627     private final Node[] grow(int sizeHint) {
628     if (resizing == 0 &&
629     UNSAFE.compareAndSwapInt(this, resizingOffset, 0, 1)) {
630     try {
631     for (;;) {
632     int cap, n;
633 dl 1.2 Node[] tab = table;
634     if (tab == null) {
635 dl 1.1 int c = initCap;
636     if (c < sizeHint)
637     c = sizeHint;
638     if (c == DEFAULT_CAPACITY)
639     cap = c;
640     else if (c >= MAXIMUM_CAPACITY)
641     cap = MAXIMUM_CAPACITY;
642     else {
643     cap = MINIMUM_CAPACITY;
644     while (cap < c)
645     cap <<= 1;
646     }
647     }
648     else if ((n = tab.length) < MAXIMUM_CAPACITY &&
649     (sizeHint <= 0 || n < sizeHint))
650     cap = n << 1;
651     else
652     break;
653     threshold = (int)(cap * loadFactor) - THRESHOLD_OFFSET;
654     Node[] nextTab = new Node[cap];
655     if (tab != null)
656     transfer(tab, nextTab);
657     table = nextTab;
658 dl 1.2 if (tab == null || cap >= MAXIMUM_CAPACITY ||
659 dl 1.10 ((sizeHint > 0) ? cap >= sizeHint :
660     counter.sum() < threshold))
661 dl 1.1 break;
662     }
663     } finally {
664     resizing = 0;
665     }
666     }
667 dl 1.2 else if (table == null)
668 dl 1.1 Thread.yield(); // lost initialization race; just spin
669 dl 1.2 return table;
670 dl 1.1 }
671    
672     /**
673 dl 1.2 * Implementation for putAll and constructor with Map
674     * argument. Tries to first override initial capacity or grow
675     * based on map size to pre-allocate table space.
676 dl 1.1 */
677     private final void internalPutAll(Map<? extends K, ? extends V> m) {
678     int s = m.size();
679 jsr166 1.4 grow((s >= (MAXIMUM_CAPACITY >>> 1)) ? s : s + (s >>> 1));
680 dl 1.1 for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
681     Object k = e.getKey();
682     Object v = e.getValue();
683     if (k == null || v == null)
684     throw new NullPointerException();
685     internalPut(k, v, true);
686     }
687     }
688    
689     /**
690 dl 1.2 * Implementation for clear. Steps through each bin, removing all nodes.
691 dl 1.1 */
692     private final void internalClear() {
693 dl 1.2 long deletions = 0L;
694 dl 1.1 int i = 0;
695     Node[] tab = table;
696     while (tab != null && i < tab.length) {
697     Node e = tabAt(tab, i);
698     if (e == null)
699     ++i;
700     else if (e.hash < 0)
701     tab = (Node[])e.key;
702     else {
703     boolean validated = false;
704 jsr166 1.4 synchronized (e) {
705 dl 1.1 if (tabAt(tab, i) == e) {
706     validated = true;
707     do {
708     if (e.val != null) {
709     e.val = null;
710 dl 1.2 ++deletions;
711 dl 1.1 }
712     } while ((e = e.next) != null);
713     setTabAt(tab, i, null);
714     }
715     }
716 dl 1.2 if (validated) {
717 dl 1.1 ++i;
718 dl 1.2 if (deletions > THRESHOLD_OFFSET) { // bound lag in counts
719     counter.add(-deletions);
720     deletions = 0L;
721     }
722     }
723 dl 1.1 }
724     }
725 dl 1.2 if (deletions != 0L)
726     counter.add(-deletions);
727 dl 1.1 }
728    
729     /**
730     * Base class for key, value, and entry iterators, plus internal
731     * implementations of public traversal-based methods, to avoid
732     * duplicating traversal code.
733     */
734     class HashIterator {
735     private Node next; // the next entry to return
736     private Node[] tab; // current table; updated if resized
737     private Node lastReturned; // the last entry returned, for remove
738     private Object nextVal; // cached value of next
739     private int index; // index of bin to use next
740     private int baseIndex; // current index of initial table
741     private final int baseSize; // initial table size
742    
743     HashIterator() {
744     Node[] t = tab = table;
745     if (t == null)
746     baseSize = 0;
747     else {
748     baseSize = t.length;
749     advance(null);
750     }
751     }
752    
753     public final boolean hasNext() { return next != null; }
754     public final boolean hasMoreElements() { return next != null; }
755    
756     /**
757     * Advances next. Normally, iteration proceeds bin-by-bin
758     * traversing lists. However, if the table has been resized,
759     * then all future steps must traverse both the bin at the
760     * current index as well as at (index + baseSize); and so on
761     * for further resizings. To paranoically cope with potential
762     * (improper) sharing of iterators across threads, table reads
763     * are bounds-checked.
764     */
765     final void advance(Node e) {
766     for (;;) {
767     Node[] t; int i; // for bounds checks
768     if (e != null) {
769     Object ek = e.key, ev = e.val;
770     if (ev != null && ek != null) {
771     nextVal = ev;
772     next = e;
773     break;
774     }
775     e = e.next;
776     }
777     else if (baseIndex < baseSize && (t = tab) != null &&
778     t.length > (i = index) && i >= 0) {
779     if ((e = tabAt(t, i)) != null && e.hash < 0) {
780     tab = (Node[])e.key;
781     e = null;
782     }
783     else if (i + baseSize < t.length)
784     index += baseSize; // visit forwarded upper slots
785     else
786     index = ++baseIndex;
787     }
788     else {
789     next = null;
790     break;
791     }
792     }
793     }
794    
795     final Object nextKey() {
796     Node e = next;
797     if (e == null)
798     throw new NoSuchElementException();
799     Object k = e.key;
800     advance((lastReturned = e).next);
801     return k;
802     }
803    
804     final Object nextValue() {
805     Node e = next;
806     if (e == null)
807     throw new NoSuchElementException();
808     Object v = nextVal;
809     advance((lastReturned = e).next);
810     return v;
811     }
812    
813     final WriteThroughEntry nextEntry() {
814     Node e = next;
815     if (e == null)
816     throw new NoSuchElementException();
817     WriteThroughEntry entry =
818     new WriteThroughEntry(e.key, nextVal);
819     advance((lastReturned = e).next);
820     return entry;
821     }
822    
823     public final void remove() {
824     if (lastReturned == null)
825     throw new IllegalStateException();
826     ConcurrentHashMapV8.this.remove(lastReturned.key);
827     lastReturned = null;
828     }
829    
830     /** Helper for serialization */
831     final void writeEntries(java.io.ObjectOutputStream s)
832     throws java.io.IOException {
833     Node e;
834     while ((e = next) != null) {
835     s.writeObject(e.key);
836     s.writeObject(nextVal);
837     advance(e.next);
838     }
839     }
840    
841     /** Helper for containsValue */
842     final boolean containsVal(Object value) {
843     if (value != null) {
844     Node e;
845     while ((e = next) != null) {
846     Object v = nextVal;
847     if (value == v || value.equals(v))
848     return true;
849     advance(e.next);
850     }
851     }
852     return false;
853     }
854    
855     /** Helper for Map.hashCode */
856     final int mapHashCode() {
857     int h = 0;
858     Node e;
859     while ((e = next) != null) {
860     h += e.key.hashCode() ^ nextVal.hashCode();
861     advance(e.next);
862     }
863     return h;
864     }
865    
866     /** Helper for Map.toString */
867     final String mapToString() {
868     Node e = next;
869     if (e == null)
870     return "{}";
871     StringBuilder sb = new StringBuilder();
872     sb.append('{');
873     for (;;) {
874     sb.append(e.key == this ? "(this Map)" : e.key);
875     sb.append('=');
876     sb.append(nextVal == this ? "(this Map)" : nextVal);
877     advance(e.next);
878     if ((e = next) != null)
879     sb.append(',').append(' ');
880     else
881     return sb.append('}').toString();
882     }
883     }
884     }
885    
886     /* ---------------- Public operations -------------- */
887    
888     /**
889     * Creates a new, empty map with the specified initial
890     * capacity, load factor and concurrency level.
891     *
892     * @param initialCapacity the initial capacity. The implementation
893     * performs internal sizing to accommodate this many elements.
894     * @param loadFactor the load factor threshold, used to control resizing.
895     * Resizing may be performed when the average number of elements per
896     * bin exceeds this threshold.
897     * @param concurrencyLevel the estimated number of concurrently
898     * updating threads. The implementation may use this value as
899     * a sizing hint.
900     * @throws IllegalArgumentException if the initial capacity is
901     * negative or the load factor or concurrencyLevel are
902     * nonpositive.
903     */
904     public ConcurrentHashMapV8(int initialCapacity,
905 jsr166 1.9 float loadFactor, int concurrencyLevel) {
906 dl 1.1 if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)
907     throw new IllegalArgumentException();
908     this.initCap = initialCapacity;
909     this.loadFactor = loadFactor;
910     this.counter = new LongAdder();
911     }
912    
913     /**
914     * Creates a new, empty map with the specified initial capacity
915     * and load factor and with the default concurrencyLevel (16).
916     *
917     * @param initialCapacity The implementation performs internal
918     * sizing to accommodate this many elements.
919     * @param loadFactor the load factor threshold, used to control resizing.
920     * Resizing may be performed when the average number of elements per
921     * bin exceeds this threshold.
922     * @throws IllegalArgumentException if the initial capacity of
923     * elements is negative or the load factor is nonpositive
924     *
925     * @since 1.6
926     */
927     public ConcurrentHashMapV8(int initialCapacity, float loadFactor) {
928     this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL);
929     }
930    
931     /**
932     * Creates a new, empty map with the specified initial capacity,
933     * and with default load factor (0.75) and concurrencyLevel (16).
934     *
935     * @param initialCapacity the initial capacity. The implementation
936     * performs internal sizing to accommodate this many elements.
937     * @throws IllegalArgumentException if the initial capacity of
938     * elements is negative.
939     */
940     public ConcurrentHashMapV8(int initialCapacity) {
941     this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
942     }
943    
944     /**
945     * Creates a new, empty map with a default initial capacity (16),
946     * load factor (0.75) and concurrencyLevel (16).
947     */
948     public ConcurrentHashMapV8() {
949     this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
950     }
951    
952     /**
953     * Creates a new map with the same mappings as the given map.
954     * The map is created with a capacity of 1.5 times the number
955     * of mappings in the given map or 16 (whichever is greater),
956     * and a default load factor (0.75) and concurrencyLevel (16).
957     *
958     * @param m the map
959     */
960     public ConcurrentHashMapV8(Map<? extends K, ? extends V> m) {
961     this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
962     if (m == null)
963     throw new NullPointerException();
964     internalPutAll(m);
965     }
966    
967     /**
968     * Returns {@code true} if this map contains no key-value mappings.
969     *
970     * @return {@code true} if this map contains no key-value mappings
971     */
972     public boolean isEmpty() {
973 dl 1.2 return counter.sum() <= 0L; // ignore transient negative values
974 dl 1.1 }
975    
976     /**
977     * Returns the number of key-value mappings in this map. If the
978     * map contains more than {@code Integer.MAX_VALUE} elements, returns
979     * {@code Integer.MAX_VALUE}.
980     *
981     * @return the number of key-value mappings in this map
982     */
983     public int size() {
984     long n = counter.sum();
985 jsr166 1.6 return ((n >>> 31) == 0) ? (int)n : (n < 0L) ? 0 : Integer.MAX_VALUE;
986 dl 1.1 }
987    
988     /**
989     * Returns the value to which the specified key is mapped,
990     * or {@code null} if this map contains no mapping for the key.
991     *
992     * <p>More formally, if this map contains a mapping from a key
993     * {@code k} to a value {@code v} such that {@code key.equals(k)},
994     * then this method returns {@code v}; otherwise it returns
995     * {@code null}. (There can be at most one such mapping.)
996     *
997     * @throws NullPointerException if the specified key is null
998     */
999     @SuppressWarnings("unchecked")
1000     public V get(Object key) {
1001     if (key == null)
1002     throw new NullPointerException();
1003     return (V)internalGet(key);
1004     }
1005    
1006     /**
1007     * Tests if the specified object is a key in this table.
1008     *
1009     * @param key possible key
1010     * @return {@code true} if and only if the specified object
1011     * is a key in this table, as determined by the
1012     * {@code equals} method; {@code false} otherwise.
1013     * @throws NullPointerException if the specified key is null
1014     */
1015     public boolean containsKey(Object key) {
1016     if (key == null)
1017     throw new NullPointerException();
1018     return internalGet(key) != null;
1019     }
1020    
1021     /**
1022     * Returns {@code true} if this map maps one or more keys to the
1023     * specified value. Note: This method requires a full internal
1024     * traversal of the hash table, and so is much slower than
1025     * method {@code containsKey}.
1026     *
1027     * @param value value whose presence in this map is to be tested
1028     * @return {@code true} if this map maps one or more keys to the
1029     * specified value
1030     * @throws NullPointerException if the specified value is null
1031     */
1032     public boolean containsValue(Object value) {
1033     if (value == null)
1034     throw new NullPointerException();
1035     return new HashIterator().containsVal(value);
1036     }
1037    
1038     /**
1039     * Legacy method testing if some key maps into the specified value
1040     * in this table. This method is identical in functionality to
1041     * {@link #containsValue}, and exists solely to ensure
1042     * full compatibility with class {@link java.util.Hashtable},
1043     * which supported this method prior to introduction of the
1044     * Java Collections framework.
1045     *
1046     * @param value a value to search for
1047     * @return {@code true} if and only if some key maps to the
1048     * {@code value} argument in this table as
1049     * determined by the {@code equals} method;
1050     * {@code false} otherwise
1051     * @throws NullPointerException if the specified value is null
1052     */
1053     public boolean contains(Object value) {
1054     return containsValue(value);
1055     }
1056    
1057     /**
1058     * Maps the specified key to the specified value in this table.
1059     * Neither the key nor the value can be null.
1060     *
1061     * <p> The value can be retrieved by calling the {@code get} method
1062     * with a key that is equal to the original key.
1063     *
1064     * @param key key with which the specified value is to be associated
1065     * @param value value to be associated with the specified key
1066     * @return the previous value associated with {@code key}, or
1067     * {@code null} if there was no mapping for {@code key}
1068     * @throws NullPointerException if the specified key or value is null
1069     */
1070     @SuppressWarnings("unchecked")
1071     public V put(K key, V value) {
1072     if (key == null || value == null)
1073     throw new NullPointerException();
1074     return (V)internalPut(key, value, true);
1075     }
1076    
1077     /**
1078     * {@inheritDoc}
1079     *
1080     * @return the previous value associated with the specified key,
1081     * or {@code null} if there was no mapping for the key
1082     * @throws NullPointerException if the specified key or value is null
1083     */
1084     @SuppressWarnings("unchecked")
1085     public V putIfAbsent(K key, V value) {
1086     if (key == null || value == null)
1087     throw new NullPointerException();
1088     return (V)internalPut(key, value, false);
1089     }
1090    
1091     /**
1092     * Copies all of the mappings from the specified map to this one.
1093     * These mappings replace any mappings that this map had for any of the
1094     * keys currently in the specified map.
1095     *
1096     * @param m mappings to be stored in this map
1097     */
1098     public void putAll(Map<? extends K, ? extends V> m) {
1099     if (m == null)
1100     throw new NullPointerException();
1101     internalPutAll(m);
1102     }
1103    
1104     /**
1105     * If the specified key is not already associated with a value,
1106     * computes its value using the given mappingFunction, and if
1107     * non-null, enters it into the map. This is equivalent to
1108 jsr166 1.13 * <pre> {@code
1109     * if (map.containsKey(key))
1110     * return map.get(key);
1111     * value = mappingFunction.map(key);
1112     * if (value != null)
1113     * map.put(key, value);
1114     * return value;}</pre>
1115 dl 1.1 *
1116     * except that the action is performed atomically. Some attempted
1117 dl 1.5 * update operations on this map by other threads may be blocked
1118     * while computation is in progress, so the computation should be
1119     * short and simple, and must not attempt to update any other
1120     * mappings of this Map. The most appropriate usage is to
1121     * construct a new object serving as an initial mapped value, or
1122     * memoized result, as in:
1123 jsr166 1.13 * <pre> {@code
1124 dl 1.5 * map.computeIfAbsent(key, new MappingFunction<K, V>() {
1125 jsr166 1.13 * public V map(K k) { return new Value(f(k)); }});}</pre>
1126 dl 1.1 *
1127     * @param key key with which the specified value is to be associated
1128     * @param mappingFunction the function to compute a value
1129     * @return the current (existing or computed) value associated with
1130     * the specified key, or {@code null} if the computation
1131     * returned {@code null}.
1132     * @throws NullPointerException if the specified key or mappingFunction
1133     * is null,
1134 dl 1.5 * @throws IllegalStateException if the computation detectably
1135     * attempts a recursive update to this map that would
1136     * otherwise never complete.
1137 dl 1.1 * @throws RuntimeException or Error if the mappingFunction does so,
1138     * in which case the mapping is left unestablished.
1139     */
1140     public V computeIfAbsent(K key, MappingFunction<? super K, ? extends V> mappingFunction) {
1141     if (key == null || mappingFunction == null)
1142     throw new NullPointerException();
1143 dl 1.2 return internalCompute(key, mappingFunction, false);
1144     }
1145    
1146     /**
1147 dl 1.5 * Computes the value associated with the given key using the given
1148 dl 1.2 * mappingFunction, and if non-null, enters it into the map. This
1149     * is equivalent to
1150 jsr166 1.13 * <pre> {@code
1151     * value = mappingFunction.map(key);
1152     * if (value != null)
1153     * map.put(key, value);
1154     * else
1155     * value = map.get(key);
1156     * return value;}</pre>
1157 dl 1.2 *
1158     * except that the action is performed atomically. Some attempted
1159 dl 1.5 * update operations on this map by other threads may be blocked
1160     * while computation is in progress, so the computation should be
1161     * short and simple, and must not attempt to update any other
1162     * mappings of this Map.
1163 dl 1.2 *
1164     * @param key key with which the specified value is to be associated
1165     * @param mappingFunction the function to compute a value
1166     * @return the current value associated with
1167     * the specified key, or {@code null} if the computation
1168     * returned {@code null} and the value was not otherwise present.
1169     * @throws NullPointerException if the specified key or mappingFunction
1170     * is null,
1171 dl 1.5 * @throws IllegalStateException if the computation detectably
1172     * attempts a recursive update to this map that would
1173     * otherwise never complete.
1174 dl 1.2 * @throws RuntimeException or Error if the mappingFunction does so,
1175     * in which case the mapping is unchanged.
1176     */
1177     public V compute(K key, MappingFunction<? super K, ? extends V> mappingFunction) {
1178     if (key == null || mappingFunction == null)
1179     throw new NullPointerException();
1180     return internalCompute(key, mappingFunction, true);
1181 dl 1.1 }
1182    
1183     /**
1184     * Removes the key (and its corresponding value) from this map.
1185     * This method does nothing if the key is not in the map.
1186     *
1187     * @param key the key that needs to be removed
1188     * @return the previous value associated with {@code key}, or
1189     * {@code null} if there was no mapping for {@code key}
1190     * @throws NullPointerException if the specified key is null
1191     */
1192     @SuppressWarnings("unchecked")
1193     public V remove(Object key) {
1194     if (key == null)
1195     throw new NullPointerException();
1196 jsr166 1.3 return (V)internalReplace(key, null, null);
1197 dl 1.1 }
1198    
1199     /**
1200     * {@inheritDoc}
1201     *
1202     * @throws NullPointerException if the specified key is null
1203     */
1204     public boolean remove(Object key, Object value) {
1205     if (key == null)
1206     throw new NullPointerException();
1207     if (value == null)
1208     return false;
1209     return internalReplace(key, null, value) != null;
1210     }
1211    
1212     /**
1213     * {@inheritDoc}
1214     *
1215     * @throws NullPointerException if any of the arguments are null
1216     */
1217     public boolean replace(K key, V oldValue, V newValue) {
1218     if (key == null || oldValue == null || newValue == null)
1219     throw new NullPointerException();
1220 jsr166 1.3 return internalReplace(key, newValue, oldValue) != null;
1221 dl 1.1 }
1222    
1223     /**
1224     * {@inheritDoc}
1225     *
1226     * @return the previous value associated with the specified key,
1227     * or {@code null} if there was no mapping for the key
1228     * @throws NullPointerException if the specified key or value is null
1229     */
1230     @SuppressWarnings("unchecked")
1231     public V replace(K key, V value) {
1232     if (key == null || value == null)
1233     throw new NullPointerException();
1234 jsr166 1.3 return (V)internalReplace(key, value, null);
1235 dl 1.1 }
1236    
1237     /**
1238     * Removes all of the mappings from this map.
1239     */
1240     public void clear() {
1241     internalClear();
1242     }
1243    
1244     /**
1245     * Returns a {@link Set} view of the keys contained in this map.
1246     * The set is backed by the map, so changes to the map are
1247     * reflected in the set, and vice-versa. The set supports element
1248     * removal, which removes the corresponding mapping from this map,
1249     * via the {@code Iterator.remove}, {@code Set.remove},
1250     * {@code removeAll}, {@code retainAll}, and {@code clear}
1251     * operations. It does not support the {@code add} or
1252     * {@code addAll} operations.
1253     *
1254     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1255     * that will never throw {@link ConcurrentModificationException},
1256     * and guarantees to traverse elements as they existed upon
1257     * construction of the iterator, and may (but is not guaranteed to)
1258     * reflect any modifications subsequent to construction.
1259     */
1260     public Set<K> keySet() {
1261     Set<K> ks = keySet;
1262     return (ks != null) ? ks : (keySet = new KeySet());
1263     }
1264    
1265     /**
1266     * Returns a {@link Collection} view of the values contained in this map.
1267     * The collection is backed by the map, so changes to the map are
1268     * reflected in the collection, and vice-versa. The collection
1269     * supports element removal, which removes the corresponding
1270     * mapping from this map, via the {@code Iterator.remove},
1271     * {@code Collection.remove}, {@code removeAll},
1272     * {@code retainAll}, and {@code clear} operations. It does not
1273     * support the {@code add} or {@code addAll} operations.
1274     *
1275     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1276     * that will never throw {@link ConcurrentModificationException},
1277     * and guarantees to traverse elements as they existed upon
1278     * construction of the iterator, and may (but is not guaranteed to)
1279     * reflect any modifications subsequent to construction.
1280     */
1281     public Collection<V> values() {
1282     Collection<V> vs = values;
1283     return (vs != null) ? vs : (values = new Values());
1284     }
1285    
1286     /**
1287     * Returns a {@link Set} view of the mappings contained in this map.
1288     * The set is backed by the map, so changes to the map are
1289     * reflected in the set, and vice-versa. The set supports element
1290     * removal, which removes the corresponding mapping from the map,
1291     * via the {@code Iterator.remove}, {@code Set.remove},
1292     * {@code removeAll}, {@code retainAll}, and {@code clear}
1293     * operations. It does not support the {@code add} or
1294     * {@code addAll} operations.
1295     *
1296     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1297     * that will never throw {@link ConcurrentModificationException},
1298     * and guarantees to traverse elements as they existed upon
1299     * construction of the iterator, and may (but is not guaranteed to)
1300     * reflect any modifications subsequent to construction.
1301     */
1302     public Set<Map.Entry<K,V>> entrySet() {
1303     Set<Map.Entry<K,V>> es = entrySet;
1304     return (es != null) ? es : (entrySet = new EntrySet());
1305     }
1306    
1307     /**
1308     * Returns an enumeration of the keys in this table.
1309     *
1310     * @return an enumeration of the keys in this table
1311     * @see #keySet()
1312     */
1313     public Enumeration<K> keys() {
1314     return new KeyIterator();
1315     }
1316    
1317     /**
1318     * Returns an enumeration of the values in this table.
1319     *
1320     * @return an enumeration of the values in this table
1321     * @see #values()
1322     */
1323     public Enumeration<V> elements() {
1324     return new ValueIterator();
1325     }
1326    
1327     /**
1328 dl 1.2 * Returns the hash code value for this {@link Map}, i.e.,
1329     * the sum of, for each key-value pair in the map,
1330     * {@code key.hashCode() ^ value.hashCode()}.
1331     *
1332     * @return the hash code value for this map
1333 dl 1.1 */
1334     public int hashCode() {
1335     return new HashIterator().mapHashCode();
1336     }
1337    
1338     /**
1339 dl 1.2 * Returns a string representation of this map. The string
1340     * representation consists of a list of key-value mappings (in no
1341     * particular order) enclosed in braces ("{@code {}}"). Adjacent
1342     * mappings are separated by the characters {@code ", "} (comma
1343     * and space). Each key-value mapping is rendered as the key
1344     * followed by an equals sign ("{@code =}") followed by the
1345     * associated value.
1346     *
1347     * @return a string representation of this map
1348 dl 1.1 */
1349     public String toString() {
1350     return new HashIterator().mapToString();
1351     }
1352    
1353     /**
1354 dl 1.2 * Compares the specified object with this map for equality.
1355     * Returns {@code true} if the given object is a map with the same
1356     * mappings as this map. This operation may return misleading
1357     * results if either map is concurrently modified during execution
1358     * of this method.
1359     *
1360     * @param o object to be compared for equality with this map
1361     * @return {@code true} if the specified object is equal to this map
1362 dl 1.1 */
1363     public boolean equals(Object o) {
1364     if (o == this)
1365     return true;
1366     if (!(o instanceof Map))
1367     return false;
1368     Map<?,?> m = (Map<?,?>) o;
1369     try {
1370     for (Map.Entry<K,V> e : this.entrySet())
1371     if (! e.getValue().equals(m.get(e.getKey())))
1372     return false;
1373     for (Map.Entry<?,?> e : m.entrySet()) {
1374     Object k = e.getKey();
1375     Object v = e.getValue();
1376     if (k == null || v == null || !v.equals(get(k)))
1377     return false;
1378     }
1379     return true;
1380     } catch (ClassCastException unused) {
1381     return false;
1382     } catch (NullPointerException unused) {
1383     return false;
1384     }
1385     }
1386    
1387     /**
1388     * Custom Entry class used by EntryIterator.next(), that relays
1389     * setValue changes to the underlying map.
1390     */
1391     final class WriteThroughEntry extends AbstractMap.SimpleEntry<K,V> {
1392     @SuppressWarnings("unchecked")
1393     WriteThroughEntry(Object k, Object v) {
1394     super((K)k, (V)v);
1395     }
1396    
1397     /**
1398     * Sets our entry's value and writes through to the map. The
1399     * value to return is somewhat arbitrary here. Since a
1400     * WriteThroughEntry does not necessarily track asynchronous
1401     * changes, the most recent "previous" value could be
1402     * different from what we return (or could even have been
1403     * removed in which case the put will re-establish). We do not
1404     * and cannot guarantee more.
1405     */
1406     public V setValue(V value) {
1407     if (value == null) throw new NullPointerException();
1408     V v = super.setValue(value);
1409     ConcurrentHashMapV8.this.put(getKey(), value);
1410     return v;
1411     }
1412     }
1413    
1414     final class KeyIterator extends HashIterator
1415     implements Iterator<K>, Enumeration<K> {
1416     @SuppressWarnings("unchecked")
1417     public final K next() { return (K)super.nextKey(); }
1418     @SuppressWarnings("unchecked")
1419     public final K nextElement() { return (K)super.nextKey(); }
1420     }
1421    
1422     final class ValueIterator extends HashIterator
1423     implements Iterator<V>, Enumeration<V> {
1424     @SuppressWarnings("unchecked")
1425     public final V next() { return (V)super.nextValue(); }
1426     @SuppressWarnings("unchecked")
1427     public final V nextElement() { return (V)super.nextValue(); }
1428     }
1429    
1430     final class EntryIterator extends HashIterator
1431     implements Iterator<Entry<K,V>> {
1432     public final Map.Entry<K,V> next() { return super.nextEntry(); }
1433     }
1434    
1435     final class KeySet extends AbstractSet<K> {
1436     public int size() {
1437     return ConcurrentHashMapV8.this.size();
1438     }
1439     public boolean isEmpty() {
1440     return ConcurrentHashMapV8.this.isEmpty();
1441     }
1442     public void clear() {
1443     ConcurrentHashMapV8.this.clear();
1444     }
1445     public Iterator<K> iterator() {
1446     return new KeyIterator();
1447     }
1448     public boolean contains(Object o) {
1449     return ConcurrentHashMapV8.this.containsKey(o);
1450     }
1451     public boolean remove(Object o) {
1452     return ConcurrentHashMapV8.this.remove(o) != null;
1453     }
1454     }
1455    
1456     final class Values extends AbstractCollection<V> {
1457     public int size() {
1458     return ConcurrentHashMapV8.this.size();
1459     }
1460     public boolean isEmpty() {
1461     return ConcurrentHashMapV8.this.isEmpty();
1462     }
1463     public void clear() {
1464     ConcurrentHashMapV8.this.clear();
1465     }
1466     public Iterator<V> iterator() {
1467     return new ValueIterator();
1468     }
1469     public boolean contains(Object o) {
1470     return ConcurrentHashMapV8.this.containsValue(o);
1471     }
1472     }
1473    
1474     final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
1475     public int size() {
1476     return ConcurrentHashMapV8.this.size();
1477     }
1478     public boolean isEmpty() {
1479     return ConcurrentHashMapV8.this.isEmpty();
1480     }
1481     public void clear() {
1482     ConcurrentHashMapV8.this.clear();
1483     }
1484     public Iterator<Map.Entry<K,V>> iterator() {
1485     return new EntryIterator();
1486     }
1487     public boolean contains(Object o) {
1488     if (!(o instanceof Map.Entry))
1489     return false;
1490     Map.Entry<?,?> e = (Map.Entry<?,?>)o;
1491     V v = ConcurrentHashMapV8.this.get(e.getKey());
1492     return v != null && v.equals(e.getValue());
1493     }
1494     public boolean remove(Object o) {
1495     if (!(o instanceof Map.Entry))
1496     return false;
1497     Map.Entry<?,?> e = (Map.Entry<?,?>)o;
1498     return ConcurrentHashMapV8.this.remove(e.getKey(), e.getValue());
1499     }
1500     }
1501    
1502     /* ---------------- Serialization Support -------------- */
1503    
1504     /**
1505     * Helper class used in previous version, declared for the sake of
1506     * serialization compatibility
1507     */
1508     static class Segment<K,V> extends java.util.concurrent.locks.ReentrantLock
1509     implements Serializable {
1510     private static final long serialVersionUID = 2249069246763182397L;
1511     final float loadFactor;
1512     Segment(float lf) { this.loadFactor = lf; }
1513     }
1514    
1515     /**
1516     * Saves the state of the {@code ConcurrentHashMapV8} instance to a
1517     * stream (i.e., serializes it).
1518     * @param s the stream
1519     * @serialData
1520     * the key (Object) and value (Object)
1521     * for each key-value mapping, followed by a null pair.
1522     * The key-value mappings are emitted in no particular order.
1523     */
1524     @SuppressWarnings("unchecked")
1525     private void writeObject(java.io.ObjectOutputStream s)
1526     throws java.io.IOException {
1527     if (segments == null) { // for serialization compatibility
1528     segments = (Segment<K,V>[])
1529     new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL];
1530     for (int i = 0; i < segments.length; ++i)
1531     segments[i] = new Segment<K,V>(loadFactor);
1532     }
1533     s.defaultWriteObject();
1534     new HashIterator().writeEntries(s);
1535     s.writeObject(null);
1536     s.writeObject(null);
1537     segments = null; // throw away
1538     }
1539    
1540     /**
1541 jsr166 1.9 * Reconstitutes the instance from a stream (that is, deserializes it).
1542 dl 1.1 * @param s the stream
1543     */
1544     @SuppressWarnings("unchecked")
1545     private void readObject(java.io.ObjectInputStream s)
1546     throws java.io.IOException, ClassNotFoundException {
1547     s.defaultReadObject();
1548     // find load factor in a segment, if one exists
1549     if (segments != null && segments.length != 0)
1550     this.loadFactor = segments[0].loadFactor;
1551     else
1552     this.loadFactor = DEFAULT_LOAD_FACTOR;
1553     this.initCap = DEFAULT_CAPACITY;
1554     LongAdder ct = new LongAdder(); // force final field write
1555     UNSAFE.putObjectVolatile(this, counterOffset, ct);
1556     this.segments = null; // unneeded
1557    
1558     // Read the keys and values, and put the mappings in the table
1559     for (;;) {
1560     K key = (K) s.readObject();
1561     V value = (V) s.readObject();
1562     if (key == null)
1563     break;
1564     put(key, value);
1565     }
1566     }
1567    
1568     // Unsafe mechanics
1569     private static final sun.misc.Unsafe UNSAFE;
1570     private static final long counterOffset;
1571     private static final long resizingOffset;
1572     private static final long ABASE;
1573     private static final int ASHIFT;
1574    
1575     static {
1576     int ss;
1577     try {
1578     UNSAFE = getUnsafe();
1579     Class<?> k = ConcurrentHashMapV8.class;
1580     counterOffset = UNSAFE.objectFieldOffset
1581     (k.getDeclaredField("counter"));
1582     resizingOffset = UNSAFE.objectFieldOffset
1583     (k.getDeclaredField("resizing"));
1584     Class<?> sc = Node[].class;
1585     ABASE = UNSAFE.arrayBaseOffset(sc);
1586     ss = UNSAFE.arrayIndexScale(sc);
1587     } catch (Exception e) {
1588     throw new Error(e);
1589     }
1590     if ((ss & (ss-1)) != 0)
1591     throw new Error("data type scale not a power of two");
1592     ASHIFT = 31 - Integer.numberOfLeadingZeros(ss);
1593     }
1594    
1595     /**
1596     * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package.
1597     * Replace with a simple call to Unsafe.getUnsafe when integrating
1598     * into a jdk.
1599     *
1600     * @return a sun.misc.Unsafe
1601     */
1602     private static sun.misc.Unsafe getUnsafe() {
1603     try {
1604     return sun.misc.Unsafe.getUnsafe();
1605     } catch (SecurityException se) {
1606     try {
1607     return java.security.AccessController.doPrivileged
1608     (new java.security
1609     .PrivilegedExceptionAction<sun.misc.Unsafe>() {
1610     public sun.misc.Unsafe run() throws Exception {
1611     java.lang.reflect.Field f = sun.misc
1612     .Unsafe.class.getDeclaredField("theUnsafe");
1613     f.setAccessible(true);
1614     return (sun.misc.Unsafe) f.get(null);
1615     }});
1616     } catch (java.security.PrivilegedActionException e) {
1617     throw new RuntimeException("Could not initialize intrinsics",
1618     e.getCause());
1619     }
1620     }
1621     }
1622    
1623     }