ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/ConcurrentHashMapV8.java
Revision: 1.83
Committed: Fri Dec 14 16:33:42 2012 UTC (11 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.82: +13 -13 lines
Log Message:
whitespace

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 package jsr166e;
8
9 import java.util.Comparator;
10 import java.util.Arrays;
11 import java.util.Map;
12 import java.util.Set;
13 import java.util.Collection;
14 import java.util.AbstractMap;
15 import java.util.AbstractSet;
16 import java.util.AbstractCollection;
17 import java.util.Hashtable;
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.Enumeration;
21 import java.util.ConcurrentModificationException;
22 import java.util.NoSuchElementException;
23 import java.util.concurrent.ConcurrentMap;
24 import java.util.concurrent.locks.AbstractQueuedSynchronizer;
25 import java.util.concurrent.atomic.AtomicInteger;
26 import java.util.concurrent.atomic.AtomicReference;
27 import java.io.Serializable;
28
29 /**
30 * A hash table supporting full concurrency of retrievals and
31 * high expected concurrency for updates. This class obeys the
32 * same functional specification as {@link java.util.Hashtable}, and
33 * includes versions of methods corresponding to each method of
34 * {@code Hashtable}. However, even though all operations are
35 * thread-safe, retrieval operations do <em>not</em> entail locking,
36 * and there is <em>not</em> any support for locking the entire table
37 * in a way that prevents all access. This class is fully
38 * interoperable with {@code Hashtable} in programs that rely on its
39 * thread safety but not on its synchronization details.
40 *
41 * <p>Retrieval operations (including {@code get}) generally do not
42 * block, so may overlap with update operations (including {@code put}
43 * and {@code remove}). Retrievals reflect the results of the most
44 * recently <em>completed</em> update operations holding upon their
45 * onset. (More formally, an update operation for a given key bears a
46 * <em>happens-before</em> relation with any (non-null) retrieval for
47 * that key reporting the updated value.) For aggregate operations
48 * such as {@code putAll} and {@code clear}, concurrent retrievals may
49 * reflect insertion or removal of only some entries. Similarly,
50 * Iterators and Enumerations return elements reflecting the state of
51 * the hash table at some point at or since the creation of the
52 * iterator/enumeration. They do <em>not</em> throw {@link
53 * ConcurrentModificationException}. However, iterators are designed
54 * to be used by only one thread at a time. Bear in mind that the
55 * results of aggregate status methods including {@code size}, {@code
56 * isEmpty}, and {@code containsValue} are typically useful only when
57 * a map is not undergoing concurrent updates in other threads.
58 * Otherwise the results of these methods reflect transient states
59 * that may be adequate for monitoring or estimation purposes, but not
60 * for program control.
61 *
62 * <p>The table is dynamically expanded when there are too many
63 * collisions (i.e., keys that have distinct hash codes but fall into
64 * the same slot modulo the table size), with the expected average
65 * effect of maintaining roughly two bins per mapping (corresponding
66 * to a 0.75 load factor threshold for resizing). There may be much
67 * variance around this average as mappings are added and removed, but
68 * overall, this maintains a commonly accepted time/space tradeoff for
69 * hash tables. However, resizing this or any other kind of hash
70 * table may be a relatively slow operation. When possible, it is a
71 * good idea to provide a size estimate as an optional {@code
72 * initialCapacity} constructor argument. An additional optional
73 * {@code loadFactor} constructor argument provides a further means of
74 * customizing initial table capacity by specifying the table density
75 * to be used in calculating the amount of space to allocate for the
76 * given number of elements. Also, for compatibility with previous
77 * versions of this class, constructors may optionally specify an
78 * expected {@code concurrencyLevel} as an additional hint for
79 * internal sizing. Note that using many keys with exactly the same
80 * {@code hashCode()} is a sure way to slow down performance of any
81 * hash table.
82 *
83 * <p>A {@link Set} projection of a ConcurrentHashMapV8 may be created
84 * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed
85 * (using {@link #keySet(Object)} when only keys are of interest, and the
86 * mapped values are (perhaps transiently) not used or all take the
87 * same mapping value.
88 *
89 * <p>A ConcurrentHashMapV8 can be used as scalable frequency map (a
90 * form of histogram or multiset) by using {@link LongAdder} values
91 * and initializing via {@link #computeIfAbsent}. For example, to add
92 * a count to a {@code ConcurrentHashMapV8<String,LongAdder> freqs}, you
93 * can use {@code freqs.computeIfAbsent(k -> new
94 * LongAdder()).increment();}
95 *
96 * <p>This class and its views and iterators implement all of the
97 * <em>optional</em> methods of the {@link Map} and {@link Iterator}
98 * interfaces.
99 *
100 * <p>Like {@link Hashtable} but unlike {@link HashMap}, this class
101 * does <em>not</em> allow {@code null} to be used as a key or value.
102 *
103 * <p>ConcurrentHashMapV8s support parallel operations using the {@link
104 * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts
105 * are available in class {@link ForkJoinTasks}). These operations are
106 * designed to be safely, and often sensibly, applied even with maps
107 * that are being concurrently updated by other threads; for example,
108 * when computing a snapshot summary of the values in a shared
109 * registry. There are three kinds of operation, each with four
110 * forms, accepting functions with Keys, Values, Entries, and (Key,
111 * Value) arguments and/or return values. (The first three forms are
112 * also available via the {@link #keySet()}, {@link #values()} and
113 * {@link #entrySet()} views). Because the elements of a
114 * ConcurrentHashMapV8 are not ordered in any particular way, and may be
115 * processed in different orders in different parallel executions, the
116 * correctness of supplied functions should not depend on any
117 * ordering, or on any other objects or values that may transiently
118 * change while computation is in progress; and except for forEach
119 * actions, should ideally be side-effect-free.
120 *
121 * <ul>
122 * <li> forEach: Perform a given action on each element.
123 * A variant form applies a given transformation on each element
124 * before performing the action.</li>
125 *
126 * <li> search: Return the first available non-null result of
127 * applying a given function on each element; skipping further
128 * search when a result is found.</li>
129 *
130 * <li> reduce: Accumulate each element. The supplied reduction
131 * function cannot rely on ordering (more formally, it should be
132 * both associative and commutative). There are five variants:
133 *
134 * <ul>
135 *
136 * <li> Plain reductions. (There is not a form of this method for
137 * (key, value) function arguments since there is no corresponding
138 * return type.)</li>
139 *
140 * <li> Mapped reductions that accumulate the results of a given
141 * function applied to each element.</li>
142 *
143 * <li> Reductions to scalar doubles, longs, and ints, using a
144 * given basis value.</li>
145 *
146 * </li>
147 * </ul>
148 * </ul>
149 *
150 * <p>The concurrency properties of bulk operations follow
151 * from those of ConcurrentHashMapV8: Any non-null result returned
152 * from {@code get(key)} and related access methods bears a
153 * happens-before relation with the associated insertion or
154 * update. The result of any bulk operation reflects the
155 * composition of these per-element relations (but is not
156 * necessarily atomic with respect to the map as a whole unless it
157 * is somehow known to be quiescent). Conversely, because keys
158 * and values in the map are never null, null serves as a reliable
159 * atomic indicator of the current lack of any result. To
160 * maintain this property, null serves as an implicit basis for
161 * all non-scalar reduction operations. For the double, long, and
162 * int versions, the basis should be one that, when combined with
163 * any other value, returns that other value (more formally, it
164 * should be the identity element for the reduction). Most common
165 * reductions have these properties; for example, computing a sum
166 * with basis 0 or a minimum with basis MAX_VALUE.
167 *
168 * <p>Search and transformation functions provided as arguments
169 * should similarly return null to indicate the lack of any result
170 * (in which case it is not used). In the case of mapped
171 * reductions, this also enables transformations to serve as
172 * filters, returning null (or, in the case of primitive
173 * specializations, the identity basis) if the element should not
174 * be combined. You can create compound transformations and
175 * filterings by composing them yourself under this "null means
176 * there is nothing there now" rule before using them in search or
177 * reduce operations.
178 *
179 * <p>Methods accepting and/or returning Entry arguments maintain
180 * key-value associations. They may be useful for example when
181 * finding the key for the greatest value. Note that "plain" Entry
182 * arguments can be supplied using {@code new
183 * AbstractMap.SimpleEntry(k,v)}.
184 *
185 * <p>Bulk operations may complete abruptly, throwing an
186 * exception encountered in the application of a supplied
187 * function. Bear in mind when handling such exceptions that other
188 * concurrently executing functions could also have thrown
189 * exceptions, or would have done so if the first exception had
190 * not occurred.
191 *
192 * <p>Parallel speedups for bulk operations compared to sequential
193 * processing are common but not guaranteed. Operations involving
194 * brief functions on small maps may execute more slowly than
195 * sequential loops if the underlying work to parallelize the
196 * computation is more expensive than the computation itself.
197 * Similarly, parallelization may not lead to much actual parallelism
198 * if all processors are busy performing unrelated tasks.
199 *
200 * <p>All arguments to all task methods must be non-null.
201 *
202 * <p><em>jsr166e note: During transition, this class
203 * uses nested functional interfaces with different names but the
204 * same forms as those expected for JDK8.</em>
205 *
206 * <p>This class is a member of the
207 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
208 * Java Collections Framework</a>.
209 *
210 * @since 1.5
211 * @author Doug Lea
212 * @param <K> the type of keys maintained by this map
213 * @param <V> the type of mapped values
214 */
215 public class ConcurrentHashMapV8<K, V>
216 implements ConcurrentMap<K, V>, Serializable {
217 private static final long serialVersionUID = 7249069246763182397L;
218
219 /**
220 * A partitionable iterator. A Spliterator can be traversed
221 * directly, but can also be partitioned (before traversal) by
222 * creating another Spliterator that covers a non-overlapping
223 * portion of the elements, and so may be amenable to parallel
224 * execution.
225 *
226 * <p>This interface exports a subset of expected JDK8
227 * functionality.
228 *
229 * <p>Sample usage: Here is one (of the several) ways to compute
230 * the sum of the values held in a map using the ForkJoin
231 * framework. As illustrated here, Spliterators are well suited to
232 * designs in which a task repeatedly splits off half its work
233 * into forked subtasks until small enough to process directly,
234 * and then joins these subtasks. Variants of this style can also
235 * be used in completion-based designs.
236 *
237 * <pre>
238 * {@code ConcurrentHashMapV8<String, Long> m = ...
239 * // split as if have 8 * parallelism, for load balance
240 * int n = m.size();
241 * int p = aForkJoinPool.getParallelism() * 8;
242 * int split = (n < p)? n : p;
243 * long sum = aForkJoinPool.invoke(new SumValues(m.valueSpliterator(), split, null));
244 * // ...
245 * static class SumValues extends RecursiveTask<Long> {
246 * final Spliterator<Long> s;
247 * final int split; // split while > 1
248 * final SumValues nextJoin; // records forked subtasks to join
249 * SumValues(Spliterator<Long> s, int depth, SumValues nextJoin) {
250 * this.s = s; this.depth = depth; this.nextJoin = nextJoin;
251 * }
252 * public Long compute() {
253 * long sum = 0;
254 * SumValues subtasks = null; // fork subtasks
255 * for (int s = split >>> 1; s > 0; s >>>= 1)
256 * (subtasks = new SumValues(s.split(), s, subtasks)).fork();
257 * while (s.hasNext()) // directly process remaining elements
258 * sum += s.next();
259 * for (SumValues t = subtasks; t != null; t = t.nextJoin)
260 * sum += t.join(); // collect subtask results
261 * return sum;
262 * }
263 * }
264 * }</pre>
265 */
266 public static interface Spliterator<T> extends Iterator<T> {
267 /**
268 * Returns a Spliterator covering approximately half of the
269 * elements, guaranteed not to overlap with those subsequently
270 * returned by this Spliterator. After invoking this method,
271 * the current Spliterator will <em>not</em> produce any of
272 * the elements of the returned Spliterator, but the two
273 * Spliterators together will produce all of the elements that
274 * would have been produced by this Spliterator had this
275 * method not been called. The exact number of elements
276 * produced by the returned Spliterator is not guaranteed, and
277 * may be zero (i.e., with {@code hasNext()} reporting {@code
278 * false}) if this Spliterator cannot be further split.
279 *
280 * @return a Spliterator covering approximately half of the
281 * elements
282 * @throws IllegalStateException if this Spliterator has
283 * already commenced traversing elements
284 */
285 Spliterator<T> split();
286 }
287
288 /*
289 * Overview:
290 *
291 * The primary design goal of this hash table is to maintain
292 * concurrent readability (typically method get(), but also
293 * iterators and related methods) while minimizing update
294 * contention. Secondary goals are to keep space consumption about
295 * the same or better than java.util.HashMap, and to support high
296 * initial insertion rates on an empty table by many threads.
297 *
298 * Each key-value mapping is held in a Node. Because Node fields
299 * can contain special values, they are defined using plain Object
300 * types. Similarly in turn, all internal methods that use them
301 * work off Object types. And similarly, so do the internal
302 * methods of auxiliary iterator and view classes. This also
303 * allows many of the public methods to be factored into a smaller
304 * number of internal methods (although sadly not so for the five
305 * variants of put-related operations). The validation-based
306 * approach explained below leads to a lot of code sprawl because
307 * retry-control precludes factoring into smaller methods.
308 *
309 * The table is lazily initialized to a power-of-two size upon the
310 * first insertion. Each bin in the table normally contains a
311 * list of Nodes (most often, the list has only zero or one Node).
312 * Table accesses require volatile/atomic reads, writes, and
313 * CASes. Because there is no other way to arrange this without
314 * adding further indirections, we use intrinsics
315 * (sun.misc.Unsafe) operations. The lists of nodes within bins
316 * are always accurately traversable under volatile reads, so long
317 * as lookups check hash code and non-nullness of value before
318 * checking key equality.
319 *
320 * We use the top (sign) bit of Node hash fields for control
321 * purposes -- it is available anyway because of addressing
322 * constraints. Nodes with negative hash fields are forwarding
323 * nodes to either TreeBins or resized tables. The lower 31 bits
324 * of each normal Node's hash field contain a transformation of
325 * the key's hash code.
326 *
327 * Insertion (via put or its variants) of the first node in an
328 * empty bin is performed by just CASing it to the bin. This is
329 * by far the most common case for put operations under most
330 * key/hash distributions. Other update operations (insert,
331 * delete, and replace) require locks. We do not want to waste
332 * the space required to associate a distinct lock object with
333 * each bin, so instead use the first node of a bin list itself as
334 * a lock. Locking support for these locks relies on builtin
335 * "synchronized" monitors.
336 *
337 * Using the first node of a list as a lock does not by itself
338 * suffice though: When a node is locked, any update must first
339 * validate that it is still the first node after locking it, and
340 * retry if not. Because new nodes are always appended to lists,
341 * once a node is first in a bin, it remains first until deleted
342 * or the bin becomes invalidated (upon resizing). However,
343 * operations that only conditionally update may inspect nodes
344 * until the point of update. This is a converse of sorts to the
345 * lazy locking technique described by Herlihy & Shavit.
346 *
347 * The main disadvantage of per-bin locks is that other update
348 * operations on other nodes in a bin list protected by the same
349 * lock can stall, for example when user equals() or mapping
350 * functions take a long time. However, statistically, under
351 * random hash codes, this is not a common problem. Ideally, the
352 * frequency of nodes in bins follows a Poisson distribution
353 * (http://en.wikipedia.org/wiki/Poisson_distribution) with a
354 * parameter of about 0.5 on average, given the resizing threshold
355 * of 0.75, although with a large variance because of resizing
356 * granularity. Ignoring variance, the expected occurrences of
357 * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The
358 * first values are:
359 *
360 * 0: 0.60653066
361 * 1: 0.30326533
362 * 2: 0.07581633
363 * 3: 0.01263606
364 * 4: 0.00157952
365 * 5: 0.00015795
366 * 6: 0.00001316
367 * 7: 0.00000094
368 * 8: 0.00000006
369 * more: less than 1 in ten million
370 *
371 * Lock contention probability for two threads accessing distinct
372 * elements is roughly 1 / (8 * #elements) under random hashes.
373 *
374 * Actual hash code distributions encountered in practice
375 * sometimes deviate significantly from uniform randomness. This
376 * includes the case when N > (1<<30), so some keys MUST collide.
377 * Similarly for dumb or hostile usages in which multiple keys are
378 * designed to have identical hash codes. Also, although we guard
379 * against the worst effects of this (see method spread), sets of
380 * hashes may differ only in bits that do not impact their bin
381 * index for a given power-of-two mask. So we use a secondary
382 * strategy that applies when the number of nodes in a bin exceeds
383 * a threshold, and at least one of the keys implements
384 * Comparable. These TreeBins use a balanced tree to hold nodes
385 * (a specialized form of red-black trees), bounding search time
386 * to O(log N). Each search step in a TreeBin is around twice as
387 * slow as in a regular list, but given that N cannot exceed
388 * (1<<64) (before running out of addresses) this bounds search
389 * steps, lock hold times, etc, to reasonable constants (roughly
390 * 100 nodes inspected per operation worst case) so long as keys
391 * are Comparable (which is very common -- String, Long, etc).
392 * TreeBin nodes (TreeNodes) also maintain the same "next"
393 * traversal pointers as regular nodes, so can be traversed in
394 * iterators in the same way.
395 *
396 * The table is resized when occupancy exceeds a percentage
397 * threshold (nominally, 0.75, but see below). Any thread
398 * noticing an overfull bin may assist in resizing after the
399 * initiating thread allocates and sets up the replacement
400 * array. However, rather than stalling, these other threads may
401 * proceed with insertions etc. The use of TreeBins shields us
402 * from the worst case effects of overfilling while resizes are in
403 * progress. Resizing proceeds by transferring bins, one by one,
404 * from the table to the next table. To enable concurrency, the
405 * next table must be (incrementally) prefilled with place-holders
406 * serving as reverse forwarders to the old table. Because we are
407 * using power-of-two expansion, the elements from each bin must
408 * either stay at same index, or move with a power of two
409 * offset. We eliminate unnecessary node creation by catching
410 * cases where old nodes can be reused because their next fields
411 * won't change. On average, only about one-sixth of them need
412 * cloning when a table doubles. The nodes they replace will be
413 * garbage collectable as soon as they are no longer referenced by
414 * any reader thread that may be in the midst of concurrently
415 * traversing table. Upon transfer, the old table bin contains
416 * only a special forwarding node (with hash field "MOVED") that
417 * contains the next table as its key. On encountering a
418 * forwarding node, access and update operations restart, using
419 * the new table.
420 *
421 * Each bin transfer requires its bin lock, which can stall
422 * waiting for locks while resizing. However, because other
423 * threads can join in and help resize rather than contend for
424 * locks, average aggregate waits become shorter as resizing
425 * progresses. The transfer operation must also ensure that all
426 * accessible bins in both the old and new table are usable by any
427 * traversal. This is arranged by proceeding from the last bin
428 * (table.length - 1) up towards the first. Upon seeing a
429 * forwarding node, traversals (see class Traverser) arrange to
430 * move to the new table without revisiting nodes. However, to
431 * ensure that no intervening nodes are skipped, bin splitting can
432 * only begin after the associated reverse-forwarders are in
433 * place.
434 *
435 * The traversal scheme also applies to partial traversals of
436 * ranges of bins (via an alternate Traverser constructor)
437 * to support partitioned aggregate operations. Also, read-only
438 * operations give up if ever forwarded to a null table, which
439 * provides support for shutdown-style clearing, which is also not
440 * currently implemented.
441 *
442 * Lazy table initialization minimizes footprint until first use,
443 * and also avoids resizings when the first operation is from a
444 * putAll, constructor with map argument, or deserialization.
445 * These cases attempt to override the initial capacity settings,
446 * but harmlessly fail to take effect in cases of races.
447 *
448 * The element count is maintained using a specialization of
449 * LongAdder. We need to incorporate a specialization rather than
450 * just use a LongAdder in order to access implicit
451 * contention-sensing that leads to creation of multiple
452 * CounterCells. The counter mechanics avoid contention on
453 * updates but can encounter cache thrashing if read too
454 * frequently during concurrent access. To avoid reading so often,
455 * resizing under contention is attempted only upon adding to a
456 * bin already holding two or more nodes. Under uniform hash
457 * distributions, the probability of this occurring at threshold
458 * is around 13%, meaning that only about 1 in 8 puts check
459 * threshold (and after resizing, many fewer do so). The bulk
460 * putAll operation further reduces contention by only committing
461 * count updates upon these size checks.
462 *
463 * Maintaining API and serialization compatibility with previous
464 * versions of this class introduces several oddities. Mainly: We
465 * leave untouched but unused constructor arguments refering to
466 * concurrencyLevel. We accept a loadFactor constructor argument,
467 * but apply it only to initial table capacity (which is the only
468 * time that we can guarantee to honor it.) We also declare an
469 * unused "Segment" class that is instantiated in minimal form
470 * only when serializing.
471 */
472
473 /* ---------------- Constants -------------- */
474
475 /**
476 * The largest possible table capacity. This value must be
477 * exactly 1<<30 to stay within Java array allocation and indexing
478 * bounds for power of two table sizes, and is further required
479 * because the top two bits of 32bit hash fields are used for
480 * control purposes.
481 */
482 private static final int MAXIMUM_CAPACITY = 1 << 30;
483
484 /**
485 * The default initial table capacity. Must be a power of 2
486 * (i.e., at least 1) and at most MAXIMUM_CAPACITY.
487 */
488 private static final int DEFAULT_CAPACITY = 16;
489
490 /**
491 * The largest possible (non-power of two) array size.
492 * Needed by toArray and related methods.
493 */
494 static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
495
496 /**
497 * The default concurrency level for this table. Unused but
498 * defined for compatibility with previous versions of this class.
499 */
500 private static final int DEFAULT_CONCURRENCY_LEVEL = 16;
501
502 /**
503 * The load factor for this table. Overrides of this value in
504 * constructors affect only the initial table capacity. The
505 * actual floating point value isn't normally used -- it is
506 * simpler to use expressions such as {@code n - (n >>> 2)} for
507 * the associated resizing threshold.
508 */
509 private static final float LOAD_FACTOR = 0.75f;
510
511 /**
512 * The bin count threshold for using a tree rather than list for a
513 * bin. The value reflects the approximate break-even point for
514 * using tree-based operations.
515 */
516 private static final int TREE_THRESHOLD = 8;
517
518 /**
519 * Minimum number of rebinnings per transfer step. Ranges are
520 * subdivided to allow multiple resizer threads. This value
521 * serves as a lower bound to avoid resizers encountering
522 * excessive memory contention. The value should be at least
523 * DEFAULT_CAPACITY.
524 */
525 private static final int MIN_TRANSFER_STRIDE = 16;
526
527 /*
528 * Encodings for Node hash fields. See above for explanation.
529 */
530 static final int MOVED = 0x80000000; // hash field for forwarding nodes
531 static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash
532
533 /** Number of CPUS, to place bounds on some sizings */
534 static final int NCPU = Runtime.getRuntime().availableProcessors();
535
536 /* ---------------- Counters -------------- */
537
538 // Adapted from LongAdder and Striped64.
539 // See their internal docs for explanation.
540
541 // A padded cell for distributing counts
542 static final class CounterCell {
543 volatile long p0, p1, p2, p3, p4, p5, p6;
544 volatile long value;
545 volatile long q0, q1, q2, q3, q4, q5, q6;
546 CounterCell(long x) { value = x; }
547 }
548
549 /**
550 * Holder for the thread-local hash code determining which
551 * CounterCell to use. The code is initialized via the
552 * counterHashCodeGenerator, but may be moved upon collisions.
553 */
554 static final class CounterHashCode {
555 int code;
556 }
557
558 /**
559 * Generates initial value for per-thread CounterHashCodes
560 */
561 static final AtomicInteger counterHashCodeGenerator = new AtomicInteger();
562
563 /**
564 * Increment for counterHashCodeGenerator. See class ThreadLocal
565 * for explanation.
566 */
567 static final int SEED_INCREMENT = 0x61c88647;
568
569 /**
570 * Per-thread counter hash codes. Shared across all instances
571 */
572 static final ThreadLocal<CounterHashCode> threadCounterHashCode =
573 new ThreadLocal<CounterHashCode>();
574
575 /* ---------------- Fields -------------- */
576
577 /**
578 * The array of bins. Lazily initialized upon first insertion.
579 * Size is always a power of two. Accessed directly by iterators.
580 */
581 transient volatile Node[] table;
582
583 /**
584 * The next table to use; non-null only while resizing.
585 */
586 private transient volatile Node[] nextTable;
587
588 /**
589 * Base counter value, used mainly when there is no contention,
590 * but also as a fallback during table initialization
591 * races. Updated via CAS.
592 */
593 private transient volatile long baseCount;
594
595 /**
596 * Table initialization and resizing control. When negative, the
597 * table is being initialized or resized: -1 for initialization,
598 * else -(1 + the number of active resizing threads). Otherwise,
599 * when table is null, holds the initial table size to use upon
600 * creation, or 0 for default. After initialization, holds the
601 * next element count value upon which to resize the table.
602 */
603 private transient volatile int sizeCtl;
604
605 /**
606 * The next table index (plus one) to split while resizing.
607 */
608 private transient volatile int transferIndex;
609
610 /**
611 * The least available table index to split while resizing.
612 */
613 private transient volatile int transferOrigin;
614
615 /**
616 * Spinlock (locked via CAS) used when resizing and/or creating Cells.
617 */
618 private transient volatile int counterBusy;
619
620 /**
621 * Table of counter cells. When non-null, size is a power of 2.
622 */
623 private transient volatile CounterCell[] counterCells;
624
625 // views
626 private transient KeySetView<K,V> keySet;
627 private transient ValuesView<K,V> values;
628 private transient EntrySetView<K,V> entrySet;
629
630 /** For serialization compatibility. Null unless serialized; see below */
631 private Segment<K,V>[] segments;
632
633 /* ---------------- Table element access -------------- */
634
635 /*
636 * Volatile access methods are used for table elements as well as
637 * elements of in-progress next table while resizing. Uses are
638 * null checked by callers, and implicitly bounds-checked, relying
639 * on the invariants that tab arrays have non-zero size, and all
640 * indices are masked with (tab.length - 1) which is never
641 * negative and always less than length. Note that, to be correct
642 * wrt arbitrary concurrency errors by users, bounds checks must
643 * operate on local variables, which accounts for some odd-looking
644 * inline assignments below.
645 */
646
647 static final Node tabAt(Node[] tab, int i) { // used by Traverser
648 return (Node)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
649 }
650
651 private static final boolean casTabAt(Node[] tab, int i, Node c, Node v) {
652 return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
653 }
654
655 private static final void setTabAt(Node[] tab, int i, Node v) {
656 U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
657 }
658
659 /* ---------------- Nodes -------------- */
660
661 /**
662 * Key-value entry. Note that this is never exported out as a
663 * user-visible Map.Entry (see MapEntry below). Nodes with a hash
664 * field of MOVED are special, and do not contain user keys or
665 * values. Otherwise, keys are never null, and null val fields
666 * indicate that a node is in the process of being deleted or
667 * created. For purposes of read-only access, a key may be read
668 * before a val, but can only be used after checking val to be
669 * non-null.
670 */
671 static class Node {
672 final int hash;
673 final Object key;
674 volatile Object val;
675 volatile Node next;
676
677 Node(int hash, Object key, Object val, Node next) {
678 this.hash = hash;
679 this.key = key;
680 this.val = val;
681 this.next = next;
682 }
683 }
684
685 /* ---------------- TreeBins -------------- */
686
687 /**
688 * Nodes for use in TreeBins
689 */
690 static final class TreeNode extends Node {
691 TreeNode parent; // red-black tree links
692 TreeNode left;
693 TreeNode right;
694 TreeNode prev; // needed to unlink next upon deletion
695 boolean red;
696
697 TreeNode(int hash, Object key, Object val, Node next, TreeNode parent) {
698 super(hash, key, val, next);
699 this.parent = parent;
700 }
701 }
702
703 /**
704 * A specialized form of red-black tree for use in bins
705 * whose size exceeds a threshold.
706 *
707 * TreeBins use a special form of comparison for search and
708 * related operations (which is the main reason we cannot use
709 * existing collections such as TreeMaps). TreeBins contain
710 * Comparable elements, but may contain others, as well as
711 * elements that are Comparable but not necessarily Comparable<T>
712 * for the same T, so we cannot invoke compareTo among them. To
713 * handle this, the tree is ordered primarily by hash value, then
714 * by getClass().getName() order, and then by Comparator order
715 * among elements of the same class. On lookup at a node, if
716 * elements are not comparable or compare as 0, both left and
717 * right children may need to be searched in the case of tied hash
718 * values. (This corresponds to the full list search that would be
719 * necessary if all elements were non-Comparable and had tied
720 * hashes.) The red-black balancing code is updated from
721 * pre-jdk-collections
722 * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java)
723 * based in turn on Cormen, Leiserson, and Rivest "Introduction to
724 * Algorithms" (CLR).
725 *
726 * TreeBins also maintain a separate locking discipline than
727 * regular bins. Because they are forwarded via special MOVED
728 * nodes at bin heads (which can never change once established),
729 * we cannot use those nodes as locks. Instead, TreeBin
730 * extends AbstractQueuedSynchronizer to support a simple form of
731 * read-write lock. For update operations and table validation,
732 * the exclusive form of lock behaves in the same way as bin-head
733 * locks. However, lookups use shared read-lock mechanics to allow
734 * multiple readers in the absence of writers. Additionally,
735 * these lookups do not ever block: While the lock is not
736 * available, they proceed along the slow traversal path (via
737 * next-pointers) until the lock becomes available or the list is
738 * exhausted, whichever comes first. (These cases are not fast,
739 * but maximize aggregate expected throughput.) The AQS mechanics
740 * for doing this are straightforward. The lock state is held as
741 * AQS getState(). Read counts are negative; the write count (1)
742 * is positive. There are no signalling preferences among readers
743 * and writers. Since we don't need to export full Lock API, we
744 * just override the minimal AQS methods and use them directly.
745 */
746 static final class TreeBin extends AbstractQueuedSynchronizer {
747 private static final long serialVersionUID = 2249069246763182397L;
748 transient TreeNode root; // root of tree
749 transient TreeNode first; // head of next-pointer list
750
751 /* AQS overrides */
752 public final boolean isHeldExclusively() { return getState() > 0; }
753 public final boolean tryAcquire(int ignore) {
754 if (compareAndSetState(0, 1)) {
755 setExclusiveOwnerThread(Thread.currentThread());
756 return true;
757 }
758 return false;
759 }
760 public final boolean tryRelease(int ignore) {
761 setExclusiveOwnerThread(null);
762 setState(0);
763 return true;
764 }
765 public final int tryAcquireShared(int ignore) {
766 for (int c;;) {
767 if ((c = getState()) > 0)
768 return -1;
769 if (compareAndSetState(c, c -1))
770 return 1;
771 }
772 }
773 public final boolean tryReleaseShared(int ignore) {
774 int c;
775 do {} while (!compareAndSetState(c = getState(), c + 1));
776 return c == -1;
777 }
778
779 /** From CLR */
780 private void rotateLeft(TreeNode p) {
781 if (p != null) {
782 TreeNode r = p.right, pp, rl;
783 if ((rl = p.right = r.left) != null)
784 rl.parent = p;
785 if ((pp = r.parent = p.parent) == null)
786 root = r;
787 else if (pp.left == p)
788 pp.left = r;
789 else
790 pp.right = r;
791 r.left = p;
792 p.parent = r;
793 }
794 }
795
796 /** From CLR */
797 private void rotateRight(TreeNode p) {
798 if (p != null) {
799 TreeNode l = p.left, pp, lr;
800 if ((lr = p.left = l.right) != null)
801 lr.parent = p;
802 if ((pp = l.parent = p.parent) == null)
803 root = l;
804 else if (pp.right == p)
805 pp.right = l;
806 else
807 pp.left = l;
808 l.right = p;
809 p.parent = l;
810 }
811 }
812
813 /**
814 * Returns the TreeNode (or null if not found) for the given key
815 * starting at given root.
816 */
817 @SuppressWarnings("unchecked") final TreeNode getTreeNode
818 (int h, Object k, TreeNode p) {
819 Class<?> c = k.getClass();
820 while (p != null) {
821 int dir, ph; Object pk; Class<?> pc;
822 if ((ph = p.hash) == h) {
823 if ((pk = p.key) == k || k.equals(pk))
824 return p;
825 if (c != (pc = pk.getClass()) ||
826 !(k instanceof Comparable) ||
827 (dir = ((Comparable)k).compareTo((Comparable)pk)) == 0) {
828 if ((dir = (c == pc) ? 0 :
829 c.getName().compareTo(pc.getName())) == 0) {
830 TreeNode r = null, pl, pr; // check both sides
831 if ((pr = p.right) != null && h >= pr.hash &&
832 (r = getTreeNode(h, k, pr)) != null)
833 return r;
834 else if ((pl = p.left) != null && h <= pl.hash)
835 dir = -1;
836 else // nothing there
837 return null;
838 }
839 }
840 }
841 else
842 dir = (h < ph) ? -1 : 1;
843 p = (dir > 0) ? p.right : p.left;
844 }
845 return null;
846 }
847
848 /**
849 * Wrapper for getTreeNode used by CHM.get. Tries to obtain
850 * read-lock to call getTreeNode, but during failure to get
851 * lock, searches along next links.
852 */
853 final Object getValue(int h, Object k) {
854 Node r = null;
855 int c = getState(); // Must read lock state first
856 for (Node e = first; e != null; e = e.next) {
857 if (c <= 0 && compareAndSetState(c, c - 1)) {
858 try {
859 r = getTreeNode(h, k, root);
860 } finally {
861 releaseShared(0);
862 }
863 break;
864 }
865 else if (e.hash == h && k.equals(e.key)) {
866 r = e;
867 break;
868 }
869 else
870 c = getState();
871 }
872 return r == null ? null : r.val;
873 }
874
875 /**
876 * Finds or adds a node.
877 * @return null if added
878 */
879 @SuppressWarnings("unchecked") final TreeNode putTreeNode
880 (int h, Object k, Object v) {
881 Class<?> c = k.getClass();
882 TreeNode pp = root, p = null;
883 int dir = 0;
884 while (pp != null) { // find existing node or leaf to insert at
885 int ph; Object pk; Class<?> pc;
886 p = pp;
887 if ((ph = p.hash) == h) {
888 if ((pk = p.key) == k || k.equals(pk))
889 return p;
890 if (c != (pc = pk.getClass()) ||
891 !(k instanceof Comparable) ||
892 (dir = ((Comparable)k).compareTo((Comparable)pk)) == 0) {
893 TreeNode s = null, r = null, pr;
894 if ((dir = (c == pc) ? 0 :
895 c.getName().compareTo(pc.getName())) == 0) {
896 if ((pr = p.right) != null && h >= pr.hash &&
897 (r = getTreeNode(h, k, pr)) != null)
898 return r;
899 else // continue left
900 dir = -1;
901 }
902 else if ((pr = p.right) != null && h >= pr.hash)
903 s = pr;
904 if (s != null && (r = getTreeNode(h, k, s)) != null)
905 return r;
906 }
907 }
908 else
909 dir = (h < ph) ? -1 : 1;
910 pp = (dir > 0) ? p.right : p.left;
911 }
912
913 TreeNode f = first;
914 TreeNode x = first = new TreeNode(h, k, v, f, p);
915 if (p == null)
916 root = x;
917 else { // attach and rebalance; adapted from CLR
918 TreeNode xp, xpp;
919 if (f != null)
920 f.prev = x;
921 if (dir <= 0)
922 p.left = x;
923 else
924 p.right = x;
925 x.red = true;
926 while (x != null && (xp = x.parent) != null && xp.red &&
927 (xpp = xp.parent) != null) {
928 TreeNode xppl = xpp.left;
929 if (xp == xppl) {
930 TreeNode y = xpp.right;
931 if (y != null && y.red) {
932 y.red = false;
933 xp.red = false;
934 xpp.red = true;
935 x = xpp;
936 }
937 else {
938 if (x == xp.right) {
939 rotateLeft(x = xp);
940 xpp = (xp = x.parent) == null ? null : xp.parent;
941 }
942 if (xp != null) {
943 xp.red = false;
944 if (xpp != null) {
945 xpp.red = true;
946 rotateRight(xpp);
947 }
948 }
949 }
950 }
951 else {
952 TreeNode y = xppl;
953 if (y != null && y.red) {
954 y.red = false;
955 xp.red = false;
956 xpp.red = true;
957 x = xpp;
958 }
959 else {
960 if (x == xp.left) {
961 rotateRight(x = xp);
962 xpp = (xp = x.parent) == null ? null : xp.parent;
963 }
964 if (xp != null) {
965 xp.red = false;
966 if (xpp != null) {
967 xpp.red = true;
968 rotateLeft(xpp);
969 }
970 }
971 }
972 }
973 }
974 TreeNode r = root;
975 if (r != null && r.red)
976 r.red = false;
977 }
978 return null;
979 }
980
981 /**
982 * Removes the given node, that must be present before this
983 * call. This is messier than typical red-black deletion code
984 * because we cannot swap the contents of an interior node
985 * with a leaf successor that is pinned by "next" pointers
986 * that are accessible independently of lock. So instead we
987 * swap the tree linkages.
988 */
989 final void deleteTreeNode(TreeNode p) {
990 TreeNode next = (TreeNode)p.next; // unlink traversal pointers
991 TreeNode pred = p.prev;
992 if (pred == null)
993 first = next;
994 else
995 pred.next = next;
996 if (next != null)
997 next.prev = pred;
998 TreeNode replacement;
999 TreeNode pl = p.left;
1000 TreeNode pr = p.right;
1001 if (pl != null && pr != null) {
1002 TreeNode s = pr, sl;
1003 while ((sl = s.left) != null) // find successor
1004 s = sl;
1005 boolean c = s.red; s.red = p.red; p.red = c; // swap colors
1006 TreeNode sr = s.right;
1007 TreeNode pp = p.parent;
1008 if (s == pr) { // p was s's direct parent
1009 p.parent = s;
1010 s.right = p;
1011 }
1012 else {
1013 TreeNode sp = s.parent;
1014 if ((p.parent = sp) != null) {
1015 if (s == sp.left)
1016 sp.left = p;
1017 else
1018 sp.right = p;
1019 }
1020 if ((s.right = pr) != null)
1021 pr.parent = s;
1022 }
1023 p.left = null;
1024 if ((p.right = sr) != null)
1025 sr.parent = p;
1026 if ((s.left = pl) != null)
1027 pl.parent = s;
1028 if ((s.parent = pp) == null)
1029 root = s;
1030 else if (p == pp.left)
1031 pp.left = s;
1032 else
1033 pp.right = s;
1034 replacement = sr;
1035 }
1036 else
1037 replacement = (pl != null) ? pl : pr;
1038 TreeNode pp = p.parent;
1039 if (replacement == null) {
1040 if (pp == null) {
1041 root = null;
1042 return;
1043 }
1044 replacement = p;
1045 }
1046 else {
1047 replacement.parent = pp;
1048 if (pp == null)
1049 root = replacement;
1050 else if (p == pp.left)
1051 pp.left = replacement;
1052 else
1053 pp.right = replacement;
1054 p.left = p.right = p.parent = null;
1055 }
1056 if (!p.red) { // rebalance, from CLR
1057 TreeNode x = replacement;
1058 while (x != null) {
1059 TreeNode xp, xpl;
1060 if (x.red || (xp = x.parent) == null) {
1061 x.red = false;
1062 break;
1063 }
1064 if (x == (xpl = xp.left)) {
1065 TreeNode sib = xp.right;
1066 if (sib != null && sib.red) {
1067 sib.red = false;
1068 xp.red = true;
1069 rotateLeft(xp);
1070 sib = (xp = x.parent) == null ? null : xp.right;
1071 }
1072 if (sib == null)
1073 x = xp;
1074 else {
1075 TreeNode sl = sib.left, sr = sib.right;
1076 if ((sr == null || !sr.red) &&
1077 (sl == null || !sl.red)) {
1078 sib.red = true;
1079 x = xp;
1080 }
1081 else {
1082 if (sr == null || !sr.red) {
1083 if (sl != null)
1084 sl.red = false;
1085 sib.red = true;
1086 rotateRight(sib);
1087 sib = (xp = x.parent) == null ?
1088 null : xp.right;
1089 }
1090 if (sib != null) {
1091 sib.red = (xp == null) ? false : xp.red;
1092 if ((sr = sib.right) != null)
1093 sr.red = false;
1094 }
1095 if (xp != null) {
1096 xp.red = false;
1097 rotateLeft(xp);
1098 }
1099 x = root;
1100 }
1101 }
1102 }
1103 else { // symmetric
1104 TreeNode sib = xpl;
1105 if (sib != null && sib.red) {
1106 sib.red = false;
1107 xp.red = true;
1108 rotateRight(xp);
1109 sib = (xp = x.parent) == null ? null : xp.left;
1110 }
1111 if (sib == null)
1112 x = xp;
1113 else {
1114 TreeNode sl = sib.left, sr = sib.right;
1115 if ((sl == null || !sl.red) &&
1116 (sr == null || !sr.red)) {
1117 sib.red = true;
1118 x = xp;
1119 }
1120 else {
1121 if (sl == null || !sl.red) {
1122 if (sr != null)
1123 sr.red = false;
1124 sib.red = true;
1125 rotateLeft(sib);
1126 sib = (xp = x.parent) == null ?
1127 null : xp.left;
1128 }
1129 if (sib != null) {
1130 sib.red = (xp == null) ? false : xp.red;
1131 if ((sl = sib.left) != null)
1132 sl.red = false;
1133 }
1134 if (xp != null) {
1135 xp.red = false;
1136 rotateRight(xp);
1137 }
1138 x = root;
1139 }
1140 }
1141 }
1142 }
1143 }
1144 if (p == replacement && (pp = p.parent) != null) {
1145 if (p == pp.left) // detach pointers
1146 pp.left = null;
1147 else if (p == pp.right)
1148 pp.right = null;
1149 p.parent = null;
1150 }
1151 }
1152 }
1153
1154 /* ---------------- Collision reduction methods -------------- */
1155
1156 /**
1157 * Spreads higher bits to lower, and also forces top bit to 0.
1158 * Because the table uses power-of-two masking, sets of hashes
1159 * that vary only in bits above the current mask will always
1160 * collide. (Among known examples are sets of Float keys holding
1161 * consecutive whole numbers in small tables.) To counter this,
1162 * we apply a transform that spreads the impact of higher bits
1163 * downward. There is a tradeoff between speed, utility, and
1164 * quality of bit-spreading. Because many common sets of hashes
1165 * are already reasonably distributed across bits (so don't benefit
1166 * from spreading), and because we use trees to handle large sets
1167 * of collisions in bins, we don't need excessively high quality.
1168 */
1169 private static final int spread(int h) {
1170 h ^= (h >>> 18) ^ (h >>> 12);
1171 return (h ^ (h >>> 10)) & HASH_BITS;
1172 }
1173
1174 /**
1175 * Replaces a list bin with a tree bin if key is comparable. Call
1176 * only when locked.
1177 */
1178 private final void replaceWithTreeBin(Node[] tab, int index, Object key) {
1179 if (key instanceof Comparable) {
1180 TreeBin t = new TreeBin();
1181 for (Node e = tabAt(tab, index); e != null; e = e.next)
1182 t.putTreeNode(e.hash, e.key, e.val);
1183 setTabAt(tab, index, new Node(MOVED, t, null, null));
1184 }
1185 }
1186
1187 /* ---------------- Internal access and update methods -------------- */
1188
1189 /** Implementation for get and containsKey */
1190 @SuppressWarnings("unchecked") private final V internalGet(Object k) {
1191 int h = spread(k.hashCode());
1192 retry: for (Node[] tab = table; tab != null;) {
1193 Node e; Object ek, ev; int eh; // locals to read fields once
1194 for (e = tabAt(tab, (tab.length - 1) & h); e != null; e = e.next) {
1195 if ((eh = e.hash) < 0) {
1196 if ((ek = e.key) instanceof TreeBin) // search TreeBin
1197 return (V)((TreeBin)ek).getValue(h, k);
1198 else { // restart with new table
1199 tab = (Node[])ek;
1200 continue retry;
1201 }
1202 }
1203 else if (eh == h && (ev = e.val) != null &&
1204 ((ek = e.key) == k || k.equals(ek)))
1205 return (V)ev;
1206 }
1207 break;
1208 }
1209 return null;
1210 }
1211
1212 /**
1213 * Implementation for the four public remove/replace methods:
1214 * Replaces node value with v, conditional upon match of cv if
1215 * non-null. If resulting value is null, delete.
1216 */
1217 @SuppressWarnings("unchecked") private final V internalReplace
1218 (Object k, V v, Object cv) {
1219 int h = spread(k.hashCode());
1220 Object oldVal = null;
1221 for (Node[] tab = table;;) {
1222 Node f; int i, fh; Object fk;
1223 if (tab == null ||
1224 (f = tabAt(tab, i = (tab.length - 1) & h)) == null)
1225 break;
1226 else if ((fh = f.hash) < 0) {
1227 if ((fk = f.key) instanceof TreeBin) {
1228 TreeBin t = (TreeBin)fk;
1229 boolean validated = false;
1230 boolean deleted = false;
1231 t.acquire(0);
1232 try {
1233 if (tabAt(tab, i) == f) {
1234 validated = true;
1235 TreeNode p = t.getTreeNode(h, k, t.root);
1236 if (p != null) {
1237 Object pv = p.val;
1238 if (cv == null || cv == pv || cv.equals(pv)) {
1239 oldVal = pv;
1240 if ((p.val = v) == null) {
1241 deleted = true;
1242 t.deleteTreeNode(p);
1243 }
1244 }
1245 }
1246 }
1247 } finally {
1248 t.release(0);
1249 }
1250 if (validated) {
1251 if (deleted)
1252 addCount(-1L, -1);
1253 break;
1254 }
1255 }
1256 else
1257 tab = (Node[])fk;
1258 }
1259 else if (fh != h && f.next == null) // precheck
1260 break; // rules out possible existence
1261 else {
1262 boolean validated = false;
1263 boolean deleted = false;
1264 synchronized (f) {
1265 if (tabAt(tab, i) == f) {
1266 validated = true;
1267 for (Node e = f, pred = null;;) {
1268 Object ek, ev;
1269 if (e.hash == h &&
1270 ((ev = e.val) != null) &&
1271 ((ek = e.key) == k || k.equals(ek))) {
1272 if (cv == null || cv == ev || cv.equals(ev)) {
1273 oldVal = ev;
1274 if ((e.val = v) == null) {
1275 deleted = true;
1276 Node en = e.next;
1277 if (pred != null)
1278 pred.next = en;
1279 else
1280 setTabAt(tab, i, en);
1281 }
1282 }
1283 break;
1284 }
1285 pred = e;
1286 if ((e = e.next) == null)
1287 break;
1288 }
1289 }
1290 }
1291 if (validated) {
1292 if (deleted)
1293 addCount(-1L, -1);
1294 break;
1295 }
1296 }
1297 }
1298 return (V)oldVal;
1299 }
1300
1301 /*
1302 * Internal versions of insertion methods
1303 * All have the same basic structure as the first (internalPut):
1304 * 1. If table uninitialized, create
1305 * 2. If bin empty, try to CAS new node
1306 * 3. If bin stale, use new table
1307 * 4. if bin converted to TreeBin, validate and relay to TreeBin methods
1308 * 5. Lock and validate; if valid, scan and add or update
1309 *
1310 * The putAll method differs mainly in attempting to pre-allocate
1311 * enough table space, and also more lazily performs count updates
1312 * and checks.
1313 *
1314 * Most of the function-accepting methods can't be factored nicely
1315 * because they require different functional forms, so instead
1316 * sprawl out similar mechanics.
1317 */
1318
1319 /** Implementation for put and putIfAbsent */
1320 @SuppressWarnings("unchecked") private final V internalPut
1321 (K k, V v, boolean onlyIfAbsent) {
1322 if (k == null || v == null) throw new NullPointerException();
1323 int h = spread(k.hashCode());
1324 int len = 0;
1325 for (Node[] tab = table;;) {
1326 int i, fh; Node f; Object fk, fv;
1327 if (tab == null)
1328 tab = initTable();
1329 else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
1330 if (casTabAt(tab, i, null, new Node(h, k, v, null)))
1331 break; // no lock when adding to empty bin
1332 }
1333 else if ((fh = f.hash) < 0) {
1334 if ((fk = f.key) instanceof TreeBin) {
1335 TreeBin t = (TreeBin)fk;
1336 Object oldVal = null;
1337 t.acquire(0);
1338 try {
1339 if (tabAt(tab, i) == f) {
1340 len = 2;
1341 TreeNode p = t.putTreeNode(h, k, v);
1342 if (p != null) {
1343 oldVal = p.val;
1344 if (!onlyIfAbsent)
1345 p.val = v;
1346 }
1347 }
1348 } finally {
1349 t.release(0);
1350 }
1351 if (len != 0) {
1352 if (oldVal != null)
1353 return (V)oldVal;
1354 break;
1355 }
1356 }
1357 else
1358 tab = (Node[])fk;
1359 }
1360 else if (onlyIfAbsent && fh == h && (fv = f.val) != null &&
1361 ((fk = f.key) == k || k.equals(fk))) // peek while nearby
1362 return (V)fv;
1363 else {
1364 Object oldVal = null;
1365 synchronized (f) {
1366 if (tabAt(tab, i) == f) {
1367 len = 1;
1368 for (Node e = f;; ++len) {
1369 Object ek, ev;
1370 if (e.hash == h &&
1371 (ev = e.val) != null &&
1372 ((ek = e.key) == k || k.equals(ek))) {
1373 oldVal = ev;
1374 if (!onlyIfAbsent)
1375 e.val = v;
1376 break;
1377 }
1378 Node last = e;
1379 if ((e = e.next) == null) {
1380 last.next = new Node(h, k, v, null);
1381 if (len >= TREE_THRESHOLD)
1382 replaceWithTreeBin(tab, i, k);
1383 break;
1384 }
1385 }
1386 }
1387 }
1388 if (len != 0) {
1389 if (oldVal != null)
1390 return (V)oldVal;
1391 break;
1392 }
1393 }
1394 }
1395 addCount(1L, len);
1396 return null;
1397 }
1398
1399 /** Implementation for computeIfAbsent */
1400 @SuppressWarnings("unchecked") private final V internalComputeIfAbsent
1401 (K k, Fun<? super K, ?> mf) {
1402 if (k == null || mf == null)
1403 throw new NullPointerException();
1404 int h = spread(k.hashCode());
1405 Object val = null;
1406 int len = 0;
1407 for (Node[] tab = table;;) {
1408 Node f; int i; Object fk;
1409 if (tab == null)
1410 tab = initTable();
1411 else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
1412 Node node = new Node(h, k, null, null);
1413 synchronized (node) {
1414 if (casTabAt(tab, i, null, node)) {
1415 len = 1;
1416 try {
1417 if ((val = mf.apply(k)) != null)
1418 node.val = val;
1419 } finally {
1420 if (val == null)
1421 setTabAt(tab, i, null);
1422 }
1423 }
1424 }
1425 if (len != 0)
1426 break;
1427 }
1428 else if (f.hash < 0) {
1429 if ((fk = f.key) instanceof TreeBin) {
1430 TreeBin t = (TreeBin)fk;
1431 boolean added = false;
1432 t.acquire(0);
1433 try {
1434 if (tabAt(tab, i) == f) {
1435 len = 1;
1436 TreeNode p = t.getTreeNode(h, k, t.root);
1437 if (p != null)
1438 val = p.val;
1439 else if ((val = mf.apply(k)) != null) {
1440 added = true;
1441 len = 2;
1442 t.putTreeNode(h, k, val);
1443 }
1444 }
1445 } finally {
1446 t.release(0);
1447 }
1448 if (len != 0) {
1449 if (!added)
1450 return (V)val;
1451 break;
1452 }
1453 }
1454 else
1455 tab = (Node[])fk;
1456 }
1457 else {
1458 for (Node e = f; e != null; e = e.next) { // prescan
1459 Object ek, ev;
1460 if (e.hash == h && (ev = e.val) != null &&
1461 ((ek = e.key) == k || k.equals(ek)))
1462 return (V)ev;
1463 }
1464 boolean added = false;
1465 synchronized (f) {
1466 if (tabAt(tab, i) == f) {
1467 len = 1;
1468 for (Node e = f;; ++len) {
1469 Object ek, ev;
1470 if (e.hash == h &&
1471 (ev = e.val) != null &&
1472 ((ek = e.key) == k || k.equals(ek))) {
1473 val = ev;
1474 break;
1475 }
1476 Node last = e;
1477 if ((e = e.next) == null) {
1478 if ((val = mf.apply(k)) != null) {
1479 added = true;
1480 last.next = new Node(h, k, val, null);
1481 if (len >= TREE_THRESHOLD)
1482 replaceWithTreeBin(tab, i, k);
1483 }
1484 break;
1485 }
1486 }
1487 }
1488 }
1489 if (len != 0) {
1490 if (!added)
1491 return (V)val;
1492 break;
1493 }
1494 }
1495 }
1496 if (val != null)
1497 addCount(1L, len);
1498 return (V)val;
1499 }
1500
1501 /** Implementation for compute */
1502 @SuppressWarnings("unchecked") private final V internalCompute
1503 (K k, boolean onlyIfPresent,
1504 BiFun<? super K, ? super V, ? extends V> mf) {
1505 if (k == null || mf == null)
1506 throw new NullPointerException();
1507 int h = spread(k.hashCode());
1508 Object val = null;
1509 int delta = 0;
1510 int len = 0;
1511 for (Node[] tab = table;;) {
1512 Node f; int i, fh; Object fk;
1513 if (tab == null)
1514 tab = initTable();
1515 else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
1516 if (onlyIfPresent)
1517 break;
1518 Node node = new Node(h, k, null, null);
1519 synchronized (node) {
1520 if (casTabAt(tab, i, null, node)) {
1521 try {
1522 len = 1;
1523 if ((val = mf.apply(k, null)) != null) {
1524 node.val = val;
1525 delta = 1;
1526 }
1527 } finally {
1528 if (delta == 0)
1529 setTabAt(tab, i, null);
1530 }
1531 }
1532 }
1533 if (len != 0)
1534 break;
1535 }
1536 else if ((fh = f.hash) < 0) {
1537 if ((fk = f.key) instanceof TreeBin) {
1538 TreeBin t = (TreeBin)fk;
1539 t.acquire(0);
1540 try {
1541 if (tabAt(tab, i) == f) {
1542 len = 1;
1543 TreeNode p = t.getTreeNode(h, k, t.root);
1544 if (p == null && onlyIfPresent)
1545 break;
1546 Object pv = (p == null) ? null : p.val;
1547 if ((val = mf.apply(k, (V)pv)) != null) {
1548 if (p != null)
1549 p.val = val;
1550 else {
1551 len = 2;
1552 delta = 1;
1553 t.putTreeNode(h, k, val);
1554 }
1555 }
1556 else if (p != null) {
1557 delta = -1;
1558 t.deleteTreeNode(p);
1559 }
1560 }
1561 } finally {
1562 t.release(0);
1563 }
1564 if (len != 0)
1565 break;
1566 }
1567 else
1568 tab = (Node[])fk;
1569 }
1570 else {
1571 synchronized (f) {
1572 if (tabAt(tab, i) == f) {
1573 len = 1;
1574 for (Node e = f, pred = null;; ++len) {
1575 Object ek, ev;
1576 if (e.hash == h &&
1577 (ev = e.val) != null &&
1578 ((ek = e.key) == k || k.equals(ek))) {
1579 val = mf.apply(k, (V)ev);
1580 if (val != null)
1581 e.val = val;
1582 else {
1583 delta = -1;
1584 Node en = e.next;
1585 if (pred != null)
1586 pred.next = en;
1587 else
1588 setTabAt(tab, i, en);
1589 }
1590 break;
1591 }
1592 pred = e;
1593 if ((e = e.next) == null) {
1594 if (!onlyIfPresent &&
1595 (val = mf.apply(k, null)) != null) {
1596 pred.next = new Node(h, k, val, null);
1597 delta = 1;
1598 if (len >= TREE_THRESHOLD)
1599 replaceWithTreeBin(tab, i, k);
1600 }
1601 break;
1602 }
1603 }
1604 }
1605 }
1606 if (len != 0)
1607 break;
1608 }
1609 }
1610 if (delta != 0)
1611 addCount((long)delta, len);
1612 return (V)val;
1613 }
1614
1615 /** Implementation for merge */
1616 @SuppressWarnings("unchecked") private final V internalMerge
1617 (K k, V v, BiFun<? super V, ? super V, ? extends V> mf) {
1618 if (k == null || v == null || mf == null)
1619 throw new NullPointerException();
1620 int h = spread(k.hashCode());
1621 Object val = null;
1622 int delta = 0;
1623 int len = 0;
1624 for (Node[] tab = table;;) {
1625 int i; Node f; Object fk, fv;
1626 if (tab == null)
1627 tab = initTable();
1628 else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
1629 if (casTabAt(tab, i, null, new Node(h, k, v, null))) {
1630 delta = 1;
1631 val = v;
1632 break;
1633 }
1634 }
1635 else if (f.hash < 0) {
1636 if ((fk = f.key) instanceof TreeBin) {
1637 TreeBin t = (TreeBin)fk;
1638 t.acquire(0);
1639 try {
1640 if (tabAt(tab, i) == f) {
1641 len = 1;
1642 TreeNode p = t.getTreeNode(h, k, t.root);
1643 val = (p == null) ? v : mf.apply((V)p.val, v);
1644 if (val != null) {
1645 if (p != null)
1646 p.val = val;
1647 else {
1648 len = 2;
1649 delta = 1;
1650 t.putTreeNode(h, k, val);
1651 }
1652 }
1653 else if (p != null) {
1654 delta = -1;
1655 t.deleteTreeNode(p);
1656 }
1657 }
1658 } finally {
1659 t.release(0);
1660 }
1661 if (len != 0)
1662 break;
1663 }
1664 else
1665 tab = (Node[])fk;
1666 }
1667 else {
1668 synchronized (f) {
1669 if (tabAt(tab, i) == f) {
1670 len = 1;
1671 for (Node e = f, pred = null;; ++len) {
1672 Object ek, ev;
1673 if (e.hash == h &&
1674 (ev = e.val) != null &&
1675 ((ek = e.key) == k || k.equals(ek))) {
1676 val = mf.apply((V)ev, v);
1677 if (val != null)
1678 e.val = val;
1679 else {
1680 delta = -1;
1681 Node en = e.next;
1682 if (pred != null)
1683 pred.next = en;
1684 else
1685 setTabAt(tab, i, en);
1686 }
1687 break;
1688 }
1689 pred = e;
1690 if ((e = e.next) == null) {
1691 val = v;
1692 pred.next = new Node(h, k, val, null);
1693 delta = 1;
1694 if (len >= TREE_THRESHOLD)
1695 replaceWithTreeBin(tab, i, k);
1696 break;
1697 }
1698 }
1699 }
1700 }
1701 if (len != 0)
1702 break;
1703 }
1704 }
1705 if (delta != 0)
1706 addCount((long)delta, len);
1707 return (V)val;
1708 }
1709
1710 /** Implementation for putAll */
1711 private final void internalPutAll(Map<?, ?> m) {
1712 tryPresize(m.size());
1713 long delta = 0L; // number of uncommitted additions
1714 boolean npe = false; // to throw exception on exit for nulls
1715 try { // to clean up counts on other exceptions
1716 for (Map.Entry<?, ?> entry : m.entrySet()) {
1717 Object k, v;
1718 if (entry == null || (k = entry.getKey()) == null ||
1719 (v = entry.getValue()) == null) {
1720 npe = true;
1721 break;
1722 }
1723 int h = spread(k.hashCode());
1724 for (Node[] tab = table;;) {
1725 int i; Node f; int fh; Object fk;
1726 if (tab == null)
1727 tab = initTable();
1728 else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null){
1729 if (casTabAt(tab, i, null, new Node(h, k, v, null))) {
1730 ++delta;
1731 break;
1732 }
1733 }
1734 else if ((fh = f.hash) < 0) {
1735 if ((fk = f.key) instanceof TreeBin) {
1736 TreeBin t = (TreeBin)fk;
1737 boolean validated = false;
1738 t.acquire(0);
1739 try {
1740 if (tabAt(tab, i) == f) {
1741 validated = true;
1742 TreeNode p = t.getTreeNode(h, k, t.root);
1743 if (p != null)
1744 p.val = v;
1745 else {
1746 t.putTreeNode(h, k, v);
1747 ++delta;
1748 }
1749 }
1750 } finally {
1751 t.release(0);
1752 }
1753 if (validated)
1754 break;
1755 }
1756 else
1757 tab = (Node[])fk;
1758 }
1759 else {
1760 int len = 0;
1761 synchronized (f) {
1762 if (tabAt(tab, i) == f) {
1763 len = 1;
1764 for (Node e = f;; ++len) {
1765 Object ek, ev;
1766 if (e.hash == h &&
1767 (ev = e.val) != null &&
1768 ((ek = e.key) == k || k.equals(ek))) {
1769 e.val = v;
1770 break;
1771 }
1772 Node last = e;
1773 if ((e = e.next) == null) {
1774 ++delta;
1775 last.next = new Node(h, k, v, null);
1776 if (len >= TREE_THRESHOLD)
1777 replaceWithTreeBin(tab, i, k);
1778 break;
1779 }
1780 }
1781 }
1782 }
1783 if (len != 0) {
1784 if (len > 1)
1785 addCount(delta, len);
1786 break;
1787 }
1788 }
1789 }
1790 }
1791 } finally {
1792 if (delta != 0L)
1793 addCount(delta, 2);
1794 }
1795 if (npe)
1796 throw new NullPointerException();
1797 }
1798
1799 /**
1800 * Implementation for clear. Steps through each bin, removing all
1801 * nodes.
1802 */
1803 private final void internalClear() {
1804 long delta = 0L; // negative number of deletions
1805 int i = 0;
1806 Node[] tab = table;
1807 while (tab != null && i < tab.length) {
1808 Node f = tabAt(tab, i);
1809 if (f == null)
1810 ++i;
1811 else if (f.hash < 0) {
1812 Object fk;
1813 if ((fk = f.key) instanceof TreeBin) {
1814 TreeBin t = (TreeBin)fk;
1815 t.acquire(0);
1816 try {
1817 if (tabAt(tab, i) == f) {
1818 for (Node p = t.first; p != null; p = p.next) {
1819 if (p.val != null) { // (currently always true)
1820 p.val = null;
1821 --delta;
1822 }
1823 }
1824 t.first = null;
1825 t.root = null;
1826 ++i;
1827 }
1828 } finally {
1829 t.release(0);
1830 }
1831 }
1832 else
1833 tab = (Node[])fk;
1834 }
1835 else {
1836 synchronized (f) {
1837 if (tabAt(tab, i) == f) {
1838 for (Node e = f; e != null; e = e.next) {
1839 if (e.val != null) { // (currently always true)
1840 e.val = null;
1841 --delta;
1842 }
1843 }
1844 setTabAt(tab, i, null);
1845 ++i;
1846 }
1847 }
1848 }
1849 }
1850 if (delta != 0L)
1851 addCount(delta, -1);
1852 }
1853
1854 /* ---------------- Table Initialization and Resizing -------------- */
1855
1856 /**
1857 * Returns a power of two table size for the given desired capacity.
1858 * See Hackers Delight, sec 3.2
1859 */
1860 private static final int tableSizeFor(int c) {
1861 int n = c - 1;
1862 n |= n >>> 1;
1863 n |= n >>> 2;
1864 n |= n >>> 4;
1865 n |= n >>> 8;
1866 n |= n >>> 16;
1867 return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
1868 }
1869
1870 /**
1871 * Initializes table, using the size recorded in sizeCtl.
1872 */
1873 private final Node[] initTable() {
1874 Node[] tab; int sc;
1875 while ((tab = table) == null) {
1876 if ((sc = sizeCtl) < 0)
1877 Thread.yield(); // lost initialization race; just spin
1878 else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
1879 try {
1880 if ((tab = table) == null) {
1881 int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
1882 tab = table = new Node[n];
1883 sc = n - (n >>> 2);
1884 }
1885 } finally {
1886 sizeCtl = sc;
1887 }
1888 break;
1889 }
1890 }
1891 return tab;
1892 }
1893
1894 /**
1895 * Adds to count, and if table is too small and not already
1896 * resizing, initiates transfer. If already resizing, helps
1897 * perform transfer if work is available. Rechecks occupancy
1898 * after a transfer to see if another resize is already needed
1899 * because resizings are lagging additions.
1900 *
1901 * @param x the count to add
1902 * @param check if <0, don't check resize, if <= 1 only check if uncontended
1903 */
1904 private final void addCount(long x, int check) {
1905 CounterCell[] as; long b, s;
1906 if ((as = counterCells) != null ||
1907 !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) {
1908 CounterHashCode hc; CounterCell a; long v; int m;
1909 boolean uncontended = true;
1910 if ((hc = threadCounterHashCode.get()) == null ||
1911 as == null || (m = as.length - 1) < 0 ||
1912 (a = as[m & hc.code]) == null ||
1913 !(uncontended =
1914 U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) {
1915 fullAddCount(x, hc, uncontended);
1916 return;
1917 }
1918 if (check <= 1)
1919 return;
1920 s = sumCount();
1921 }
1922 if (check >= 0) {
1923 Node[] tab, nt; int sc;
1924 while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
1925 tab.length < MAXIMUM_CAPACITY) {
1926 if (sc < 0) {
1927 if (sc == -1 || transferIndex <= transferOrigin ||
1928 (nt = nextTable) == null)
1929 break;
1930 if (U.compareAndSwapInt(this, SIZECTL, sc, sc - 1))
1931 transfer(tab, nt);
1932 }
1933 else if (U.compareAndSwapInt(this, SIZECTL, sc, -2))
1934 transfer(tab, null);
1935 s = sumCount();
1936 }
1937 }
1938 }
1939
1940 /**
1941 * Tries to presize table to accommodate the given number of elements.
1942 *
1943 * @param size number of elements (doesn't need to be perfectly accurate)
1944 */
1945 private final void tryPresize(int size) {
1946 int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :
1947 tableSizeFor(size + (size >>> 1) + 1);
1948 int sc;
1949 while ((sc = sizeCtl) >= 0) {
1950 Node[] tab = table; int n;
1951 if (tab == null || (n = tab.length) == 0) {
1952 n = (sc > c) ? sc : c;
1953 if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
1954 try {
1955 if (table == tab) {
1956 table = new Node[n];
1957 sc = n - (n >>> 2);
1958 }
1959 } finally {
1960 sizeCtl = sc;
1961 }
1962 }
1963 }
1964 else if (c <= sc || n >= MAXIMUM_CAPACITY)
1965 break;
1966 else if (tab == table &&
1967 U.compareAndSwapInt(this, SIZECTL, sc, -2))
1968 transfer(tab, null);
1969 }
1970 }
1971
1972 /*
1973 * Moves and/or copies the nodes in each bin to new table. See
1974 * above for explanation.
1975 */
1976 private final void transfer(Node[] tab, Node[] nextTab) {
1977 int n = tab.length, stride;
1978 if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)
1979 stride = MIN_TRANSFER_STRIDE; // subdivide range
1980 if (nextTab == null) { // initiating
1981 try {
1982 nextTab = new Node[n << 1];
1983 } catch (Throwable ex) { // try to cope with OOME
1984 sizeCtl = Integer.MAX_VALUE;
1985 return;
1986 }
1987 nextTable = nextTab;
1988 transferOrigin = n;
1989 transferIndex = n;
1990 Node rev = new Node(MOVED, tab, null, null);
1991 for (int k = n; k > 0;) { // progressively reveal ready slots
1992 int nextk = (k > stride) ? k - stride : 0;
1993 for (int m = nextk; m < k; ++m)
1994 nextTab[m] = rev;
1995 for (int m = n + nextk; m < n + k; ++m)
1996 nextTab[m] = rev;
1997 U.putOrderedInt(this, TRANSFERORIGIN, k = nextk);
1998 }
1999 }
2000 int nextn = nextTab.length;
2001 Node fwd = new Node(MOVED, nextTab, null, null);
2002 boolean advance = true;
2003 for (int i = 0, bound = 0;;) {
2004 int nextIndex, nextBound; Node f; Object fk;
2005 while (advance) {
2006 if (--i >= bound)
2007 advance = false;
2008 else if ((nextIndex = transferIndex) <= transferOrigin) {
2009 i = -1;
2010 advance = false;
2011 }
2012 else if (U.compareAndSwapInt
2013 (this, TRANSFERINDEX, nextIndex,
2014 nextBound = (nextIndex > stride ?
2015 nextIndex - stride : 0))) {
2016 bound = nextBound;
2017 i = nextIndex - 1;
2018 advance = false;
2019 }
2020 }
2021 if (i < 0 || i >= n || i + n >= nextn) {
2022 for (int sc;;) {
2023 if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) {
2024 if (sc == -1) {
2025 nextTable = null;
2026 table = nextTab;
2027 sizeCtl = (n << 1) - (n >>> 1);
2028 }
2029 return;
2030 }
2031 }
2032 }
2033 else if ((f = tabAt(tab, i)) == null) {
2034 if (casTabAt(tab, i, null, fwd)) {
2035 setTabAt(nextTab, i, null);
2036 setTabAt(nextTab, i + n, null);
2037 advance = true;
2038 }
2039 }
2040 else if (f.hash >= 0) {
2041 synchronized (f) {
2042 if (tabAt(tab, i) == f) {
2043 int runBit = f.hash & n;
2044 Node lastRun = f, lo = null, hi = null;
2045 for (Node p = f.next; p != null; p = p.next) {
2046 int b = p.hash & n;
2047 if (b != runBit) {
2048 runBit = b;
2049 lastRun = p;
2050 }
2051 }
2052 if (runBit == 0)
2053 lo = lastRun;
2054 else
2055 hi = lastRun;
2056 for (Node p = f; p != lastRun; p = p.next) {
2057 int ph = p.hash;
2058 Object pk = p.key, pv = p.val;
2059 if ((ph & n) == 0)
2060 lo = new Node(ph, pk, pv, lo);
2061 else
2062 hi = new Node(ph, pk, pv, hi);
2063 }
2064 setTabAt(nextTab, i, lo);
2065 setTabAt(nextTab, i + n, hi);
2066 setTabAt(tab, i, fwd);
2067 advance = true;
2068 }
2069 }
2070 }
2071 else if ((fk = f.key) instanceof TreeBin) {
2072 TreeBin t = (TreeBin)fk;
2073 t.acquire(0);
2074 try {
2075 if (tabAt(tab, i) == f) {
2076 TreeBin lt = new TreeBin();
2077 TreeBin ht = new TreeBin();
2078 int lc = 0, hc = 0;
2079 for (Node e = t.first; e != null; e = e.next) {
2080 int h = e.hash;
2081 Object k = e.key, v = e.val;
2082 if ((h & n) == 0) {
2083 ++lc;
2084 lt.putTreeNode(h, k, v);
2085 }
2086 else {
2087 ++hc;
2088 ht.putTreeNode(h, k, v);
2089 }
2090 }
2091 Node ln, hn; // throw away trees if too small
2092 if (lc < TREE_THRESHOLD) {
2093 ln = null;
2094 for (Node p = lt.first; p != null; p = p.next)
2095 ln = new Node(p.hash, p.key, p.val, ln);
2096 }
2097 else
2098 ln = new Node(MOVED, lt, null, null);
2099 setTabAt(nextTab, i, ln);
2100 if (hc < TREE_THRESHOLD) {
2101 hn = null;
2102 for (Node p = ht.first; p != null; p = p.next)
2103 hn = new Node(p.hash, p.key, p.val, hn);
2104 }
2105 else
2106 hn = new Node(MOVED, ht, null, null);
2107 setTabAt(nextTab, i + n, hn);
2108 setTabAt(tab, i, fwd);
2109 advance = true;
2110 }
2111 } finally {
2112 t.release(0);
2113 }
2114 }
2115 else
2116 advance = true; // already processed
2117 }
2118 }
2119
2120 /* ---------------- Counter support -------------- */
2121
2122 final long sumCount() {
2123 CounterCell[] as = counterCells; CounterCell a;
2124 long sum = baseCount;
2125 if (as != null) {
2126 for (int i = 0; i < as.length; ++i) {
2127 if ((a = as[i]) != null)
2128 sum += a.value;
2129 }
2130 }
2131 return sum;
2132 }
2133
2134 // See LongAdder version for explanation
2135 private final void fullAddCount(long x, CounterHashCode hc,
2136 boolean wasUncontended) {
2137 int h;
2138 if (hc == null) {
2139 hc = new CounterHashCode();
2140 int s = counterHashCodeGenerator.addAndGet(SEED_INCREMENT);
2141 h = hc.code = (s == 0) ? 1 : s; // Avoid zero
2142 threadCounterHashCode.set(hc);
2143 }
2144 else
2145 h = hc.code;
2146 boolean collide = false; // True if last slot nonempty
2147 for (;;) {
2148 CounterCell[] as; CounterCell a; int n; long v;
2149 if ((as = counterCells) != null && (n = as.length) > 0) {
2150 if ((a = as[(n - 1) & h]) == null) {
2151 if (counterBusy == 0) { // Try to attach new Cell
2152 CounterCell r = new CounterCell(x); // Optimistic create
2153 if (counterBusy == 0 &&
2154 U.compareAndSwapInt(this, COUNTERBUSY, 0, 1)) {
2155 boolean created = false;
2156 try { // Recheck under lock
2157 CounterCell[] rs; int m, j;
2158 if ((rs = counterCells) != null &&
2159 (m = rs.length) > 0 &&
2160 rs[j = (m - 1) & h] == null) {
2161 rs[j] = r;
2162 created = true;
2163 }
2164 } finally {
2165 counterBusy = 0;
2166 }
2167 if (created)
2168 break;
2169 continue; // Slot is now non-empty
2170 }
2171 }
2172 collide = false;
2173 }
2174 else if (!wasUncontended) // CAS already known to fail
2175 wasUncontended = true; // Continue after rehash
2176 else if (U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))
2177 break;
2178 else if (counterCells != as || n >= NCPU)
2179 collide = false; // At max size or stale
2180 else if (!collide)
2181 collide = true;
2182 else if (counterBusy == 0 &&
2183 U.compareAndSwapInt(this, COUNTERBUSY, 0, 1)) {
2184 try {
2185 if (counterCells == as) {// Expand table unless stale
2186 CounterCell[] rs = new CounterCell[n << 1];
2187 for (int i = 0; i < n; ++i)
2188 rs[i] = as[i];
2189 counterCells = rs;
2190 }
2191 } finally {
2192 counterBusy = 0;
2193 }
2194 collide = false;
2195 continue; // Retry with expanded table
2196 }
2197 h ^= h << 13; // Rehash
2198 h ^= h >>> 17;
2199 h ^= h << 5;
2200 }
2201 else if (counterBusy == 0 && counterCells == as &&
2202 U.compareAndSwapInt(this, COUNTERBUSY, 0, 1)) {
2203 boolean init = false;
2204 try { // Initialize table
2205 if (counterCells == as) {
2206 CounterCell[] rs = new CounterCell[2];
2207 rs[h & 1] = new CounterCell(x);
2208 counterCells = rs;
2209 init = true;
2210 }
2211 } finally {
2212 counterBusy = 0;
2213 }
2214 if (init)
2215 break;
2216 }
2217 else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x))
2218 break; // Fall back on using base
2219 }
2220 hc.code = h; // Record index for next time
2221 }
2222
2223 /* ----------------Table Traversal -------------- */
2224
2225 /**
2226 * Encapsulates traversal for methods such as containsValue; also
2227 * serves as a base class for other iterators and bulk tasks.
2228 *
2229 * At each step, the iterator snapshots the key ("nextKey") and
2230 * value ("nextVal") of a valid node (i.e., one that, at point of
2231 * snapshot, has a non-null user value). Because val fields can
2232 * change (including to null, indicating deletion), field nextVal
2233 * might not be accurate at point of use, but still maintains the
2234 * weak consistency property of holding a value that was once
2235 * valid. To support iterator.remove, the nextKey field is not
2236 * updated (nulled out) when the iterator cannot advance.
2237 *
2238 * Internal traversals directly access these fields, as in:
2239 * {@code while (it.advance() != null) { process(it.nextKey); }}
2240 *
2241 * Exported iterators must track whether the iterator has advanced
2242 * (in hasNext vs next) (by setting/checking/nulling field
2243 * nextVal), and then extract key, value, or key-value pairs as
2244 * return values of next().
2245 *
2246 * The iterator visits once each still-valid node that was
2247 * reachable upon iterator construction. It might miss some that
2248 * were added to a bin after the bin was visited, which is OK wrt
2249 * consistency guarantees. Maintaining this property in the face
2250 * of possible ongoing resizes requires a fair amount of
2251 * bookkeeping state that is difficult to optimize away amidst
2252 * volatile accesses. Even so, traversal maintains reasonable
2253 * throughput.
2254 *
2255 * Normally, iteration proceeds bin-by-bin traversing lists.
2256 * However, if the table has been resized, then all future steps
2257 * must traverse both the bin at the current index as well as at
2258 * (index + baseSize); and so on for further resizings. To
2259 * paranoically cope with potential sharing by users of iterators
2260 * across threads, iteration terminates if a bounds checks fails
2261 * for a table read.
2262 *
2263 * This class extends CountedCompleter to streamline parallel
2264 * iteration in bulk operations. This adds only a few fields of
2265 * space overhead, which is small enough in cases where it is not
2266 * needed to not worry about it. Because CountedCompleter is
2267 * Serializable, but iterators need not be, we need to add warning
2268 * suppressions.
2269 */
2270 @SuppressWarnings("serial") static class Traverser<K,V,R>
2271 extends CountedCompleter<R> {
2272 final ConcurrentHashMapV8<K, V> map;
2273 Node next; // the next entry to use
2274 Object nextKey; // cached key field of next
2275 Object nextVal; // cached val field of next
2276 Node[] tab; // current table; updated if resized
2277 int index; // index of bin to use next
2278 int baseIndex; // current index of initial table
2279 int baseLimit; // index bound for initial table
2280 int baseSize; // initial table size
2281 int batch; // split control
2282
2283 /** Creates iterator for all entries in the table. */
2284 Traverser(ConcurrentHashMapV8<K, V> map) {
2285 this.map = map;
2286 }
2287
2288 /** Creates iterator for split() methods and task constructors */
2289 Traverser(ConcurrentHashMapV8<K,V> map, Traverser<K,V,?> it, int batch) {
2290 super(it);
2291 this.batch = batch;
2292 if ((this.map = map) != null && it != null) { // split parent
2293 Node[] t;
2294 if ((t = it.tab) == null &&
2295 (t = it.tab = map.table) != null)
2296 it.baseLimit = it.baseSize = t.length;
2297 this.tab = t;
2298 this.baseSize = it.baseSize;
2299 int hi = this.baseLimit = it.baseLimit;
2300 it.baseLimit = this.index = this.baseIndex =
2301 (hi + it.baseIndex + 1) >>> 1;
2302 }
2303 }
2304
2305 /**
2306 * Advances next; returns nextVal or null if terminated.
2307 * See above for explanation.
2308 */
2309 final Object advance() {
2310 Node e = next;
2311 Object ev = null;
2312 outer: do {
2313 if (e != null) // advance past used/skipped node
2314 e = e.next;
2315 while (e == null) { // get to next non-null bin
2316 ConcurrentHashMapV8<K, V> m;
2317 Node[] t; int b, i, n; Object ek; // checks must use locals
2318 if ((t = tab) != null)
2319 n = t.length;
2320 else if ((m = map) != null && (t = tab = m.table) != null)
2321 n = baseLimit = baseSize = t.length;
2322 else
2323 break outer;
2324 if ((b = baseIndex) >= baseLimit ||
2325 (i = index) < 0 || i >= n)
2326 break outer;
2327 if ((e = tabAt(t, i)) != null && e.hash < 0) {
2328 if ((ek = e.key) instanceof TreeBin)
2329 e = ((TreeBin)ek).first;
2330 else {
2331 tab = (Node[])ek;
2332 continue; // restarts due to null val
2333 }
2334 } // visit upper slots if present
2335 index = (i += baseSize) < n ? i : (baseIndex = b + 1);
2336 }
2337 nextKey = e.key;
2338 } while ((ev = e.val) == null); // skip deleted or special nodes
2339 next = e;
2340 return nextVal = ev;
2341 }
2342
2343 public final void remove() {
2344 Object k = nextKey;
2345 if (k == null && (advance() == null || (k = nextKey) == null))
2346 throw new IllegalStateException();
2347 map.internalReplace(k, null, null);
2348 }
2349
2350 public final boolean hasNext() {
2351 return nextVal != null || advance() != null;
2352 }
2353
2354 public final boolean hasMoreElements() { return hasNext(); }
2355
2356 public void compute() { } // default no-op CountedCompleter body
2357
2358 /**
2359 * Returns a batch value > 0 if this task should (and must) be
2360 * split, if so, adding to pending count, and in any case
2361 * updating batch value. The initial batch value is approx
2362 * exp2 of the number of times (minus one) to split task by
2363 * two before executing leaf action. This value is faster to
2364 * compute and more convenient to use as a guide to splitting
2365 * than is the depth, since it is used while dividing by two
2366 * anyway.
2367 */
2368 final int preSplit() {
2369 ConcurrentHashMapV8<K, V> m; int b; Node[] t; ForkJoinPool pool;
2370 if ((b = batch) < 0 && (m = map) != null) { // force initialization
2371 if ((t = tab) == null && (t = tab = m.table) != null)
2372 baseLimit = baseSize = t.length;
2373 if (t != null) {
2374 long n = m.sumCount();
2375 int par = ((pool = getPool()) == null) ?
2376 ForkJoinPool.getCommonPoolParallelism() :
2377 pool.getParallelism();
2378 int sp = par << 3; // slack of 8
2379 b = (n <= 0L) ? 0 : (n < (long)sp) ? (int)n : sp;
2380 }
2381 }
2382 b = (b <= 1 || baseIndex == baseLimit) ? 0 : (b >>> 1);
2383 if ((batch = b) > 0)
2384 addToPendingCount(1);
2385 return b;
2386 }
2387
2388 }
2389
2390 /* ---------------- Public operations -------------- */
2391
2392 /**
2393 * Creates a new, empty map with the default initial table size (16).
2394 */
2395 public ConcurrentHashMapV8() {
2396 }
2397
2398 /**
2399 * Creates a new, empty map with an initial table size
2400 * accommodating the specified number of elements without the need
2401 * to dynamically resize.
2402 *
2403 * @param initialCapacity The implementation performs internal
2404 * sizing to accommodate this many elements.
2405 * @throws IllegalArgumentException if the initial capacity of
2406 * elements is negative
2407 */
2408 public ConcurrentHashMapV8(int initialCapacity) {
2409 if (initialCapacity < 0)
2410 throw new IllegalArgumentException();
2411 int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
2412 MAXIMUM_CAPACITY :
2413 tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));
2414 this.sizeCtl = cap;
2415 }
2416
2417 /**
2418 * Creates a new map with the same mappings as the given map.
2419 *
2420 * @param m the map
2421 */
2422 public ConcurrentHashMapV8(Map<? extends K, ? extends V> m) {
2423 this.sizeCtl = DEFAULT_CAPACITY;
2424 internalPutAll(m);
2425 }
2426
2427 /**
2428 * Creates a new, empty map with an initial table size based on
2429 * the given number of elements ({@code initialCapacity}) and
2430 * initial table density ({@code loadFactor}).
2431 *
2432 * @param initialCapacity the initial capacity. The implementation
2433 * performs internal sizing to accommodate this many elements,
2434 * given the specified load factor.
2435 * @param loadFactor the load factor (table density) for
2436 * establishing the initial table size
2437 * @throws IllegalArgumentException if the initial capacity of
2438 * elements is negative or the load factor is nonpositive
2439 *
2440 * @since 1.6
2441 */
2442 public ConcurrentHashMapV8(int initialCapacity, float loadFactor) {
2443 this(initialCapacity, loadFactor, 1);
2444 }
2445
2446 /**
2447 * Creates a new, empty map with an initial table size based on
2448 * the given number of elements ({@code initialCapacity}), table
2449 * density ({@code loadFactor}), and number of concurrently
2450 * updating threads ({@code concurrencyLevel}).
2451 *
2452 * @param initialCapacity the initial capacity. The implementation
2453 * performs internal sizing to accommodate this many elements,
2454 * given the specified load factor.
2455 * @param loadFactor the load factor (table density) for
2456 * establishing the initial table size
2457 * @param concurrencyLevel the estimated number of concurrently
2458 * updating threads. The implementation may use this value as
2459 * a sizing hint.
2460 * @throws IllegalArgumentException if the initial capacity is
2461 * negative or the load factor or concurrencyLevel are
2462 * nonpositive
2463 */
2464 public ConcurrentHashMapV8(int initialCapacity,
2465 float loadFactor, int concurrencyLevel) {
2466 if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0)
2467 throw new IllegalArgumentException();
2468 if (initialCapacity < concurrencyLevel) // Use at least as many bins
2469 initialCapacity = concurrencyLevel; // as estimated threads
2470 long size = (long)(1.0 + (long)initialCapacity / loadFactor);
2471 int cap = (size >= (long)MAXIMUM_CAPACITY) ?
2472 MAXIMUM_CAPACITY : tableSizeFor((int)size);
2473 this.sizeCtl = cap;
2474 }
2475
2476 /**
2477 * Creates a new {@link Set} backed by a ConcurrentHashMapV8
2478 * from the given type to {@code Boolean.TRUE}.
2479 *
2480 * @return the new set
2481 */
2482 public static <K> KeySetView<K,Boolean> newKeySet() {
2483 return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(),
2484 Boolean.TRUE);
2485 }
2486
2487 /**
2488 * Creates a new {@link Set} backed by a ConcurrentHashMapV8
2489 * from the given type to {@code Boolean.TRUE}.
2490 *
2491 * @param initialCapacity The implementation performs internal
2492 * sizing to accommodate this many elements.
2493 * @throws IllegalArgumentException if the initial capacity of
2494 * elements is negative
2495 * @return the new set
2496 */
2497 public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) {
2498 return new KeySetView<K,Boolean>
2499 (new ConcurrentHashMapV8<K,Boolean>(initialCapacity), Boolean.TRUE);
2500 }
2501
2502 /**
2503 * {@inheritDoc}
2504 */
2505 public boolean isEmpty() {
2506 return sumCount() <= 0L; // ignore transient negative values
2507 }
2508
2509 /**
2510 * {@inheritDoc}
2511 */
2512 public int size() {
2513 long n = sumCount();
2514 return ((n < 0L) ? 0 :
2515 (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE :
2516 (int)n);
2517 }
2518
2519 /**
2520 * Returns the number of mappings. This method should be used
2521 * instead of {@link #size} because a ConcurrentHashMapV8 may
2522 * contain more mappings than can be represented as an int. The
2523 * value returned is an estimate; the actual count may differ if
2524 * there are concurrent insertions or removals.
2525 *
2526 * @return the number of mappings
2527 */
2528 public long mappingCount() {
2529 long n = sumCount();
2530 return (n < 0L) ? 0L : n; // ignore transient negative values
2531 }
2532
2533 /**
2534 * Returns the value to which the specified key is mapped,
2535 * or {@code null} if this map contains no mapping for the key.
2536 *
2537 * <p>More formally, if this map contains a mapping from a key
2538 * {@code k} to a value {@code v} such that {@code key.equals(k)},
2539 * then this method returns {@code v}; otherwise it returns
2540 * {@code null}. (There can be at most one such mapping.)
2541 *
2542 * @throws NullPointerException if the specified key is null
2543 */
2544 public V get(Object key) {
2545 return internalGet(key);
2546 }
2547
2548 /**
2549 * Returns the value to which the specified key is mapped,
2550 * or the given defaultValue if this map contains no mapping for the key.
2551 *
2552 * @param key the key
2553 * @param defaultValue the value to return if this map contains
2554 * no mapping for the given key
2555 * @return the mapping for the key, if present; else the defaultValue
2556 * @throws NullPointerException if the specified key is null
2557 */
2558 public V getValueOrDefault(Object key, V defaultValue) {
2559 V v;
2560 return (v = internalGet(key)) == null ? defaultValue : v;
2561 }
2562
2563 /**
2564 * Tests if the specified object is a key in this table.
2565 *
2566 * @param key possible key
2567 * @return {@code true} if and only if the specified object
2568 * is a key in this table, as determined by the
2569 * {@code equals} method; {@code false} otherwise
2570 * @throws NullPointerException if the specified key is null
2571 */
2572 public boolean containsKey(Object key) {
2573 return internalGet(key) != null;
2574 }
2575
2576 /**
2577 * Returns {@code true} if this map maps one or more keys to the
2578 * specified value. Note: This method may require a full traversal
2579 * of the map, and is much slower than method {@code containsKey}.
2580 *
2581 * @param value value whose presence in this map is to be tested
2582 * @return {@code true} if this map maps one or more keys to the
2583 * specified value
2584 * @throws NullPointerException if the specified value is null
2585 */
2586 public boolean containsValue(Object value) {
2587 if (value == null)
2588 throw new NullPointerException();
2589 Object v;
2590 Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
2591 while ((v = it.advance()) != null) {
2592 if (v == value || value.equals(v))
2593 return true;
2594 }
2595 return false;
2596 }
2597
2598 /**
2599 * Legacy method testing if some key maps into the specified value
2600 * in this table. This method is identical in functionality to
2601 * {@link #containsValue}, and exists solely to ensure
2602 * full compatibility with class {@link java.util.Hashtable},
2603 * which supported this method prior to introduction of the
2604 * Java Collections framework.
2605 *
2606 * @param value a value to search for
2607 * @return {@code true} if and only if some key maps to the
2608 * {@code value} argument in this table as
2609 * determined by the {@code equals} method;
2610 * {@code false} otherwise
2611 * @throws NullPointerException if the specified value is null
2612 */
2613 public boolean contains(Object value) {
2614 return containsValue(value);
2615 }
2616
2617 /**
2618 * Maps the specified key to the specified value in this table.
2619 * Neither the key nor the value can be null.
2620 *
2621 * <p>The value can be retrieved by calling the {@code get} method
2622 * with a key that is equal to the original key.
2623 *
2624 * @param key key with which the specified value is to be associated
2625 * @param value value to be associated with the specified key
2626 * @return the previous value associated with {@code key}, or
2627 * {@code null} if there was no mapping for {@code key}
2628 * @throws NullPointerException if the specified key or value is null
2629 */
2630 public V put(K key, V value) {
2631 return internalPut(key, value, false);
2632 }
2633
2634 /**
2635 * {@inheritDoc}
2636 *
2637 * @return the previous value associated with the specified key,
2638 * or {@code null} if there was no mapping for the key
2639 * @throws NullPointerException if the specified key or value is null
2640 */
2641 public V putIfAbsent(K key, V value) {
2642 return internalPut(key, value, true);
2643 }
2644
2645 /**
2646 * Copies all of the mappings from the specified map to this one.
2647 * These mappings replace any mappings that this map had for any of the
2648 * keys currently in the specified map.
2649 *
2650 * @param m mappings to be stored in this map
2651 */
2652 public void putAll(Map<? extends K, ? extends V> m) {
2653 internalPutAll(m);
2654 }
2655
2656 /**
2657 * If the specified key is not already associated with a value,
2658 * computes its value using the given mappingFunction and enters
2659 * it into the map unless null. This is equivalent to
2660 * <pre> {@code
2661 * if (map.containsKey(key))
2662 * return map.get(key);
2663 * value = mappingFunction.apply(key);
2664 * if (value != null)
2665 * map.put(key, value);
2666 * return value;}</pre>
2667 *
2668 * except that the action is performed atomically. If the
2669 * function returns {@code null} no mapping is recorded. If the
2670 * function itself throws an (unchecked) exception, the exception
2671 * is rethrown to its caller, and no mapping is recorded. Some
2672 * attempted update operations on this map by other threads may be
2673 * blocked while computation is in progress, so the computation
2674 * should be short and simple, and must not attempt to update any
2675 * other mappings of this Map. The most appropriate usage is to
2676 * construct a new object serving as an initial mapped value, or
2677 * memoized result, as in:
2678 *
2679 * <pre> {@code
2680 * map.computeIfAbsent(key, new Fun<K, V>() {
2681 * public V map(K k) { return new Value(f(k)); }});}</pre>
2682 *
2683 * @param key key with which the specified value is to be associated
2684 * @param mappingFunction the function to compute a value
2685 * @return the current (existing or computed) value associated with
2686 * the specified key, or null if the computed value is null
2687 * @throws NullPointerException if the specified key or mappingFunction
2688 * is null
2689 * @throws IllegalStateException if the computation detectably
2690 * attempts a recursive update to this map that would
2691 * otherwise never complete
2692 * @throws RuntimeException or Error if the mappingFunction does so,
2693 * in which case the mapping is left unestablished
2694 */
2695 public V computeIfAbsent
2696 (K key, Fun<? super K, ? extends V> mappingFunction) {
2697 return internalComputeIfAbsent(key, mappingFunction);
2698 }
2699
2700 /**
2701 * If the given key is present, computes a new mapping value given a key and
2702 * its current mapped value. This is equivalent to
2703 * <pre> {@code
2704 * if (map.containsKey(key)) {
2705 * value = remappingFunction.apply(key, map.get(key));
2706 * if (value != null)
2707 * map.put(key, value);
2708 * else
2709 * map.remove(key);
2710 * }
2711 * }</pre>
2712 *
2713 * except that the action is performed atomically. If the
2714 * function returns {@code null}, the mapping is removed. If the
2715 * function itself throws an (unchecked) exception, the exception
2716 * is rethrown to its caller, and the current mapping is left
2717 * unchanged. Some attempted update operations on this map by
2718 * other threads may be blocked while computation is in progress,
2719 * so the computation should be short and simple, and must not
2720 * attempt to update any other mappings of this Map. For example,
2721 * to either create or append new messages to a value mapping:
2722 *
2723 * @param key key with which the specified value is to be associated
2724 * @param remappingFunction the function to compute a value
2725 * @return the new value associated with the specified key, or null if none
2726 * @throws NullPointerException if the specified key or remappingFunction
2727 * is null
2728 * @throws IllegalStateException if the computation detectably
2729 * attempts a recursive update to this map that would
2730 * otherwise never complete
2731 * @throws RuntimeException or Error if the remappingFunction does so,
2732 * in which case the mapping is unchanged
2733 */
2734 public V computeIfPresent
2735 (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2736 return internalCompute(key, true, remappingFunction);
2737 }
2738
2739 /**
2740 * Computes a new mapping value given a key and
2741 * its current mapped value (or {@code null} if there is no current
2742 * mapping). This is equivalent to
2743 * <pre> {@code
2744 * value = remappingFunction.apply(key, map.get(key));
2745 * if (value != null)
2746 * map.put(key, value);
2747 * else
2748 * map.remove(key);
2749 * }</pre>
2750 *
2751 * except that the action is performed atomically. If the
2752 * function returns {@code null}, the mapping is removed. If the
2753 * function itself throws an (unchecked) exception, the exception
2754 * is rethrown to its caller, and the current mapping is left
2755 * unchanged. Some attempted update operations on this map by
2756 * other threads may be blocked while computation is in progress,
2757 * so the computation should be short and simple, and must not
2758 * attempt to update any other mappings of this Map. For example,
2759 * to either create or append new messages to a value mapping:
2760 *
2761 * <pre> {@code
2762 * Map<Key, String> map = ...;
2763 * final String msg = ...;
2764 * map.compute(key, new BiFun<Key, String, String>() {
2765 * public String apply(Key k, String v) {
2766 * return (v == null) ? msg : v + msg;});}}</pre>
2767 *
2768 * @param key key with which the specified value is to be associated
2769 * @param remappingFunction the function to compute a value
2770 * @return the new value associated with the specified key, or null if none
2771 * @throws NullPointerException if the specified key or remappingFunction
2772 * is null
2773 * @throws IllegalStateException if the computation detectably
2774 * attempts a recursive update to this map that would
2775 * otherwise never complete
2776 * @throws RuntimeException or Error if the remappingFunction does so,
2777 * in which case the mapping is unchanged
2778 */
2779 public V compute
2780 (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2781 return internalCompute(key, false, remappingFunction);
2782 }
2783
2784 /**
2785 * If the specified key is not already associated
2786 * with a value, associate it with the given value.
2787 * Otherwise, replace the value with the results of
2788 * the given remapping function. This is equivalent to:
2789 * <pre> {@code
2790 * if (!map.containsKey(key))
2791 * map.put(value);
2792 * else {
2793 * newValue = remappingFunction.apply(map.get(key), value);
2794 * if (value != null)
2795 * map.put(key, value);
2796 * else
2797 * map.remove(key);
2798 * }
2799 * }</pre>
2800 * except that the action is performed atomically. If the
2801 * function returns {@code null}, the mapping is removed. If the
2802 * function itself throws an (unchecked) exception, the exception
2803 * is rethrown to its caller, and the current mapping is left
2804 * unchanged. Some attempted update operations on this map by
2805 * other threads may be blocked while computation is in progress,
2806 * so the computation should be short and simple, and must not
2807 * attempt to update any other mappings of this Map.
2808 */
2809 public V merge
2810 (K key, V value,
2811 BiFun<? super V, ? super V, ? extends V> remappingFunction) {
2812 return internalMerge(key, value, remappingFunction);
2813 }
2814
2815 /**
2816 * Removes the key (and its corresponding value) from this map.
2817 * This method does nothing if the key is not in the map.
2818 *
2819 * @param key the key that needs to be removed
2820 * @return the previous value associated with {@code key}, or
2821 * {@code null} if there was no mapping for {@code key}
2822 * @throws NullPointerException if the specified key is null
2823 */
2824 public V remove(Object key) {
2825 return internalReplace(key, null, null);
2826 }
2827
2828 /**
2829 * {@inheritDoc}
2830 *
2831 * @throws NullPointerException if the specified key is null
2832 */
2833 public boolean remove(Object key, Object value) {
2834 return value != null && internalReplace(key, null, value) != null;
2835 }
2836
2837 /**
2838 * {@inheritDoc}
2839 *
2840 * @throws NullPointerException if any of the arguments are null
2841 */
2842 public boolean replace(K key, V oldValue, V newValue) {
2843 if (key == null || oldValue == null || newValue == null)
2844 throw new NullPointerException();
2845 return internalReplace(key, newValue, oldValue) != null;
2846 }
2847
2848 /**
2849 * {@inheritDoc}
2850 *
2851 * @return the previous value associated with the specified key,
2852 * or {@code null} if there was no mapping for the key
2853 * @throws NullPointerException if the specified key or value is null
2854 */
2855 public V replace(K key, V value) {
2856 if (key == null || value == null)
2857 throw new NullPointerException();
2858 return internalReplace(key, value, null);
2859 }
2860
2861 /**
2862 * Removes all of the mappings from this map.
2863 */
2864 public void clear() {
2865 internalClear();
2866 }
2867
2868 /**
2869 * Returns a {@link Set} view of the keys contained in this map.
2870 * The set is backed by the map, so changes to the map are
2871 * reflected in the set, and vice-versa.
2872 *
2873 * @return the set view
2874 */
2875 public KeySetView<K,V> keySet() {
2876 KeySetView<K,V> ks = keySet;
2877 return (ks != null) ? ks : (keySet = new KeySetView<K,V>(this, null));
2878 }
2879
2880 /**
2881 * Returns a {@link Set} view of the keys in this map, using the
2882 * given common mapped value for any additions (i.e., {@link
2883 * Collection#add} and {@link Collection#addAll}). This is of
2884 * course only appropriate if it is acceptable to use the same
2885 * value for all additions from this view.
2886 *
2887 * @param mappedValue the mapped value to use for any
2888 * additions.
2889 * @return the set view
2890 * @throws NullPointerException if the mappedValue is null
2891 */
2892 public KeySetView<K,V> keySet(V mappedValue) {
2893 if (mappedValue == null)
2894 throw new NullPointerException();
2895 return new KeySetView<K,V>(this, mappedValue);
2896 }
2897
2898 /**
2899 * Returns a {@link Collection} view of the values contained in this map.
2900 * The collection is backed by the map, so changes to the map are
2901 * reflected in the collection, and vice-versa.
2902 */
2903 public ValuesView<K,V> values() {
2904 ValuesView<K,V> vs = values;
2905 return (vs != null) ? vs : (values = new ValuesView<K,V>(this));
2906 }
2907
2908 /**
2909 * Returns a {@link Set} view of the mappings contained in this map.
2910 * The set is backed by the map, so changes to the map are
2911 * reflected in the set, and vice-versa. The set supports element
2912 * removal, which removes the corresponding mapping from the map,
2913 * via the {@code Iterator.remove}, {@code Set.remove},
2914 * {@code removeAll}, {@code retainAll}, and {@code clear}
2915 * operations. It does not support the {@code add} or
2916 * {@code addAll} operations.
2917 *
2918 * <p>The view's {@code iterator} is a "weakly consistent" iterator
2919 * that will never throw {@link ConcurrentModificationException},
2920 * and guarantees to traverse elements as they existed upon
2921 * construction of the iterator, and may (but is not guaranteed to)
2922 * reflect any modifications subsequent to construction.
2923 */
2924 public Set<Map.Entry<K,V>> entrySet() {
2925 EntrySetView<K,V> es = entrySet;
2926 return (es != null) ? es : (entrySet = new EntrySetView<K,V>(this));
2927 }
2928
2929 /**
2930 * Returns an enumeration of the keys in this table.
2931 *
2932 * @return an enumeration of the keys in this table
2933 * @see #keySet()
2934 */
2935 public Enumeration<K> keys() {
2936 return new KeyIterator<K,V>(this);
2937 }
2938
2939 /**
2940 * Returns an enumeration of the values in this table.
2941 *
2942 * @return an enumeration of the values in this table
2943 * @see #values()
2944 */
2945 public Enumeration<V> elements() {
2946 return new ValueIterator<K,V>(this);
2947 }
2948
2949 /**
2950 * Returns a partitionable iterator of the keys in this map.
2951 *
2952 * @return a partitionable iterator of the keys in this map
2953 */
2954 public Spliterator<K> keySpliterator() {
2955 return new KeyIterator<K,V>(this);
2956 }
2957
2958 /**
2959 * Returns a partitionable iterator of the values in this map.
2960 *
2961 * @return a partitionable iterator of the values in this map
2962 */
2963 public Spliterator<V> valueSpliterator() {
2964 return new ValueIterator<K,V>(this);
2965 }
2966
2967 /**
2968 * Returns a partitionable iterator of the entries in this map.
2969 *
2970 * @return a partitionable iterator of the entries in this map
2971 */
2972 public Spliterator<Map.Entry<K,V>> entrySpliterator() {
2973 return new EntryIterator<K,V>(this);
2974 }
2975
2976 /**
2977 * Returns the hash code value for this {@link Map}, i.e.,
2978 * the sum of, for each key-value pair in the map,
2979 * {@code key.hashCode() ^ value.hashCode()}.
2980 *
2981 * @return the hash code value for this map
2982 */
2983 public int hashCode() {
2984 int h = 0;
2985 Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
2986 Object v;
2987 while ((v = it.advance()) != null) {
2988 h += it.nextKey.hashCode() ^ v.hashCode();
2989 }
2990 return h;
2991 }
2992
2993 /**
2994 * Returns a string representation of this map. The string
2995 * representation consists of a list of key-value mappings (in no
2996 * particular order) enclosed in braces ("{@code {}}"). Adjacent
2997 * mappings are separated by the characters {@code ", "} (comma
2998 * and space). Each key-value mapping is rendered as the key
2999 * followed by an equals sign ("{@code =}") followed by the
3000 * associated value.
3001 *
3002 * @return a string representation of this map
3003 */
3004 public String toString() {
3005 Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3006 StringBuilder sb = new StringBuilder();
3007 sb.append('{');
3008 Object v;
3009 if ((v = it.advance()) != null) {
3010 for (;;) {
3011 Object k = it.nextKey;
3012 sb.append(k == this ? "(this Map)" : k);
3013 sb.append('=');
3014 sb.append(v == this ? "(this Map)" : v);
3015 if ((v = it.advance()) == null)
3016 break;
3017 sb.append(',').append(' ');
3018 }
3019 }
3020 return sb.append('}').toString();
3021 }
3022
3023 /**
3024 * Compares the specified object with this map for equality.
3025 * Returns {@code true} if the given object is a map with the same
3026 * mappings as this map. This operation may return misleading
3027 * results if either map is concurrently modified during execution
3028 * of this method.
3029 *
3030 * @param o object to be compared for equality with this map
3031 * @return {@code true} if the specified object is equal to this map
3032 */
3033 public boolean equals(Object o) {
3034 if (o != this) {
3035 if (!(o instanceof Map))
3036 return false;
3037 Map<?,?> m = (Map<?,?>) o;
3038 Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3039 Object val;
3040 while ((val = it.advance()) != null) {
3041 Object v = m.get(it.nextKey);
3042 if (v == null || (v != val && !v.equals(val)))
3043 return false;
3044 }
3045 for (Map.Entry<?,?> e : m.entrySet()) {
3046 Object mk, mv, v;
3047 if ((mk = e.getKey()) == null ||
3048 (mv = e.getValue()) == null ||
3049 (v = internalGet(mk)) == null ||
3050 (mv != v && !mv.equals(v)))
3051 return false;
3052 }
3053 }
3054 return true;
3055 }
3056
3057 /* ----------------Iterators -------------- */
3058
3059 @SuppressWarnings("serial") static final class KeyIterator<K,V>
3060 extends Traverser<K,V,Object>
3061 implements Spliterator<K>, Enumeration<K> {
3062 KeyIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3063 KeyIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3064 super(map, it, -1);
3065 }
3066 public KeyIterator<K,V> split() {
3067 if (nextKey != null)
3068 throw new IllegalStateException();
3069 return new KeyIterator<K,V>(map, this);
3070 }
3071 @SuppressWarnings("unchecked") public final K next() {
3072 if (nextVal == null && advance() == null)
3073 throw new NoSuchElementException();
3074 Object k = nextKey;
3075 nextVal = null;
3076 return (K) k;
3077 }
3078
3079 public final K nextElement() { return next(); }
3080 }
3081
3082 @SuppressWarnings("serial") static final class ValueIterator<K,V>
3083 extends Traverser<K,V,Object>
3084 implements Spliterator<V>, Enumeration<V> {
3085 ValueIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3086 ValueIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3087 super(map, it, -1);
3088 }
3089 public ValueIterator<K,V> split() {
3090 if (nextKey != null)
3091 throw new IllegalStateException();
3092 return new ValueIterator<K,V>(map, this);
3093 }
3094
3095 @SuppressWarnings("unchecked") public final V next() {
3096 Object v;
3097 if ((v = nextVal) == null && (v = advance()) == null)
3098 throw new NoSuchElementException();
3099 nextVal = null;
3100 return (V) v;
3101 }
3102
3103 public final V nextElement() { return next(); }
3104 }
3105
3106 @SuppressWarnings("serial") static final class EntryIterator<K,V>
3107 extends Traverser<K,V,Object>
3108 implements Spliterator<Map.Entry<K,V>> {
3109 EntryIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3110 EntryIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3111 super(map, it, -1);
3112 }
3113 public EntryIterator<K,V> split() {
3114 if (nextKey != null)
3115 throw new IllegalStateException();
3116 return new EntryIterator<K,V>(map, this);
3117 }
3118
3119 @SuppressWarnings("unchecked") public final Map.Entry<K,V> next() {
3120 Object v;
3121 if ((v = nextVal) == null && (v = advance()) == null)
3122 throw new NoSuchElementException();
3123 Object k = nextKey;
3124 nextVal = null;
3125 return new MapEntry<K,V>((K)k, (V)v, map);
3126 }
3127 }
3128
3129 /**
3130 * Exported Entry for iterators
3131 */
3132 static final class MapEntry<K,V> implements Map.Entry<K, V> {
3133 final K key; // non-null
3134 V val; // non-null
3135 final ConcurrentHashMapV8<K, V> map;
3136 MapEntry(K key, V val, ConcurrentHashMapV8<K, V> map) {
3137 this.key = key;
3138 this.val = val;
3139 this.map = map;
3140 }
3141 public final K getKey() { return key; }
3142 public final V getValue() { return val; }
3143 public final int hashCode() { return key.hashCode() ^ val.hashCode(); }
3144 public final String toString(){ return key + "=" + val; }
3145
3146 public final boolean equals(Object o) {
3147 Object k, v; Map.Entry<?,?> e;
3148 return ((o instanceof Map.Entry) &&
3149 (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
3150 (v = e.getValue()) != null &&
3151 (k == key || k.equals(key)) &&
3152 (v == val || v.equals(val)));
3153 }
3154
3155 /**
3156 * Sets our entry's value and writes through to the map. The
3157 * value to return is somewhat arbitrary here. Since we do not
3158 * necessarily track asynchronous changes, the most recent
3159 * "previous" value could be different from what we return (or
3160 * could even have been removed in which case the put will
3161 * re-establish). We do not and cannot guarantee more.
3162 */
3163 public final V setValue(V value) {
3164 if (value == null) throw new NullPointerException();
3165 V v = val;
3166 val = value;
3167 map.put(key, value);
3168 return v;
3169 }
3170 }
3171
3172 /**
3173 * Returns exportable snapshot entry for the given key and value
3174 * when write-through can't or shouldn't be used.
3175 */
3176 static <K,V> AbstractMap.SimpleEntry<K,V> entryFor(K k, V v) {
3177 return new AbstractMap.SimpleEntry<K,V>(k, v);
3178 }
3179
3180 /* ---------------- Serialization Support -------------- */
3181
3182 /**
3183 * Stripped-down version of helper class used in previous version,
3184 * declared for the sake of serialization compatibility
3185 */
3186 static class Segment<K,V> implements Serializable {
3187 private static final long serialVersionUID = 2249069246763182397L;
3188 final float loadFactor;
3189 Segment(float lf) { this.loadFactor = lf; }
3190 }
3191
3192 /**
3193 * Saves the state of the {@code ConcurrentHashMapV8} instance to a
3194 * stream (i.e., serializes it).
3195 * @param s the stream
3196 * @serialData
3197 * the key (Object) and value (Object)
3198 * for each key-value mapping, followed by a null pair.
3199 * The key-value mappings are emitted in no particular order.
3200 */
3201 @SuppressWarnings("unchecked") private void writeObject
3202 (java.io.ObjectOutputStream s)
3203 throws java.io.IOException {
3204 if (segments == null) { // for serialization compatibility
3205 segments = (Segment<K,V>[])
3206 new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL];
3207 for (int i = 0; i < segments.length; ++i)
3208 segments[i] = new Segment<K,V>(LOAD_FACTOR);
3209 }
3210 s.defaultWriteObject();
3211 Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3212 Object v;
3213 while ((v = it.advance()) != null) {
3214 s.writeObject(it.nextKey);
3215 s.writeObject(v);
3216 }
3217 s.writeObject(null);
3218 s.writeObject(null);
3219 segments = null; // throw away
3220 }
3221
3222 /**
3223 * Reconstitutes the instance from a stream (that is, deserializes it).
3224 * @param s the stream
3225 */
3226 @SuppressWarnings("unchecked") private void readObject
3227 (java.io.ObjectInputStream s)
3228 throws java.io.IOException, ClassNotFoundException {
3229 s.defaultReadObject();
3230 this.segments = null; // unneeded
3231
3232 // Create all nodes, then place in table once size is known
3233 long size = 0L;
3234 Node p = null;
3235 for (;;) {
3236 K k = (K) s.readObject();
3237 V v = (V) s.readObject();
3238 if (k != null && v != null) {
3239 int h = spread(k.hashCode());
3240 p = new Node(h, k, v, p);
3241 ++size;
3242 }
3243 else
3244 break;
3245 }
3246 if (p != null) {
3247 boolean init = false;
3248 int n;
3249 if (size >= (long)(MAXIMUM_CAPACITY >>> 1))
3250 n = MAXIMUM_CAPACITY;
3251 else {
3252 int sz = (int)size;
3253 n = tableSizeFor(sz + (sz >>> 1) + 1);
3254 }
3255 int sc = sizeCtl;
3256 boolean collide = false;
3257 if (n > sc &&
3258 U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
3259 try {
3260 if (table == null) {
3261 init = true;
3262 Node[] tab = new Node[n];
3263 int mask = n - 1;
3264 while (p != null) {
3265 int j = p.hash & mask;
3266 Node next = p.next;
3267 Node q = p.next = tabAt(tab, j);
3268 setTabAt(tab, j, p);
3269 if (!collide && q != null && q.hash == p.hash)
3270 collide = true;
3271 p = next;
3272 }
3273 table = tab;
3274 addCount(size, -1);
3275 sc = n - (n >>> 2);
3276 }
3277 } finally {
3278 sizeCtl = sc;
3279 }
3280 if (collide) { // rescan and convert to TreeBins
3281 Node[] tab = table;
3282 for (int i = 0; i < tab.length; ++i) {
3283 int c = 0;
3284 for (Node e = tabAt(tab, i); e != null; e = e.next) {
3285 if (++c > TREE_THRESHOLD &&
3286 (e.key instanceof Comparable)) {
3287 replaceWithTreeBin(tab, i, e.key);
3288 break;
3289 }
3290 }
3291 }
3292 }
3293 }
3294 if (!init) { // Can only happen if unsafely published.
3295 while (p != null) {
3296 internalPut((K)p.key, (V)p.val, false);
3297 p = p.next;
3298 }
3299 }
3300 }
3301 }
3302
3303 // -------------------------------------------------------
3304
3305 // Sams
3306 /** Interface describing a void action of one argument */
3307 public interface Action<A> { void apply(A a); }
3308 /** Interface describing a void action of two arguments */
3309 public interface BiAction<A,B> { void apply(A a, B b); }
3310 /** Interface describing a function of one argument */
3311 public interface Fun<A,T> { T apply(A a); }
3312 /** Interface describing a function of two arguments */
3313 public interface BiFun<A,B,T> { T apply(A a, B b); }
3314 /** Interface describing a function of no arguments */
3315 public interface Generator<T> { T apply(); }
3316 /** Interface describing a function mapping its argument to a double */
3317 public interface ObjectToDouble<A> { double apply(A a); }
3318 /** Interface describing a function mapping its argument to a long */
3319 public interface ObjectToLong<A> { long apply(A a); }
3320 /** Interface describing a function mapping its argument to an int */
3321 public interface ObjectToInt<A> {int apply(A a); }
3322 /** Interface describing a function mapping two arguments to a double */
3323 public interface ObjectByObjectToDouble<A,B> { double apply(A a, B b); }
3324 /** Interface describing a function mapping two arguments to a long */
3325 public interface ObjectByObjectToLong<A,B> { long apply(A a, B b); }
3326 /** Interface describing a function mapping two arguments to an int */
3327 public interface ObjectByObjectToInt<A,B> {int apply(A a, B b); }
3328 /** Interface describing a function mapping a double to a double */
3329 public interface DoubleToDouble { double apply(double a); }
3330 /** Interface describing a function mapping a long to a long */
3331 public interface LongToLong { long apply(long a); }
3332 /** Interface describing a function mapping an int to an int */
3333 public interface IntToInt { int apply(int a); }
3334 /** Interface describing a function mapping two doubles to a double */
3335 public interface DoubleByDoubleToDouble { double apply(double a, double b); }
3336 /** Interface describing a function mapping two longs to a long */
3337 public interface LongByLongToLong { long apply(long a, long b); }
3338 /** Interface describing a function mapping two ints to an int */
3339 public interface IntByIntToInt { int apply(int a, int b); }
3340
3341
3342 // -------------------------------------------------------
3343
3344 /**
3345 * Performs the given action for each (key, value).
3346 *
3347 * @param action the action
3348 */
3349 public void forEach(BiAction<K,V> action) {
3350 ForkJoinTasks.forEach
3351 (this, action).invoke();
3352 }
3353
3354 /**
3355 * Performs the given action for each non-null transformation
3356 * of each (key, value).
3357 *
3358 * @param transformer a function returning the transformation
3359 * for an element, or null of there is no transformation (in
3360 * which case the action is not applied).
3361 * @param action the action
3362 */
3363 public <U> void forEach(BiFun<? super K, ? super V, ? extends U> transformer,
3364 Action<U> action) {
3365 ForkJoinTasks.forEach
3366 (this, transformer, action).invoke();
3367 }
3368
3369 /**
3370 * Returns a non-null result from applying the given search
3371 * function on each (key, value), or null if none. Upon
3372 * success, further element processing is suppressed and the
3373 * results of any other parallel invocations of the search
3374 * function are ignored.
3375 *
3376 * @param searchFunction a function returning a non-null
3377 * result on success, else null
3378 * @return a non-null result from applying the given search
3379 * function on each (key, value), or null if none
3380 */
3381 public <U> U search(BiFun<? super K, ? super V, ? extends U> searchFunction) {
3382 return ForkJoinTasks.search
3383 (this, searchFunction).invoke();
3384 }
3385
3386 /**
3387 * Returns the result of accumulating the given transformation
3388 * of all (key, value) pairs using the given reducer to
3389 * combine values, or null if none.
3390 *
3391 * @param transformer a function returning the transformation
3392 * for an element, or null of there is no transformation (in
3393 * which case it is not combined).
3394 * @param reducer a commutative associative combining function
3395 * @return the result of accumulating the given transformation
3396 * of all (key, value) pairs
3397 */
3398 public <U> U reduce(BiFun<? super K, ? super V, ? extends U> transformer,
3399 BiFun<? super U, ? super U, ? extends U> reducer) {
3400 return ForkJoinTasks.reduce
3401 (this, transformer, reducer).invoke();
3402 }
3403
3404 /**
3405 * Returns the result of accumulating the given transformation
3406 * of all (key, value) pairs using the given reducer to
3407 * combine values, and the given basis as an identity value.
3408 *
3409 * @param transformer a function returning the transformation
3410 * for an element
3411 * @param basis the identity (initial default value) for the reduction
3412 * @param reducer a commutative associative combining function
3413 * @return the result of accumulating the given transformation
3414 * of all (key, value) pairs
3415 */
3416 public double reduceToDouble(ObjectByObjectToDouble<? super K, ? super V> transformer,
3417 double basis,
3418 DoubleByDoubleToDouble reducer) {
3419 return ForkJoinTasks.reduceToDouble
3420 (this, transformer, basis, reducer).invoke();
3421 }
3422
3423 /**
3424 * Returns the result of accumulating the given transformation
3425 * of all (key, value) pairs using the given reducer to
3426 * combine values, and the given basis as an identity value.
3427 *
3428 * @param transformer a function returning the transformation
3429 * for an element
3430 * @param basis the identity (initial default value) for the reduction
3431 * @param reducer a commutative associative combining function
3432 * @return the result of accumulating the given transformation
3433 * of all (key, value) pairs
3434 */
3435 public long reduceToLong(ObjectByObjectToLong<? super K, ? super V> transformer,
3436 long basis,
3437 LongByLongToLong reducer) {
3438 return ForkJoinTasks.reduceToLong
3439 (this, transformer, basis, reducer).invoke();
3440 }
3441
3442 /**
3443 * Returns the result of accumulating the given transformation
3444 * of all (key, value) pairs using the given reducer to
3445 * combine values, and the given basis as an identity value.
3446 *
3447 * @param transformer a function returning the transformation
3448 * for an element
3449 * @param basis the identity (initial default value) for the reduction
3450 * @param reducer a commutative associative combining function
3451 * @return the result of accumulating the given transformation
3452 * of all (key, value) pairs
3453 */
3454 public int reduceToInt(ObjectByObjectToInt<? super K, ? super V> transformer,
3455 int basis,
3456 IntByIntToInt reducer) {
3457 return ForkJoinTasks.reduceToInt
3458 (this, transformer, basis, reducer).invoke();
3459 }
3460
3461 /**
3462 * Performs the given action for each key.
3463 *
3464 * @param action the action
3465 */
3466 public void forEachKey(Action<K> action) {
3467 ForkJoinTasks.forEachKey
3468 (this, action).invoke();
3469 }
3470
3471 /**
3472 * Performs the given action for each non-null transformation
3473 * of each key.
3474 *
3475 * @param transformer a function returning the transformation
3476 * for an element, or null of there is no transformation (in
3477 * which case the action is not applied).
3478 * @param action the action
3479 */
3480 public <U> void forEachKey(Fun<? super K, ? extends U> transformer,
3481 Action<U> action) {
3482 ForkJoinTasks.forEachKey
3483 (this, transformer, action).invoke();
3484 }
3485
3486 /**
3487 * Returns a non-null result from applying the given search
3488 * function on each key, or null if none. Upon success,
3489 * further element processing is suppressed and the results of
3490 * any other parallel invocations of the search function are
3491 * ignored.
3492 *
3493 * @param searchFunction a function returning a non-null
3494 * result on success, else null
3495 * @return a non-null result from applying the given search
3496 * function on each key, or null if none
3497 */
3498 public <U> U searchKeys(Fun<? super K, ? extends U> searchFunction) {
3499 return ForkJoinTasks.searchKeys
3500 (this, searchFunction).invoke();
3501 }
3502
3503 /**
3504 * Returns the result of accumulating all keys using the given
3505 * reducer to combine values, or null if none.
3506 *
3507 * @param reducer a commutative associative combining function
3508 * @return the result of accumulating all keys using the given
3509 * reducer to combine values, or null if none
3510 */
3511 public K reduceKeys(BiFun<? super K, ? super K, ? extends K> reducer) {
3512 return ForkJoinTasks.reduceKeys
3513 (this, reducer).invoke();
3514 }
3515
3516 /**
3517 * Returns the result of accumulating the given transformation
3518 * of all keys using the given reducer to combine values, or
3519 * null if none.
3520 *
3521 * @param transformer a function returning the transformation
3522 * for an element, or null of there is no transformation (in
3523 * which case it is not combined).
3524 * @param reducer a commutative associative combining function
3525 * @return the result of accumulating the given transformation
3526 * of all keys
3527 */
3528 public <U> U reduceKeys(Fun<? super K, ? extends U> transformer,
3529 BiFun<? super U, ? super U, ? extends U> reducer) {
3530 return ForkJoinTasks.reduceKeys
3531 (this, transformer, reducer).invoke();
3532 }
3533
3534 /**
3535 * Returns the result of accumulating the given transformation
3536 * of all keys using the given reducer to combine values, and
3537 * the given basis as an identity value.
3538 *
3539 * @param transformer a function returning the transformation
3540 * for an element
3541 * @param basis the identity (initial default value) for the reduction
3542 * @param reducer a commutative associative combining function
3543 * @return the result of accumulating the given transformation
3544 * of all keys
3545 */
3546 public double reduceKeysToDouble(ObjectToDouble<? super K> transformer,
3547 double basis,
3548 DoubleByDoubleToDouble reducer) {
3549 return ForkJoinTasks.reduceKeysToDouble
3550 (this, transformer, basis, reducer).invoke();
3551 }
3552
3553 /**
3554 * Returns the result of accumulating the given transformation
3555 * of all keys using the given reducer to combine values, and
3556 * the given basis as an identity value.
3557 *
3558 * @param transformer a function returning the transformation
3559 * for an element
3560 * @param basis the identity (initial default value) for the reduction
3561 * @param reducer a commutative associative combining function
3562 * @return the result of accumulating the given transformation
3563 * of all keys
3564 */
3565 public long reduceKeysToLong(ObjectToLong<? super K> transformer,
3566 long basis,
3567 LongByLongToLong reducer) {
3568 return ForkJoinTasks.reduceKeysToLong
3569 (this, transformer, basis, reducer).invoke();
3570 }
3571
3572 /**
3573 * Returns the result of accumulating the given transformation
3574 * of all keys using the given reducer to combine values, and
3575 * the given basis as an identity value.
3576 *
3577 * @param transformer a function returning the transformation
3578 * for an element
3579 * @param basis the identity (initial default value) for the reduction
3580 * @param reducer a commutative associative combining function
3581 * @return the result of accumulating the given transformation
3582 * of all keys
3583 */
3584 public int reduceKeysToInt(ObjectToInt<? super K> transformer,
3585 int basis,
3586 IntByIntToInt reducer) {
3587 return ForkJoinTasks.reduceKeysToInt
3588 (this, transformer, basis, reducer).invoke();
3589 }
3590
3591 /**
3592 * Performs the given action for each value.
3593 *
3594 * @param action the action
3595 */
3596 public void forEachValue(Action<V> action) {
3597 ForkJoinTasks.forEachValue
3598 (this, action).invoke();
3599 }
3600
3601 /**
3602 * Performs the given action for each non-null transformation
3603 * of each value.
3604 *
3605 * @param transformer a function returning the transformation
3606 * for an element, or null of there is no transformation (in
3607 * which case the action is not applied).
3608 */
3609 public <U> void forEachValue(Fun<? super V, ? extends U> transformer,
3610 Action<U> action) {
3611 ForkJoinTasks.forEachValue
3612 (this, transformer, action).invoke();
3613 }
3614
3615 /**
3616 * Returns a non-null result from applying the given search
3617 * function on each value, or null if none. Upon success,
3618 * further element processing is suppressed and the results of
3619 * any other parallel invocations of the search function are
3620 * ignored.
3621 *
3622 * @param searchFunction a function returning a non-null
3623 * result on success, else null
3624 * @return a non-null result from applying the given search
3625 * function on each value, or null if none
3626 *
3627 */
3628 public <U> U searchValues(Fun<? super V, ? extends U> searchFunction) {
3629 return ForkJoinTasks.searchValues
3630 (this, searchFunction).invoke();
3631 }
3632
3633 /**
3634 * Returns the result of accumulating all values using the
3635 * given reducer to combine values, or null if none.
3636 *
3637 * @param reducer a commutative associative combining function
3638 * @return the result of accumulating all values
3639 */
3640 public V reduceValues(BiFun<? super V, ? super V, ? extends V> reducer) {
3641 return ForkJoinTasks.reduceValues
3642 (this, reducer).invoke();
3643 }
3644
3645 /**
3646 * Returns the result of accumulating the given transformation
3647 * of all values using the given reducer to combine values, or
3648 * null if none.
3649 *
3650 * @param transformer a function returning the transformation
3651 * for an element, or null of there is no transformation (in
3652 * which case it is not combined).
3653 * @param reducer a commutative associative combining function
3654 * @return the result of accumulating the given transformation
3655 * of all values
3656 */
3657 public <U> U reduceValues(Fun<? super V, ? extends U> transformer,
3658 BiFun<? super U, ? super U, ? extends U> reducer) {
3659 return ForkJoinTasks.reduceValues
3660 (this, transformer, reducer).invoke();
3661 }
3662
3663 /**
3664 * Returns the result of accumulating the given transformation
3665 * of all values using the given reducer to combine values,
3666 * and the given basis as an identity value.
3667 *
3668 * @param transformer a function returning the transformation
3669 * for an element
3670 * @param basis the identity (initial default value) for the reduction
3671 * @param reducer a commutative associative combining function
3672 * @return the result of accumulating the given transformation
3673 * of all values
3674 */
3675 public double reduceValuesToDouble(ObjectToDouble<? super V> transformer,
3676 double basis,
3677 DoubleByDoubleToDouble reducer) {
3678 return ForkJoinTasks.reduceValuesToDouble
3679 (this, transformer, basis, reducer).invoke();
3680 }
3681
3682 /**
3683 * Returns the result of accumulating the given transformation
3684 * of all values using the given reducer to combine values,
3685 * and the given basis as an identity value.
3686 *
3687 * @param transformer a function returning the transformation
3688 * for an element
3689 * @param basis the identity (initial default value) for the reduction
3690 * @param reducer a commutative associative combining function
3691 * @return the result of accumulating the given transformation
3692 * of all values
3693 */
3694 public long reduceValuesToLong(ObjectToLong<? super V> transformer,
3695 long basis,
3696 LongByLongToLong reducer) {
3697 return ForkJoinTasks.reduceValuesToLong
3698 (this, transformer, basis, reducer).invoke();
3699 }
3700
3701 /**
3702 * Returns the result of accumulating the given transformation
3703 * of all values using the given reducer to combine values,
3704 * and the given basis as an identity value.
3705 *
3706 * @param transformer a function returning the transformation
3707 * for an element
3708 * @param basis the identity (initial default value) for the reduction
3709 * @param reducer a commutative associative combining function
3710 * @return the result of accumulating the given transformation
3711 * of all values
3712 */
3713 public int reduceValuesToInt(ObjectToInt<? super V> transformer,
3714 int basis,
3715 IntByIntToInt reducer) {
3716 return ForkJoinTasks.reduceValuesToInt
3717 (this, transformer, basis, reducer).invoke();
3718 }
3719
3720 /**
3721 * Performs the given action for each entry.
3722 *
3723 * @param action the action
3724 */
3725 public void forEachEntry(Action<Map.Entry<K,V>> action) {
3726 ForkJoinTasks.forEachEntry
3727 (this, action).invoke();
3728 }
3729
3730 /**
3731 * Performs the given action for each non-null transformation
3732 * of each entry.
3733 *
3734 * @param transformer a function returning the transformation
3735 * for an element, or null of there is no transformation (in
3736 * which case the action is not applied).
3737 * @param action the action
3738 */
3739 public <U> void forEachEntry(Fun<Map.Entry<K,V>, ? extends U> transformer,
3740 Action<U> action) {
3741 ForkJoinTasks.forEachEntry
3742 (this, transformer, action).invoke();
3743 }
3744
3745 /**
3746 * Returns a non-null result from applying the given search
3747 * function on each entry, or null if none. Upon success,
3748 * further element processing is suppressed and the results of
3749 * any other parallel invocations of the search function are
3750 * ignored.
3751 *
3752 * @param searchFunction a function returning a non-null
3753 * result on success, else null
3754 * @return a non-null result from applying the given search
3755 * function on each entry, or null if none
3756 */
3757 public <U> U searchEntries(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
3758 return ForkJoinTasks.searchEntries
3759 (this, searchFunction).invoke();
3760 }
3761
3762 /**
3763 * Returns the result of accumulating all entries using the
3764 * given reducer to combine values, or null if none.
3765 *
3766 * @param reducer a commutative associative combining function
3767 * @return the result of accumulating all entries
3768 */
3769 public Map.Entry<K,V> reduceEntries(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
3770 return ForkJoinTasks.reduceEntries
3771 (this, reducer).invoke();
3772 }
3773
3774 /**
3775 * Returns the result of accumulating the given transformation
3776 * of all entries using the given reducer to combine values,
3777 * or null if none.
3778 *
3779 * @param transformer a function returning the transformation
3780 * for an element, or null of there is no transformation (in
3781 * which case it is not combined).
3782 * @param reducer a commutative associative combining function
3783 * @return the result of accumulating the given transformation
3784 * of all entries
3785 */
3786 public <U> U reduceEntries(Fun<Map.Entry<K,V>, ? extends U> transformer,
3787 BiFun<? super U, ? super U, ? extends U> reducer) {
3788 return ForkJoinTasks.reduceEntries
3789 (this, transformer, reducer).invoke();
3790 }
3791
3792 /**
3793 * Returns the result of accumulating the given transformation
3794 * of all entries using the given reducer to combine values,
3795 * and the given basis as an identity value.
3796 *
3797 * @param transformer a function returning the transformation
3798 * for an element
3799 * @param basis the identity (initial default value) for the reduction
3800 * @param reducer a commutative associative combining function
3801 * @return the result of accumulating the given transformation
3802 * of all entries
3803 */
3804 public double reduceEntriesToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
3805 double basis,
3806 DoubleByDoubleToDouble reducer) {
3807 return ForkJoinTasks.reduceEntriesToDouble
3808 (this, transformer, basis, reducer).invoke();
3809 }
3810
3811 /**
3812 * Returns the result of accumulating the given transformation
3813 * of all entries using the given reducer to combine values,
3814 * and the given basis as an identity value.
3815 *
3816 * @param transformer a function returning the transformation
3817 * for an element
3818 * @param basis the identity (initial default value) for the reduction
3819 * @param reducer a commutative associative combining function
3820 * @return the result of accumulating the given transformation
3821 * of all entries
3822 */
3823 public long reduceEntriesToLong(ObjectToLong<Map.Entry<K,V>> transformer,
3824 long basis,
3825 LongByLongToLong reducer) {
3826 return ForkJoinTasks.reduceEntriesToLong
3827 (this, transformer, basis, reducer).invoke();
3828 }
3829
3830 /**
3831 * Returns the result of accumulating the given transformation
3832 * of all entries using the given reducer to combine values,
3833 * and the given basis as an identity value.
3834 *
3835 * @param transformer a function returning the transformation
3836 * for an element
3837 * @param basis the identity (initial default value) for the reduction
3838 * @param reducer a commutative associative combining function
3839 * @return the result of accumulating the given transformation
3840 * of all entries
3841 */
3842 public int reduceEntriesToInt(ObjectToInt<Map.Entry<K,V>> transformer,
3843 int basis,
3844 IntByIntToInt reducer) {
3845 return ForkJoinTasks.reduceEntriesToInt
3846 (this, transformer, basis, reducer).invoke();
3847 }
3848
3849 /* ----------------Views -------------- */
3850
3851 /**
3852 * Base class for views.
3853 */
3854 static abstract class CHMView<K, V> {
3855 final ConcurrentHashMapV8<K, V> map;
3856 CHMView(ConcurrentHashMapV8<K, V> map) { this.map = map; }
3857
3858 /**
3859 * Returns the map backing this view.
3860 *
3861 * @return the map backing this view
3862 */
3863 public ConcurrentHashMapV8<K,V> getMap() { return map; }
3864
3865 public final int size() { return map.size(); }
3866 public final boolean isEmpty() { return map.isEmpty(); }
3867 public final void clear() { map.clear(); }
3868
3869 // implementations below rely on concrete classes supplying these
3870 abstract public Iterator<?> iterator();
3871 abstract public boolean contains(Object o);
3872 abstract public boolean remove(Object o);
3873
3874 private static final String oomeMsg = "Required array size too large";
3875
3876 public final Object[] toArray() {
3877 long sz = map.mappingCount();
3878 if (sz > (long)(MAX_ARRAY_SIZE))
3879 throw new OutOfMemoryError(oomeMsg);
3880 int n = (int)sz;
3881 Object[] r = new Object[n];
3882 int i = 0;
3883 Iterator<?> it = iterator();
3884 while (it.hasNext()) {
3885 if (i == n) {
3886 if (n >= MAX_ARRAY_SIZE)
3887 throw new OutOfMemoryError(oomeMsg);
3888 if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3889 n = MAX_ARRAY_SIZE;
3890 else
3891 n += (n >>> 1) + 1;
3892 r = Arrays.copyOf(r, n);
3893 }
3894 r[i++] = it.next();
3895 }
3896 return (i == n) ? r : Arrays.copyOf(r, i);
3897 }
3898
3899 @SuppressWarnings("unchecked") public final <T> T[] toArray(T[] a) {
3900 long sz = map.mappingCount();
3901 if (sz > (long)(MAX_ARRAY_SIZE))
3902 throw new OutOfMemoryError(oomeMsg);
3903 int m = (int)sz;
3904 T[] r = (a.length >= m) ? a :
3905 (T[])java.lang.reflect.Array
3906 .newInstance(a.getClass().getComponentType(), m);
3907 int n = r.length;
3908 int i = 0;
3909 Iterator<?> it = iterator();
3910 while (it.hasNext()) {
3911 if (i == n) {
3912 if (n >= MAX_ARRAY_SIZE)
3913 throw new OutOfMemoryError(oomeMsg);
3914 if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3915 n = MAX_ARRAY_SIZE;
3916 else
3917 n += (n >>> 1) + 1;
3918 r = Arrays.copyOf(r, n);
3919 }
3920 r[i++] = (T)it.next();
3921 }
3922 if (a == r && i < n) {
3923 r[i] = null; // null-terminate
3924 return r;
3925 }
3926 return (i == n) ? r : Arrays.copyOf(r, i);
3927 }
3928
3929 public final int hashCode() {
3930 int h = 0;
3931 for (Iterator<?> it = iterator(); it.hasNext();)
3932 h += it.next().hashCode();
3933 return h;
3934 }
3935
3936 public final String toString() {
3937 StringBuilder sb = new StringBuilder();
3938 sb.append('[');
3939 Iterator<?> it = iterator();
3940 if (it.hasNext()) {
3941 for (;;) {
3942 Object e = it.next();
3943 sb.append(e == this ? "(this Collection)" : e);
3944 if (!it.hasNext())
3945 break;
3946 sb.append(',').append(' ');
3947 }
3948 }
3949 return sb.append(']').toString();
3950 }
3951
3952 public final boolean containsAll(Collection<?> c) {
3953 if (c != this) {
3954 for (Iterator<?> it = c.iterator(); it.hasNext();) {
3955 Object e = it.next();
3956 if (e == null || !contains(e))
3957 return false;
3958 }
3959 }
3960 return true;
3961 }
3962
3963 public final boolean removeAll(Collection<?> c) {
3964 boolean modified = false;
3965 for (Iterator<?> it = iterator(); it.hasNext();) {
3966 if (c.contains(it.next())) {
3967 it.remove();
3968 modified = true;
3969 }
3970 }
3971 return modified;
3972 }
3973
3974 public final boolean retainAll(Collection<?> c) {
3975 boolean modified = false;
3976 for (Iterator<?> it = iterator(); it.hasNext();) {
3977 if (!c.contains(it.next())) {
3978 it.remove();
3979 modified = true;
3980 }
3981 }
3982 return modified;
3983 }
3984
3985 }
3986
3987 /**
3988 * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in
3989 * which additions may optionally be enabled by mapping to a
3990 * common value. This class cannot be directly instantiated. See
3991 * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
3992 * {@link #newKeySet(int)}.
3993 */
3994 public static class KeySetView<K,V> extends CHMView<K,V>
3995 implements Set<K>, java.io.Serializable {
3996 private static final long serialVersionUID = 7249069246763182397L;
3997 private final V value;
3998 KeySetView(ConcurrentHashMapV8<K, V> map, V value) { // non-public
3999 super(map);
4000 this.value = value;
4001 }
4002
4003 /**
4004 * Returns the default mapped value for additions,
4005 * or {@code null} if additions are not supported.
4006 *
4007 * @return the default mapped value for additions, or {@code null}
4008 * if not supported.
4009 */
4010 public V getMappedValue() { return value; }
4011
4012 // implement Set API
4013
4014 public boolean contains(Object o) { return map.containsKey(o); }
4015 public boolean remove(Object o) { return map.remove(o) != null; }
4016
4017 /**
4018 * Returns a "weakly consistent" iterator that will never
4019 * throw {@link ConcurrentModificationException}, and
4020 * guarantees to traverse elements as they existed upon
4021 * construction of the iterator, and may (but is not
4022 * guaranteed to) reflect any modifications subsequent to
4023 * construction.
4024 *
4025 * @return an iterator over the keys of this map
4026 */
4027 public Iterator<K> iterator() { return new KeyIterator<K,V>(map); }
4028 public boolean add(K e) {
4029 V v;
4030 if ((v = value) == null)
4031 throw new UnsupportedOperationException();
4032 if (e == null)
4033 throw new NullPointerException();
4034 return map.internalPut(e, v, true) == null;
4035 }
4036 public boolean addAll(Collection<? extends K> c) {
4037 boolean added = false;
4038 V v;
4039 if ((v = value) == null)
4040 throw new UnsupportedOperationException();
4041 for (K e : c) {
4042 if (e == null)
4043 throw new NullPointerException();
4044 if (map.internalPut(e, v, true) == null)
4045 added = true;
4046 }
4047 return added;
4048 }
4049 public boolean equals(Object o) {
4050 Set<?> c;
4051 return ((o instanceof Set) &&
4052 ((c = (Set<?>)o) == this ||
4053 (containsAll(c) && c.containsAll(this))));
4054 }
4055
4056 /**
4057 * Performs the given action for each key.
4058 *
4059 * @param action the action
4060 */
4061 public void forEach(Action<K> action) {
4062 ForkJoinTasks.forEachKey
4063 (map, action).invoke();
4064 }
4065
4066 /**
4067 * Performs the given action for each non-null transformation
4068 * of each key.
4069 *
4070 * @param transformer a function returning the transformation
4071 * for an element, or null of there is no transformation (in
4072 * which case the action is not applied).
4073 * @param action the action
4074 */
4075 public <U> void forEach(Fun<? super K, ? extends U> transformer,
4076 Action<U> action) {
4077 ForkJoinTasks.forEachKey
4078 (map, transformer, action).invoke();
4079 }
4080
4081 /**
4082 * Returns a non-null result from applying the given search
4083 * function on each key, or null if none. Upon success,
4084 * further element processing is suppressed and the results of
4085 * any other parallel invocations of the search function are
4086 * ignored.
4087 *
4088 * @param searchFunction a function returning a non-null
4089 * result on success, else null
4090 * @return a non-null result from applying the given search
4091 * function on each key, or null if none
4092 */
4093 public <U> U search(Fun<? super K, ? extends U> searchFunction) {
4094 return ForkJoinTasks.searchKeys
4095 (map, searchFunction).invoke();
4096 }
4097
4098 /**
4099 * Returns the result of accumulating all keys using the given
4100 * reducer to combine values, or null if none.
4101 *
4102 * @param reducer a commutative associative combining function
4103 * @return the result of accumulating all keys using the given
4104 * reducer to combine values, or null if none
4105 */
4106 public K reduce(BiFun<? super K, ? super K, ? extends K> reducer) {
4107 return ForkJoinTasks.reduceKeys
4108 (map, reducer).invoke();
4109 }
4110
4111 /**
4112 * Returns the result of accumulating the given transformation
4113 * of all keys using the given reducer to combine values, and
4114 * the given basis as an identity value.
4115 *
4116 * @param transformer a function returning the transformation
4117 * for an element
4118 * @param basis the identity (initial default value) for the reduction
4119 * @param reducer a commutative associative combining function
4120 * @return the result of accumulating the given transformation
4121 * of all keys
4122 */
4123 public double reduceToDouble(ObjectToDouble<? super K> transformer,
4124 double basis,
4125 DoubleByDoubleToDouble reducer) {
4126 return ForkJoinTasks.reduceKeysToDouble
4127 (map, transformer, basis, reducer).invoke();
4128 }
4129
4130 /**
4131 * Returns the result of accumulating the given transformation
4132 * of all keys using the given reducer to combine values, and
4133 * the given basis as an identity value.
4134 *
4135 * @param transformer a function returning the transformation
4136 * for an element
4137 * @param basis the identity (initial default value) for the reduction
4138 * @param reducer a commutative associative combining function
4139 * @return the result of accumulating the given transformation
4140 * of all keys
4141 */
4142 public long reduceToLong(ObjectToLong<? super K> transformer,
4143 long basis,
4144 LongByLongToLong reducer) {
4145 return ForkJoinTasks.reduceKeysToLong
4146 (map, transformer, basis, reducer).invoke();
4147 }
4148
4149 /**
4150 * Returns the result of accumulating the given transformation
4151 * of all keys using the given reducer to combine values, and
4152 * the given basis as an identity value.
4153 *
4154 * @param transformer a function returning the transformation
4155 * for an element
4156 * @param basis the identity (initial default value) for the reduction
4157 * @param reducer a commutative associative combining function
4158 * @return the result of accumulating the given transformation
4159 * of all keys
4160 */
4161 public int reduceToInt(ObjectToInt<? super K> transformer,
4162 int basis,
4163 IntByIntToInt reducer) {
4164 return ForkJoinTasks.reduceKeysToInt
4165 (map, transformer, basis, reducer).invoke();
4166 }
4167
4168 }
4169
4170 /**
4171 * A view of a ConcurrentHashMapV8 as a {@link Collection} of
4172 * values, in which additions are disabled. This class cannot be
4173 * directly instantiated. See {@link #values},
4174 *
4175 * <p>The view's {@code iterator} is a "weakly consistent" iterator
4176 * that will never throw {@link ConcurrentModificationException},
4177 * and guarantees to traverse elements as they existed upon
4178 * construction of the iterator, and may (but is not guaranteed to)
4179 * reflect any modifications subsequent to construction.
4180 */
4181 public static final class ValuesView<K,V> extends CHMView<K,V>
4182 implements Collection<V> {
4183 ValuesView(ConcurrentHashMapV8<K, V> map) { super(map); }
4184 public final boolean contains(Object o) { return map.containsValue(o); }
4185 public final boolean remove(Object o) {
4186 if (o != null) {
4187 Iterator<V> it = new ValueIterator<K,V>(map);
4188 while (it.hasNext()) {
4189 if (o.equals(it.next())) {
4190 it.remove();
4191 return true;
4192 }
4193 }
4194 }
4195 return false;
4196 }
4197
4198 /**
4199 * Returns a "weakly consistent" iterator that will never
4200 * throw {@link ConcurrentModificationException}, and
4201 * guarantees to traverse elements as they existed upon
4202 * construction of the iterator, and may (but is not
4203 * guaranteed to) reflect any modifications subsequent to
4204 * construction.
4205 *
4206 * @return an iterator over the values of this map
4207 */
4208 public final Iterator<V> iterator() {
4209 return new ValueIterator<K,V>(map);
4210 }
4211 public final boolean add(V e) {
4212 throw new UnsupportedOperationException();
4213 }
4214 public final boolean addAll(Collection<? extends V> c) {
4215 throw new UnsupportedOperationException();
4216 }
4217
4218 /**
4219 * Performs the given action for each value.
4220 *
4221 * @param action the action
4222 */
4223 public void forEach(Action<V> action) {
4224 ForkJoinTasks.forEachValue
4225 (map, action).invoke();
4226 }
4227
4228 /**
4229 * Performs the given action for each non-null transformation
4230 * of each value.
4231 *
4232 * @param transformer a function returning the transformation
4233 * for an element, or null of there is no transformation (in
4234 * which case the action is not applied).
4235 */
4236 public <U> void forEach(Fun<? super V, ? extends U> transformer,
4237 Action<U> action) {
4238 ForkJoinTasks.forEachValue
4239 (map, transformer, action).invoke();
4240 }
4241
4242 /**
4243 * Returns a non-null result from applying the given search
4244 * function on each value, or null if none. Upon success,
4245 * further element processing is suppressed and the results of
4246 * any other parallel invocations of the search function are
4247 * ignored.
4248 *
4249 * @param searchFunction a function returning a non-null
4250 * result on success, else null
4251 * @return a non-null result from applying the given search
4252 * function on each value, or null if none
4253 *
4254 */
4255 public <U> U search(Fun<? super V, ? extends U> searchFunction) {
4256 return ForkJoinTasks.searchValues
4257 (map, searchFunction).invoke();
4258 }
4259
4260 /**
4261 * Returns the result of accumulating all values using the
4262 * given reducer to combine values, or null if none.
4263 *
4264 * @param reducer a commutative associative combining function
4265 * @return the result of accumulating all values
4266 */
4267 public V reduce(BiFun<? super V, ? super V, ? extends V> reducer) {
4268 return ForkJoinTasks.reduceValues
4269 (map, reducer).invoke();
4270 }
4271
4272 /**
4273 * Returns the result of accumulating the given transformation
4274 * of all values using the given reducer to combine values, or
4275 * null if none.
4276 *
4277 * @param transformer a function returning the transformation
4278 * for an element, or null of there is no transformation (in
4279 * which case it is not combined).
4280 * @param reducer a commutative associative combining function
4281 * @return the result of accumulating the given transformation
4282 * of all values
4283 */
4284 public <U> U reduce(Fun<? super V, ? extends U> transformer,
4285 BiFun<? super U, ? super U, ? extends U> reducer) {
4286 return ForkJoinTasks.reduceValues
4287 (map, transformer, reducer).invoke();
4288 }
4289
4290 /**
4291 * Returns the result of accumulating the given transformation
4292 * of all values using the given reducer to combine values,
4293 * and the given basis as an identity value.
4294 *
4295 * @param transformer a function returning the transformation
4296 * for an element
4297 * @param basis the identity (initial default value) for the reduction
4298 * @param reducer a commutative associative combining function
4299 * @return the result of accumulating the given transformation
4300 * of all values
4301 */
4302 public double reduceToDouble(ObjectToDouble<? super V> transformer,
4303 double basis,
4304 DoubleByDoubleToDouble reducer) {
4305 return ForkJoinTasks.reduceValuesToDouble
4306 (map, transformer, basis, reducer).invoke();
4307 }
4308
4309 /**
4310 * Returns the result of accumulating the given transformation
4311 * of all values using the given reducer to combine values,
4312 * and the given basis as an identity value.
4313 *
4314 * @param transformer a function returning the transformation
4315 * for an element
4316 * @param basis the identity (initial default value) for the reduction
4317 * @param reducer a commutative associative combining function
4318 * @return the result of accumulating the given transformation
4319 * of all values
4320 */
4321 public long reduceToLong(ObjectToLong<? super V> transformer,
4322 long basis,
4323 LongByLongToLong reducer) {
4324 return ForkJoinTasks.reduceValuesToLong
4325 (map, transformer, basis, reducer).invoke();
4326 }
4327
4328 /**
4329 * Returns the result of accumulating the given transformation
4330 * of all values using the given reducer to combine values,
4331 * and the given basis as an identity value.
4332 *
4333 * @param transformer a function returning the transformation
4334 * for an element
4335 * @param basis the identity (initial default value) for the reduction
4336 * @param reducer a commutative associative combining function
4337 * @return the result of accumulating the given transformation
4338 * of all values
4339 */
4340 public int reduceToInt(ObjectToInt<? super V> transformer,
4341 int basis,
4342 IntByIntToInt reducer) {
4343 return ForkJoinTasks.reduceValuesToInt
4344 (map, transformer, basis, reducer).invoke();
4345 }
4346
4347 }
4348
4349 /**
4350 * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value)
4351 * entries. This class cannot be directly instantiated. See
4352 * {@link #entrySet}.
4353 */
4354 public static final class EntrySetView<K,V> extends CHMView<K,V>
4355 implements Set<Map.Entry<K,V>> {
4356 EntrySetView(ConcurrentHashMapV8<K, V> map) { super(map); }
4357 public final boolean contains(Object o) {
4358 Object k, v, r; Map.Entry<?,?> e;
4359 return ((o instanceof Map.Entry) &&
4360 (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
4361 (r = map.get(k)) != null &&
4362 (v = e.getValue()) != null &&
4363 (v == r || v.equals(r)));
4364 }
4365 public final boolean remove(Object o) {
4366 Object k, v; Map.Entry<?,?> e;
4367 return ((o instanceof Map.Entry) &&
4368 (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
4369 (v = e.getValue()) != null &&
4370 map.remove(k, v));
4371 }
4372
4373 /**
4374 * Returns a "weakly consistent" iterator that will never
4375 * throw {@link ConcurrentModificationException}, and
4376 * guarantees to traverse elements as they existed upon
4377 * construction of the iterator, and may (but is not
4378 * guaranteed to) reflect any modifications subsequent to
4379 * construction.
4380 *
4381 * @return an iterator over the entries of this map
4382 */
4383 public final Iterator<Map.Entry<K,V>> iterator() {
4384 return new EntryIterator<K,V>(map);
4385 }
4386
4387 public final boolean add(Entry<K,V> e) {
4388 K key = e.getKey();
4389 V value = e.getValue();
4390 if (key == null || value == null)
4391 throw new NullPointerException();
4392 return map.internalPut(key, value, false) == null;
4393 }
4394 public final boolean addAll(Collection<? extends Entry<K,V>> c) {
4395 boolean added = false;
4396 for (Entry<K,V> e : c) {
4397 if (add(e))
4398 added = true;
4399 }
4400 return added;
4401 }
4402 public boolean equals(Object o) {
4403 Set<?> c;
4404 return ((o instanceof Set) &&
4405 ((c = (Set<?>)o) == this ||
4406 (containsAll(c) && c.containsAll(this))));
4407 }
4408
4409 /**
4410 * Performs the given action for each entry.
4411 *
4412 * @param action the action
4413 */
4414 public void forEach(Action<Map.Entry<K,V>> action) {
4415 ForkJoinTasks.forEachEntry
4416 (map, action).invoke();
4417 }
4418
4419 /**
4420 * Performs the given action for each non-null transformation
4421 * of each entry.
4422 *
4423 * @param transformer a function returning the transformation
4424 * for an element, or null of there is no transformation (in
4425 * which case the action is not applied).
4426 * @param action the action
4427 */
4428 public <U> void forEach(Fun<Map.Entry<K,V>, ? extends U> transformer,
4429 Action<U> action) {
4430 ForkJoinTasks.forEachEntry
4431 (map, transformer, action).invoke();
4432 }
4433
4434 /**
4435 * Returns a non-null result from applying the given search
4436 * function on each entry, or null if none. Upon success,
4437 * further element processing is suppressed and the results of
4438 * any other parallel invocations of the search function are
4439 * ignored.
4440 *
4441 * @param searchFunction a function returning a non-null
4442 * result on success, else null
4443 * @return a non-null result from applying the given search
4444 * function on each entry, or null if none
4445 */
4446 public <U> U search(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4447 return ForkJoinTasks.searchEntries
4448 (map, searchFunction).invoke();
4449 }
4450
4451 /**
4452 * Returns the result of accumulating all entries using the
4453 * given reducer to combine values, or null if none.
4454 *
4455 * @param reducer a commutative associative combining function
4456 * @return the result of accumulating all entries
4457 */
4458 public Map.Entry<K,V> reduce(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4459 return ForkJoinTasks.reduceEntries
4460 (map, reducer).invoke();
4461 }
4462
4463 /**
4464 * Returns the result of accumulating the given transformation
4465 * of all entries using the given reducer to combine values,
4466 * or null if none.
4467 *
4468 * @param transformer a function returning the transformation
4469 * for an element, or null of there is no transformation (in
4470 * which case it is not combined).
4471 * @param reducer a commutative associative combining function
4472 * @return the result of accumulating the given transformation
4473 * of all entries
4474 */
4475 public <U> U reduce(Fun<Map.Entry<K,V>, ? extends U> transformer,
4476 BiFun<? super U, ? super U, ? extends U> reducer) {
4477 return ForkJoinTasks.reduceEntries
4478 (map, transformer, reducer).invoke();
4479 }
4480
4481 /**
4482 * Returns the result of accumulating the given transformation
4483 * of all entries using the given reducer to combine values,
4484 * and the given basis as an identity value.
4485 *
4486 * @param transformer a function returning the transformation
4487 * for an element
4488 * @param basis the identity (initial default value) for the reduction
4489 * @param reducer a commutative associative combining function
4490 * @return the result of accumulating the given transformation
4491 * of all entries
4492 */
4493 public double reduceToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
4494 double basis,
4495 DoubleByDoubleToDouble reducer) {
4496 return ForkJoinTasks.reduceEntriesToDouble
4497 (map, transformer, basis, reducer).invoke();
4498 }
4499
4500 /**
4501 * Returns the result of accumulating the given transformation
4502 * of all entries using the given reducer to combine values,
4503 * and the given basis as an identity value.
4504 *
4505 * @param transformer a function returning the transformation
4506 * for an element
4507 * @param basis the identity (initial default value) for the reduction
4508 * @param reducer a commutative associative combining function
4509 * @return the result of accumulating the given transformation
4510 * of all entries
4511 */
4512 public long reduceToLong(ObjectToLong<Map.Entry<K,V>> transformer,
4513 long basis,
4514 LongByLongToLong reducer) {
4515 return ForkJoinTasks.reduceEntriesToLong
4516 (map, transformer, basis, reducer).invoke();
4517 }
4518
4519 /**
4520 * Returns the result of accumulating the given transformation
4521 * of all entries using the given reducer to combine values,
4522 * and the given basis as an identity value.
4523 *
4524 * @param transformer a function returning the transformation
4525 * for an element
4526 * @param basis the identity (initial default value) for the reduction
4527 * @param reducer a commutative associative combining function
4528 * @return the result of accumulating the given transformation
4529 * of all entries
4530 */
4531 public int reduceToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4532 int basis,
4533 IntByIntToInt reducer) {
4534 return ForkJoinTasks.reduceEntriesToInt
4535 (map, transformer, basis, reducer).invoke();
4536 }
4537
4538 }
4539
4540 // ---------------------------------------------------------------------
4541
4542 /**
4543 * Predefined tasks for performing bulk parallel operations on
4544 * ConcurrentHashMapV8s. These tasks follow the forms and rules used
4545 * for bulk operations. Each method has the same name, but returns
4546 * a task rather than invoking it. These methods may be useful in
4547 * custom applications such as submitting a task without waiting
4548 * for completion, using a custom pool, or combining with other
4549 * tasks.
4550 */
4551 public static class ForkJoinTasks {
4552 private ForkJoinTasks() {}
4553
4554 /**
4555 * Returns a task that when invoked, performs the given
4556 * action for each (key, value)
4557 *
4558 * @param map the map
4559 * @param action the action
4560 * @return the task
4561 */
4562 public static <K,V> ForkJoinTask<Void> forEach
4563 (ConcurrentHashMapV8<K,V> map,
4564 BiAction<K,V> action) {
4565 if (action == null) throw new NullPointerException();
4566 return new ForEachMappingTask<K,V>(map, null, -1, action);
4567 }
4568
4569 /**
4570 * Returns a task that when invoked, performs the given
4571 * action for each non-null transformation of each (key, value)
4572 *
4573 * @param map the map
4574 * @param transformer a function returning the transformation
4575 * for an element, or null if there is no transformation (in
4576 * which case the action is not applied)
4577 * @param action the action
4578 * @return the task
4579 */
4580 public static <K,V,U> ForkJoinTask<Void> forEach
4581 (ConcurrentHashMapV8<K,V> map,
4582 BiFun<? super K, ? super V, ? extends U> transformer,
4583 Action<U> action) {
4584 if (transformer == null || action == null)
4585 throw new NullPointerException();
4586 return new ForEachTransformedMappingTask<K,V,U>
4587 (map, null, -1, transformer, action);
4588 }
4589
4590 /**
4591 * Returns a task that when invoked, returns a non-null result
4592 * from applying the given search function on each (key,
4593 * value), or null if none. Upon success, further element
4594 * processing is suppressed and the results of any other
4595 * parallel invocations of the search function are ignored.
4596 *
4597 * @param map the map
4598 * @param searchFunction a function returning a non-null
4599 * result on success, else null
4600 * @return the task
4601 */
4602 public static <K,V,U> ForkJoinTask<U> search
4603 (ConcurrentHashMapV8<K,V> map,
4604 BiFun<? super K, ? super V, ? extends U> searchFunction) {
4605 if (searchFunction == null) throw new NullPointerException();
4606 return new SearchMappingsTask<K,V,U>
4607 (map, null, -1, searchFunction,
4608 new AtomicReference<U>());
4609 }
4610
4611 /**
4612 * Returns a task that when invoked, returns the result of
4613 * accumulating the given transformation of all (key, value) pairs
4614 * using the given reducer to combine values, or null if none.
4615 *
4616 * @param map the map
4617 * @param transformer a function returning the transformation
4618 * for an element, or null if there is no transformation (in
4619 * which case it is not combined).
4620 * @param reducer a commutative associative combining function
4621 * @return the task
4622 */
4623 public static <K,V,U> ForkJoinTask<U> reduce
4624 (ConcurrentHashMapV8<K,V> map,
4625 BiFun<? super K, ? super V, ? extends U> transformer,
4626 BiFun<? super U, ? super U, ? extends U> reducer) {
4627 if (transformer == null || reducer == null)
4628 throw new NullPointerException();
4629 return new MapReduceMappingsTask<K,V,U>
4630 (map, null, -1, null, transformer, reducer);
4631 }
4632
4633 /**
4634 * Returns a task that when invoked, returns the result of
4635 * accumulating the given transformation of all (key, value) pairs
4636 * using the given reducer to combine values, and the given
4637 * basis as an identity value.
4638 *
4639 * @param map the map
4640 * @param transformer a function returning the transformation
4641 * for an element
4642 * @param basis the identity (initial default value) for the reduction
4643 * @param reducer a commutative associative combining function
4644 * @return the task
4645 */
4646 public static <K,V> ForkJoinTask<Double> reduceToDouble
4647 (ConcurrentHashMapV8<K,V> map,
4648 ObjectByObjectToDouble<? super K, ? super V> transformer,
4649 double basis,
4650 DoubleByDoubleToDouble reducer) {
4651 if (transformer == null || reducer == null)
4652 throw new NullPointerException();
4653 return new MapReduceMappingsToDoubleTask<K,V>
4654 (map, null, -1, null, transformer, basis, reducer);
4655 }
4656
4657 /**
4658 * Returns a task that when invoked, returns the result of
4659 * accumulating the given transformation of all (key, value) pairs
4660 * using the given reducer to combine values, and the given
4661 * basis as an identity value.
4662 *
4663 * @param map the map
4664 * @param transformer a function returning the transformation
4665 * for an element
4666 * @param basis the identity (initial default value) for the reduction
4667 * @param reducer a commutative associative combining function
4668 * @return the task
4669 */
4670 public static <K,V> ForkJoinTask<Long> reduceToLong
4671 (ConcurrentHashMapV8<K,V> map,
4672 ObjectByObjectToLong<? super K, ? super V> transformer,
4673 long basis,
4674 LongByLongToLong reducer) {
4675 if (transformer == null || reducer == null)
4676 throw new NullPointerException();
4677 return new MapReduceMappingsToLongTask<K,V>
4678 (map, null, -1, null, transformer, basis, reducer);
4679 }
4680
4681 /**
4682 * Returns a task that when invoked, returns the result of
4683 * accumulating the given transformation of all (key, value) pairs
4684 * using the given reducer to combine values, and the given
4685 * basis as an identity value.
4686 *
4687 * @param transformer a function returning the transformation
4688 * for an element
4689 * @param basis the identity (initial default value) for the reduction
4690 * @param reducer a commutative associative combining function
4691 * @return the task
4692 */
4693 public static <K,V> ForkJoinTask<Integer> reduceToInt
4694 (ConcurrentHashMapV8<K,V> map,
4695 ObjectByObjectToInt<? super K, ? super V> transformer,
4696 int basis,
4697 IntByIntToInt reducer) {
4698 if (transformer == null || reducer == null)
4699 throw new NullPointerException();
4700 return new MapReduceMappingsToIntTask<K,V>
4701 (map, null, -1, null, transformer, basis, reducer);
4702 }
4703
4704 /**
4705 * Returns a task that when invoked, performs the given action
4706 * for each key.
4707 *
4708 * @param map the map
4709 * @param action the action
4710 * @return the task
4711 */
4712 public static <K,V> ForkJoinTask<Void> forEachKey
4713 (ConcurrentHashMapV8<K,V> map,
4714 Action<K> action) {
4715 if (action == null) throw new NullPointerException();
4716 return new ForEachKeyTask<K,V>(map, null, -1, action);
4717 }
4718
4719 /**
4720 * Returns a task that when invoked, performs the given action
4721 * for each non-null transformation of each key.
4722 *
4723 * @param map the map
4724 * @param transformer a function returning the transformation
4725 * for an element, or null if there is no transformation (in
4726 * which case the action is not applied)
4727 * @param action the action
4728 * @return the task
4729 */
4730 public static <K,V,U> ForkJoinTask<Void> forEachKey
4731 (ConcurrentHashMapV8<K,V> map,
4732 Fun<? super K, ? extends U> transformer,
4733 Action<U> action) {
4734 if (transformer == null || action == null)
4735 throw new NullPointerException();
4736 return new ForEachTransformedKeyTask<K,V,U>
4737 (map, null, -1, transformer, action);
4738 }
4739
4740 /**
4741 * Returns a task that when invoked, returns a non-null result
4742 * from applying the given search function on each key, or
4743 * null if none. Upon success, further element processing is
4744 * suppressed and the results of any other parallel
4745 * invocations of the search function are ignored.
4746 *
4747 * @param map the map
4748 * @param searchFunction a function returning a non-null
4749 * result on success, else null
4750 * @return the task
4751 */
4752 public static <K,V,U> ForkJoinTask<U> searchKeys
4753 (ConcurrentHashMapV8<K,V> map,
4754 Fun<? super K, ? extends U> searchFunction) {
4755 if (searchFunction == null) throw new NullPointerException();
4756 return new SearchKeysTask<K,V,U>
4757 (map, null, -1, searchFunction,
4758 new AtomicReference<U>());
4759 }
4760
4761 /**
4762 * Returns a task that when invoked, returns the result of
4763 * accumulating all keys using the given reducer to combine
4764 * values, or null if none.
4765 *
4766 * @param map the map
4767 * @param reducer a commutative associative combining function
4768 * @return the task
4769 */
4770 public static <K,V> ForkJoinTask<K> reduceKeys
4771 (ConcurrentHashMapV8<K,V> map,
4772 BiFun<? super K, ? super K, ? extends K> reducer) {
4773 if (reducer == null) throw new NullPointerException();
4774 return new ReduceKeysTask<K,V>
4775 (map, null, -1, null, reducer);
4776 }
4777
4778 /**
4779 * Returns a task that when invoked, returns the result of
4780 * accumulating the given transformation of all keys using the given
4781 * reducer to combine values, or null if none.
4782 *
4783 * @param map the map
4784 * @param transformer a function returning the transformation
4785 * for an element, or null if there is no transformation (in
4786 * which case it is not combined).
4787 * @param reducer a commutative associative combining function
4788 * @return the task
4789 */
4790 public static <K,V,U> ForkJoinTask<U> reduceKeys
4791 (ConcurrentHashMapV8<K,V> map,
4792 Fun<? super K, ? extends U> transformer,
4793 BiFun<? super U, ? super U, ? extends U> reducer) {
4794 if (transformer == null || reducer == null)
4795 throw new NullPointerException();
4796 return new MapReduceKeysTask<K,V,U>
4797 (map, null, -1, null, transformer, reducer);
4798 }
4799
4800 /**
4801 * Returns a task that when invoked, returns the result of
4802 * accumulating the given transformation of all keys using the given
4803 * reducer to combine values, and the given basis as an
4804 * identity value.
4805 *
4806 * @param map the map
4807 * @param transformer a function returning the transformation
4808 * for an element
4809 * @param basis the identity (initial default value) for the reduction
4810 * @param reducer a commutative associative combining function
4811 * @return the task
4812 */
4813 public static <K,V> ForkJoinTask<Double> reduceKeysToDouble
4814 (ConcurrentHashMapV8<K,V> map,
4815 ObjectToDouble<? super K> transformer,
4816 double basis,
4817 DoubleByDoubleToDouble reducer) {
4818 if (transformer == null || reducer == null)
4819 throw new NullPointerException();
4820 return new MapReduceKeysToDoubleTask<K,V>
4821 (map, null, -1, null, transformer, basis, reducer);
4822 }
4823
4824 /**
4825 * Returns a task that when invoked, returns the result of
4826 * accumulating the given transformation of all keys using the given
4827 * reducer to combine values, and the given basis as an
4828 * identity value.
4829 *
4830 * @param map the map
4831 * @param transformer a function returning the transformation
4832 * for an element
4833 * @param basis the identity (initial default value) for the reduction
4834 * @param reducer a commutative associative combining function
4835 * @return the task
4836 */
4837 public static <K,V> ForkJoinTask<Long> reduceKeysToLong
4838 (ConcurrentHashMapV8<K,V> map,
4839 ObjectToLong<? super K> transformer,
4840 long basis,
4841 LongByLongToLong reducer) {
4842 if (transformer == null || reducer == null)
4843 throw new NullPointerException();
4844 return new MapReduceKeysToLongTask<K,V>
4845 (map, null, -1, null, transformer, basis, reducer);
4846 }
4847
4848 /**
4849 * Returns a task that when invoked, returns the result of
4850 * accumulating the given transformation of all keys using the given
4851 * reducer to combine values, and the given basis as an
4852 * identity value.
4853 *
4854 * @param map the map
4855 * @param transformer a function returning the transformation
4856 * for an element
4857 * @param basis the identity (initial default value) for the reduction
4858 * @param reducer a commutative associative combining function
4859 * @return the task
4860 */
4861 public static <K,V> ForkJoinTask<Integer> reduceKeysToInt
4862 (ConcurrentHashMapV8<K,V> map,
4863 ObjectToInt<? super K> transformer,
4864 int basis,
4865 IntByIntToInt reducer) {
4866 if (transformer == null || reducer == null)
4867 throw new NullPointerException();
4868 return new MapReduceKeysToIntTask<K,V>
4869 (map, null, -1, null, transformer, basis, reducer);
4870 }
4871
4872 /**
4873 * Returns a task that when invoked, performs the given action
4874 * for each value.
4875 *
4876 * @param map the map
4877 * @param action the action
4878 */
4879 public static <K,V> ForkJoinTask<Void> forEachValue
4880 (ConcurrentHashMapV8<K,V> map,
4881 Action<V> action) {
4882 if (action == null) throw new NullPointerException();
4883 return new ForEachValueTask<K,V>(map, null, -1, action);
4884 }
4885
4886 /**
4887 * Returns a task that when invoked, performs the given action
4888 * for each non-null transformation of each value.
4889 *
4890 * @param map the map
4891 * @param transformer a function returning the transformation
4892 * for an element, or null if there is no transformation (in
4893 * which case the action is not applied)
4894 * @param action the action
4895 */
4896 public static <K,V,U> ForkJoinTask<Void> forEachValue
4897 (ConcurrentHashMapV8<K,V> map,
4898 Fun<? super V, ? extends U> transformer,
4899 Action<U> action) {
4900 if (transformer == null || action == null)
4901 throw new NullPointerException();
4902 return new ForEachTransformedValueTask<K,V,U>
4903 (map, null, -1, transformer, action);
4904 }
4905
4906 /**
4907 * Returns a task that when invoked, returns a non-null result
4908 * from applying the given search function on each value, or
4909 * null if none. Upon success, further element processing is
4910 * suppressed and the results of any other parallel
4911 * invocations of the search function are ignored.
4912 *
4913 * @param map the map
4914 * @param searchFunction a function returning a non-null
4915 * result on success, else null
4916 * @return the task
4917 */
4918 public static <K,V,U> ForkJoinTask<U> searchValues
4919 (ConcurrentHashMapV8<K,V> map,
4920 Fun<? super V, ? extends U> searchFunction) {
4921 if (searchFunction == null) throw new NullPointerException();
4922 return new SearchValuesTask<K,V,U>
4923 (map, null, -1, searchFunction,
4924 new AtomicReference<U>());
4925 }
4926
4927 /**
4928 * Returns a task that when invoked, returns the result of
4929 * accumulating all values using the given reducer to combine
4930 * values, or null if none.
4931 *
4932 * @param map the map
4933 * @param reducer a commutative associative combining function
4934 * @return the task
4935 */
4936 public static <K,V> ForkJoinTask<V> reduceValues
4937 (ConcurrentHashMapV8<K,V> map,
4938 BiFun<? super V, ? super V, ? extends V> reducer) {
4939 if (reducer == null) throw new NullPointerException();
4940 return new ReduceValuesTask<K,V>
4941 (map, null, -1, null, reducer);
4942 }
4943
4944 /**
4945 * Returns a task that when invoked, returns the result of
4946 * accumulating the given transformation of all values using the
4947 * given reducer to combine values, or null if none.
4948 *
4949 * @param map the map
4950 * @param transformer a function returning the transformation
4951 * for an element, or null if there is no transformation (in
4952 * which case it is not combined).
4953 * @param reducer a commutative associative combining function
4954 * @return the task
4955 */
4956 public static <K,V,U> ForkJoinTask<U> reduceValues
4957 (ConcurrentHashMapV8<K,V> map,
4958 Fun<? super V, ? extends U> transformer,
4959 BiFun<? super U, ? super U, ? extends U> reducer) {
4960 if (transformer == null || reducer == null)
4961 throw new NullPointerException();
4962 return new MapReduceValuesTask<K,V,U>
4963 (map, null, -1, null, transformer, reducer);
4964 }
4965
4966 /**
4967 * Returns a task that when invoked, returns the result of
4968 * accumulating the given transformation of all values using the
4969 * given reducer to combine values, and the given basis as an
4970 * identity value.
4971 *
4972 * @param map the map
4973 * @param transformer a function returning the transformation
4974 * for an element
4975 * @param basis the identity (initial default value) for the reduction
4976 * @param reducer a commutative associative combining function
4977 * @return the task
4978 */
4979 public static <K,V> ForkJoinTask<Double> reduceValuesToDouble
4980 (ConcurrentHashMapV8<K,V> map,
4981 ObjectToDouble<? super V> transformer,
4982 double basis,
4983 DoubleByDoubleToDouble reducer) {
4984 if (transformer == null || reducer == null)
4985 throw new NullPointerException();
4986 return new MapReduceValuesToDoubleTask<K,V>
4987 (map, null, -1, null, transformer, basis, reducer);
4988 }
4989
4990 /**
4991 * Returns a task that when invoked, returns the result of
4992 * accumulating the given transformation of all values using the
4993 * given reducer to combine values, and the given basis as an
4994 * identity value.
4995 *
4996 * @param map the map
4997 * @param transformer a function returning the transformation
4998 * for an element
4999 * @param basis the identity (initial default value) for the reduction
5000 * @param reducer a commutative associative combining function
5001 * @return the task
5002 */
5003 public static <K,V> ForkJoinTask<Long> reduceValuesToLong
5004 (ConcurrentHashMapV8<K,V> map,
5005 ObjectToLong<? super V> transformer,
5006 long basis,
5007 LongByLongToLong reducer) {
5008 if (transformer == null || reducer == null)
5009 throw new NullPointerException();
5010 return new MapReduceValuesToLongTask<K,V>
5011 (map, null, -1, null, transformer, basis, reducer);
5012 }
5013
5014 /**
5015 * Returns a task that when invoked, returns the result of
5016 * accumulating the given transformation of all values using the
5017 * given reducer to combine values, and the given basis as an
5018 * identity value.
5019 *
5020 * @param map the map
5021 * @param transformer a function returning the transformation
5022 * for an element
5023 * @param basis the identity (initial default value) for the reduction
5024 * @param reducer a commutative associative combining function
5025 * @return the task
5026 */
5027 public static <K,V> ForkJoinTask<Integer> reduceValuesToInt
5028 (ConcurrentHashMapV8<K,V> map,
5029 ObjectToInt<? super V> transformer,
5030 int basis,
5031 IntByIntToInt reducer) {
5032 if (transformer == null || reducer == null)
5033 throw new NullPointerException();
5034 return new MapReduceValuesToIntTask<K,V>
5035 (map, null, -1, null, transformer, basis, reducer);
5036 }
5037
5038 /**
5039 * Returns a task that when invoked, perform the given action
5040 * for each entry.
5041 *
5042 * @param map the map
5043 * @param action the action
5044 */
5045 public static <K,V> ForkJoinTask<Void> forEachEntry
5046 (ConcurrentHashMapV8<K,V> map,
5047 Action<Map.Entry<K,V>> action) {
5048 if (action == null) throw new NullPointerException();
5049 return new ForEachEntryTask<K,V>(map, null, -1, action);
5050 }
5051
5052 /**
5053 * Returns a task that when invoked, perform the given action
5054 * for each non-null transformation of each entry.
5055 *
5056 * @param map the map
5057 * @param transformer a function returning the transformation
5058 * for an element, or null if there is no transformation (in
5059 * which case the action is not applied)
5060 * @param action the action
5061 */
5062 public static <K,V,U> ForkJoinTask<Void> forEachEntry
5063 (ConcurrentHashMapV8<K,V> map,
5064 Fun<Map.Entry<K,V>, ? extends U> transformer,
5065 Action<U> action) {
5066 if (transformer == null || action == null)
5067 throw new NullPointerException();
5068 return new ForEachTransformedEntryTask<K,V,U>
5069 (map, null, -1, transformer, action);
5070 }
5071
5072 /**
5073 * Returns a task that when invoked, returns a non-null result
5074 * from applying the given search function on each entry, or
5075 * null if none. Upon success, further element processing is
5076 * suppressed and the results of any other parallel
5077 * invocations of the search function are ignored.
5078 *
5079 * @param map the map
5080 * @param searchFunction a function returning a non-null
5081 * result on success, else null
5082 * @return the task
5083 */
5084 public static <K,V,U> ForkJoinTask<U> searchEntries
5085 (ConcurrentHashMapV8<K,V> map,
5086 Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
5087 if (searchFunction == null) throw new NullPointerException();
5088 return new SearchEntriesTask<K,V,U>
5089 (map, null, -1, searchFunction,
5090 new AtomicReference<U>());
5091 }
5092
5093 /**
5094 * Returns a task that when invoked, returns the result of
5095 * accumulating all entries using the given reducer to combine
5096 * values, or null if none.
5097 *
5098 * @param map the map
5099 * @param reducer a commutative associative combining function
5100 * @return the task
5101 */
5102 public static <K,V> ForkJoinTask<Map.Entry<K,V>> reduceEntries
5103 (ConcurrentHashMapV8<K,V> map,
5104 BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5105 if (reducer == null) throw new NullPointerException();
5106 return new ReduceEntriesTask<K,V>
5107 (map, null, -1, null, reducer);
5108 }
5109
5110 /**
5111 * Returns a task that when invoked, returns the result of
5112 * accumulating the given transformation of all entries using the
5113 * given reducer to combine values, or null if none.
5114 *
5115 * @param map the map
5116 * @param transformer a function returning the transformation
5117 * for an element, or null if there is no transformation (in
5118 * which case it is not combined).
5119 * @param reducer a commutative associative combining function
5120 * @return the task
5121 */
5122 public static <K,V,U> ForkJoinTask<U> reduceEntries
5123 (ConcurrentHashMapV8<K,V> map,
5124 Fun<Map.Entry<K,V>, ? extends U> transformer,
5125 BiFun<? super U, ? super U, ? extends U> reducer) {
5126 if (transformer == null || reducer == null)
5127 throw new NullPointerException();
5128 return new MapReduceEntriesTask<K,V,U>
5129 (map, null, -1, null, transformer, reducer);
5130 }
5131
5132 /**
5133 * Returns a task that when invoked, returns the result of
5134 * accumulating the given transformation of all entries using the
5135 * given reducer to combine values, and the given basis as an
5136 * identity value.
5137 *
5138 * @param map the map
5139 * @param transformer a function returning the transformation
5140 * for an element
5141 * @param basis the identity (initial default value) for the reduction
5142 * @param reducer a commutative associative combining function
5143 * @return the task
5144 */
5145 public static <K,V> ForkJoinTask<Double> reduceEntriesToDouble
5146 (ConcurrentHashMapV8<K,V> map,
5147 ObjectToDouble<Map.Entry<K,V>> transformer,
5148 double basis,
5149 DoubleByDoubleToDouble reducer) {
5150 if (transformer == null || reducer == null)
5151 throw new NullPointerException();
5152 return new MapReduceEntriesToDoubleTask<K,V>
5153 (map, null, -1, null, transformer, basis, reducer);
5154 }
5155
5156 /**
5157 * Returns a task that when invoked, returns the result of
5158 * accumulating the given transformation of all entries using the
5159 * given reducer to combine values, and the given basis as an
5160 * identity value.
5161 *
5162 * @param map the map
5163 * @param transformer a function returning the transformation
5164 * for an element
5165 * @param basis the identity (initial default value) for the reduction
5166 * @param reducer a commutative associative combining function
5167 * @return the task
5168 */
5169 public static <K,V> ForkJoinTask<Long> reduceEntriesToLong
5170 (ConcurrentHashMapV8<K,V> map,
5171 ObjectToLong<Map.Entry<K,V>> transformer,
5172 long basis,
5173 LongByLongToLong reducer) {
5174 if (transformer == null || reducer == null)
5175 throw new NullPointerException();
5176 return new MapReduceEntriesToLongTask<K,V>
5177 (map, null, -1, null, transformer, basis, reducer);
5178 }
5179
5180 /**
5181 * Returns a task that when invoked, returns the result of
5182 * accumulating the given transformation of all entries using the
5183 * given reducer to combine values, and the given basis as an
5184 * identity value.
5185 *
5186 * @param map the map
5187 * @param transformer a function returning the transformation
5188 * for an element
5189 * @param basis the identity (initial default value) for the reduction
5190 * @param reducer a commutative associative combining function
5191 * @return the task
5192 */
5193 public static <K,V> ForkJoinTask<Integer> reduceEntriesToInt
5194 (ConcurrentHashMapV8<K,V> map,
5195 ObjectToInt<Map.Entry<K,V>> transformer,
5196 int basis,
5197 IntByIntToInt reducer) {
5198 if (transformer == null || reducer == null)
5199 throw new NullPointerException();
5200 return new MapReduceEntriesToIntTask<K,V>
5201 (map, null, -1, null, transformer, basis, reducer);
5202 }
5203 }
5204
5205 // -------------------------------------------------------
5206
5207 /*
5208 * Task classes. Coded in a regular but ugly format/style to
5209 * simplify checks that each variant differs in the right way from
5210 * others. The null screenings exist because compilers cannot tell
5211 * that we've already null-checked task arguments, so we force
5212 * simplest hoisted bypass to help avoid convoluted traps.
5213 */
5214
5215 @SuppressWarnings("serial") static final class ForEachKeyTask<K,V>
5216 extends Traverser<K,V,Void> {
5217 final Action<K> action;
5218 ForEachKeyTask
5219 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5220 Action<K> action) {
5221 super(m, p, b);
5222 this.action = action;
5223 }
5224 @SuppressWarnings("unchecked") public final void compute() {
5225 final Action<K> action;
5226 if ((action = this.action) != null) {
5227 for (int b; (b = preSplit()) > 0;)
5228 new ForEachKeyTask<K,V>(map, this, b, action).fork();
5229 while (advance() != null)
5230 action.apply((K)nextKey);
5231 propagateCompletion();
5232 }
5233 }
5234 }
5235
5236 @SuppressWarnings("serial") static final class ForEachValueTask<K,V>
5237 extends Traverser<K,V,Void> {
5238 final Action<V> action;
5239 ForEachValueTask
5240 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5241 Action<V> action) {
5242 super(m, p, b);
5243 this.action = action;
5244 }
5245 @SuppressWarnings("unchecked") public final void compute() {
5246 final Action<V> action;
5247 if ((action = this.action) != null) {
5248 for (int b; (b = preSplit()) > 0;)
5249 new ForEachValueTask<K,V>(map, this, b, action).fork();
5250 Object v;
5251 while ((v = advance()) != null)
5252 action.apply((V)v);
5253 propagateCompletion();
5254 }
5255 }
5256 }
5257
5258 @SuppressWarnings("serial") static final class ForEachEntryTask<K,V>
5259 extends Traverser<K,V,Void> {
5260 final Action<Entry<K,V>> action;
5261 ForEachEntryTask
5262 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5263 Action<Entry<K,V>> action) {
5264 super(m, p, b);
5265 this.action = action;
5266 }
5267 @SuppressWarnings("unchecked") public final void compute() {
5268 final Action<Entry<K,V>> action;
5269 if ((action = this.action) != null) {
5270 for (int b; (b = preSplit()) > 0;)
5271 new ForEachEntryTask<K,V>(map, this, b, action).fork();
5272 Object v;
5273 while ((v = advance()) != null)
5274 action.apply(entryFor((K)nextKey, (V)v));
5275 propagateCompletion();
5276 }
5277 }
5278 }
5279
5280 @SuppressWarnings("serial") static final class ForEachMappingTask<K,V>
5281 extends Traverser<K,V,Void> {
5282 final BiAction<K,V> action;
5283 ForEachMappingTask
5284 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5285 BiAction<K,V> action) {
5286 super(m, p, b);
5287 this.action = action;
5288 }
5289 @SuppressWarnings("unchecked") public final void compute() {
5290 final BiAction<K,V> action;
5291 if ((action = this.action) != null) {
5292 for (int b; (b = preSplit()) > 0;)
5293 new ForEachMappingTask<K,V>(map, this, b, action).fork();
5294 Object v;
5295 while ((v = advance()) != null)
5296 action.apply((K)nextKey, (V)v);
5297 propagateCompletion();
5298 }
5299 }
5300 }
5301
5302 @SuppressWarnings("serial") static final class ForEachTransformedKeyTask<K,V,U>
5303 extends Traverser<K,V,Void> {
5304 final Fun<? super K, ? extends U> transformer;
5305 final Action<U> action;
5306 ForEachTransformedKeyTask
5307 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5308 Fun<? super K, ? extends U> transformer, Action<U> action) {
5309 super(m, p, b);
5310 this.transformer = transformer; this.action = action;
5311 }
5312 @SuppressWarnings("unchecked") public final void compute() {
5313 final Fun<? super K, ? extends U> transformer;
5314 final Action<U> action;
5315 if ((transformer = this.transformer) != null &&
5316 (action = this.action) != null) {
5317 for (int b; (b = preSplit()) > 0;)
5318 new ForEachTransformedKeyTask<K,V,U>
5319 (map, this, b, transformer, action).fork();
5320 U u;
5321 while (advance() != null) {
5322 if ((u = transformer.apply((K)nextKey)) != null)
5323 action.apply(u);
5324 }
5325 propagateCompletion();
5326 }
5327 }
5328 }
5329
5330 @SuppressWarnings("serial") static final class ForEachTransformedValueTask<K,V,U>
5331 extends Traverser<K,V,Void> {
5332 final Fun<? super V, ? extends U> transformer;
5333 final Action<U> action;
5334 ForEachTransformedValueTask
5335 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5336 Fun<? super V, ? extends U> transformer, Action<U> action) {
5337 super(m, p, b);
5338 this.transformer = transformer; this.action = action;
5339 }
5340 @SuppressWarnings("unchecked") public final void compute() {
5341 final Fun<? super V, ? extends U> transformer;
5342 final Action<U> action;
5343 if ((transformer = this.transformer) != null &&
5344 (action = this.action) != null) {
5345 for (int b; (b = preSplit()) > 0;)
5346 new ForEachTransformedValueTask<K,V,U>
5347 (map, this, b, transformer, action).fork();
5348 Object v; U u;
5349 while ((v = advance()) != null) {
5350 if ((u = transformer.apply((V)v)) != null)
5351 action.apply(u);
5352 }
5353 propagateCompletion();
5354 }
5355 }
5356 }
5357
5358 @SuppressWarnings("serial") static final class ForEachTransformedEntryTask<K,V,U>
5359 extends Traverser<K,V,Void> {
5360 final Fun<Map.Entry<K,V>, ? extends U> transformer;
5361 final Action<U> action;
5362 ForEachTransformedEntryTask
5363 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5364 Fun<Map.Entry<K,V>, ? extends U> transformer, Action<U> action) {
5365 super(m, p, b);
5366 this.transformer = transformer; this.action = action;
5367 }
5368 @SuppressWarnings("unchecked") public final void compute() {
5369 final Fun<Map.Entry<K,V>, ? extends U> transformer;
5370 final Action<U> action;
5371 if ((transformer = this.transformer) != null &&
5372 (action = this.action) != null) {
5373 for (int b; (b = preSplit()) > 0;)
5374 new ForEachTransformedEntryTask<K,V,U>
5375 (map, this, b, transformer, action).fork();
5376 Object v; U u;
5377 while ((v = advance()) != null) {
5378 if ((u = transformer.apply(entryFor((K)nextKey,
5379 (V)v))) != null)
5380 action.apply(u);
5381 }
5382 propagateCompletion();
5383 }
5384 }
5385 }
5386
5387 @SuppressWarnings("serial") static final class ForEachTransformedMappingTask<K,V,U>
5388 extends Traverser<K,V,Void> {
5389 final BiFun<? super K, ? super V, ? extends U> transformer;
5390 final Action<U> action;
5391 ForEachTransformedMappingTask
5392 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5393 BiFun<? super K, ? super V, ? extends U> transformer,
5394 Action<U> action) {
5395 super(m, p, b);
5396 this.transformer = transformer; this.action = action;
5397 }
5398 @SuppressWarnings("unchecked") public final void compute() {
5399 final BiFun<? super K, ? super V, ? extends U> transformer;
5400 final Action<U> action;
5401 if ((transformer = this.transformer) != null &&
5402 (action = this.action) != null) {
5403 for (int b; (b = preSplit()) > 0;)
5404 new ForEachTransformedMappingTask<K,V,U>
5405 (map, this, b, transformer, action).fork();
5406 Object v; U u;
5407 while ((v = advance()) != null) {
5408 if ((u = transformer.apply((K)nextKey, (V)v)) != null)
5409 action.apply(u);
5410 }
5411 propagateCompletion();
5412 }
5413 }
5414 }
5415
5416 @SuppressWarnings("serial") static final class SearchKeysTask<K,V,U>
5417 extends Traverser<K,V,U> {
5418 final Fun<? super K, ? extends U> searchFunction;
5419 final AtomicReference<U> result;
5420 SearchKeysTask
5421 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5422 Fun<? super K, ? extends U> searchFunction,
5423 AtomicReference<U> result) {
5424 super(m, p, b);
5425 this.searchFunction = searchFunction; this.result = result;
5426 }
5427 public final U getRawResult() { return result.get(); }
5428 @SuppressWarnings("unchecked") public final void compute() {
5429 final Fun<? super K, ? extends U> searchFunction;
5430 final AtomicReference<U> result;
5431 if ((searchFunction = this.searchFunction) != null &&
5432 (result = this.result) != null) {
5433 for (int b;;) {
5434 if (result.get() != null)
5435 return;
5436 if ((b = preSplit()) <= 0)
5437 break;
5438 new SearchKeysTask<K,V,U>
5439 (map, this, b, searchFunction, result).fork();
5440 }
5441 while (result.get() == null) {
5442 U u;
5443 if (advance() == null) {
5444 propagateCompletion();
5445 break;
5446 }
5447 if ((u = searchFunction.apply((K)nextKey)) != null) {
5448 if (result.compareAndSet(null, u))
5449 quietlyCompleteRoot();
5450 break;
5451 }
5452 }
5453 }
5454 }
5455 }
5456
5457 @SuppressWarnings("serial") static final class SearchValuesTask<K,V,U>
5458 extends Traverser<K,V,U> {
5459 final Fun<? super V, ? extends U> searchFunction;
5460 final AtomicReference<U> result;
5461 SearchValuesTask
5462 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5463 Fun<? super V, ? extends U> searchFunction,
5464 AtomicReference<U> result) {
5465 super(m, p, b);
5466 this.searchFunction = searchFunction; this.result = result;
5467 }
5468 public final U getRawResult() { return result.get(); }
5469 @SuppressWarnings("unchecked") public final void compute() {
5470 final Fun<? super V, ? extends U> searchFunction;
5471 final AtomicReference<U> result;
5472 if ((searchFunction = this.searchFunction) != null &&
5473 (result = this.result) != null) {
5474 for (int b;;) {
5475 if (result.get() != null)
5476 return;
5477 if ((b = preSplit()) <= 0)
5478 break;
5479 new SearchValuesTask<K,V,U>
5480 (map, this, b, searchFunction, result).fork();
5481 }
5482 while (result.get() == null) {
5483 Object v; U u;
5484 if ((v = advance()) == null) {
5485 propagateCompletion();
5486 break;
5487 }
5488 if ((u = searchFunction.apply((V)v)) != null) {
5489 if (result.compareAndSet(null, u))
5490 quietlyCompleteRoot();
5491 break;
5492 }
5493 }
5494 }
5495 }
5496 }
5497
5498 @SuppressWarnings("serial") static final class SearchEntriesTask<K,V,U>
5499 extends Traverser<K,V,U> {
5500 final Fun<Entry<K,V>, ? extends U> searchFunction;
5501 final AtomicReference<U> result;
5502 SearchEntriesTask
5503 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5504 Fun<Entry<K,V>, ? extends U> searchFunction,
5505 AtomicReference<U> result) {
5506 super(m, p, b);
5507 this.searchFunction = searchFunction; this.result = result;
5508 }
5509 public final U getRawResult() { return result.get(); }
5510 @SuppressWarnings("unchecked") public final void compute() {
5511 final Fun<Entry<K,V>, ? extends U> searchFunction;
5512 final AtomicReference<U> result;
5513 if ((searchFunction = this.searchFunction) != null &&
5514 (result = this.result) != null) {
5515 for (int b;;) {
5516 if (result.get() != null)
5517 return;
5518 if ((b = preSplit()) <= 0)
5519 break;
5520 new SearchEntriesTask<K,V,U>
5521 (map, this, b, searchFunction, result).fork();
5522 }
5523 while (result.get() == null) {
5524 Object v; U u;
5525 if ((v = advance()) == null) {
5526 propagateCompletion();
5527 break;
5528 }
5529 if ((u = searchFunction.apply(entryFor((K)nextKey,
5530 (V)v))) != null) {
5531 if (result.compareAndSet(null, u))
5532 quietlyCompleteRoot();
5533 return;
5534 }
5535 }
5536 }
5537 }
5538 }
5539
5540 @SuppressWarnings("serial") static final class SearchMappingsTask<K,V,U>
5541 extends Traverser<K,V,U> {
5542 final BiFun<? super K, ? super V, ? extends U> searchFunction;
5543 final AtomicReference<U> result;
5544 SearchMappingsTask
5545 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5546 BiFun<? super K, ? super V, ? extends U> searchFunction,
5547 AtomicReference<U> result) {
5548 super(m, p, b);
5549 this.searchFunction = searchFunction; this.result = result;
5550 }
5551 public final U getRawResult() { return result.get(); }
5552 @SuppressWarnings("unchecked") public final void compute() {
5553 final BiFun<? super K, ? super V, ? extends U> searchFunction;
5554 final AtomicReference<U> result;
5555 if ((searchFunction = this.searchFunction) != null &&
5556 (result = this.result) != null) {
5557 for (int b;;) {
5558 if (result.get() != null)
5559 return;
5560 if ((b = preSplit()) <= 0)
5561 break;
5562 new SearchMappingsTask<K,V,U>
5563 (map, this, b, searchFunction, result).fork();
5564 }
5565 while (result.get() == null) {
5566 Object v; U u;
5567 if ((v = advance()) == null) {
5568 propagateCompletion();
5569 break;
5570 }
5571 if ((u = searchFunction.apply((K)nextKey, (V)v)) != null) {
5572 if (result.compareAndSet(null, u))
5573 quietlyCompleteRoot();
5574 break;
5575 }
5576 }
5577 }
5578 }
5579 }
5580
5581 @SuppressWarnings("serial") static final class ReduceKeysTask<K,V>
5582 extends Traverser<K,V,K> {
5583 final BiFun<? super K, ? super K, ? extends K> reducer;
5584 K result;
5585 ReduceKeysTask<K,V> rights, nextRight;
5586 ReduceKeysTask
5587 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5588 ReduceKeysTask<K,V> nextRight,
5589 BiFun<? super K, ? super K, ? extends K> reducer) {
5590 super(m, p, b); this.nextRight = nextRight;
5591 this.reducer = reducer;
5592 }
5593 public final K getRawResult() { return result; }
5594 @SuppressWarnings("unchecked") public final void compute() {
5595 final BiFun<? super K, ? super K, ? extends K> reducer;
5596 if ((reducer = this.reducer) != null) {
5597 for (int b; (b = preSplit()) > 0;)
5598 (rights = new ReduceKeysTask<K,V>
5599 (map, this, b, rights, reducer)).fork();
5600 K r = null;
5601 while (advance() != null) {
5602 K u = (K)nextKey;
5603 r = (r == null) ? u : reducer.apply(r, u);
5604 }
5605 result = r;
5606 CountedCompleter<?> c;
5607 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5608 ReduceKeysTask<K,V>
5609 t = (ReduceKeysTask<K,V>)c,
5610 s = t.rights;
5611 while (s != null) {
5612 K tr, sr;
5613 if ((sr = s.result) != null)
5614 t.result = (((tr = t.result) == null) ? sr :
5615 reducer.apply(tr, sr));
5616 s = t.rights = s.nextRight;
5617 }
5618 }
5619 }
5620 }
5621 }
5622
5623 @SuppressWarnings("serial") static final class ReduceValuesTask<K,V>
5624 extends Traverser<K,V,V> {
5625 final BiFun<? super V, ? super V, ? extends V> reducer;
5626 V result;
5627 ReduceValuesTask<K,V> rights, nextRight;
5628 ReduceValuesTask
5629 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5630 ReduceValuesTask<K,V> nextRight,
5631 BiFun<? super V, ? super V, ? extends V> reducer) {
5632 super(m, p, b); this.nextRight = nextRight;
5633 this.reducer = reducer;
5634 }
5635 public final V getRawResult() { return result; }
5636 @SuppressWarnings("unchecked") public final void compute() {
5637 final BiFun<? super V, ? super V, ? extends V> reducer;
5638 if ((reducer = this.reducer) != null) {
5639 for (int b; (b = preSplit()) > 0;)
5640 (rights = new ReduceValuesTask<K,V>
5641 (map, this, b, rights, reducer)).fork();
5642 V r = null;
5643 Object v;
5644 while ((v = advance()) != null) {
5645 V u = (V)v;
5646 r = (r == null) ? u : reducer.apply(r, u);
5647 }
5648 result = r;
5649 CountedCompleter<?> c;
5650 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5651 ReduceValuesTask<K,V>
5652 t = (ReduceValuesTask<K,V>)c,
5653 s = t.rights;
5654 while (s != null) {
5655 V tr, sr;
5656 if ((sr = s.result) != null)
5657 t.result = (((tr = t.result) == null) ? sr :
5658 reducer.apply(tr, sr));
5659 s = t.rights = s.nextRight;
5660 }
5661 }
5662 }
5663 }
5664 }
5665
5666 @SuppressWarnings("serial") static final class ReduceEntriesTask<K,V>
5667 extends Traverser<K,V,Map.Entry<K,V>> {
5668 final BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer;
5669 Map.Entry<K,V> result;
5670 ReduceEntriesTask<K,V> rights, nextRight;
5671 ReduceEntriesTask
5672 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5673 ReduceEntriesTask<K,V> nextRight,
5674 BiFun<Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5675 super(m, p, b); this.nextRight = nextRight;
5676 this.reducer = reducer;
5677 }
5678 public final Map.Entry<K,V> getRawResult() { return result; }
5679 @SuppressWarnings("unchecked") public final void compute() {
5680 final BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer;
5681 if ((reducer = this.reducer) != null) {
5682 for (int b; (b = preSplit()) > 0;)
5683 (rights = new ReduceEntriesTask<K,V>
5684 (map, this, b, rights, reducer)).fork();
5685 Map.Entry<K,V> r = null;
5686 Object v;
5687 while ((v = advance()) != null) {
5688 Map.Entry<K,V> u = entryFor((K)nextKey, (V)v);
5689 r = (r == null) ? u : reducer.apply(r, u);
5690 }
5691 result = r;
5692 CountedCompleter<?> c;
5693 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5694 ReduceEntriesTask<K,V>
5695 t = (ReduceEntriesTask<K,V>)c,
5696 s = t.rights;
5697 while (s != null) {
5698 Map.Entry<K,V> tr, sr;
5699 if ((sr = s.result) != null)
5700 t.result = (((tr = t.result) == null) ? sr :
5701 reducer.apply(tr, sr));
5702 s = t.rights = s.nextRight;
5703 }
5704 }
5705 }
5706 }
5707 }
5708
5709 @SuppressWarnings("serial") static final class MapReduceKeysTask<K,V,U>
5710 extends Traverser<K,V,U> {
5711 final Fun<? super K, ? extends U> transformer;
5712 final BiFun<? super U, ? super U, ? extends U> reducer;
5713 U result;
5714 MapReduceKeysTask<K,V,U> rights, nextRight;
5715 MapReduceKeysTask
5716 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5717 MapReduceKeysTask<K,V,U> nextRight,
5718 Fun<? super K, ? extends U> transformer,
5719 BiFun<? super U, ? super U, ? extends U> reducer) {
5720 super(m, p, b); this.nextRight = nextRight;
5721 this.transformer = transformer;
5722 this.reducer = reducer;
5723 }
5724 public final U getRawResult() { return result; }
5725 @SuppressWarnings("unchecked") public final void compute() {
5726 final Fun<? super K, ? extends U> transformer;
5727 final BiFun<? super U, ? super U, ? extends U> reducer;
5728 if ((transformer = this.transformer) != null &&
5729 (reducer = this.reducer) != null) {
5730 for (int b; (b = preSplit()) > 0;)
5731 (rights = new MapReduceKeysTask<K,V,U>
5732 (map, this, b, rights, transformer, reducer)).fork();
5733 U r = null, u;
5734 while (advance() != null) {
5735 if ((u = transformer.apply((K)nextKey)) != null)
5736 r = (r == null) ? u : reducer.apply(r, u);
5737 }
5738 result = r;
5739 CountedCompleter<?> c;
5740 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5741 MapReduceKeysTask<K,V,U>
5742 t = (MapReduceKeysTask<K,V,U>)c,
5743 s = t.rights;
5744 while (s != null) {
5745 U tr, sr;
5746 if ((sr = s.result) != null)
5747 t.result = (((tr = t.result) == null) ? sr :
5748 reducer.apply(tr, sr));
5749 s = t.rights = s.nextRight;
5750 }
5751 }
5752 }
5753 }
5754 }
5755
5756 @SuppressWarnings("serial") static final class MapReduceValuesTask<K,V,U>
5757 extends Traverser<K,V,U> {
5758 final Fun<? super V, ? extends U> transformer;
5759 final BiFun<? super U, ? super U, ? extends U> reducer;
5760 U result;
5761 MapReduceValuesTask<K,V,U> rights, nextRight;
5762 MapReduceValuesTask
5763 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5764 MapReduceValuesTask<K,V,U> nextRight,
5765 Fun<? super V, ? extends U> transformer,
5766 BiFun<? super U, ? super U, ? extends U> reducer) {
5767 super(m, p, b); this.nextRight = nextRight;
5768 this.transformer = transformer;
5769 this.reducer = reducer;
5770 }
5771 public final U getRawResult() { return result; }
5772 @SuppressWarnings("unchecked") public final void compute() {
5773 final Fun<? super V, ? extends U> transformer;
5774 final BiFun<? super U, ? super U, ? extends U> reducer;
5775 if ((transformer = this.transformer) != null &&
5776 (reducer = this.reducer) != null) {
5777 for (int b; (b = preSplit()) > 0;)
5778 (rights = new MapReduceValuesTask<K,V,U>
5779 (map, this, b, rights, transformer, reducer)).fork();
5780 U r = null, u;
5781 Object v;
5782 while ((v = advance()) != null) {
5783 if ((u = transformer.apply((V)v)) != null)
5784 r = (r == null) ? u : reducer.apply(r, u);
5785 }
5786 result = r;
5787 CountedCompleter<?> c;
5788 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5789 MapReduceValuesTask<K,V,U>
5790 t = (MapReduceValuesTask<K,V,U>)c,
5791 s = t.rights;
5792 while (s != null) {
5793 U tr, sr;
5794 if ((sr = s.result) != null)
5795 t.result = (((tr = t.result) == null) ? sr :
5796 reducer.apply(tr, sr));
5797 s = t.rights = s.nextRight;
5798 }
5799 }
5800 }
5801 }
5802 }
5803
5804 @SuppressWarnings("serial") static final class MapReduceEntriesTask<K,V,U>
5805 extends Traverser<K,V,U> {
5806 final Fun<Map.Entry<K,V>, ? extends U> transformer;
5807 final BiFun<? super U, ? super U, ? extends U> reducer;
5808 U result;
5809 MapReduceEntriesTask<K,V,U> rights, nextRight;
5810 MapReduceEntriesTask
5811 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5812 MapReduceEntriesTask<K,V,U> nextRight,
5813 Fun<Map.Entry<K,V>, ? extends U> transformer,
5814 BiFun<? super U, ? super U, ? extends U> reducer) {
5815 super(m, p, b); this.nextRight = nextRight;
5816 this.transformer = transformer;
5817 this.reducer = reducer;
5818 }
5819 public final U getRawResult() { return result; }
5820 @SuppressWarnings("unchecked") public final void compute() {
5821 final Fun<Map.Entry<K,V>, ? extends U> transformer;
5822 final BiFun<? super U, ? super U, ? extends U> reducer;
5823 if ((transformer = this.transformer) != null &&
5824 (reducer = this.reducer) != null) {
5825 for (int b; (b = preSplit()) > 0;)
5826 (rights = new MapReduceEntriesTask<K,V,U>
5827 (map, this, b, rights, transformer, reducer)).fork();
5828 U r = null, u;
5829 Object v;
5830 while ((v = advance()) != null) {
5831 if ((u = transformer.apply(entryFor((K)nextKey,
5832 (V)v))) != null)
5833 r = (r == null) ? u : reducer.apply(r, u);
5834 }
5835 result = r;
5836 CountedCompleter<?> c;
5837 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5838 MapReduceEntriesTask<K,V,U>
5839 t = (MapReduceEntriesTask<K,V,U>)c,
5840 s = t.rights;
5841 while (s != null) {
5842 U tr, sr;
5843 if ((sr = s.result) != null)
5844 t.result = (((tr = t.result) == null) ? sr :
5845 reducer.apply(tr, sr));
5846 s = t.rights = s.nextRight;
5847 }
5848 }
5849 }
5850 }
5851 }
5852
5853 @SuppressWarnings("serial") static final class MapReduceMappingsTask<K,V,U>
5854 extends Traverser<K,V,U> {
5855 final BiFun<? super K, ? super V, ? extends U> transformer;
5856 final BiFun<? super U, ? super U, ? extends U> reducer;
5857 U result;
5858 MapReduceMappingsTask<K,V,U> rights, nextRight;
5859 MapReduceMappingsTask
5860 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5861 MapReduceMappingsTask<K,V,U> nextRight,
5862 BiFun<? super K, ? super V, ? extends U> transformer,
5863 BiFun<? super U, ? super U, ? extends U> reducer) {
5864 super(m, p, b); this.nextRight = nextRight;
5865 this.transformer = transformer;
5866 this.reducer = reducer;
5867 }
5868 public final U getRawResult() { return result; }
5869 @SuppressWarnings("unchecked") public final void compute() {
5870 final BiFun<? super K, ? super V, ? extends U> transformer;
5871 final BiFun<? super U, ? super U, ? extends U> reducer;
5872 if ((transformer = this.transformer) != null &&
5873 (reducer = this.reducer) != null) {
5874 for (int b; (b = preSplit()) > 0;)
5875 (rights = new MapReduceMappingsTask<K,V,U>
5876 (map, this, b, rights, transformer, reducer)).fork();
5877 U r = null, u;
5878 Object v;
5879 while ((v = advance()) != null) {
5880 if ((u = transformer.apply((K)nextKey, (V)v)) != null)
5881 r = (r == null) ? u : reducer.apply(r, u);
5882 }
5883 result = r;
5884 CountedCompleter<?> c;
5885 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5886 MapReduceMappingsTask<K,V,U>
5887 t = (MapReduceMappingsTask<K,V,U>)c,
5888 s = t.rights;
5889 while (s != null) {
5890 U tr, sr;
5891 if ((sr = s.result) != null)
5892 t.result = (((tr = t.result) == null) ? sr :
5893 reducer.apply(tr, sr));
5894 s = t.rights = s.nextRight;
5895 }
5896 }
5897 }
5898 }
5899 }
5900
5901 @SuppressWarnings("serial") static final class MapReduceKeysToDoubleTask<K,V>
5902 extends Traverser<K,V,Double> {
5903 final ObjectToDouble<? super K> transformer;
5904 final DoubleByDoubleToDouble reducer;
5905 final double basis;
5906 double result;
5907 MapReduceKeysToDoubleTask<K,V> rights, nextRight;
5908 MapReduceKeysToDoubleTask
5909 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5910 MapReduceKeysToDoubleTask<K,V> nextRight,
5911 ObjectToDouble<? super K> transformer,
5912 double basis,
5913 DoubleByDoubleToDouble reducer) {
5914 super(m, p, b); this.nextRight = nextRight;
5915 this.transformer = transformer;
5916 this.basis = basis; this.reducer = reducer;
5917 }
5918 public final Double getRawResult() { return result; }
5919 @SuppressWarnings("unchecked") public final void compute() {
5920 final ObjectToDouble<? super K> transformer;
5921 final DoubleByDoubleToDouble reducer;
5922 if ((transformer = this.transformer) != null &&
5923 (reducer = this.reducer) != null) {
5924 double r = this.basis;
5925 for (int b; (b = preSplit()) > 0;)
5926 (rights = new MapReduceKeysToDoubleTask<K,V>
5927 (map, this, b, rights, transformer, r, reducer)).fork();
5928 while (advance() != null)
5929 r = reducer.apply(r, transformer.apply((K)nextKey));
5930 result = r;
5931 CountedCompleter<?> c;
5932 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5933 MapReduceKeysToDoubleTask<K,V>
5934 t = (MapReduceKeysToDoubleTask<K,V>)c,
5935 s = t.rights;
5936 while (s != null) {
5937 t.result = reducer.apply(t.result, s.result);
5938 s = t.rights = s.nextRight;
5939 }
5940 }
5941 }
5942 }
5943 }
5944
5945 @SuppressWarnings("serial") static final class MapReduceValuesToDoubleTask<K,V>
5946 extends Traverser<K,V,Double> {
5947 final ObjectToDouble<? super V> transformer;
5948 final DoubleByDoubleToDouble reducer;
5949 final double basis;
5950 double result;
5951 MapReduceValuesToDoubleTask<K,V> rights, nextRight;
5952 MapReduceValuesToDoubleTask
5953 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5954 MapReduceValuesToDoubleTask<K,V> nextRight,
5955 ObjectToDouble<? super V> transformer,
5956 double basis,
5957 DoubleByDoubleToDouble reducer) {
5958 super(m, p, b); this.nextRight = nextRight;
5959 this.transformer = transformer;
5960 this.basis = basis; this.reducer = reducer;
5961 }
5962 public final Double getRawResult() { return result; }
5963 @SuppressWarnings("unchecked") public final void compute() {
5964 final ObjectToDouble<? super V> transformer;
5965 final DoubleByDoubleToDouble reducer;
5966 if ((transformer = this.transformer) != null &&
5967 (reducer = this.reducer) != null) {
5968 double r = this.basis;
5969 for (int b; (b = preSplit()) > 0;)
5970 (rights = new MapReduceValuesToDoubleTask<K,V>
5971 (map, this, b, rights, transformer, r, reducer)).fork();
5972 Object v;
5973 while ((v = advance()) != null)
5974 r = reducer.apply(r, transformer.apply((V)v));
5975 result = r;
5976 CountedCompleter<?> c;
5977 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5978 MapReduceValuesToDoubleTask<K,V>
5979 t = (MapReduceValuesToDoubleTask<K,V>)c,
5980 s = t.rights;
5981 while (s != null) {
5982 t.result = reducer.apply(t.result, s.result);
5983 s = t.rights = s.nextRight;
5984 }
5985 }
5986 }
5987 }
5988 }
5989
5990 @SuppressWarnings("serial") static final class MapReduceEntriesToDoubleTask<K,V>
5991 extends Traverser<K,V,Double> {
5992 final ObjectToDouble<Map.Entry<K,V>> transformer;
5993 final DoubleByDoubleToDouble reducer;
5994 final double basis;
5995 double result;
5996 MapReduceEntriesToDoubleTask<K,V> rights, nextRight;
5997 MapReduceEntriesToDoubleTask
5998 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5999 MapReduceEntriesToDoubleTask<K,V> nextRight,
6000 ObjectToDouble<Map.Entry<K,V>> transformer,
6001 double basis,
6002 DoubleByDoubleToDouble reducer) {
6003 super(m, p, b); this.nextRight = nextRight;
6004 this.transformer = transformer;
6005 this.basis = basis; this.reducer = reducer;
6006 }
6007 public final Double getRawResult() { return result; }
6008 @SuppressWarnings("unchecked") public final void compute() {
6009 final ObjectToDouble<Map.Entry<K,V>> transformer;
6010 final DoubleByDoubleToDouble reducer;
6011 if ((transformer = this.transformer) != null &&
6012 (reducer = this.reducer) != null) {
6013 double r = this.basis;
6014 for (int b; (b = preSplit()) > 0;)
6015 (rights = new MapReduceEntriesToDoubleTask<K,V>
6016 (map, this, b, rights, transformer, r, reducer)).fork();
6017 Object v;
6018 while ((v = advance()) != null)
6019 r = reducer.apply(r, transformer.apply(entryFor((K)nextKey,
6020 (V)v)));
6021 result = r;
6022 CountedCompleter<?> c;
6023 for (c = firstComplete(); c != null; c = c.nextComplete()) {
6024 MapReduceEntriesToDoubleTask<K,V>
6025 t = (MapReduceEntriesToDoubleTask<K,V>)c,
6026 s = t.rights;
6027 while (s != null) {
6028 t.result = reducer.apply(t.result, s.result);
6029 s = t.rights = s.nextRight;
6030 }
6031 }
6032 }
6033 }
6034 }
6035
6036 @SuppressWarnings("serial") static final class MapReduceMappingsToDoubleTask<K,V>
6037 extends Traverser<K,V,Double> {
6038 final ObjectByObjectToDouble<? super K, ? super V> transformer;
6039 final DoubleByDoubleToDouble reducer;
6040 final double basis;
6041 double result;
6042 MapReduceMappingsToDoubleTask<K,V> rights, nextRight;
6043 MapReduceMappingsToDoubleTask
6044 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6045 MapReduceMappingsToDoubleTask<K,V> nextRight,
6046 ObjectByObjectToDouble<? super K, ? super V> transformer,
6047 double basis,
6048 DoubleByDoubleToDouble reducer) {
6049 super(m, p, b); this.nextRight = nextRight;
6050 this.transformer = transformer;
6051 this.basis = basis; this.reducer = reducer;
6052 }
6053 public final Double getRawResult() { return result; }
6054 @SuppressWarnings("unchecked") public final void compute() {
6055 final ObjectByObjectToDouble<? super K, ? super V> transformer;
6056 final DoubleByDoubleToDouble reducer;
6057 if ((transformer = this.transformer) != null &&
6058 (reducer = this.reducer) != null) {
6059 double r = this.basis;
6060 for (int b; (b = preSplit()) > 0;)
6061 (rights = new MapReduceMappingsToDoubleTask<K,V>
6062 (map, this, b, rights, transformer, r, reducer)).fork();
6063 Object v;
6064 while ((v = advance()) != null)
6065 r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6066 result = r;
6067 CountedCompleter<?> c;
6068 for (c = firstComplete(); c != null; c = c.nextComplete()) {
6069 MapReduceMappingsToDoubleTask<K,V>
6070 t = (MapReduceMappingsToDoubleTask<K,V>)c,
6071 s = t.rights;
6072 while (s != null) {
6073 t.result = reducer.apply(t.result, s.result);
6074 s = t.rights = s.nextRight;
6075 }
6076 }
6077 }
6078 }
6079 }
6080
6081 @SuppressWarnings("serial") static final class MapReduceKeysToLongTask<K,V>
6082 extends Traverser<K,V,Long> {
6083 final ObjectToLong<? super K> transformer;
6084 final LongByLongToLong reducer;
6085 final long basis;
6086 long result;
6087 MapReduceKeysToLongTask<K,V> rights, nextRight;
6088 MapReduceKeysToLongTask
6089 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6090 MapReduceKeysToLongTask<K,V> nextRight,
6091 ObjectToLong<? super K> transformer,
6092 long basis,
6093 LongByLongToLong reducer) {
6094 super(m, p, b); this.nextRight = nextRight;
6095 this.transformer = transformer;
6096 this.basis = basis; this.reducer = reducer;
6097 }
6098 public final Long getRawResult() { return result; }
6099 @SuppressWarnings("unchecked") public final void compute() {
6100 final ObjectToLong<? super K> transformer;
6101 final LongByLongToLong reducer;
6102 if ((transformer = this.transformer) != null &&
6103 (reducer = this.reducer) != null) {
6104 long r = this.basis;
6105 for (int b; (b = preSplit()) > 0;)
6106 (rights = new MapReduceKeysToLongTask<K,V>
6107 (map, this, b, rights, transformer, r, reducer)).fork();
6108 while (advance() != null)
6109 r = reducer.apply(r, transformer.apply((K)nextKey));
6110 result = r;
6111 CountedCompleter<?> c;
6112 for (c = firstComplete(); c != null; c = c.nextComplete()) {
6113 MapReduceKeysToLongTask<K,V>
6114 t = (MapReduceKeysToLongTask<K,V>)c,
6115 s = t.rights;
6116 while (s != null) {
6117 t.result = reducer.apply(t.result, s.result);
6118 s = t.rights = s.nextRight;
6119 }
6120 }
6121 }
6122 }
6123 }
6124
6125 @SuppressWarnings("serial") static final class MapReduceValuesToLongTask<K,V>
6126 extends Traverser<K,V,Long> {
6127 final ObjectToLong<? super V> transformer;
6128 final LongByLongToLong reducer;
6129 final long basis;
6130 long result;
6131 MapReduceValuesToLongTask<K,V> rights, nextRight;
6132 MapReduceValuesToLongTask
6133 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6134 MapReduceValuesToLongTask<K,V> nextRight,
6135 ObjectToLong<? super V> transformer,
6136 long basis,
6137 LongByLongToLong reducer) {
6138 super(m, p, b); this.nextRight = nextRight;
6139 this.transformer = transformer;
6140 this.basis = basis; this.reducer = reducer;
6141 }
6142 public final Long getRawResult() { return result; }
6143 @SuppressWarnings("unchecked") public final void compute() {
6144 final ObjectToLong<? super V> transformer;
6145 final LongByLongToLong reducer;
6146 if ((transformer = this.transformer) != null &&
6147 (reducer = this.reducer) != null) {
6148 long r = this.basis;
6149 for (int b; (b = preSplit()) > 0;)
6150 (rights = new MapReduceValuesToLongTask<K,V>
6151 (map, this, b, rights, transformer, r, reducer)).fork();
6152 Object v;
6153 while ((v = advance()) != null)
6154 r = reducer.apply(r, transformer.apply((V)v));
6155 result = r;
6156 CountedCompleter<?> c;
6157 for (c = firstComplete(); c != null; c = c.nextComplete()) {
6158 MapReduceValuesToLongTask<K,V>
6159 t = (MapReduceValuesToLongTask<K,V>)c,
6160 s = t.rights;
6161 while (s != null) {
6162 t.result = reducer.apply(t.result, s.result);
6163 s = t.rights = s.nextRight;
6164 }
6165 }
6166 }
6167 }
6168 }
6169
6170 @SuppressWarnings("serial") static final class MapReduceEntriesToLongTask<K,V>
6171 extends Traverser<K,V,Long> {
6172 final ObjectToLong<Map.Entry<K,V>> transformer;
6173 final LongByLongToLong reducer;
6174 final long basis;
6175 long result;
6176 MapReduceEntriesToLongTask<K,V> rights, nextRight;
6177 MapReduceEntriesToLongTask
6178 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6179 MapReduceEntriesToLongTask<K,V> nextRight,
6180 ObjectToLong<Map.Entry<K,V>> transformer,
6181 long basis,
6182 LongByLongToLong reducer) {
6183 super(m, p, b); this.nextRight = nextRight;
6184 this.transformer = transformer;
6185 this.basis = basis; this.reducer = reducer;
6186 }
6187 public final Long getRawResult() { return result; }
6188 @SuppressWarnings("unchecked") public final void compute() {
6189 final ObjectToLong<Map.Entry<K,V>> transformer;
6190 final LongByLongToLong reducer;
6191 if ((transformer = this.transformer) != null &&
6192 (reducer = this.reducer) != null) {
6193 long r = this.basis;
6194 for (int b; (b = preSplit()) > 0;)
6195 (rights = new MapReduceEntriesToLongTask<K,V>
6196 (map, this, b, rights, transformer, r, reducer)).fork();
6197 Object v;
6198 while ((v = advance()) != null)
6199 r = reducer.apply(r, transformer.apply(entryFor((K)nextKey,
6200 (V)v)));
6201 result = r;
6202 CountedCompleter<?> c;
6203 for (c = firstComplete(); c != null; c = c.nextComplete()) {
6204 MapReduceEntriesToLongTask<K,V>
6205 t = (MapReduceEntriesToLongTask<K,V>)c,
6206 s = t.rights;
6207 while (s != null) {
6208 t.result = reducer.apply(t.result, s.result);
6209 s = t.rights = s.nextRight;
6210 }
6211 }
6212 }
6213 }
6214 }
6215
6216 @SuppressWarnings("serial") static final class MapReduceMappingsToLongTask<K,V>
6217 extends Traverser<K,V,Long> {
6218 final ObjectByObjectToLong<? super K, ? super V> transformer;
6219 final LongByLongToLong reducer;
6220 final long basis;
6221 long result;
6222 MapReduceMappingsToLongTask<K,V> rights, nextRight;
6223 MapReduceMappingsToLongTask
6224 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6225 MapReduceMappingsToLongTask<K,V> nextRight,
6226 ObjectByObjectToLong<? super K, ? super V> transformer,
6227 long basis,
6228 LongByLongToLong reducer) {
6229 super(m, p, b); this.nextRight = nextRight;
6230 this.transformer = transformer;
6231 this.basis = basis; this.reducer = reducer;
6232 }
6233 public final Long getRawResult() { return result; }
6234 @SuppressWarnings("unchecked") public final void compute() {
6235 final ObjectByObjectToLong<? super K, ? super V> transformer;
6236 final LongByLongToLong reducer;
6237 if ((transformer = this.transformer) != null &&
6238 (reducer = this.reducer) != null) {
6239 long r = this.basis;
6240 for (int b; (b = preSplit()) > 0;)
6241 (rights = new MapReduceMappingsToLongTask<K,V>
6242 (map, this, b, rights, transformer, r, reducer)).fork();
6243 Object v;
6244 while ((v = advance()) != null)
6245 r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6246 result = r;
6247 CountedCompleter<?> c;
6248 for (c = firstComplete(); c != null; c = c.nextComplete()) {
6249 MapReduceMappingsToLongTask<K,V>
6250 t = (MapReduceMappingsToLongTask<K,V>)c,
6251 s = t.rights;
6252 while (s != null) {
6253 t.result = reducer.apply(t.result, s.result);
6254 s = t.rights = s.nextRight;
6255 }
6256 }
6257 }
6258 }
6259 }
6260
6261 @SuppressWarnings("serial") static final class MapReduceKeysToIntTask<K,V>
6262 extends Traverser<K,V,Integer> {
6263 final ObjectToInt<? super K> transformer;
6264 final IntByIntToInt reducer;
6265 final int basis;
6266 int result;
6267 MapReduceKeysToIntTask<K,V> rights, nextRight;
6268 MapReduceKeysToIntTask
6269 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6270 MapReduceKeysToIntTask<K,V> nextRight,
6271 ObjectToInt<? super K> transformer,
6272 int basis,
6273 IntByIntToInt reducer) {
6274 super(m, p, b); this.nextRight = nextRight;
6275 this.transformer = transformer;
6276 this.basis = basis; this.reducer = reducer;
6277 }
6278 public final Integer getRawResult() { return result; }
6279 @SuppressWarnings("unchecked") public final void compute() {
6280 final ObjectToInt<? super K> transformer;
6281 final IntByIntToInt reducer;
6282 if ((transformer = this.transformer) != null &&
6283 (reducer = this.reducer) != null) {
6284 int r = this.basis;
6285 for (int b; (b = preSplit()) > 0;)
6286 (rights = new MapReduceKeysToIntTask<K,V>
6287 (map, this, b, rights, transformer, r, reducer)).fork();
6288 while (advance() != null)
6289 r = reducer.apply(r, transformer.apply((K)nextKey));
6290 result = r;
6291 CountedCompleter<?> c;
6292 for (c = firstComplete(); c != null; c = c.nextComplete()) {
6293 MapReduceKeysToIntTask<K,V>
6294 t = (MapReduceKeysToIntTask<K,V>)c,
6295 s = t.rights;
6296 while (s != null) {
6297 t.result = reducer.apply(t.result, s.result);
6298 s = t.rights = s.nextRight;
6299 }
6300 }
6301 }
6302 }
6303 }
6304
6305 @SuppressWarnings("serial") static final class MapReduceValuesToIntTask<K,V>
6306 extends Traverser<K,V,Integer> {
6307 final ObjectToInt<? super V> transformer;
6308 final IntByIntToInt reducer;
6309 final int basis;
6310 int result;
6311 MapReduceValuesToIntTask<K,V> rights, nextRight;
6312 MapReduceValuesToIntTask
6313 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6314 MapReduceValuesToIntTask<K,V> nextRight,
6315 ObjectToInt<? super V> transformer,
6316 int basis,
6317 IntByIntToInt reducer) {
6318 super(m, p, b); this.nextRight = nextRight;
6319 this.transformer = transformer;
6320 this.basis = basis; this.reducer = reducer;
6321 }
6322 public final Integer getRawResult() { return result; }
6323 @SuppressWarnings("unchecked") public final void compute() {
6324 final ObjectToInt<? super V> transformer;
6325 final IntByIntToInt reducer;
6326 if ((transformer = this.transformer) != null &&
6327 (reducer = this.reducer) != null) {
6328 int r = this.basis;
6329 for (int b; (b = preSplit()) > 0;)
6330 (rights = new MapReduceValuesToIntTask<K,V>
6331 (map, this, b, rights, transformer, r, reducer)).fork();
6332 Object v;
6333 while ((v = advance()) != null)
6334 r = reducer.apply(r, transformer.apply((V)v));
6335 result = r;
6336 CountedCompleter<?> c;
6337 for (c = firstComplete(); c != null; c = c.nextComplete()) {
6338 MapReduceValuesToIntTask<K,V>
6339 t = (MapReduceValuesToIntTask<K,V>)c,
6340 s = t.rights;
6341 while (s != null) {
6342 t.result = reducer.apply(t.result, s.result);
6343 s = t.rights = s.nextRight;
6344 }
6345 }
6346 }
6347 }
6348 }
6349
6350 @SuppressWarnings("serial") static final class MapReduceEntriesToIntTask<K,V>
6351 extends Traverser<K,V,Integer> {
6352 final ObjectToInt<Map.Entry<K,V>> transformer;
6353 final IntByIntToInt reducer;
6354 final int basis;
6355 int result;
6356 MapReduceEntriesToIntTask<K,V> rights, nextRight;
6357 MapReduceEntriesToIntTask
6358 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6359 MapReduceEntriesToIntTask<K,V> nextRight,
6360 ObjectToInt<Map.Entry<K,V>> transformer,
6361 int basis,
6362 IntByIntToInt reducer) {
6363 super(m, p, b); this.nextRight = nextRight;
6364 this.transformer = transformer;
6365 this.basis = basis; this.reducer = reducer;
6366 }
6367 public final Integer getRawResult() { return result; }
6368 @SuppressWarnings("unchecked") public final void compute() {
6369 final ObjectToInt<Map.Entry<K,V>> transformer;
6370 final IntByIntToInt reducer;
6371 if ((transformer = this.transformer) != null &&
6372 (reducer = this.reducer) != null) {
6373 int r = this.basis;
6374 for (int b; (b = preSplit()) > 0;)
6375 (rights = new MapReduceEntriesToIntTask<K,V>
6376 (map, this, b, rights, transformer, r, reducer)).fork();
6377 Object v;
6378 while ((v = advance()) != null)
6379 r = reducer.apply(r, transformer.apply(entryFor((K)nextKey,
6380 (V)v)));
6381 result = r;
6382 CountedCompleter<?> c;
6383 for (c = firstComplete(); c != null; c = c.nextComplete()) {
6384 MapReduceEntriesToIntTask<K,V>
6385 t = (MapReduceEntriesToIntTask<K,V>)c,
6386 s = t.rights;
6387 while (s != null) {
6388 t.result = reducer.apply(t.result, s.result);
6389 s = t.rights = s.nextRight;
6390 }
6391 }
6392 }
6393 }
6394 }
6395
6396 @SuppressWarnings("serial") static final class MapReduceMappingsToIntTask<K,V>
6397 extends Traverser<K,V,Integer> {
6398 final ObjectByObjectToInt<? super K, ? super V> transformer;
6399 final IntByIntToInt reducer;
6400 final int basis;
6401 int result;
6402 MapReduceMappingsToIntTask<K,V> rights, nextRight;
6403 MapReduceMappingsToIntTask
6404 (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6405 MapReduceMappingsToIntTask<K,V> nextRight,
6406 ObjectByObjectToInt<? super K, ? super V> transformer,
6407 int basis,
6408 IntByIntToInt reducer) {
6409 super(m, p, b); this.nextRight = nextRight;
6410 this.transformer = transformer;
6411 this.basis = basis; this.reducer = reducer;
6412 }
6413 public final Integer getRawResult() { return result; }
6414 @SuppressWarnings("unchecked") public final void compute() {
6415 final ObjectByObjectToInt<? super K, ? super V> transformer;
6416 final IntByIntToInt reducer;
6417 if ((transformer = this.transformer) != null &&
6418 (reducer = this.reducer) != null) {
6419 int r = this.basis;
6420 for (int b; (b = preSplit()) > 0;)
6421 (rights = new MapReduceMappingsToIntTask<K,V>
6422 (map, this, b, rights, transformer, r, reducer)).fork();
6423 Object v;
6424 while ((v = advance()) != null)
6425 r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6426 result = r;
6427 CountedCompleter<?> c;
6428 for (c = firstComplete(); c != null; c = c.nextComplete()) {
6429 MapReduceMappingsToIntTask<K,V>
6430 t = (MapReduceMappingsToIntTask<K,V>)c,
6431 s = t.rights;
6432 while (s != null) {
6433 t.result = reducer.apply(t.result, s.result);
6434 s = t.rights = s.nextRight;
6435 }
6436 }
6437 }
6438 }
6439 }
6440
6441 // Unsafe mechanics
6442 private static final sun.misc.Unsafe U;
6443 private static final long SIZECTL;
6444 private static final long TRANSFERINDEX;
6445 private static final long TRANSFERORIGIN;
6446 private static final long BASECOUNT;
6447 private static final long COUNTERBUSY;
6448 private static final long CELLVALUE;
6449 private static final long ABASE;
6450 private static final int ASHIFT;
6451
6452 static {
6453 int ss;
6454 try {
6455 U = getUnsafe();
6456 Class<?> k = ConcurrentHashMapV8.class;
6457 SIZECTL = U.objectFieldOffset
6458 (k.getDeclaredField("sizeCtl"));
6459 TRANSFERINDEX = U.objectFieldOffset
6460 (k.getDeclaredField("transferIndex"));
6461 TRANSFERORIGIN = U.objectFieldOffset
6462 (k.getDeclaredField("transferOrigin"));
6463 BASECOUNT = U.objectFieldOffset
6464 (k.getDeclaredField("baseCount"));
6465 COUNTERBUSY = U.objectFieldOffset
6466 (k.getDeclaredField("counterBusy"));
6467 Class<?> ck = CounterCell.class;
6468 CELLVALUE = U.objectFieldOffset
6469 (ck.getDeclaredField("value"));
6470 Class<?> sc = Node[].class;
6471 ABASE = U.arrayBaseOffset(sc);
6472 ss = U.arrayIndexScale(sc);
6473 ASHIFT = 31 - Integer.numberOfLeadingZeros(ss);
6474 } catch (Exception e) {
6475 throw new Error(e);
6476 }
6477 if ((ss & (ss-1)) != 0)
6478 throw new Error("data type scale not a power of two");
6479 }
6480
6481 /**
6482 * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package.
6483 * Replace with a simple call to Unsafe.getUnsafe when integrating
6484 * into a jdk.
6485 *
6486 * @return a sun.misc.Unsafe
6487 */
6488 private static sun.misc.Unsafe getUnsafe() {
6489 try {
6490 return sun.misc.Unsafe.getUnsafe();
6491 } catch (SecurityException se) {
6492 try {
6493 return java.security.AccessController.doPrivileged
6494 (new java.security
6495 .PrivilegedExceptionAction<sun.misc.Unsafe>() {
6496 public sun.misc.Unsafe run() throws Exception {
6497 java.lang.reflect.Field f = sun.misc
6498 .Unsafe.class.getDeclaredField("theUnsafe");
6499 f.setAccessible(true);
6500 return (sun.misc.Unsafe) f.get(null);
6501 }});
6502 } catch (java.security.PrivilegedActionException e) {
6503 throw new RuntimeException("Could not initialize intrinsics",
6504 e.getCause());
6505 }
6506 }
6507 }
6508 }