ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/ConcurrentHashMapV8.java
Revision: 1.24
Committed: Thu Sep 15 14:25:46 2011 UTC (12 years, 7 months ago) by dl
Branch: MAIN
Changes since 1.23: +813 -384 lines
Log Message:
Overlay trylocks; atomic size control; more traversal scaffolding

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.Arrays;
10 import java.util.Map;
11 import java.util.Set;
12 import java.util.Collection;
13 import java.util.AbstractMap;
14 import java.util.AbstractSet;
15 import java.util.AbstractCollection;
16 import java.util.Hashtable;
17 import java.util.HashMap;
18 import java.util.Iterator;
19 import java.util.Enumeration;
20 import java.util.ConcurrentModificationException;
21 import java.util.NoSuchElementException;
22 import java.util.concurrent.ConcurrentMap;
23 import java.util.concurrent.locks.LockSupport;
24 import java.io.Serializable;
25
26 /**
27 * A hash table supporting full concurrency of retrievals and
28 * high expected concurrency for updates. This class obeys the
29 * same functional specification as {@link java.util.Hashtable}, and
30 * includes versions of methods corresponding to each method of
31 * {@code Hashtable}. However, even though all operations are
32 * thread-safe, retrieval operations do <em>not</em> entail locking,
33 * and there is <em>not</em> any support for locking the entire table
34 * in a way that prevents all access. This class is fully
35 * interoperable with {@code Hashtable} in programs that rely on its
36 * thread safety but not on its synchronization details.
37 *
38 * <p> Retrieval operations (including {@code get}) generally do not
39 * block, so may overlap with update operations (including {@code put}
40 * and {@code remove}). Retrievals reflect the results of the most
41 * recently <em>completed</em> update operations holding upon their
42 * onset. For aggregate operations such as {@code putAll} and {@code
43 * clear}, concurrent retrievals may reflect insertion or removal of
44 * only some entries. Similarly, Iterators and Enumerations return
45 * elements reflecting the state of the hash table at some point at or
46 * since the creation of the iterator/enumeration. They do
47 * <em>not</em> throw {@link ConcurrentModificationException}.
48 * However, iterators are designed to be used by only one thread at a
49 * time. Bear in mind that the results of aggregate status methods
50 * including {@code size}, {@code isEmpty}, and {@code containsValue}
51 * are typically useful only when a map is not undergoing concurrent
52 * updates in other threads. Otherwise the results of these methods
53 * reflect transient states that may be adequate for monitoring
54 * or estimation purposes, but not for program control.
55 *
56 * <p> The table is dynamically expanded when there are too many
57 * collisions (i.e., keys that have distinct hash codes but fall into
58 * the same slot modulo the table size), with the expected average
59 * effect of maintaining roughly two bins per mapping (corresponding
60 * to a 0.75 load factor threshold for resizing). There may be much
61 * variance around this average as mappings are added and removed, but
62 * overall, this maintains a commonly accepted time/space tradeoff for
63 * hash tables. However, resizing this or any other kind of hash
64 * table may be a relatively slow operation. When possible, it is a
65 * good idea to provide a size estimate as an optional {@code
66 * initialCapacity} constructor argument. An additional optional
67 * {@code loadFactor} constructor argument provides a further means of
68 * customizing initial table capacity by specifying the table density
69 * to be used in calculating the amount of space to allocate for the
70 * given number of elements. Also, for compatibility with previous
71 * versions of this class, constructors may optionally specify an
72 * expected {@code concurrencyLevel} as an additional hint for
73 * internal sizing. Note that using many keys with exactly the same
74 * {@code hashCode{}} is a sure way to slow down performance of any
75 * hash table.
76 *
77 * <p>This class and its views and iterators implement all of the
78 * <em>optional</em> methods of the {@link Map} and {@link Iterator}
79 * interfaces.
80 *
81 * <p> Like {@link Hashtable} but unlike {@link HashMap}, this class
82 * does <em>not</em> allow {@code null} to be used as a key or value.
83 *
84 * <p>This class is a member of the
85 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
86 * Java Collections Framework</a>.
87 *
88 * <p><em>jsr166e note: This class is a candidate replacement for
89 * java.util.concurrent.ConcurrentHashMap.<em>
90 *
91 * @since 1.5
92 * @author Doug Lea
93 * @param <K> the type of keys maintained by this map
94 * @param <V> the type of mapped values
95 */
96 public class ConcurrentHashMapV8<K, V>
97 implements ConcurrentMap<K, V>, Serializable {
98 private static final long serialVersionUID = 7249069246763182397L;
99
100 /**
101 * A function computing a mapping from the given key to a value,
102 * or {@code null} if there is no mapping. This is a place-holder
103 * for an upcoming JDK8 interface.
104 */
105 public static interface MappingFunction<K, V> {
106 /**
107 * Returns a value for the given key, or null if there is no
108 * mapping. If this function throws an (unchecked) exception,
109 * the exception is rethrown to its caller, and no mapping is
110 * recorded. Because this function is invoked within
111 * atomicity control, the computation should be short and
112 * simple. The most common usage is to construct a new object
113 * serving as an initial mapped value.
114 *
115 * @param key the (non-null) key
116 * @return a value, or null if none
117 */
118 V map(K key);
119 }
120
121 /*
122 * Overview:
123 *
124 * The primary design goal of this hash table is to maintain
125 * concurrent readability (typically method get(), but also
126 * iterators and related methods) while minimizing update
127 * contention. Secondary goals are to keep space consumption about
128 * the same or better than java.util.HashMap, and to support high
129 * initial insertion rates on an empty table by many threads.
130 *
131 * Each key-value mapping is held in a Node. Because Node fields
132 * can contain special values, they are defined using plain Object
133 * types. Similarly in turn, all internal methods that use them
134 * work off Object types. And similarly, so do the internal
135 * methods of auxiliary iterator and view classes. All public
136 * generic typed methods relay in/out of these internal methods,
137 * supplying null-checks and casts as needed.
138 *
139 * The table is lazily initialized to a power-of-two size upon the
140 * first insertion. Each bin in the table contains a list of
141 * Nodes (most often, zero or one Node). Table accesses require
142 * volatile/atomic reads, writes, and CASes. Because there is no
143 * other way to arrange this without adding further indirections,
144 * we use intrinsics (sun.misc.Unsafe) operations. The lists of
145 * nodes within bins are always accurately traversable under
146 * volatile reads, so long as lookups check hash code and
147 * non-nullness of value before checking key equality.
148 *
149 * We use the top two bits of Node hash fields for control
150 * purposes -- they are available anyway because of addressing
151 * constraints. As explained further below, these top bits are
152 * usd as follows:
153 * 00 - Normal
154 * 01 - Locked
155 * 11 - Locked and may have a thread waiting for lock
156 * 10 - Node is a forwarding node
157 *
158 * The lower 30 bits of each Node's hash field contain a
159 * transformation (for better randomization -- method "spread") of
160 * the key's hash code, except for forwarding nodes, for which the
161 * lower bits are zero (and so always have hash field == "MOVED").
162 *
163 * Insertion (via put or putIfAbsent) of the first node in an
164 * empty bin is performed by just CASing it to the bin. This is
165 * by far the most common case for put operations. Other update
166 * operations (insert, delete, and replace) require locks. We do
167 * not want to waste the space required to associate a distinct
168 * lock object with each bin, so instead use the first node of a
169 * bin list itself as a lock. Blocking support for these locks
170 * relies on the builtin "synchronized" monitors. However, we
171 * also need a tryLock construction, so we overlay these by using
172 * bits of the Node hash field for lock control (see above), and
173 * so normally use builtin monitors only for blocking and
174 * signalling using wait/notifyAll constructions. See
175 * Node.tryAwaitLock.
176 *
177 * Using the first node of a list as a lock does not by itself
178 * suffice though: When a node is locked, any update must first
179 * validate that it is still the first node after locking it, and
180 * retry if not. Because new nodes are always appended to lists,
181 * once a node is first in a bin, it remains first until deleted
182 * or the bin becomes invalidated. However, operations that only
183 * conditionally update may inspect nodes until the point of
184 * update. This is a converse of sorts to the lazy locking
185 * technique described by Herlihy & Shavit.
186 *
187 * The main disadvantage of per-bin locks is that other update
188 * operations on other nodes in a bin list protected by the same
189 * lock can stall, for example when user equals() or mapping
190 * functions take a long time. However, statistically, this is
191 * not a common enough problem to outweigh the time/space overhead
192 * of alternatives: Under random hash codes, the frequency of
193 * nodes in bins follows a Poisson distribution
194 * (http://en.wikipedia.org/wiki/Poisson_distribution) with a
195 * parameter of about 0.5 on average, given the resizing threshold
196 * of 0.75, although with a large variance because of resizing
197 * granularity. Ignoring variance, the expected occurrences of
198 * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The
199 * first few values are:
200 *
201 * 0: 0.607
202 * 1: 0.303
203 * 2: 0.076
204 * 3: 0.012
205 * more: 0.002
206 *
207 * Lock contention probability for two threads accessing distinct
208 * elements is roughly 1 / (8 * #elements). Function "spread"
209 * performs hashCode randomization that improves the likelihood
210 * that these assumptions hold unless users define exactly the
211 * same value for too many hashCodes.
212 *
213 * The table is resized when occupancy exceeds an occupancy
214 * threshold (nominally, 0.75, but see below). Only a single
215 * thread performs the resize (using field "sizeCtl", to arrange
216 * exclusion), but the table otherwise remains usable for reads
217 * and updates. Resizing proceeds by transferring bins, one by
218 * one, from the table to the next table. Because we are using
219 * power-of-two expansion, the elements from each bin must either
220 * stay at same index, or move with a power of two offset. We
221 * eliminate unnecessary node creation by catching cases where old
222 * nodes can be reused because their next fields won't change. On
223 * average, only about one-sixth of them need cloning when a table
224 * doubles. The nodes they replace will be garbage collectable as
225 * soon as they are no longer referenced by any reader thread that
226 * may be in the midst of concurrently traversing table. Upon
227 * transfer, the old table bin contains only a special forwarding
228 * node (with hash field "MOVED") that contains the next table as
229 * its key. On encountering a forwarding node, access and update
230 * operations restart, using the new table.
231 *
232 * Each bin transfer requires its bin lock. However, unlike other
233 * cases, a transfer can skip a bin if it fails to acquire its
234 * lock, and revisit it later. Method rebuild maintains a buffer
235 * of TRANSFER_BUFFER_SIZE bins that have been skipped because of
236 * failure to acquire a lock, and blocks only if none are
237 * available (i.e., only very rarely). The transfer operation
238 * must also ensure that all accessible bins in both the old and
239 * new table are usable by any traversal. When there are no lock
240 * acquisition failures, this is arranged simply by proceeding
241 * from the last bin (table.length - 1) up towards the first.
242 * Upon seeing a forwarding node, traversals (see class
243 * InternalIterator) arrange to move to the new table without
244 * revisiting nodes. However, when any node is skipped during a
245 * transfer, all earlier table bins may have become visible, so
246 * are initialized with a reverse-forwarding node back to the old
247 * table until the new ones are established. (This sometimes
248 * requires transiently locking a forwarding node, which is
249 * possible under the above encoding.) These more expensive
250 * mechanics trigger only when necessary.
251 *
252 * The traversal scheme also applies to partial traversals of
253 * ranges of bins (via an alternate InternalIterator constructor)
254 * to support partitioned aggregate operations (that are not
255 * otherwise implemented yet). Also, read-only operations give up
256 * if ever forwarded to a null table, which provides support for
257 * shutdown-style clearing, which is also not currently
258 * implemented.
259 *
260 * Lazy table initialization minimizes footprint until first use,
261 * and also avoids resizings when the first operation is from a
262 * putAll, constructor with map argument, or deserialization.
263 * These cases attempt to override the initial capacity settings,
264 * but harmlessly fail to take effect in cases of races.
265 *
266 * The element count is maintained using a LongAdder, which avoids
267 * contention on updates but can encounter cache thrashing if read
268 * too frequently during concurrent access. To avoid reading so
269 * often, resizing is normally attempted only upon adding to a bin
270 * already holding two or more nodes. Under uniform hash
271 * distributions, the probability of this occurring at threshold
272 * is around 13%, meaning that only about 1 in 8 puts check
273 * threshold (and after resizing, many fewer do so). But this
274 * approximation has high variance for small table sizes, so we
275 * check on any collision for sizes <= 64.
276 *
277 * Maintaining API and serialization compatibility with previous
278 * versions of this class introduces several oddities. Mainly: We
279 * leave untouched but unused constructor arguments refering to
280 * concurrencyLevel. We accept a loadFactor constructor argument,
281 * but apply it only to initial table capacity (which is the only
282 * time that we can guarantee to honor it.) We also declare an
283 * unused "Segment" class that is instantiated in minimal form
284 * only when serializing.
285 */
286
287 /* ---------------- Constants -------------- */
288
289 /**
290 * The largest possible table capacity. This value must be
291 * exactly 1<<30 to stay within Java array allocation and indexing
292 * bounds for power of two table sizes, and is further required
293 * because the top two bits of 32bit hash fields are used for
294 * control purposes.
295 */
296 private static final int MAXIMUM_CAPACITY = 1 << 30;
297
298 /**
299 * The default initial table capacity. Must be a power of 2
300 * (i.e., at least 1) and at most MAXIMUM_CAPACITY.
301 */
302 private static final int DEFAULT_CAPACITY = 16;
303
304 /**
305 * The largest possible (non-power of two) array size.
306 * Needed by toArray and related methods.
307 */
308 static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
309
310 /**
311 * The default concurrency level for this table. Unused but
312 * defined for compatibility with previous versions of this class.
313 */
314 private static final int DEFAULT_CONCURRENCY_LEVEL = 16;
315
316 /**
317 * The load factor for this table. Overrides of this value in
318 * constructors affect only the initial table capacity. The
319 * actual floating point value isn't normally used -- it is
320 * simpler to use expressions such as {@code n - (n >>> 2)} for
321 * the associated resizing threshold.
322 */
323 private static final float LOAD_FACTOR = 0.75f;
324
325 /**
326 * The buffer size for skipped bins during transfers. The
327 * value is arbitrary but should be large enough to avoid
328 * most locking stalls during resizes.
329 */
330 private static final int TRANSFER_BUFFER_SIZE = 32;
331
332 /*
333 * Encodings for special uses of Node hash fields. See above for
334 * explanation.
335 */
336 static final int MOVED = 0x80000000; // hash field for fowarding nodes
337 static final int LOCKED = 0x40000000; // set/tested only as a bit
338 static final int WAITING = 0xc0000000; // both bits set/tested together
339 static final int HASH_BITS = 0x3fffffff; // usable bits of normal node hash
340
341 /* ---------------- Fields -------------- */
342
343 /**
344 * The array of bins. Lazily initialized upon first insertion.
345 * Size is always a power of two. Accessed directly by iterators.
346 */
347 transient volatile Node[] table;
348
349 /**
350 * The counter maintaining number of elements.
351 */
352 private transient final LongAdder counter;
353
354 /**
355 * Table initialization and resizing control. When negative, the
356 * table is being initialized or resized. Otherwise, when table is
357 * null, holds the initial table size to use upon creation, or 0
358 * for default. After initialization, holds the next element count
359 * value upon which to resize the table.
360 */
361 private transient volatile int sizeCtl;
362
363 // views
364 private transient KeySet<K,V> keySet;
365 private transient Values<K,V> values;
366 private transient EntrySet<K,V> entrySet;
367
368 /** For serialization compatibility. Null unless serialized; see below */
369 private Segment<K,V>[] segments;
370
371 /* ---------------- Nodes -------------- */
372
373 /**
374 * Key-value entry. Note that this is never exported out as a
375 * user-visible Map.Entry (see WriteThroughEntry and SnapshotEntry
376 * below). Nodes with a negative hash field are special, and do
377 * not contain user keys or values. Otherwise, keys are never
378 * null, and null val fields indicate that a node is in the
379 * process of being deleted or created. For purposes of read-only
380 * access, a key may be read before a val, but can only be used
381 * after checking val to be non-null.
382 */
383 static final class Node {
384 volatile int hash;
385 final Object key;
386 volatile Object val;
387 volatile Node next;
388
389 Node(int hash, Object key, Object val, Node next) {
390 this.hash = hash;
391 this.key = key;
392 this.val = val;
393 this.next = next;
394 }
395
396 /** CompareAndSet the hash field */
397 final boolean casHash(int cmp, int val) {
398 return UNSAFE.compareAndSwapInt(this, hashOffset, cmp, val);
399 }
400
401 /** The number of spins before blocking for a lock */
402 static final int MAX_SPINS =
403 Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1;
404
405 /**
406 * Spins a while if LOCKED bit set and this node is the first
407 * of its bin, and then sets WAITING bits on hash field and
408 * blocks (once) if they are still set. It is OK for this
409 * method to return even if lock is not available upon exit,
410 * which enables these simple single-wait mechanics.
411 *
412 * The corresponding signalling operation is performed within
413 * callers: Upon detecting that WAITING has been set when
414 * unlocking lock (via a failed CAS from non-waiting LOCKED
415 * state), unlockers acquire the sync lock and perform a
416 * notifyAll.
417 */
418 final void tryAwaitLock(Node[] tab, int i) {
419 if (tab != null && i >= 0 && i < tab.length) { // bounds check
420 int spins = MAX_SPINS, h;
421 while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) {
422 if (spins >= 0) {
423 if (--spins == MAX_SPINS >>> 1)
424 Thread.yield(); // heuristically yield mid-way
425 }
426 else if (casHash(h, h | WAITING)) {
427 synchronized(this) {
428 if (tabAt(tab, i) == this &&
429 (hash & WAITING) == WAITING) {
430 try {
431 wait();
432 } catch (InterruptedException ie) {
433 Thread.currentThread().interrupt();
434 }
435 }
436 else
437 notifyAll(); // possibly won race vs signaller
438 }
439 break;
440 }
441 }
442 }
443 }
444
445 // Unsafe mechanics for casHash
446 private static final sun.misc.Unsafe UNSAFE;
447 private static final long hashOffset;
448
449 static {
450 try {
451 UNSAFE = getUnsafe();
452 Class<?> k = Node.class;
453 hashOffset = UNSAFE.objectFieldOffset
454 (k.getDeclaredField("hash"));
455 } catch (Exception e) {
456 throw new Error(e);
457 }
458 }
459 }
460
461 /* ---------------- Table element access -------------- */
462
463 /*
464 * Volatile access methods are used for table elements as well as
465 * elements of in-progress next table while resizing. Uses are
466 * null checked by callers, and implicitly bounds-checked, relying
467 * on the invariants that tab arrays have non-zero size, and all
468 * indices are masked with (tab.length - 1) which is never
469 * negative and always less than length. Note that, to be correct
470 * wrt arbitrary concurrency errors by users, bounds checks must
471 * operate on local variables, which accounts for some odd-looking
472 * inline assignments below.
473 */
474
475 static final Node tabAt(Node[] tab, int i) { // used by InternalIterator
476 return (Node)UNSAFE.getObjectVolatile(tab, ((long)i<<ASHIFT)+ABASE);
477 }
478
479 private static final boolean casTabAt(Node[] tab, int i, Node c, Node v) {
480 return UNSAFE.compareAndSwapObject(tab, ((long)i<<ASHIFT)+ABASE, c, v);
481 }
482
483 private static final void setTabAt(Node[] tab, int i, Node v) {
484 UNSAFE.putObjectVolatile(tab, ((long)i<<ASHIFT)+ABASE, v);
485 }
486
487 /* ---------------- Internal access and update methods -------------- */
488
489 /**
490 * Applies a supplemental hash function to a given hashCode, which
491 * defends against poor quality hash functions. The result must
492 * be have the top 2 bits clear. For reasonable performance, this
493 * function must have good avalanche properties; i.e., that each
494 * bit of the argument affects each bit of the result. (Although
495 * we don't care about the unused top 2 bits.)
496 */
497 private static final int spread(int h) {
498 // Apply base step of MurmurHash; see http://code.google.com/p/smhasher/
499 h ^= h >>> 16;
500 h *= 0x85ebca6b;
501 h ^= h >>> 13;
502 h *= 0xc2b2ae35;
503 return ((h >>> 16) ^ h) & HASH_BITS; // mask out top bits
504 }
505
506 /** Implementation for get and containsKey */
507 private final Object internalGet(Object k) {
508 int h = spread(k.hashCode());
509 retry: for (Node[] tab = table; tab != null;) {
510 Node e; Object ek, ev; int eh; // locals to read fields once
511 for (e = tabAt(tab, (tab.length - 1) & h); e != null; e = e.next) {
512 if ((eh = e.hash) == MOVED) {
513 tab = (Node[])e.key; // restart with new table
514 continue retry;
515 }
516 if ((eh & HASH_BITS) == h && (ev = e.val) != null &&
517 ((ek = e.key) == k || k.equals(ek)))
518 return ev;
519 }
520 break;
521 }
522 return null;
523 }
524
525 /** Implementation for put and putIfAbsent */
526 private final Object internalPut(Object k, Object v, boolean replace) {
527 int h = spread(k.hashCode());
528 Object oldVal = null; // previous value or null if none
529 for (Node[] tab = table;;) {
530 int i; Node f; int fh; Object fk, fv;
531 if (tab == null)
532 tab = initTable();
533 else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
534 if (casTabAt(tab, i, null, new Node(h, k, v, null)))
535 break; // no lock when adding to empty bin
536 }
537 else if ((fh = f.hash) == MOVED)
538 tab = (Node[])f.key;
539 else if (!replace && (fh & HASH_BITS) == h && (fv = f.val) != null &&
540 ((fk = f.key) == k || k.equals(fk))) {
541 oldVal = fv; // precheck 1st node for putIfAbsent
542 break;
543 }
544 else if ((fh & LOCKED) != 0)
545 f.tryAwaitLock(tab, i);
546 else if (f.casHash(fh, fh | LOCKED)) {
547 boolean validated = false;
548 boolean checkSize = false;
549 try {
550 if (tabAt(tab, i) == f) {
551 validated = true; // retry if 1st already deleted
552 for (Node e = f;;) {
553 Object ek, ev;
554 if ((e.hash & HASH_BITS) == h &&
555 (ev = e.val) != null &&
556 ((ek = e.key) == k || k.equals(ek))) {
557 oldVal = ev;
558 if (replace)
559 e.val = v;
560 break;
561 }
562 Node last = e;
563 if ((e = e.next) == null) {
564 last.next = new Node(h, k, v, null);
565 if (last != f || tab.length <= 64)
566 checkSize = true;
567 break;
568 }
569 }
570 }
571 } finally { // unlock and signal if needed
572 if (!f.casHash(fh | LOCKED, fh)) {
573 f.hash = fh;
574 synchronized(f) { f.notifyAll(); };
575 }
576 }
577 if (validated) {
578 int sc;
579 if (checkSize && tab.length < MAXIMUM_CAPACITY &&
580 (sc = sizeCtl) >= 0 && counter.sum() >= (long)sc)
581 growTable();
582 break;
583 }
584 }
585 }
586 if (oldVal == null)
587 counter.increment(); // update counter outside of locks
588 return oldVal;
589 }
590
591 /**
592 * Implementation for the four public remove/replace methods:
593 * Replaces node value with v, conditional upon match of cv if
594 * non-null. If resulting value is null, delete.
595 */
596 private final Object internalReplace(Object k, Object v, Object cv) {
597 int h = spread(k.hashCode());
598 Object oldVal = null;
599 for (Node[] tab = table;;) {
600 Node f; int i, fh;
601 if (tab == null ||
602 (f = tabAt(tab, i = (tab.length - 1) & h)) == null)
603 break;
604 else if ((fh = f.hash) == MOVED)
605 tab = (Node[])f.key;
606 else if ((fh & HASH_BITS) != h && f.next == null) // precheck
607 break; // rules out possible existence
608 else if ((fh & LOCKED) != 0)
609 f.tryAwaitLock(tab, i);
610 else if (f.casHash(fh, fh | LOCKED)) {
611 boolean validated = false;
612 boolean deleted = false;
613 try {
614 if (tabAt(tab, i) == f) {
615 validated = true;
616 for (Node e = f, pred = null;;) {
617 Object ek, ev;
618 if ((e.hash & HASH_BITS) == h &&
619 ((ev = e.val) != null) &&
620 ((ek = e.key) == k || k.equals(ek))) {
621 if (cv == null || cv == ev || cv.equals(ev)) {
622 oldVal = ev;
623 if ((e.val = v) == null) {
624 deleted = true;
625 Node en = e.next;
626 if (pred != null)
627 pred.next = en;
628 else
629 setTabAt(tab, i, en);
630 }
631 }
632 break;
633 }
634 pred = e;
635 if ((e = e.next) == null)
636 break;
637 }
638 }
639 } finally {
640 if (!f.casHash(fh | LOCKED, fh)) {
641 f.hash = fh;
642 synchronized(f) { f.notifyAll(); };
643 }
644 }
645 if (validated) {
646 if (deleted)
647 counter.decrement();
648 break;
649 }
650 }
651 }
652 return oldVal;
653 }
654
655 /** Implementation for computeIfAbsent and compute. Like put, but messier. */
656 // Todo: Somehow reinstate non-termination check
657 @SuppressWarnings("unchecked")
658 private final V internalCompute(K k,
659 MappingFunction<? super K, ? extends V> fn,
660 boolean replace) {
661 int h = spread(k.hashCode());
662 V val = null;
663 boolean added = false;
664 Node[] tab = table;
665 outer:for (;;) {
666 Node f; int i, fh; Object fk, fv;
667 if (tab == null)
668 tab = initTable();
669 else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
670 Node node = new Node(fh = h | LOCKED, k, null, null);
671 boolean validated = false;
672 if (casTabAt(tab, i, null, node)) {
673 validated = true;
674 try {
675 val = fn.map(k);
676 if (val != null) {
677 node.val = val;
678 added = true;
679 }
680 } finally {
681 if (!added)
682 setTabAt(tab, i, null);
683 if (!node.casHash(fh, h)) {
684 node.hash = fh;
685 synchronized(node) { node.notifyAll(); };
686 }
687 }
688 }
689 if (validated)
690 break;
691 }
692 else if ((fh = f.hash) == MOVED)
693 tab = (Node[])f.key;
694 else if (!replace && (fh & HASH_BITS) == h && (fv = f.val) != null &&
695 ((fk = f.key) == k || k.equals(fk))) {
696 if (tabAt(tab, i) == f) {
697 val = (V)fv;
698 break;
699 }
700 }
701 else if ((fh & LOCKED) != 0)
702 f.tryAwaitLock(tab, i);
703 else if (f.casHash(fh, fh | LOCKED)) {
704 boolean validated = false;
705 boolean checkSize = false;
706 try {
707 if (tabAt(tab, i) == f) {
708 validated = true;
709 for (Node e = f;;) {
710 Object ek, ev, v;
711 if ((e.hash & HASH_BITS) == h &&
712 (ev = e.val) != null &&
713 ((ek = e.key) == k || k.equals(ek))) {
714 if (replace && (v = fn.map(k)) != null)
715 ev = e.val = v;
716 val = (V)ev;
717 break;
718 }
719 Node last = e;
720 if ((e = e.next) == null) {
721 if ((val = fn.map(k)) != null) {
722 last.next = new Node(h, k, val, null);
723 added = true;
724 if (last != f || tab.length <= 64)
725 checkSize = true;
726 }
727 break;
728 }
729 }
730 }
731 } finally {
732 if (!f.casHash(fh | LOCKED, fh)) {
733 f.hash = fh;
734 synchronized(f) { f.notifyAll(); };
735 }
736 }
737 if (validated) {
738 int sc;
739 if (checkSize && tab.length < MAXIMUM_CAPACITY &&
740 (sc = sizeCtl) >= 0 && counter.sum() >= (long)sc)
741 growTable();
742 break;
743 }
744 }
745 }
746 if (added)
747 counter.increment();
748 return val;
749 }
750
751 /**
752 * Implementation for clear. Steps through each bin, removing all nodes.
753 */
754 private final void internalClear() {
755 long delta = 0L; // negative number of deletions
756 int i = 0;
757 Node[] tab = table;
758 while (tab != null && i < tab.length) {
759 int fh;
760 Node f = tabAt(tab, i);
761 if (f == null)
762 ++i;
763 else if ((fh = f.hash) == MOVED)
764 tab = (Node[])f.key;
765 else if ((fh & LOCKED) != 0)
766 f.tryAwaitLock(tab, i);
767 else if (f.casHash(fh, fh | LOCKED)) {
768 boolean validated = false;
769 try {
770 if (tabAt(tab, i) == f) {
771 validated = true;
772 for (Node e = f; e != null; e = e.next) {
773 if (e.val != null) { // currently always true
774 e.val = null;
775 --delta;
776 }
777 }
778 setTabAt(tab, i, null);
779 }
780 } finally {
781 if (!f.casHash(fh | LOCKED, fh)) {
782 f.hash = fh;
783 synchronized(f) { f.notifyAll(); };
784 }
785 }
786 if (validated)
787 ++i;
788 }
789 }
790 counter.add(delta);
791 }
792
793 /* ----------------Table Initialization and Resizing -------------- */
794
795 /**
796 * Returns a power of two table size for the given desired capacity.
797 * See Hackers Delight, sec 3.2
798 */
799 private static final int tableSizeFor(int c) {
800 int n = c - 1;
801 n |= n >>> 1;
802 n |= n >>> 2;
803 n |= n >>> 4;
804 n |= n >>> 8;
805 n |= n >>> 16;
806 return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
807 }
808
809 /**
810 * Initializes table, using the size recorded in sizeCtl.
811 */
812 private final Node[] initTable() {
813 Node[] tab; int sc;
814 while ((tab = table) == null) {
815 if ((sc = sizeCtl) < 0)
816 Thread.yield(); // lost initialization race; just spin
817 else if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) {
818 try {
819 if ((tab = table) == null) {
820 int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
821 tab = table = new Node[n];
822 sc = n - (n >>> 2) - 1;
823 }
824 } finally {
825 sizeCtl = sc;
826 }
827 break;
828 }
829 }
830 return tab;
831 }
832
833 /**
834 * If not already resizing, creates next table and transfers bins.
835 * Rechecks occupancy after a transfer to see if another resize is
836 * already needed because resizings are lagging additions.
837 */
838 private final void growTable() {
839 int sc = sizeCtl;
840 if (sc >= 0 && UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) {
841 try {
842 Node[] tab; int n;
843 while ((tab = table) != null &&
844 (n = tab.length) > 0 && n < MAXIMUM_CAPACITY &&
845 counter.sum() >= (long)sc) {
846 table = rebuild(tab);
847 sc = (n << 1) - (n >>> 1) - 1;
848 }
849 } finally {
850 sizeCtl = sc;
851 }
852 }
853 }
854
855 /*
856 * Moves and/or copies the nodes in each bin to new table. See
857 * above for explanation.
858 *
859 * @return the new table
860 */
861 private static final Node[] rebuild(Node[] tab) {
862 int n = tab.length;
863 Node[] nextTab = new Node[n << 1];
864 Node fwd = new Node(MOVED, nextTab, null, null);
865 int[] buffer = null; // holds bins to revisit; null until needed
866 Node rev = null; // reverse forwarder; null until needed
867 int nbuffered = 0; // the number of bins in buffer list
868 int bufferIndex = 0; // buffer index of current buffered bin
869 int bin = n - 1; // current non-buffered bin or -1 if none
870
871 for (int i = bin;;) { // start upwards sweep
872 int fh; Node f;
873 if ((f = tabAt(tab, i)) == null) {
874 if (bin >= 0) { // no lock needed (or available)
875 if (!casTabAt(tab, i, f, fwd))
876 continue;
877 }
878 else { // transiently use a locked forwarding node
879 Node g = new Node(MOVED|LOCKED, nextTab, null, null);
880 if (!casTabAt(tab, i, f, g))
881 continue;
882 setTabAt(nextTab, i, null);
883 setTabAt(nextTab, i + n, null);
884 setTabAt(tab, i, fwd);
885 if (!g.casHash(MOVED|LOCKED, MOVED)) {
886 g.hash = MOVED;
887 synchronized(g) { g.notifyAll(); }
888 }
889 }
890 }
891 else if (((fh = f.hash) & LOCKED) == 0 && f.casHash(fh, fh|LOCKED)) {
892 boolean validated = false;
893 try { // split to lo and hi lists; copying as needed
894 if (tabAt(tab, i) == f) {
895 validated = true;
896 Node e = f, lastRun = f;
897 Node lo = null, hi = null;
898 int runBit = e.hash & n;
899 for (Node p = e.next; p != null; p = p.next) {
900 int b = p.hash & n;
901 if (b != runBit) {
902 runBit = b;
903 lastRun = p;
904 }
905 }
906 if (runBit == 0)
907 lo = lastRun;
908 else
909 hi = lastRun;
910 for (Node p = e; p != lastRun; p = p.next) {
911 int ph = p.hash & HASH_BITS;
912 Object pk = p.key, pv = p.val;
913 if ((ph & n) == 0)
914 lo = new Node(ph, pk, pv, lo);
915 else
916 hi = new Node(ph, pk, pv, hi);
917 }
918 setTabAt(nextTab, i, lo);
919 setTabAt(nextTab, i + n, hi);
920 setTabAt(tab, i, fwd);
921 }
922 } finally {
923 if (!f.casHash(fh | LOCKED, fh)) {
924 f.hash = fh;
925 synchronized(f) { f.notifyAll(); };
926 }
927 }
928 if (!validated)
929 continue;
930 }
931 else {
932 if (buffer == null) // initialize buffer for revisits
933 buffer = new int[TRANSFER_BUFFER_SIZE];
934 if (bin < 0 && bufferIndex > 0) {
935 int j = buffer[--bufferIndex];
936 buffer[bufferIndex] = i;
937 i = j; // swap with another bin
938 continue;
939 }
940 if (bin < 0 || nbuffered >= TRANSFER_BUFFER_SIZE) {
941 f.tryAwaitLock(tab, i);
942 continue; // no other options -- block
943 }
944 if (rev == null) // initialize reverse-forwarder
945 rev = new Node(MOVED, tab, null, null);
946 if (tabAt(tab, i) != f || (f.hash & LOCKED) == 0)
947 continue; // recheck before adding to list
948 buffer[nbuffered++] = i;
949 setTabAt(nextTab, i, rev); // install place-holders
950 setTabAt(nextTab, i + n, rev);
951 }
952
953 if (bin > 0)
954 i = --bin;
955 else if (buffer != null && nbuffered > 0) {
956 bin = -1;
957 i = buffer[bufferIndex = --nbuffered];
958 }
959 else
960 return nextTab;
961 }
962 }
963
964 /* ----------------Table Traversal -------------- */
965
966 /**
967 * Encapsulates traversal for methods such as containsValue; also
968 * serves as a base class for other iterators.
969 *
970 * At each step, the iterator snapshots the key ("nextKey") and
971 * value ("nextVal") of a valid node (i.e., one that, at point of
972 * snapshot, has a nonnull user value). Because val fields can
973 * change (including to null, indicating deletion), field nextVal
974 * might not be accurate at point of use, but still maintains the
975 * weak consistency property of holding a value that was once
976 * valid.
977 *
978 * Internal traversals directly access these fields, as in:
979 * {@code while (it.next != null) { process(it.nextKey); it.advance(); }}
980 *
981 * Exported iterators (subclasses of ViewIterator) extract key,
982 * value, or key-value pairs as return values of Iterator.next(),
983 * and encapsulate the it.next check as hasNext();
984 *
985 * The iterator visits each valid node that was reachable upon
986 * iterator construction once. It might miss some that were added
987 * to a bin after the bin was visited, which is OK wrt consistency
988 * guarantees. Maintaining this property in the face of possible
989 * ongoing resizes requires a fair amount of bookkeeping state
990 * that is difficult to optimize away amidst volatile accesses.
991 * Even so, traversal maintains reasonable throughput.
992 *
993 * Normally, iteration proceeds bin-by-bin traversing lists.
994 * However, if the table has been resized, then all future steps
995 * must traverse both the bin at the current index as well as at
996 * (index + baseSize); and so on for further resizings. To
997 * paranoically cope with potential sharing by users of iterators
998 * across threads, iteration terminates if a bounds checks fails
999 * for a table read.
1000 *
1001 * The range-based constructor enables creation of parallel
1002 * range-splitting traversals. (Not yet implemented.)
1003 */
1004 static class InternalIterator {
1005 Node next; // the next entry to use
1006 Node last; // the last entry used
1007 Object nextKey; // cached key field of next
1008 Object nextVal; // cached val field of next
1009 Node[] tab; // current table; updated if resized
1010 int index; // index of bin to use next
1011 int baseIndex; // current index of initial table
1012 final int baseLimit; // index bound for initial table
1013 final int baseSize; // initial table size
1014
1015 /** Creates iterator for all entries in the table. */
1016 InternalIterator(Node[] tab) {
1017 this.tab = tab;
1018 baseLimit = baseSize = (tab == null) ? 0 : tab.length;
1019 index = baseIndex = 0;
1020 next = null;
1021 advance();
1022 }
1023
1024 /** Creates iterator for the given range of the table */
1025 InternalIterator(Node[] tab, int lo, int hi) {
1026 this.tab = tab;
1027 baseSize = (tab == null) ? 0 : tab.length;
1028 baseLimit = (hi <= baseSize) ? hi : baseSize;
1029 index = baseIndex = lo;
1030 next = null;
1031 advance();
1032 }
1033
1034 /** Advances next. See above for explanation. */
1035 final void advance() {
1036 Node e = last = next;
1037 outer: do {
1038 if (e != null) // advance past used/skipped node
1039 e = e.next;
1040 while (e == null) { // get to next non-null bin
1041 Node[] t; int b, i, n; // checks must use locals
1042 if ((b = baseIndex) >= baseLimit || (i = index) < 0 ||
1043 (t = tab) == null || i >= (n = t.length))
1044 break outer;
1045 else if ((e = tabAt(t, i)) != null && e.hash == MOVED)
1046 tab = (Node[])e.key; // restarts due to null val
1047 else // visit upper slots if present
1048 index = (i += baseSize) < n ? i : (baseIndex = b + 1);
1049 }
1050 nextKey = e.key;
1051 } while ((nextVal = e.val) == null);// skip deleted or special nodes
1052 next = e;
1053 }
1054 }
1055
1056 /* ---------------- Public operations -------------- */
1057
1058 /**
1059 * Creates a new, empty map with the default initial table size (16),
1060 */
1061 public ConcurrentHashMapV8() {
1062 this.counter = new LongAdder();
1063 }
1064
1065 /**
1066 * Creates a new, empty map with an initial table size
1067 * accommodating the specified number of elements without the need
1068 * to dynamically resize.
1069 *
1070 * @param initialCapacity The implementation performs internal
1071 * sizing to accommodate this many elements.
1072 * @throws IllegalArgumentException if the initial capacity of
1073 * elements is negative
1074 */
1075 public ConcurrentHashMapV8(int initialCapacity) {
1076 if (initialCapacity < 0)
1077 throw new IllegalArgumentException();
1078 int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
1079 MAXIMUM_CAPACITY :
1080 tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));
1081 this.counter = new LongAdder();
1082 this.sizeCtl = cap;
1083 }
1084
1085 /**
1086 * Creates a new map with the same mappings as the given map.
1087 *
1088 * @param m the map
1089 */
1090 public ConcurrentHashMapV8(Map<? extends K, ? extends V> m) {
1091 this.counter = new LongAdder();
1092 this.sizeCtl = DEFAULT_CAPACITY;
1093 putAll(m);
1094 }
1095
1096 /**
1097 * Creates a new, empty map with an initial table size based on
1098 * the given number of elements ({@code initialCapacity}) and
1099 * initial table density ({@code loadFactor}).
1100 *
1101 * @param initialCapacity the initial capacity. The implementation
1102 * performs internal sizing to accommodate this many elements,
1103 * given the specified load factor.
1104 * @param loadFactor the load factor (table density) for
1105 * establishing the initial table size
1106 * @throws IllegalArgumentException if the initial capacity of
1107 * elements is negative or the load factor is nonpositive
1108 *
1109 * @since 1.6
1110 */
1111 public ConcurrentHashMapV8(int initialCapacity, float loadFactor) {
1112 this(initialCapacity, loadFactor, 1);
1113 }
1114
1115 /**
1116 * Creates a new, empty map with an initial table size based on
1117 * the given number of elements ({@code initialCapacity}), table
1118 * density ({@code loadFactor}), and number of concurrently
1119 * updating threads ({@code concurrencyLevel}).
1120 *
1121 * @param initialCapacity the initial capacity. The implementation
1122 * performs internal sizing to accommodate this many elements,
1123 * given the specified load factor.
1124 * @param loadFactor the load factor (table density) for
1125 * establishing the initial table size
1126 * @param concurrencyLevel the estimated number of concurrently
1127 * updating threads. The implementation may use this value as
1128 * a sizing hint.
1129 * @throws IllegalArgumentException if the initial capacity is
1130 * negative or the load factor or concurrencyLevel are
1131 * nonpositive
1132 */
1133 public ConcurrentHashMapV8(int initialCapacity,
1134 float loadFactor, int concurrencyLevel) {
1135 if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0)
1136 throw new IllegalArgumentException();
1137 if (initialCapacity < concurrencyLevel) // Use at least as many bins
1138 initialCapacity = concurrencyLevel; // as estimated threads
1139 long size = (long)(1.0 + (long)initialCapacity / loadFactor);
1140 int cap = ((size >= (long)MAXIMUM_CAPACITY) ?
1141 MAXIMUM_CAPACITY: tableSizeFor((int)size));
1142 this.counter = new LongAdder();
1143 this.sizeCtl = cap;
1144 }
1145
1146 /**
1147 * {@inheritDoc}
1148 */
1149 public boolean isEmpty() {
1150 return counter.sum() <= 0L; // ignore transient negative values
1151 }
1152
1153 /**
1154 * {@inheritDoc}
1155 */
1156 public int size() {
1157 long n = counter.sum();
1158 return ((n < 0L) ? 0 :
1159 (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE :
1160 (int)n);
1161 }
1162
1163 final long longSize() { // accurate version of size needed for views
1164 long n = counter.sum();
1165 return (n < 0L) ? 0L : n;
1166 }
1167
1168 /**
1169 * Returns the value to which the specified key is mapped,
1170 * or {@code null} if this map contains no mapping for the key.
1171 *
1172 * <p>More formally, if this map contains a mapping from a key
1173 * {@code k} to a value {@code v} such that {@code key.equals(k)},
1174 * then this method returns {@code v}; otherwise it returns
1175 * {@code null}. (There can be at most one such mapping.)
1176 *
1177 * @throws NullPointerException if the specified key is null
1178 */
1179 @SuppressWarnings("unchecked")
1180 public V get(Object key) {
1181 if (key == null)
1182 throw new NullPointerException();
1183 return (V)internalGet(key);
1184 }
1185
1186 /**
1187 * Tests if the specified object is a key in this table.
1188 *
1189 * @param key possible key
1190 * @return {@code true} if and only if the specified object
1191 * is a key in this table, as determined by the
1192 * {@code equals} method; {@code false} otherwise
1193 * @throws NullPointerException if the specified key is null
1194 */
1195 public boolean containsKey(Object key) {
1196 if (key == null)
1197 throw new NullPointerException();
1198 return internalGet(key) != null;
1199 }
1200
1201 /**
1202 * Returns {@code true} if this map maps one or more keys to the
1203 * specified value. Note: This method may require a full traversal
1204 * of the map, and is much slower than method {@code containsKey}.
1205 *
1206 * @param value value whose presence in this map is to be tested
1207 * @return {@code true} if this map maps one or more keys to the
1208 * specified value
1209 * @throws NullPointerException if the specified value is null
1210 */
1211 public boolean containsValue(Object value) {
1212 if (value == null)
1213 throw new NullPointerException();
1214 Object v;
1215 InternalIterator it = new InternalIterator(table);
1216 while (it.next != null) {
1217 if ((v = it.nextVal) == value || value.equals(v))
1218 return true;
1219 it.advance();
1220 }
1221 return false;
1222 }
1223
1224 /**
1225 * Legacy method testing if some key maps into the specified value
1226 * in this table. This method is identical in functionality to
1227 * {@link #containsValue}, and exists solely to ensure
1228 * full compatibility with class {@link java.util.Hashtable},
1229 * which supported this method prior to introduction of the
1230 * Java Collections framework.
1231 *
1232 * @param value a value to search for
1233 * @return {@code true} if and only if some key maps to the
1234 * {@code value} argument in this table as
1235 * determined by the {@code equals} method;
1236 * {@code false} otherwise
1237 * @throws NullPointerException if the specified value is null
1238 */
1239 public boolean contains(Object value) {
1240 return containsValue(value);
1241 }
1242
1243 /**
1244 * Maps the specified key to the specified value in this table.
1245 * Neither the key nor the value can be null.
1246 *
1247 * <p> The value can be retrieved by calling the {@code get} method
1248 * with a key that is equal to the original key.
1249 *
1250 * @param key key with which the specified value is to be associated
1251 * @param value value to be associated with the specified key
1252 * @return the previous value associated with {@code key}, or
1253 * {@code null} if there was no mapping for {@code key}
1254 * @throws NullPointerException if the specified key or value is null
1255 */
1256 @SuppressWarnings("unchecked")
1257 public V put(K key, V value) {
1258 if (key == null || value == null)
1259 throw new NullPointerException();
1260 return (V)internalPut(key, value, true);
1261 }
1262
1263 /**
1264 * {@inheritDoc}
1265 *
1266 * @return the previous value associated with the specified key,
1267 * or {@code null} if there was no mapping for the key
1268 * @throws NullPointerException if the specified key or value is null
1269 */
1270 @SuppressWarnings("unchecked")
1271 public V putIfAbsent(K key, V value) {
1272 if (key == null || value == null)
1273 throw new NullPointerException();
1274 return (V)internalPut(key, value, false);
1275 }
1276
1277 /**
1278 * Copies all of the mappings from the specified map to this one.
1279 * These mappings replace any mappings that this map had for any of the
1280 * keys currently in the specified map.
1281 *
1282 * @param m mappings to be stored in this map
1283 */
1284 public void putAll(Map<? extends K, ? extends V> m) {
1285 if (m == null)
1286 throw new NullPointerException();
1287 /*
1288 * If uninitialized, try to preallocate big enough table
1289 */
1290 if (table == null) {
1291 int size = m.size();
1292 int n = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :
1293 tableSizeFor(size + (size >>> 1) + 1);
1294 int sc = sizeCtl;
1295 if (n < sc)
1296 n = sc;
1297 if (sc >= 0 &&
1298 UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) {
1299 try {
1300 if (table == null) {
1301 table = new Node[n];
1302 sc = n - (n >>> 2) - 1;
1303 }
1304 } finally {
1305 sizeCtl = sc;
1306 }
1307 }
1308 }
1309 for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
1310 Object ek = e.getKey(), ev = e.getValue();
1311 if (ek == null || ev == null)
1312 throw new NullPointerException();
1313 internalPut(ek, ev, true);
1314 }
1315 }
1316
1317 /**
1318 * If the specified key is not already associated with a value,
1319 * computes its value using the given mappingFunction, and if
1320 * non-null, enters it into the map. This is equivalent to
1321 * <pre> {@code
1322 * if (map.containsKey(key))
1323 * return map.get(key);
1324 * value = mappingFunction.map(key);
1325 * if (value != null)
1326 * map.put(key, value);
1327 * return value;}</pre>
1328 *
1329 * except that the action is performed atomically. Some attempted
1330 * update operations on this map by other threads may be blocked
1331 * while computation is in progress, so the computation should be
1332 * short and simple, and must not attempt to update any other
1333 * mappings of this Map. The most appropriate usage is to
1334 * construct a new object serving as an initial mapped value, or
1335 * memoized result, as in:
1336 * <pre> {@code
1337 * map.computeIfAbsent(key, new MappingFunction<K, V>() {
1338 * public V map(K k) { return new Value(f(k)); }});}</pre>
1339 *
1340 * @param key key with which the specified value is to be associated
1341 * @param mappingFunction the function to compute a value
1342 * @return the current (existing or computed) value associated with
1343 * the specified key, or {@code null} if the computation
1344 * returned {@code null}
1345 * @throws NullPointerException if the specified key or mappingFunction
1346 * is null
1347 * @throws IllegalStateException if the computation detectably
1348 * attempts a recursive update to this map that would
1349 * otherwise never complete
1350 * @throws RuntimeException or Error if the mappingFunction does so,
1351 * in which case the mapping is left unestablished
1352 */
1353 public V computeIfAbsent(K key, MappingFunction<? super K, ? extends V> mappingFunction) {
1354 if (key == null || mappingFunction == null)
1355 throw new NullPointerException();
1356 return internalCompute(key, mappingFunction, false);
1357 }
1358
1359 /**
1360 * Computes the value associated with the given key using the given
1361 * mappingFunction, and if non-null, enters it into the map. This
1362 * is equivalent to
1363 * <pre> {@code
1364 * value = mappingFunction.map(key);
1365 * if (value != null)
1366 * map.put(key, value);
1367 * else
1368 * value = map.get(key);
1369 * return value;}</pre>
1370 *
1371 * except that the action is performed atomically. Some attempted
1372 * update operations on this map by other threads may be blocked
1373 * while computation is in progress, so the computation should be
1374 * short and simple, and must not attempt to update any other
1375 * mappings of this Map.
1376 *
1377 * @param key key with which the specified value is to be associated
1378 * @param mappingFunction the function to compute a value
1379 * @return the current value associated with
1380 * the specified key, or {@code null} if the computation
1381 * returned {@code null} and the value was not otherwise present
1382 * @throws NullPointerException if the specified key or mappingFunction
1383 * is null
1384 * @throws IllegalStateException if the computation detectably
1385 * attempts a recursive update to this map that would
1386 * otherwise never complete
1387 * @throws RuntimeException or Error if the mappingFunction does so,
1388 * in which case the mapping is unchanged
1389 */
1390 public V compute(K key, MappingFunction<? super K, ? extends V> mappingFunction) {
1391 if (key == null || mappingFunction == null)
1392 throw new NullPointerException();
1393 return internalCompute(key, mappingFunction, true);
1394 }
1395
1396 /**
1397 * Removes the key (and its corresponding value) from this map.
1398 * This method does nothing if the key is not in the map.
1399 *
1400 * @param key the key that needs to be removed
1401 * @return the previous value associated with {@code key}, or
1402 * {@code null} if there was no mapping for {@code key}
1403 * @throws NullPointerException if the specified key is null
1404 */
1405 @SuppressWarnings("unchecked")
1406 public V remove(Object key) {
1407 if (key == null)
1408 throw new NullPointerException();
1409 return (V)internalReplace(key, null, null);
1410 }
1411
1412 /**
1413 * {@inheritDoc}
1414 *
1415 * @throws NullPointerException if the specified key is null
1416 */
1417 public boolean remove(Object key, Object value) {
1418 if (key == null)
1419 throw new NullPointerException();
1420 if (value == null)
1421 return false;
1422 return internalReplace(key, null, value) != null;
1423 }
1424
1425 /**
1426 * {@inheritDoc}
1427 *
1428 * @throws NullPointerException if any of the arguments are null
1429 */
1430 public boolean replace(K key, V oldValue, V newValue) {
1431 if (key == null || oldValue == null || newValue == null)
1432 throw new NullPointerException();
1433 return internalReplace(key, newValue, oldValue) != null;
1434 }
1435
1436 /**
1437 * {@inheritDoc}
1438 *
1439 * @return the previous value associated with the specified key,
1440 * or {@code null} if there was no mapping for the key
1441 * @throws NullPointerException if the specified key or value is null
1442 */
1443 @SuppressWarnings("unchecked")
1444 public V replace(K key, V value) {
1445 if (key == null || value == null)
1446 throw new NullPointerException();
1447 return (V)internalReplace(key, value, null);
1448 }
1449
1450 /**
1451 * Removes all of the mappings from this map.
1452 */
1453 public void clear() {
1454 internalClear();
1455 }
1456
1457 /**
1458 * Returns a {@link Set} view of the keys contained in this map.
1459 * The set is backed by the map, so changes to the map are
1460 * reflected in the set, and vice-versa. The set supports element
1461 * removal, which removes the corresponding mapping from this map,
1462 * via the {@code Iterator.remove}, {@code Set.remove},
1463 * {@code removeAll}, {@code retainAll}, and {@code clear}
1464 * operations. It does not support the {@code add} or
1465 * {@code addAll} operations.
1466 *
1467 * <p>The view's {@code iterator} is a "weakly consistent" iterator
1468 * that will never throw {@link ConcurrentModificationException},
1469 * and guarantees to traverse elements as they existed upon
1470 * construction of the iterator, and may (but is not guaranteed to)
1471 * reflect any modifications subsequent to construction.
1472 */
1473 public Set<K> keySet() {
1474 KeySet<K,V> ks = keySet;
1475 return (ks != null) ? ks : (keySet = new KeySet<K,V>(this));
1476 }
1477
1478 /**
1479 * Returns a {@link Collection} view of the values contained in this map.
1480 * The collection is backed by the map, so changes to the map are
1481 * reflected in the collection, and vice-versa. The collection
1482 * supports element removal, which removes the corresponding
1483 * mapping from this map, via the {@code Iterator.remove},
1484 * {@code Collection.remove}, {@code removeAll},
1485 * {@code retainAll}, and {@code clear} operations. It does not
1486 * support the {@code add} or {@code addAll} operations.
1487 *
1488 * <p>The view's {@code iterator} is a "weakly consistent" iterator
1489 * that will never throw {@link ConcurrentModificationException},
1490 * and guarantees to traverse elements as they existed upon
1491 * construction of the iterator, and may (but is not guaranteed to)
1492 * reflect any modifications subsequent to construction.
1493 */
1494 public Collection<V> values() {
1495 Values<K,V> vs = values;
1496 return (vs != null) ? vs : (values = new Values<K,V>(this));
1497 }
1498
1499 /**
1500 * Returns a {@link Set} view of the mappings contained in this map.
1501 * The set is backed by the map, so changes to the map are
1502 * reflected in the set, and vice-versa. The set supports element
1503 * removal, which removes the corresponding mapping from the map,
1504 * via the {@code Iterator.remove}, {@code Set.remove},
1505 * {@code removeAll}, {@code retainAll}, and {@code clear}
1506 * operations. It does not support the {@code add} or
1507 * {@code addAll} operations.
1508 *
1509 * <p>The view's {@code iterator} is a "weakly consistent" iterator
1510 * that will never throw {@link ConcurrentModificationException},
1511 * and guarantees to traverse elements as they existed upon
1512 * construction of the iterator, and may (but is not guaranteed to)
1513 * reflect any modifications subsequent to construction.
1514 */
1515 public Set<Map.Entry<K,V>> entrySet() {
1516 EntrySet<K,V> es = entrySet;
1517 return (es != null) ? es : (entrySet = new EntrySet<K,V>(this));
1518 }
1519
1520 /**
1521 * Returns an enumeration of the keys in this table.
1522 *
1523 * @return an enumeration of the keys in this table
1524 * @see #keySet()
1525 */
1526 public Enumeration<K> keys() {
1527 return new KeyIterator<K,V>(this);
1528 }
1529
1530 /**
1531 * Returns an enumeration of the values in this table.
1532 *
1533 * @return an enumeration of the values in this table
1534 * @see #values()
1535 */
1536 public Enumeration<V> elements() {
1537 return new ValueIterator<K,V>(this);
1538 }
1539
1540 /**
1541 * Returns the hash code value for this {@link Map}, i.e.,
1542 * the sum of, for each key-value pair in the map,
1543 * {@code key.hashCode() ^ value.hashCode()}.
1544 *
1545 * @return the hash code value for this map
1546 */
1547 public int hashCode() {
1548 int h = 0;
1549 InternalIterator it = new InternalIterator(table);
1550 while (it.next != null) {
1551 h += it.nextKey.hashCode() ^ it.nextVal.hashCode();
1552 it.advance();
1553 }
1554 return h;
1555 }
1556
1557 /**
1558 * Returns a string representation of this map. The string
1559 * representation consists of a list of key-value mappings (in no
1560 * particular order) enclosed in braces ("{@code {}}"). Adjacent
1561 * mappings are separated by the characters {@code ", "} (comma
1562 * and space). Each key-value mapping is rendered as the key
1563 * followed by an equals sign ("{@code =}") followed by the
1564 * associated value.
1565 *
1566 * @return a string representation of this map
1567 */
1568 public String toString() {
1569 InternalIterator it = new InternalIterator(table);
1570 StringBuilder sb = new StringBuilder();
1571 sb.append('{');
1572 if (it.next != null) {
1573 for (;;) {
1574 Object k = it.nextKey, v = it.nextVal;
1575 sb.append(k == this ? "(this Map)" : k);
1576 sb.append('=');
1577 sb.append(v == this ? "(this Map)" : v);
1578 it.advance();
1579 if (it.next == null)
1580 break;
1581 sb.append(',').append(' ');
1582 }
1583 }
1584 return sb.append('}').toString();
1585 }
1586
1587 /**
1588 * Compares the specified object with this map for equality.
1589 * Returns {@code true} if the given object is a map with the same
1590 * mappings as this map. This operation may return misleading
1591 * results if either map is concurrently modified during execution
1592 * of this method.
1593 *
1594 * @param o object to be compared for equality with this map
1595 * @return {@code true} if the specified object is equal to this map
1596 */
1597 public boolean equals(Object o) {
1598 if (o != this) {
1599 if (!(o instanceof Map))
1600 return false;
1601 Map<?,?> m = (Map<?,?>) o;
1602 InternalIterator it = new InternalIterator(table);
1603 while (it.next != null) {
1604 Object val = it.nextVal;
1605 Object v = m.get(it.nextKey);
1606 if (v == null || (v != val && !v.equals(val)))
1607 return false;
1608 it.advance();
1609 }
1610 for (Map.Entry<?,?> e : m.entrySet()) {
1611 Object mk, mv, v;
1612 if ((mk = e.getKey()) == null ||
1613 (mv = e.getValue()) == null ||
1614 (v = internalGet(mk)) == null ||
1615 (mv != v && !mv.equals(v)))
1616 return false;
1617 }
1618 }
1619 return true;
1620 }
1621
1622 /* ----------------Iterators -------------- */
1623
1624 /**
1625 * Base class for key, value, and entry iterators. Adds a map
1626 * reference to InternalIterator to support Iterator.remove.
1627 */
1628 static abstract class ViewIterator<K,V> extends InternalIterator {
1629 final ConcurrentHashMapV8<K, V> map;
1630 ViewIterator(ConcurrentHashMapV8<K, V> map) {
1631 super(map.table);
1632 this.map = map;
1633 }
1634
1635 public final void remove() {
1636 if (last == null)
1637 throw new IllegalStateException();
1638 map.remove(last.key);
1639 last = null;
1640 }
1641
1642 public final boolean hasNext() { return next != null; }
1643 public final boolean hasMoreElements() { return next != null; }
1644 }
1645
1646 static final class KeyIterator<K,V> extends ViewIterator<K,V>
1647 implements Iterator<K>, Enumeration<K> {
1648 KeyIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
1649
1650 @SuppressWarnings("unchecked")
1651 public final K next() {
1652 if (next == null)
1653 throw new NoSuchElementException();
1654 Object k = nextKey;
1655 advance();
1656 return (K)k;
1657 }
1658
1659 public final K nextElement() { return next(); }
1660 }
1661
1662 static final class ValueIterator<K,V> extends ViewIterator<K,V>
1663 implements Iterator<V>, Enumeration<V> {
1664 ValueIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
1665
1666 @SuppressWarnings("unchecked")
1667 public final V next() {
1668 if (next == null)
1669 throw new NoSuchElementException();
1670 Object v = nextVal;
1671 advance();
1672 return (V)v;
1673 }
1674
1675 public final V nextElement() { return next(); }
1676 }
1677
1678 static final class EntryIterator<K,V> extends ViewIterator<K,V>
1679 implements Iterator<Map.Entry<K,V>> {
1680 EntryIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
1681
1682 @SuppressWarnings("unchecked")
1683 public final Map.Entry<K,V> next() {
1684 if (next == null)
1685 throw new NoSuchElementException();
1686 Object k = nextKey;
1687 Object v = nextVal;
1688 advance();
1689 return new WriteThroughEntry<K,V>((K)k, (V)v, map);
1690 }
1691 }
1692
1693 static final class SnapshotEntryIterator<K,V> extends ViewIterator<K,V>
1694 implements Iterator<Map.Entry<K,V>> {
1695 SnapshotEntryIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
1696
1697 @SuppressWarnings("unchecked")
1698 public final Map.Entry<K,V> next() {
1699 if (next == null)
1700 throw new NoSuchElementException();
1701 Object k = nextKey;
1702 Object v = nextVal;
1703 advance();
1704 return new SnapshotEntry<K,V>((K)k, (V)v);
1705 }
1706 }
1707
1708 /**
1709 * Base of writeThrough and Snapshot entry classes
1710 */
1711 static abstract class MapEntry<K,V> implements Map.Entry<K, V> {
1712 final K key; // non-null
1713 V val; // non-null
1714 MapEntry(K key, V val) { this.key = key; this.val = val; }
1715 public final K getKey() { return key; }
1716 public final V getValue() { return val; }
1717 public final int hashCode() { return key.hashCode() ^ val.hashCode(); }
1718 public final String toString(){ return key + "=" + val; }
1719
1720 public final boolean equals(Object o) {
1721 Object k, v; Map.Entry<?,?> e;
1722 return ((o instanceof Map.Entry) &&
1723 (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
1724 (v = e.getValue()) != null &&
1725 (k == key || k.equals(key)) &&
1726 (v == val || v.equals(val)));
1727 }
1728
1729 public abstract V setValue(V value);
1730 }
1731
1732 /**
1733 * Entry used by EntryIterator.next(), that relays setValue
1734 * changes to the underlying map.
1735 */
1736 static final class WriteThroughEntry<K,V> extends MapEntry<K,V>
1737 implements Map.Entry<K, V> {
1738 final ConcurrentHashMapV8<K, V> map;
1739 WriteThroughEntry(K key, V val, ConcurrentHashMapV8<K, V> map) {
1740 super(key, val);
1741 this.map = map;
1742 }
1743
1744 /**
1745 * Sets our entry's value and writes through to the map. The
1746 * value to return is somewhat arbitrary here. Since a
1747 * WriteThroughEntry does not necessarily track asynchronous
1748 * changes, the most recent "previous" value could be
1749 * different from what we return (or could even have been
1750 * removed in which case the put will re-establish). We do not
1751 * and cannot guarantee more.
1752 */
1753 public final V setValue(V value) {
1754 if (value == null) throw new NullPointerException();
1755 V v = val;
1756 val = value;
1757 map.put(key, value);
1758 return v;
1759 }
1760 }
1761
1762 /**
1763 * Internal version of entry, that doesn't write though changes
1764 */
1765 static final class SnapshotEntry<K,V> extends MapEntry<K,V>
1766 implements Map.Entry<K, V> {
1767 SnapshotEntry(K key, V val) { super(key, val); }
1768 public final V setValue(V value) { // only locally update
1769 if (value == null) throw new NullPointerException();
1770 V v = val;
1771 val = value;
1772 return v;
1773 }
1774 }
1775
1776 /* ----------------Views -------------- */
1777
1778 /**
1779 * Base class for views. This is done mainly to allow adding
1780 * customized parallel traversals (not yet implemented.)
1781 */
1782 static abstract class MapView<K, V> {
1783 final ConcurrentHashMapV8<K, V> map;
1784 MapView(ConcurrentHashMapV8<K, V> map) { this.map = map; }
1785 public final int size() { return map.size(); }
1786 public final boolean isEmpty() { return map.isEmpty(); }
1787 public final void clear() { map.clear(); }
1788
1789 // implementations below rely on concrete classes supplying these
1790 abstract Iterator<?> iter();
1791 abstract public boolean contains(Object o);
1792 abstract public boolean remove(Object o);
1793
1794 private static final String oomeMsg = "Required array size too large";
1795
1796 public final Object[] toArray() {
1797 long sz = map.longSize();
1798 if (sz > (long)(MAX_ARRAY_SIZE))
1799 throw new OutOfMemoryError(oomeMsg);
1800 int n = (int)sz;
1801 Object[] r = new Object[n];
1802 int i = 0;
1803 Iterator<?> it = iter();
1804 while (it.hasNext()) {
1805 if (i == n) {
1806 if (n >= MAX_ARRAY_SIZE)
1807 throw new OutOfMemoryError(oomeMsg);
1808 if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
1809 n = MAX_ARRAY_SIZE;
1810 else
1811 n += (n >>> 1) + 1;
1812 r = Arrays.copyOf(r, n);
1813 }
1814 r[i++] = it.next();
1815 }
1816 return (i == n) ? r : Arrays.copyOf(r, i);
1817 }
1818
1819 @SuppressWarnings("unchecked")
1820 public final <T> T[] toArray(T[] a) {
1821 long sz = map.longSize();
1822 if (sz > (long)(MAX_ARRAY_SIZE))
1823 throw new OutOfMemoryError(oomeMsg);
1824 int m = (int)sz;
1825 T[] r = (a.length >= m) ? a :
1826 (T[])java.lang.reflect.Array
1827 .newInstance(a.getClass().getComponentType(), m);
1828 int n = r.length;
1829 int i = 0;
1830 Iterator<?> it = iter();
1831 while (it.hasNext()) {
1832 if (i == n) {
1833 if (n >= MAX_ARRAY_SIZE)
1834 throw new OutOfMemoryError(oomeMsg);
1835 if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
1836 n = MAX_ARRAY_SIZE;
1837 else
1838 n += (n >>> 1) + 1;
1839 r = Arrays.copyOf(r, n);
1840 }
1841 r[i++] = (T)it.next();
1842 }
1843 if (a == r && i < n) {
1844 r[i] = null; // null-terminate
1845 return r;
1846 }
1847 return (i == n) ? r : Arrays.copyOf(r, i);
1848 }
1849
1850 public final int hashCode() {
1851 int h = 0;
1852 for (Iterator<?> it = iter(); it.hasNext();)
1853 h += it.next().hashCode();
1854 return h;
1855 }
1856
1857 public final String toString() {
1858 StringBuilder sb = new StringBuilder();
1859 sb.append('[');
1860 Iterator<?> it = iter();
1861 if (it.hasNext()) {
1862 for (;;) {
1863 Object e = it.next();
1864 sb.append(e == this ? "(this Collection)" : e);
1865 if (!it.hasNext())
1866 break;
1867 sb.append(',').append(' ');
1868 }
1869 }
1870 return sb.append(']').toString();
1871 }
1872
1873 public final boolean containsAll(Collection<?> c) {
1874 if (c != this) {
1875 for (Iterator<?> it = c.iterator(); it.hasNext();) {
1876 Object e = it.next();
1877 if (e == null || !contains(e))
1878 return false;
1879 }
1880 }
1881 return true;
1882 }
1883
1884 public final boolean removeAll(Collection c) {
1885 boolean modified = false;
1886 for (Iterator<?> it = iter(); it.hasNext();) {
1887 if (c.contains(it.next())) {
1888 it.remove();
1889 modified = true;
1890 }
1891 }
1892 return modified;
1893 }
1894
1895 public final boolean retainAll(Collection<?> c) {
1896 boolean modified = false;
1897 for (Iterator<?> it = iter(); it.hasNext();) {
1898 if (!c.contains(it.next())) {
1899 it.remove();
1900 modified = true;
1901 }
1902 }
1903 return modified;
1904 }
1905
1906 }
1907
1908 static final class KeySet<K,V> extends MapView<K,V> implements Set<K> {
1909 KeySet(ConcurrentHashMapV8<K, V> map) { super(map); }
1910 public final boolean contains(Object o) { return map.containsKey(o); }
1911 public final boolean remove(Object o) { return map.remove(o) != null; }
1912
1913 public final Iterator<K> iterator() {
1914 return new KeyIterator<K,V>(map);
1915 }
1916 final Iterator<?> iter() {
1917 return new KeyIterator<K,V>(map);
1918 }
1919 public final boolean add(K e) {
1920 throw new UnsupportedOperationException();
1921 }
1922 public final boolean addAll(Collection<? extends K> c) {
1923 throw new UnsupportedOperationException();
1924 }
1925 public boolean equals(Object o) {
1926 Set<?> c;
1927 return ((o instanceof Set) &&
1928 ((c = (Set<?>)o) == this ||
1929 (containsAll(c) && c.containsAll(this))));
1930 }
1931 }
1932
1933 static final class Values<K,V> extends MapView<K,V>
1934 implements Collection<V> {
1935 Values(ConcurrentHashMapV8<K, V> map) { super(map); }
1936 public final boolean contains(Object o) { return map.containsValue(o); }
1937
1938 public final boolean remove(Object o) {
1939 if (o != null) {
1940 Iterator<V> it = new ValueIterator<K,V>(map);
1941 while (it.hasNext()) {
1942 if (o.equals(it.next())) {
1943 it.remove();
1944 return true;
1945 }
1946 }
1947 }
1948 return false;
1949 }
1950 public final Iterator<V> iterator() {
1951 return new ValueIterator<K,V>(map);
1952 }
1953 final Iterator<?> iter() {
1954 return new ValueIterator<K,V>(map);
1955 }
1956 public final boolean add(V e) {
1957 throw new UnsupportedOperationException();
1958 }
1959 public final boolean addAll(Collection<? extends V> c) {
1960 throw new UnsupportedOperationException();
1961 }
1962 }
1963
1964 static final class EntrySet<K,V> extends MapView<K,V>
1965 implements Set<Map.Entry<K,V>> {
1966 EntrySet(ConcurrentHashMapV8<K, V> map) { super(map); }
1967
1968 public final boolean contains(Object o) {
1969 Object k, v, r; Map.Entry<?,?> e;
1970 return ((o instanceof Map.Entry) &&
1971 (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
1972 (r = map.get(k)) != null &&
1973 (v = e.getValue()) != null &&
1974 (v == r || v.equals(r)));
1975 }
1976
1977 public final boolean remove(Object o) {
1978 Object k, v; Map.Entry<?,?> e;
1979 return ((o instanceof Map.Entry) &&
1980 (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
1981 (v = e.getValue()) != null &&
1982 map.remove(k, v));
1983 }
1984
1985 public final Iterator<Map.Entry<K,V>> iterator() {
1986 return new EntryIterator<K,V>(map);
1987 }
1988 final Iterator<?> iter() {
1989 return new SnapshotEntryIterator<K,V>(map);
1990 }
1991 public final boolean add(Entry<K,V> e) {
1992 throw new UnsupportedOperationException();
1993 }
1994 public final boolean addAll(Collection<? extends Entry<K,V>> c) {
1995 throw new UnsupportedOperationException();
1996 }
1997 public boolean equals(Object o) {
1998 Set<?> c;
1999 return ((o instanceof Set) &&
2000 ((c = (Set<?>)o) == this ||
2001 (containsAll(c) && c.containsAll(this))));
2002 }
2003 }
2004
2005 /* ---------------- Serialization Support -------------- */
2006
2007 /**
2008 * Stripped-down version of helper class used in previous version,
2009 * declared for the sake of serialization compatibility
2010 */
2011 static class Segment<K,V> implements Serializable {
2012 private static final long serialVersionUID = 2249069246763182397L;
2013 final float loadFactor;
2014 Segment(float lf) { this.loadFactor = lf; }
2015 }
2016
2017 /**
2018 * Saves the state of the {@code ConcurrentHashMapV8} instance to a
2019 * stream (i.e., serializes it).
2020 * @param s the stream
2021 * @serialData
2022 * the key (Object) and value (Object)
2023 * for each key-value mapping, followed by a null pair.
2024 * The key-value mappings are emitted in no particular order.
2025 */
2026 @SuppressWarnings("unchecked")
2027 private void writeObject(java.io.ObjectOutputStream s)
2028 throws java.io.IOException {
2029 if (segments == null) { // for serialization compatibility
2030 segments = (Segment<K,V>[])
2031 new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL];
2032 for (int i = 0; i < segments.length; ++i)
2033 segments[i] = new Segment<K,V>(LOAD_FACTOR);
2034 }
2035 s.defaultWriteObject();
2036 InternalIterator it = new InternalIterator(table);
2037 while (it.next != null) {
2038 s.writeObject(it.nextKey);
2039 s.writeObject(it.nextVal);
2040 it.advance();
2041 }
2042 s.writeObject(null);
2043 s.writeObject(null);
2044 segments = null; // throw away
2045 }
2046
2047 /**
2048 * Reconstitutes the instance from a stream (that is, deserializes it).
2049 * @param s the stream
2050 */
2051 @SuppressWarnings("unchecked")
2052 private void readObject(java.io.ObjectInputStream s)
2053 throws java.io.IOException, ClassNotFoundException {
2054 s.defaultReadObject();
2055 this.segments = null; // unneeded
2056 // initialize transient final field
2057 UNSAFE.putObjectVolatile(this, counterOffset, new LongAdder());
2058
2059 // Create all nodes, then place in table once size is known
2060 long size = 0L;
2061 Node p = null;
2062 for (;;) {
2063 K k = (K) s.readObject();
2064 V v = (V) s.readObject();
2065 if (k != null && v != null) {
2066 p = new Node(spread(k.hashCode()), k, v, p);
2067 ++size;
2068 }
2069 else
2070 break;
2071 }
2072 if (p != null) {
2073 boolean init = false;
2074 int n;
2075 if (size >= (long)(MAXIMUM_CAPACITY >>> 1))
2076 n = MAXIMUM_CAPACITY;
2077 else {
2078 int sz = (int)size;
2079 n = tableSizeFor(sz + (sz >>> 1) + 1);
2080 }
2081 int sc = sizeCtl;
2082 if (n > sc &&
2083 UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) {
2084 try {
2085 if (table == null) {
2086 init = true;
2087 Node[] tab = new Node[n];
2088 int mask = n - 1;
2089 while (p != null) {
2090 int j = p.hash & mask;
2091 Node next = p.next;
2092 p.next = tabAt(tab, j);
2093 setTabAt(tab, j, p);
2094 p = next;
2095 }
2096 table = tab;
2097 counter.add(size);
2098 sc = n - (n >>> 2) - 1;
2099 }
2100 } finally {
2101 sizeCtl = sc;
2102 }
2103 }
2104 if (!init) { // Can only happen if unsafely published.
2105 while (p != null) {
2106 internalPut(p.key, p.val, true);
2107 p = p.next;
2108 }
2109 }
2110 }
2111 }
2112
2113 // Unsafe mechanics
2114 private static final sun.misc.Unsafe UNSAFE;
2115 private static final long counterOffset;
2116 private static final long sizeCtlOffset;
2117 private static final long ABASE;
2118 private static final int ASHIFT;
2119
2120 static {
2121 int ss;
2122 try {
2123 UNSAFE = getUnsafe();
2124 Class<?> k = ConcurrentHashMapV8.class;
2125 counterOffset = UNSAFE.objectFieldOffset
2126 (k.getDeclaredField("counter"));
2127 sizeCtlOffset = UNSAFE.objectFieldOffset
2128 (k.getDeclaredField("sizeCtl"));
2129 Class<?> sc = Node[].class;
2130 ABASE = UNSAFE.arrayBaseOffset(sc);
2131 ss = UNSAFE.arrayIndexScale(sc);
2132 } catch (Exception e) {
2133 throw new Error(e);
2134 }
2135 if ((ss & (ss-1)) != 0)
2136 throw new Error("data type scale not a power of two");
2137 ASHIFT = 31 - Integer.numberOfLeadingZeros(ss);
2138 }
2139
2140 /**
2141 * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package.
2142 * Replace with a simple call to Unsafe.getUnsafe when integrating
2143 * into a jdk.
2144 *
2145 * @return a sun.misc.Unsafe
2146 */
2147 private static sun.misc.Unsafe getUnsafe() {
2148 try {
2149 return sun.misc.Unsafe.getUnsafe();
2150 } catch (SecurityException se) {
2151 try {
2152 return java.security.AccessController.doPrivileged
2153 (new java.security
2154 .PrivilegedExceptionAction<sun.misc.Unsafe>() {
2155 public sun.misc.Unsafe run() throws Exception {
2156 java.lang.reflect.Field f = sun.misc
2157 .Unsafe.class.getDeclaredField("theUnsafe");
2158 f.setAccessible(true);
2159 return (sun.misc.Unsafe) f.get(null);
2160 }});
2161 } catch (java.security.PrivilegedActionException e) {
2162 throw new RuntimeException("Could not initialize intrinsics",
2163 e.getCause());
2164 }
2165 }
2166 }
2167
2168 }