ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/ConcurrentHashMapV8.java
Revision: 1.15
Committed: Thu Sep 8 23:34:50 2011 UTC (12 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.14: +3 -3 lines
Log Message:
whitespace

File Contents

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