ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/ConcurrentHashMapV8.java
Revision: 1.19
Committed: Sat Sep 10 01:38:28 2011 UTC (12 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.18: +1 -3 lines
Log Message:
fix up @since

File Contents

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