ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/ConcurrentHashMapV8.java
(Generate patch)

Comparing jsr166/src/jsr166e/ConcurrentHashMapV8.java (file contents):
Revision 1.59 by dl, Tue Aug 14 13:16:50 2012 UTC vs.
Revision 1.79 by dl, Fri Nov 23 17:50:51 2012 UTC

# Line 5 | Line 5
5   */
6  
7   package jsr166e;
8 < import jsr166e.LongAdder;
9 < import jsr166e.ForkJoinPool;
10 < import jsr166e.ForkJoinTask;
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.ThreadLocalRandom;
25 > import java.util.concurrent.locks.LockSupport;
26 > import java.util.concurrent.locks.AbstractQueuedSynchronizer;
27 > import java.util.concurrent.atomic.AtomicReference;
28 >
29 > import java.io.Serializable;
30  
31   import java.util.Comparator;
32   import java.util.Arrays;
# Line 43 | Line 62 | import java.io.Serializable;
62   * interoperable with {@code Hashtable} in programs that rely on its
63   * thread safety but not on its synchronization details.
64   *
65 < * <p> Retrieval operations (including {@code get}) generally do not
65 > * <p>Retrieval operations (including {@code get}) generally do not
66   * block, so may overlap with update operations (including {@code put}
67   * and {@code remove}). Retrievals reflect the results of the most
68   * recently <em>completed</em> update operations holding upon their
# Line 64 | Line 83 | import java.io.Serializable;
83   * that may be adequate for monitoring or estimation purposes, but not
84   * for program control.
85   *
86 < * <p> The table is dynamically expanded when there are too many
86 > * <p>The table is dynamically expanded when there are too many
87   * collisions (i.e., keys that have distinct hash codes but fall into
88   * the same slot modulo the table size), with the expected average
89   * effect of maintaining roughly two bins per mapping (corresponding
# Line 85 | Line 104 | import java.io.Serializable;
104   * {@code hashCode()} is a sure way to slow down performance of any
105   * hash table.
106   *
107 + * <p>A {@link Set} projection of a ConcurrentHashMapV8 may be created
108 + * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed
109 + * (using {@link #keySet(Object)} when only keys are of interest, and the
110 + * mapped values are (perhaps transiently) not used or all take the
111 + * same mapping value.
112 + *
113 + * <p>A ConcurrentHashMapV8 can be used as scalable frequency map (a
114 + * form of histogram or multiset) by using {@link LongAdder} values
115 + * and initializing via {@link #computeIfAbsent}. For example, to add
116 + * a count to a {@code ConcurrentHashMapV8<String,LongAdder> freqs}, you
117 + * can use {@code freqs.computeIfAbsent(k -> new
118 + * LongAdder()).increment();}
119 + *
120   * <p>This class and its views and iterators implement all of the
121   * <em>optional</em> methods of the {@link Map} and {@link Iterator}
122   * interfaces.
123   *
124 < * <p> Like {@link Hashtable} but unlike {@link HashMap}, this class
124 > * <p>Like {@link Hashtable} but unlike {@link HashMap}, this class
125   * does <em>not</em> allow {@code null} to be used as a key or value.
126   *
127 + * <p>ConcurrentHashMapV8s support parallel operations using the {@link
128 + * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts
129 + * are available in class {@link ForkJoinTasks}). These operations are
130 + * designed to be safely, and often sensibly, applied even with maps
131 + * that are being concurrently updated by other threads; for example,
132 + * when computing a snapshot summary of the values in a shared
133 + * registry.  There are three kinds of operation, each with four
134 + * forms, accepting functions with Keys, Values, Entries, and (Key,
135 + * Value) arguments and/or return values. (The first three forms are
136 + * also available via the {@link #keySet()}, {@link #values()} and
137 + * {@link #entrySet()} views). Because the elements of a
138 + * ConcurrentHashMapV8 are not ordered in any particular way, and may be
139 + * processed in different orders in different parallel executions, the
140 + * correctness of supplied functions should not depend on any
141 + * ordering, or on any other objects or values that may transiently
142 + * change while computation is in progress; and except for forEach
143 + * actions, should ideally be side-effect-free.
144 + *
145 + * <ul>
146 + * <li> forEach: Perform a given action on each element.
147 + * A variant form applies a given transformation on each element
148 + * before performing the action.</li>
149 + *
150 + * <li> search: Return the first available non-null result of
151 + * applying a given function on each element; skipping further
152 + * search when a result is found.</li>
153 + *
154 + * <li> reduce: Accumulate each element.  The supplied reduction
155 + * function cannot rely on ordering (more formally, it should be
156 + * both associative and commutative).  There are five variants:
157 + *
158 + * <ul>
159 + *
160 + * <li> Plain reductions. (There is not a form of this method for
161 + * (key, value) function arguments since there is no corresponding
162 + * return type.)</li>
163 + *
164 + * <li> Mapped reductions that accumulate the results of a given
165 + * function applied to each element.</li>
166 + *
167 + * <li> Reductions to scalar doubles, longs, and ints, using a
168 + * given basis value.</li>
169 + *
170 + * </li>
171 + * </ul>
172 + * </ul>
173 + *
174 + * <p>The concurrency properties of bulk operations follow
175 + * from those of ConcurrentHashMapV8: Any non-null result returned
176 + * from {@code get(key)} and related access methods bears a
177 + * happens-before relation with the associated insertion or
178 + * update.  The result of any bulk operation reflects the
179 + * composition of these per-element relations (but is not
180 + * necessarily atomic with respect to the map as a whole unless it
181 + * is somehow known to be quiescent).  Conversely, because keys
182 + * and values in the map are never null, null serves as a reliable
183 + * atomic indicator of the current lack of any result.  To
184 + * maintain this property, null serves as an implicit basis for
185 + * all non-scalar reduction operations. For the double, long, and
186 + * int versions, the basis should be one that, when combined with
187 + * any other value, returns that other value (more formally, it
188 + * should be the identity element for the reduction). Most common
189 + * reductions have these properties; for example, computing a sum
190 + * with basis 0 or a minimum with basis MAX_VALUE.
191 + *
192 + * <p>Search and transformation functions provided as arguments
193 + * should similarly return null to indicate the lack of any result
194 + * (in which case it is not used). In the case of mapped
195 + * reductions, this also enables transformations to serve as
196 + * filters, returning null (or, in the case of primitive
197 + * specializations, the identity basis) if the element should not
198 + * be combined. You can create compound transformations and
199 + * filterings by composing them yourself under this "null means
200 + * there is nothing there now" rule before using them in search or
201 + * reduce operations.
202 + *
203 + * <p>Methods accepting and/or returning Entry arguments maintain
204 + * key-value associations. They may be useful for example when
205 + * finding the key for the greatest value. Note that "plain" Entry
206 + * arguments can be supplied using {@code new
207 + * AbstractMap.SimpleEntry(k,v)}.
208 + *
209 + * <p>Bulk operations may complete abruptly, throwing an
210 + * exception encountered in the application of a supplied
211 + * function. Bear in mind when handling such exceptions that other
212 + * concurrently executing functions could also have thrown
213 + * exceptions, or would have done so if the first exception had
214 + * not occurred.
215 + *
216 + * <p>Parallel speedups for bulk operations compared to sequential
217 + * processing are common but not guaranteed.  Operations involving
218 + * brief functions on small maps may execute more slowly than
219 + * sequential loops if the underlying work to parallelize the
220 + * computation is more expensive than the computation itself.
221 + * Similarly, parallelization may not lead to much actual parallelism
222 + * if all processors are busy performing unrelated tasks.
223 + *
224 + * <p>All arguments to all task methods must be non-null.
225 + *
226 + * <p><em>jsr166e note: During transition, this class
227 + * uses nested functional interfaces with different names but the
228 + * same forms as those expected for JDK8.</em>
229 + *
230   * <p>This class is a member of the
231   * <a href="{@docRoot}/../technotes/guides/collections/index.html">
232   * Java Collections Framework</a>.
233   *
99 * <p><em>jsr166e note: This class is a candidate replacement for
100 * java.util.concurrent.ConcurrentHashMap.  During transition, this
101 * class declares and uses nested functional interfaces with different
102 * names but the same forms as those expected for JDK8.<em>
103 *
234   * @since 1.5
235   * @author Doug Lea
236   * @param <K> the type of keys maintained by this map
# Line 117 | Line 247 | public class ConcurrentHashMapV8<K, V>
247       * portion of the elements, and so may be amenable to parallel
248       * execution.
249       *
250 <     * <p> This interface exports a subset of expected JDK8
250 >     * <p>This interface exports a subset of expected JDK8
251       * functionality.
252       *
253       * <p>Sample usage: Here is one (of the several) ways to compute
# Line 179 | Line 309 | public class ConcurrentHashMapV8<K, V>
309          Spliterator<T> split();
310      }
311  
312 +
313      /*
314       * Overview:
315       *
# Line 461 | Line 592 | public class ConcurrentHashMapV8<K, V>
592      private transient volatile int sizeCtl;
593  
594      // views
595 <    private transient KeySet<K,V> keySet;
596 <    private transient Values<K,V> values;
597 <    private transient EntrySet<K,V> entrySet;
595 >    private transient KeySetView<K,V> keySet;
596 >    private transient ValuesView<K,V> values;
597 >    private transient EntrySetView<K,V> entrySet;
598  
599      /** For serialization compatibility. Null unless serialized; see below */
600      private Segment<K,V>[] segments;
# Line 540 | Line 671 | public class ConcurrentHashMapV8<K, V>
671           * unlocking lock (via a failed CAS from non-waiting LOCKED
672           * state), unlockers acquire the sync lock and perform a
673           * notifyAll.
674 +         *
675 +         * The initial sanity check on tab and bounds is not currently
676 +         * necessary in the only usages of this method, but enables
677 +         * use in other future contexts.
678           */
679          final void tryAwaitLock(Node[] tab, int i) {
680 <            if (tab != null && i >= 0 && i < tab.length) { // bounds check
680 >            if (tab != null && i >= 0 && i < tab.length) { // sanity check
681                  int r = ThreadLocalRandom.current().nextInt(); // randomize spins
682                  int spins = MAX_SPINS, h;
683                  while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) {
# Line 558 | Line 693 | public class ConcurrentHashMapV8<K, V>
693                                  try {
694                                      wait();
695                                  } catch (InterruptedException ie) {
696 <                                    Thread.currentThread().interrupt();
696 >                                    try {
697 >                                        Thread.currentThread().interrupt();
698 >                                    } catch (SecurityException ignore) {
699 >                                    }
700                                  }
701                              }
702                              else
# Line 718 | Line 856 | public class ConcurrentHashMapV8<K, V>
856           * Returns the TreeNode (or null if not found) for the given key
857           * starting at given root.
858           */
859 <        @SuppressWarnings("unchecked") // suppress Comparable cast warning
860 <        final TreeNode getTreeNode(int h, Object k, TreeNode p) {
859 >        @SuppressWarnings("unchecked") final TreeNode getTreeNode
860 >            (int h, Object k, TreeNode p) {
861              Class<?> c = k.getClass();
862              while (p != null) {
863                  int dir, ph;  Object pk; Class<?> pc;
# Line 779 | Line 917 | public class ConcurrentHashMapV8<K, V>
917           * Finds or adds a node.
918           * @return null if added
919           */
920 <        @SuppressWarnings("unchecked") // suppress Comparable cast warning
921 <        final TreeNode putTreeNode(int h, Object k, Object v) {
920 >        @SuppressWarnings("unchecked") final TreeNode putTreeNode
921 >            (int h, Object k, Object v) {
922              Class<?> c = k.getClass();
923              TreeNode pp = root, p = null;
924              int dir = 0;
# Line 1550 | Line 1688 | public class ConcurrentHashMapV8<K, V>
1688      }
1689  
1690      /** Implementation for compute */
1691 <    @SuppressWarnings("unchecked")
1692 <    private final Object internalCompute(K k, boolean onlyIfPresent,
1555 <                                             BiFun<? super K, ? super V, ? extends V> mf) {
1691 >    @SuppressWarnings("unchecked") private final Object internalCompute
1692 >        (K k, boolean onlyIfPresent, BiFun<? super K, ? super V, ? extends V> mf) {
1693          int h = spread(k.hashCode());
1694          Object val = null;
1695          int delta = 0;
# Line 1676 | Line 1813 | public class ConcurrentHashMapV8<K, V>
1813      }
1814  
1815      /** Implementation for merge */
1816 <    @SuppressWarnings("unchecked")
1817 <    private final Object internalMerge(K k, V v,
1681 <                                       BiFun<? super V, ? super V, ? extends V> mf) {
1816 >    @SuppressWarnings("unchecked") private final Object internalMerge
1817 >        (K k, V v, BiFun<? super V, ? super V, ? extends V> mf) {
1818          int h = spread(k.hashCode());
1819          Object val = null;
1820          int delta = 0;
# Line 2008 | Line 2144 | public class ConcurrentHashMapV8<K, V>
2144          for (int i = bin;;) {      // start upwards sweep
2145              int fh; Node f;
2146              if ((f = tabAt(tab, i)) == null) {
2147 <                if (bin >= 0) {    // no lock needed (or available)
2147 >                if (bin >= 0) {    // Unbuffered; no lock needed (or available)
2148                      if (!casTabAt(tab, i, f, fwd))
2149                          continue;
2150                  }
# Line 2184 | Line 2320 | public class ConcurrentHashMapV8<K, V>
2320                      try {
2321                          if (tabAt(tab, i) == f) {
2322                              for (Node p = t.first; p != null; p = p.next) {
2323 <                                p.val = null;
2324 <                                --delta;
2323 >                                if (p.val != null) { // (currently always true)
2324 >                                    p.val = null;
2325 >                                    --delta;
2326 >                                }
2327                              }
2328                              t.first = null;
2329                              t.root = null;
# Line 2207 | Line 2345 | public class ConcurrentHashMapV8<K, V>
2345                  try {
2346                      if (tabAt(tab, i) == f) {
2347                          for (Node e = f; e != null; e = e.next) {
2348 <                            e.val = null;
2349 <                            --delta;
2348 >                            if (e.val != null) {  // (currently always true)
2349 >                                e.val = null;
2350 >                                --delta;
2351 >                            }
2352                          }
2353                          setTabAt(tab, i, null);
2354                          ++i;
# Line 2237 | Line 2377 | public class ConcurrentHashMapV8<K, V>
2377       * change (including to null, indicating deletion), field nextVal
2378       * might not be accurate at point of use, but still maintains the
2379       * weak consistency property of holding a value that was once
2380 <     * valid.
2380 >     * valid. To support iterator.remove, the nextKey field is not
2381 >     * updated (nulled out) when the iterator cannot advance.
2382       *
2383       * Internal traversals directly access these fields, as in:
2384       * {@code while (it.advance() != null) { process(it.nextKey); }}
# Line 2264 | Line 2405 | public class ConcurrentHashMapV8<K, V>
2405       * across threads, iteration terminates if a bounds checks fails
2406       * for a table read.
2407       *
2408 <     * This class extends ForkJoinTask to streamline parallel
2409 <     * iteration in bulk operations (see BulkTask). This adds only an
2410 <     * int of space overhead, which is close enough to negligible in
2411 <     * cases where it is not needed to not worry about it.  Because
2412 <     * ForkJoinTask is Serializable, but iterators need not be, we
2413 <     * need to add warning suppressions.
2408 >     * This class extends CountedCompleter to streamline parallel
2409 >     * iteration in bulk operations. This adds only a few fields of
2410 >     * space overhead, which is small enough in cases where it is not
2411 >     * needed to not worry about it.  Because CountedCompleter is
2412 >     * Serializable, but iterators need not be, we need to add warning
2413 >     * suppressions.
2414       */
2415 <    @SuppressWarnings("serial")
2275 <    static class Traverser<K,V,R> extends ForkJoinTask<R> {
2415 >    @SuppressWarnings("serial") static class Traverser<K,V,R> extends CountedCompleter<R> {
2416          final ConcurrentHashMapV8<K, V> map;
2417          Node next;           // the next entry to use
2278        Node last;           // the last entry used
2418          Object nextKey;      // cached key field of next
2419          Object nextVal;      // cached val field of next
2420          Node[] tab;          // current table; updated if resized
2421          int index;           // index of bin to use next
2422          int baseIndex;       // current index of initial table
2423          int baseLimit;       // index bound for initial table
2424 <        final int baseSize;  // initial table size
2424 >        int baseSize;        // initial table size
2425 >        int batch;           // split control
2426  
2427          /** Creates iterator for all entries in the table. */
2428          Traverser(ConcurrentHashMapV8<K, V> map) {
2429 <            this.tab = (this.map = map).table;
2290 <            baseLimit = baseSize = (tab == null) ? 0 : tab.length;
2429 >            this.map = map;
2430          }
2431  
2432 <        /** Creates iterator for split() methods */
2433 <        Traverser(Traverser<K,V,?> it, boolean split) {
2434 <            this.map = it.map;
2435 <            this.tab = it.tab;
2436 <            this.baseSize = it.baseSize;
2437 <            int lo = it.baseIndex;
2438 <            int hi = this.baseLimit = it.baseLimit;
2439 <            int i;
2440 <            if (split) // adjust parent
2441 <                i = it.baseLimit = (lo + hi + 1) >>> 1;
2442 <            else       // clone parent
2443 <                i = lo;
2444 <            this.index = this.baseIndex = i;
2432 >        /** Creates iterator for split() methods and task constructors */
2433 >        Traverser(ConcurrentHashMapV8<K,V> map, Traverser<K,V,?> it, int batch) {
2434 >            super(it);
2435 >            this.batch = batch;
2436 >            if ((this.map = map) != null && it != null) { // split parent
2437 >                Node[] t;
2438 >                if ((t = it.tab) == null &&
2439 >                    (t = it.tab = map.table) != null)
2440 >                    it.baseLimit = it.baseSize = t.length;
2441 >                this.tab = t;
2442 >                this.baseSize = it.baseSize;
2443 >                int hi = this.baseLimit = it.baseLimit;
2444 >                it.baseLimit = this.index = this.baseIndex =
2445 >                    (hi + it.baseIndex + 1) >>> 1;
2446 >            }
2447          }
2448  
2449          /**
# Line 2310 | Line 2451 | public class ConcurrentHashMapV8<K, V>
2451           * See above for explanation.
2452           */
2453          final Object advance() {
2454 <            Node e = last = next;
2454 >            Node e = next;
2455              Object ev = null;
2456              outer: do {
2457                  if (e != null)                  // advance past used/skipped node
2458                      e = e.next;
2459                  while (e == null) {             // get to next non-null bin
2460 +                    ConcurrentHashMapV8<K, V> m;
2461                      Node[] t; int b, i, n; Object ek; // checks must use locals
2462 <                    if ((b = baseIndex) >= baseLimit || (i = index) < 0 ||
2463 <                        (t = tab) == null || i >= (n = t.length))
2462 >                    if ((t = tab) != null)
2463 >                        n = t.length;
2464 >                    else if ((m = map) != null && (t = tab = m.table) != null)
2465 >                        n = baseLimit = baseSize = t.length;
2466 >                    else
2467                          break outer;
2468 <                    else if ((e = tabAt(t, i)) != null && e.hash == MOVED) {
2468 >                    if ((b = baseIndex) >= baseLimit ||
2469 >                        (i = index) < 0 || i >= n)
2470 >                        break outer;
2471 >                    if ((e = tabAt(t, i)) != null && e.hash == MOVED) {
2472                          if ((ek = e.key) instanceof TreeBin)
2473                              e = ((TreeBin)ek).first;
2474                          else {
# Line 2337 | Line 2485 | public class ConcurrentHashMapV8<K, V>
2485          }
2486  
2487          public final void remove() {
2488 <            if (nextVal == null && last == null)
2489 <                advance();
2342 <            Node e = last;
2343 <            if (e == null)
2488 >            Object k = nextKey;
2489 >            if (k == null && (advance() == null || (k = nextKey) == null))
2490                  throw new IllegalStateException();
2491 <            last = null;
2346 <            map.remove(e.key);
2491 >            map.internalReplace(k, null, null);
2492          }
2493  
2494          public final boolean hasNext() {
# Line 2351 | Line 2496 | public class ConcurrentHashMapV8<K, V>
2496          }
2497  
2498          public final boolean hasMoreElements() { return hasNext(); }
2499 <        public final void setRawResult(Object x) { }
2500 <        public R getRawResult() { return null; }
2501 <        public boolean exec() { return true; }
2499 >
2500 >        public void compute() { } // default no-op CountedCompleter body
2501 >
2502 >        /**
2503 >         * Returns a batch value > 0 if this task should (and must) be
2504 >         * split, if so, adding to pending count, and in any case
2505 >         * updating batch value. The initial batch value is approx
2506 >         * exp2 of the number of times (minus one) to split task by
2507 >         * two before executing leaf action. This value is faster to
2508 >         * compute and more convenient to use as a guide to splitting
2509 >         * than is the depth, since it is used while dividing by two
2510 >         * anyway.
2511 >         */
2512 >        final int preSplit() {
2513 >            ConcurrentHashMapV8<K, V> m; int b; Node[] t;  ForkJoinPool pool;
2514 >            if ((b = batch) < 0 && (m = map) != null) { // force initialization
2515 >                if ((t = tab) == null && (t = tab = m.table) != null)
2516 >                    baseLimit = baseSize = t.length;
2517 >                if (t != null) {
2518 >                    long n = m.counter.sum();
2519 >                    int par = ((pool = getPool()) == null) ?
2520 >                        ForkJoinPool.getCommonPoolParallelism() :
2521 >                        pool.getParallelism();
2522 >                    int sp = par << 3; // slack of 8
2523 >                    b = (n <= 0L) ? 0 : (n < (long)sp) ? (int)n : sp;
2524 >                }
2525 >            }
2526 >            b = (b <= 1 || baseIndex == baseLimit)? 0 : (b >>> 1);
2527 >            if ((batch = b) > 0)
2528 >                addToPendingCount(1);
2529 >            return b;
2530 >        }
2531 >
2532      }
2533  
2534      /* ---------------- Public operations -------------- */
# Line 2447 | Line 2622 | public class ConcurrentHashMapV8<K, V>
2622      }
2623  
2624      /**
2625 +     * Creates a new {@link Set} backed by a ConcurrentHashMapV8
2626 +     * from the given type to {@code Boolean.TRUE}.
2627 +     *
2628 +     * @return the new set
2629 +     */
2630 +    public static <K> KeySetView<K,Boolean> newKeySet() {
2631 +        return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(),
2632 +                                      Boolean.TRUE);
2633 +    }
2634 +
2635 +    /**
2636 +     * Creates a new {@link Set} backed by a ConcurrentHashMapV8
2637 +     * from the given type to {@code Boolean.TRUE}.
2638 +     *
2639 +     * @param initialCapacity The implementation performs internal
2640 +     * sizing to accommodate this many elements.
2641 +     * @throws IllegalArgumentException if the initial capacity of
2642 +     * elements is negative
2643 +     * @return the new set
2644 +     */
2645 +    public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) {
2646 +        return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(initialCapacity),
2647 +                                      Boolean.TRUE);
2648 +    }
2649 +
2650 +    /**
2651       * {@inheritDoc}
2652       */
2653      public boolean isEmpty() {
# Line 2465 | Line 2666 | public class ConcurrentHashMapV8<K, V>
2666  
2667      /**
2668       * Returns the number of mappings. This method should be used
2669 <     * instead of {@link #size} because a ConcurrentHashMap may
2669 >     * instead of {@link #size} because a ConcurrentHashMapV8 may
2670       * contain more mappings than can be represented as an int. The
2671 <     * value returned is a snapshot; the actual count may differ if
2672 <     * there are ongoing concurrent insertions of removals.
2671 >     * value returned is an estimate; the actual count may differ if
2672 >     * there are concurrent insertions or removals.
2673       *
2674       * @return the number of mappings
2675       */
# Line 2488 | Line 2689 | public class ConcurrentHashMapV8<K, V>
2689       *
2690       * @throws NullPointerException if the specified key is null
2691       */
2692 <    @SuppressWarnings("unchecked")
2492 <    public V get(Object key) {
2692 >    @SuppressWarnings("unchecked") public V get(Object key) {
2693          if (key == null)
2694              throw new NullPointerException();
2695          return (V)internalGet(key);
2696      }
2697  
2698      /**
2699 +     * Returns the value to which the specified key is mapped,
2700 +     * or the given defaultValue if this map contains no mapping for the key.
2701 +     *
2702 +     * @param key the key
2703 +     * @param defaultValue the value to return if this map contains
2704 +     * no mapping for the given key
2705 +     * @return the mapping for the key, if present; else the defaultValue
2706 +     * @throws NullPointerException if the specified key is null
2707 +     */
2708 +    @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) {
2709 +        if (key == null)
2710 +            throw new NullPointerException();
2711 +        V v = (V) internalGet(key);
2712 +        return v == null ? defaultValue : v;
2713 +    }
2714 +
2715 +    /**
2716       * Tests if the specified object is a key in this table.
2717       *
2718       * @param  key   possible key
# Line 2555 | Line 2772 | public class ConcurrentHashMapV8<K, V>
2772       * Maps the specified key to the specified value in this table.
2773       * Neither the key nor the value can be null.
2774       *
2775 <     * <p> The value can be retrieved by calling the {@code get} method
2775 >     * <p>The value can be retrieved by calling the {@code get} method
2776       * with a key that is equal to the original key.
2777       *
2778       * @param key key with which the specified value is to be associated
# Line 2564 | Line 2781 | public class ConcurrentHashMapV8<K, V>
2781       *         {@code null} if there was no mapping for {@code key}
2782       * @throws NullPointerException if the specified key or value is null
2783       */
2784 <    @SuppressWarnings("unchecked")
2568 <    public V put(K key, V value) {
2784 >    @SuppressWarnings("unchecked") public V put(K key, V value) {
2785          if (key == null || value == null)
2786              throw new NullPointerException();
2787          return (V)internalPut(key, value);
# Line 2578 | Line 2794 | public class ConcurrentHashMapV8<K, V>
2794       *         or {@code null} if there was no mapping for the key
2795       * @throws NullPointerException if the specified key or value is null
2796       */
2797 <    @SuppressWarnings("unchecked")
2582 <    public V putIfAbsent(K key, V value) {
2797 >    @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) {
2798          if (key == null || value == null)
2799              throw new NullPointerException();
2800          return (V)internalPutIfAbsent(key, value);
# Line 2626 | Line 2841 | public class ConcurrentHashMapV8<K, V>
2841       * @param key key with which the specified value is to be associated
2842       * @param mappingFunction the function to compute a value
2843       * @return the current (existing or computed) value associated with
2844 <     *         the specified key, or null if the computed value is null.
2844 >     *         the specified key, or null if the computed value is null
2845       * @throws NullPointerException if the specified key or mappingFunction
2846       *         is null
2847       * @throws IllegalStateException if the computation detectably
# Line 2635 | Line 2850 | public class ConcurrentHashMapV8<K, V>
2850       * @throws RuntimeException or Error if the mappingFunction does so,
2851       *         in which case the mapping is left unestablished
2852       */
2853 <    @SuppressWarnings("unchecked")
2854 <    public V computeIfAbsent(K key, Fun<? super K, ? extends V> mappingFunction) {
2853 >    @SuppressWarnings("unchecked") public V computeIfAbsent
2854 >        (K key, Fun<? super K, ? extends V> mappingFunction) {
2855          if (key == null || mappingFunction == null)
2856              throw new NullPointerException();
2857          return (V)internalComputeIfAbsent(key, mappingFunction);
# Line 2676 | Line 2891 | public class ConcurrentHashMapV8<K, V>
2891       * @throws RuntimeException or Error if the remappingFunction does so,
2892       *         in which case the mapping is unchanged
2893       */
2894 <    @SuppressWarnings("unchecked")
2895 <    public V computeIfPresent(K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2894 >    @SuppressWarnings("unchecked") public V computeIfPresent
2895 >        (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2896          if (key == null || remappingFunction == null)
2897              throw new NullPointerException();
2898          return (V)internalCompute(key, true, remappingFunction);
# Line 2723 | Line 2938 | public class ConcurrentHashMapV8<K, V>
2938       * @throws RuntimeException or Error if the remappingFunction does so,
2939       *         in which case the mapping is unchanged
2940       */
2941 <    @SuppressWarnings("unchecked")
2942 <    public V compute(K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2941 >    @SuppressWarnings("unchecked") public V compute
2942 >        (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2943          if (key == null || remappingFunction == null)
2944              throw new NullPointerException();
2945          return (V)internalCompute(key, false, remappingFunction);
# Line 2755 | Line 2970 | public class ConcurrentHashMapV8<K, V>
2970       * so the computation should be short and simple, and must not
2971       * attempt to update any other mappings of this Map.
2972       */
2973 <    @SuppressWarnings("unchecked")
2974 <    public V merge(K key, V value, BiFun<? super V, ? super V, ? extends V> remappingFunction) {
2973 >    @SuppressWarnings("unchecked") public V merge
2974 >        (K key, V value, BiFun<? super V, ? super V, ? extends V> remappingFunction) {
2975          if (key == null || value == null || remappingFunction == null)
2976              throw new NullPointerException();
2977          return (V)internalMerge(key, value, remappingFunction);
# Line 2771 | Line 2986 | public class ConcurrentHashMapV8<K, V>
2986       *         {@code null} if there was no mapping for {@code key}
2987       * @throws NullPointerException if the specified key is null
2988       */
2989 <    @SuppressWarnings("unchecked")
2775 <        public V remove(Object key) {
2989 >    @SuppressWarnings("unchecked") public V remove(Object key) {
2990          if (key == null)
2991              throw new NullPointerException();
2992          return (V)internalReplace(key, null, null);
# Line 2809 | Line 3023 | public class ConcurrentHashMapV8<K, V>
3023       *         or {@code null} if there was no mapping for the key
3024       * @throws NullPointerException if the specified key or value is null
3025       */
3026 <    @SuppressWarnings("unchecked")
2813 <        public V replace(K key, V value) {
3026 >    @SuppressWarnings("unchecked") public V replace(K key, V value) {
3027          if (key == null || value == null)
3028              throw new NullPointerException();
3029          return (V)internalReplace(key, value, null);
# Line 2826 | Line 3039 | public class ConcurrentHashMapV8<K, V>
3039      /**
3040       * Returns a {@link Set} view of the keys contained in this map.
3041       * The set is backed by the map, so changes to the map are
3042 <     * reflected in the set, and vice-versa.  The set supports element
2830 <     * removal, which removes the corresponding mapping from this map,
2831 <     * via the {@code Iterator.remove}, {@code Set.remove},
2832 <     * {@code removeAll}, {@code retainAll}, and {@code clear}
2833 <     * operations.  It does not support the {@code add} or
2834 <     * {@code addAll} operations.
3042 >     * reflected in the set, and vice-versa.
3043       *
3044 <     * <p>The view's {@code iterator} is a "weakly consistent" iterator
3045 <     * that will never throw {@link ConcurrentModificationException},
3046 <     * and guarantees to traverse elements as they existed upon
3047 <     * construction of the iterator, and may (but is not guaranteed to)
3048 <     * reflect any modifications subsequent to construction.
3044 >     * @return the set view
3045 >     */
3046 >    public KeySetView<K,V> keySet() {
3047 >        KeySetView<K,V> ks = keySet;
3048 >        return (ks != null) ? ks : (keySet = new KeySetView<K,V>(this, null));
3049 >    }
3050 >
3051 >    /**
3052 >     * Returns a {@link Set} view of the keys in this map, using the
3053 >     * given common mapped value for any additions (i.e., {@link
3054 >     * Collection#add} and {@link Collection#addAll}). This is of
3055 >     * course only appropriate if it is acceptable to use the same
3056 >     * value for all additions from this view.
3057 >     *
3058 >     * @param mappedValue the mapped value to use for any
3059 >     * additions.
3060 >     * @return the set view
3061 >     * @throws NullPointerException if the mappedValue is null
3062       */
3063 <    public Set<K> keySet() {
3064 <        KeySet<K,V> ks = keySet;
3065 <        return (ks != null) ? ks : (keySet = new KeySet<K,V>(this));
3063 >    public KeySetView<K,V> keySet(V mappedValue) {
3064 >        if (mappedValue == null)
3065 >            throw new NullPointerException();
3066 >        return new KeySetView<K,V>(this, mappedValue);
3067      }
3068  
3069      /**
3070       * Returns a {@link Collection} view of the values contained in this map.
3071       * The collection is backed by the map, so changes to the map are
3072 <     * reflected in the collection, and vice-versa.  The collection
2851 <     * supports element removal, which removes the corresponding
2852 <     * mapping from this map, via the {@code Iterator.remove},
2853 <     * {@code Collection.remove}, {@code removeAll},
2854 <     * {@code retainAll}, and {@code clear} operations.  It does not
2855 <     * support the {@code add} or {@code addAll} operations.
2856 <     *
2857 <     * <p>The view's {@code iterator} is a "weakly consistent" iterator
2858 <     * that will never throw {@link ConcurrentModificationException},
2859 <     * and guarantees to traverse elements as they existed upon
2860 <     * construction of the iterator, and may (but is not guaranteed to)
2861 <     * reflect any modifications subsequent to construction.
3072 >     * reflected in the collection, and vice-versa.
3073       */
3074 <    public Collection<V> values() {
3075 <        Values<K,V> vs = values;
3076 <        return (vs != null) ? vs : (values = new Values<K,V>(this));
3074 >    public ValuesView<K,V> values() {
3075 >        ValuesView<K,V> vs = values;
3076 >        return (vs != null) ? vs : (values = new ValuesView<K,V>(this));
3077      }
3078  
3079      /**
# Line 2882 | Line 3093 | public class ConcurrentHashMapV8<K, V>
3093       * reflect any modifications subsequent to construction.
3094       */
3095      public Set<Map.Entry<K,V>> entrySet() {
3096 <        EntrySet<K,V> es = entrySet;
3097 <        return (es != null) ? es : (entrySet = new EntrySet<K,V>(this));
3096 >        EntrySetView<K,V> es = entrySet;
3097 >        return (es != null) ? es : (entrySet = new EntrySetView<K,V>(this));
3098      }
3099  
3100      /**
# Line 3016 | Line 3227 | public class ConcurrentHashMapV8<K, V>
3227  
3228      /* ----------------Iterators -------------- */
3229  
3230 <    @SuppressWarnings("serial")
3020 <    static final class KeyIterator<K,V> extends Traverser<K,V,Object>
3230 >    @SuppressWarnings("serial") static final class KeyIterator<K,V> extends Traverser<K,V,Object>
3231          implements Spliterator<K>, Enumeration<K> {
3232          KeyIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3233 <        KeyIterator(Traverser<K,V,Object> it, boolean split) {
3234 <            super(it, split);
3233 >        KeyIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3234 >            super(map, it, -1);
3235          }
3236          public KeyIterator<K,V> split() {
3237 <            if (last != null || (next != null && nextVal == null))
3237 >            if (nextKey != null)
3238                  throw new IllegalStateException();
3239 <            return new KeyIterator<K,V>(this, true);
3239 >            return new KeyIterator<K,V>(map, this);
3240          }
3241 <        @SuppressWarnings("unchecked")
3032 <            public final K next() {
3241 >        @SuppressWarnings("unchecked") public final K next() {
3242              if (nextVal == null && advance() == null)
3243                  throw new NoSuchElementException();
3244              Object k = nextKey;
# Line 3040 | Line 3249 | public class ConcurrentHashMapV8<K, V>
3249          public final K nextElement() { return next(); }
3250      }
3251  
3252 <    @SuppressWarnings("serial")
3044 <    static final class ValueIterator<K,V> extends Traverser<K,V,Object>
3252 >    @SuppressWarnings("serial") static final class ValueIterator<K,V> extends Traverser<K,V,Object>
3253          implements Spliterator<V>, Enumeration<V> {
3254          ValueIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3255 <        ValueIterator(Traverser<K,V,Object> it, boolean split) {
3256 <            super(it, split);
3255 >        ValueIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3256 >            super(map, it, -1);
3257          }
3258          public ValueIterator<K,V> split() {
3259 <            if (last != null || (next != null && nextVal == null))
3259 >            if (nextKey != null)
3260                  throw new IllegalStateException();
3261 <            return new ValueIterator<K,V>(this, true);
3261 >            return new ValueIterator<K,V>(map, this);
3262          }
3263  
3264 <        @SuppressWarnings("unchecked")
3057 <            public final V next() {
3264 >        @SuppressWarnings("unchecked") public final V next() {
3265              Object v;
3266              if ((v = nextVal) == null && (v = advance()) == null)
3267                  throw new NoSuchElementException();
# Line 3065 | Line 3272 | public class ConcurrentHashMapV8<K, V>
3272          public final V nextElement() { return next(); }
3273      }
3274  
3275 <    @SuppressWarnings("serial")
3069 <    static final class EntryIterator<K,V> extends Traverser<K,V,Object>
3275 >    @SuppressWarnings("serial") static final class EntryIterator<K,V> extends Traverser<K,V,Object>
3276          implements Spliterator<Map.Entry<K,V>> {
3277          EntryIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3278 <        EntryIterator(Traverser<K,V,Object> it, boolean split) {
3279 <            super(it, split);
3278 >        EntryIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3279 >            super(map, it, -1);
3280          }
3281          public EntryIterator<K,V> split() {
3282 <            if (last != null || (next != null && nextVal == null))
3282 >            if (nextKey != null)
3283                  throw new IllegalStateException();
3284 <            return new EntryIterator<K,V>(this, true);
3284 >            return new EntryIterator<K,V>(map, this);
3285          }
3286  
3287 <        @SuppressWarnings("unchecked")
3082 <            public final Map.Entry<K,V> next() {
3287 >        @SuppressWarnings("unchecked") public final Map.Entry<K,V> next() {
3288              Object v;
3289              if ((v = nextVal) == null && (v = advance()) == null)
3290                  throw new NoSuchElementException();
# Line 3132 | Line 3337 | public class ConcurrentHashMapV8<K, V>
3337          }
3338      }
3339  
3135    /* ----------------Views -------------- */
3136
3340      /**
3341 <     * Base class for views.
3341 >     * Returns exportable snapshot entry for the given key and value
3342 >     * when write-through can't or shouldn't be used.
3343       */
3344 <    static abstract class CHMView<K, V> {
3345 <        final ConcurrentHashMapV8<K, V> map;
3142 <        CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
3143 <        public final int size()                 { return map.size(); }
3144 <        public final boolean isEmpty()          { return map.isEmpty(); }
3145 <        public final void clear()               { map.clear(); }
3146 <
3147 <        // implementations below rely on concrete classes supplying these
3148 <        abstract public Iterator<?> iterator();
3149 <        abstract public boolean contains(Object o);
3150 <        abstract public boolean remove(Object o);
3151 <
3152 <        private static final String oomeMsg = "Required array size too large";
3153 <
3154 <        public final Object[] toArray() {
3155 <            long sz = map.mappingCount();
3156 <            if (sz > (long)(MAX_ARRAY_SIZE))
3157 <                throw new OutOfMemoryError(oomeMsg);
3158 <            int n = (int)sz;
3159 <            Object[] r = new Object[n];
3160 <            int i = 0;
3161 <            Iterator<?> it = iterator();
3162 <            while (it.hasNext()) {
3163 <                if (i == n) {
3164 <                    if (n >= MAX_ARRAY_SIZE)
3165 <                        throw new OutOfMemoryError(oomeMsg);
3166 <                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3167 <                        n = MAX_ARRAY_SIZE;
3168 <                    else
3169 <                        n += (n >>> 1) + 1;
3170 <                    r = Arrays.copyOf(r, n);
3171 <                }
3172 <                r[i++] = it.next();
3173 <            }
3174 <            return (i == n) ? r : Arrays.copyOf(r, i);
3175 <        }
3176 <
3177 <        @SuppressWarnings("unchecked")
3178 <            public final <T> T[] toArray(T[] a) {
3179 <            long sz = map.mappingCount();
3180 <            if (sz > (long)(MAX_ARRAY_SIZE))
3181 <                throw new OutOfMemoryError(oomeMsg);
3182 <            int m = (int)sz;
3183 <            T[] r = (a.length >= m) ? a :
3184 <                (T[])java.lang.reflect.Array
3185 <                .newInstance(a.getClass().getComponentType(), m);
3186 <            int n = r.length;
3187 <            int i = 0;
3188 <            Iterator<?> it = iterator();
3189 <            while (it.hasNext()) {
3190 <                if (i == n) {
3191 <                    if (n >= MAX_ARRAY_SIZE)
3192 <                        throw new OutOfMemoryError(oomeMsg);
3193 <                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3194 <                        n = MAX_ARRAY_SIZE;
3195 <                    else
3196 <                        n += (n >>> 1) + 1;
3197 <                    r = Arrays.copyOf(r, n);
3198 <                }
3199 <                r[i++] = (T)it.next();
3200 <            }
3201 <            if (a == r && i < n) {
3202 <                r[i] = null; // null-terminate
3203 <                return r;
3204 <            }
3205 <            return (i == n) ? r : Arrays.copyOf(r, i);
3206 <        }
3207 <
3208 <        public final int hashCode() {
3209 <            int h = 0;
3210 <            for (Iterator<?> it = iterator(); it.hasNext();)
3211 <                h += it.next().hashCode();
3212 <            return h;
3213 <        }
3214 <
3215 <        public final String toString() {
3216 <            StringBuilder sb = new StringBuilder();
3217 <            sb.append('[');
3218 <            Iterator<?> it = iterator();
3219 <            if (it.hasNext()) {
3220 <                for (;;) {
3221 <                    Object e = it.next();
3222 <                    sb.append(e == this ? "(this Collection)" : e);
3223 <                    if (!it.hasNext())
3224 <                        break;
3225 <                    sb.append(',').append(' ');
3226 <                }
3227 <            }
3228 <            return sb.append(']').toString();
3229 <        }
3230 <
3231 <        public final boolean containsAll(Collection<?> c) {
3232 <            if (c != this) {
3233 <                for (Iterator<?> it = c.iterator(); it.hasNext();) {
3234 <                    Object e = it.next();
3235 <                    if (e == null || !contains(e))
3236 <                        return false;
3237 <                }
3238 <            }
3239 <            return true;
3240 <        }
3241 <
3242 <        public final boolean removeAll(Collection<?> c) {
3243 <            boolean modified = false;
3244 <            for (Iterator<?> it = iterator(); it.hasNext();) {
3245 <                if (c.contains(it.next())) {
3246 <                    it.remove();
3247 <                    modified = true;
3248 <                }
3249 <            }
3250 <            return modified;
3251 <        }
3252 <
3253 <        public final boolean retainAll(Collection<?> c) {
3254 <            boolean modified = false;
3255 <            for (Iterator<?> it = iterator(); it.hasNext();) {
3256 <                if (!c.contains(it.next())) {
3257 <                    it.remove();
3258 <                    modified = true;
3259 <                }
3260 <            }
3261 <            return modified;
3262 <        }
3263 <
3264 <    }
3265 <
3266 <    static final class KeySet<K,V> extends CHMView<K,V> implements Set<K> {
3267 <        KeySet(ConcurrentHashMapV8<K, V> map)  {
3268 <            super(map);
3269 <        }
3270 <        public final boolean contains(Object o) { return map.containsKey(o); }
3271 <        public final boolean remove(Object o)   { return map.remove(o) != null; }
3272 <        public final Iterator<K> iterator() {
3273 <            return new KeyIterator<K,V>(map);
3274 <        }
3275 <        public final boolean add(K e) {
3276 <            throw new UnsupportedOperationException();
3277 <        }
3278 <        public final boolean addAll(Collection<? extends K> c) {
3279 <            throw new UnsupportedOperationException();
3280 <        }
3281 <        public boolean equals(Object o) {
3282 <            Set<?> c;
3283 <            return ((o instanceof Set) &&
3284 <                    ((c = (Set<?>)o) == this ||
3285 <                     (containsAll(c) && c.containsAll(this))));
3286 <        }
3287 <    }
3288 <
3289 <
3290 <    static final class Values<K,V> extends CHMView<K,V>
3291 <        implements Collection<V> {
3292 <        Values(ConcurrentHashMapV8<K, V> map)   { super(map); }
3293 <        public final boolean contains(Object o) { return map.containsValue(o); }
3294 <        public final boolean remove(Object o) {
3295 <            if (o != null) {
3296 <                Iterator<V> it = new ValueIterator<K,V>(map);
3297 <                while (it.hasNext()) {
3298 <                    if (o.equals(it.next())) {
3299 <                        it.remove();
3300 <                        return true;
3301 <                    }
3302 <                }
3303 <            }
3304 <            return false;
3305 <        }
3306 <        public final Iterator<V> iterator() {
3307 <            return new ValueIterator<K,V>(map);
3308 <        }
3309 <        public final boolean add(V e) {
3310 <            throw new UnsupportedOperationException();
3311 <        }
3312 <        public final boolean addAll(Collection<? extends V> c) {
3313 <            throw new UnsupportedOperationException();
3314 <        }
3315 <
3316 <    }
3317 <
3318 <    static final class EntrySet<K,V> extends CHMView<K,V>
3319 <        implements Set<Map.Entry<K,V>> {
3320 <        EntrySet(ConcurrentHashMapV8<K, V> map) { super(map); }
3321 <        public final boolean contains(Object o) {
3322 <            Object k, v, r; Map.Entry<?,?> e;
3323 <            return ((o instanceof Map.Entry) &&
3324 <                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
3325 <                    (r = map.get(k)) != null &&
3326 <                    (v = e.getValue()) != null &&
3327 <                    (v == r || v.equals(r)));
3328 <        }
3329 <        public final boolean remove(Object o) {
3330 <            Object k, v; Map.Entry<?,?> e;
3331 <            return ((o instanceof Map.Entry) &&
3332 <                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
3333 <                    (v = e.getValue()) != null &&
3334 <                    map.remove(k, v));
3335 <        }
3336 <        public final Iterator<Map.Entry<K,V>> iterator() {
3337 <            return new EntryIterator<K,V>(map);
3338 <        }
3339 <        public final boolean add(Entry<K,V> e) {
3340 <            throw new UnsupportedOperationException();
3341 <        }
3342 <        public final boolean addAll(Collection<? extends Entry<K,V>> c) {
3343 <            throw new UnsupportedOperationException();
3344 <        }
3345 <        public boolean equals(Object o) {
3346 <            Set<?> c;
3347 <            return ((o instanceof Set) &&
3348 <                    ((c = (Set<?>)o) == this ||
3349 <                     (containsAll(c) && c.containsAll(this))));
3350 <        }
3344 >    static <K,V> AbstractMap.SimpleEntry<K,V> entryFor(K k, V v) {
3345 >        return new AbstractMap.SimpleEntry<K,V>(k, v);
3346      }
3347  
3348      /* ---------------- Serialization Support -------------- */
# Line 3371 | Line 3366 | public class ConcurrentHashMapV8<K, V>
3366       * for each key-value mapping, followed by a null pair.
3367       * The key-value mappings are emitted in no particular order.
3368       */
3369 <    @SuppressWarnings("unchecked")
3375 <        private void writeObject(java.io.ObjectOutputStream s)
3369 >    @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s)
3370          throws java.io.IOException {
3371          if (segments == null) { // for serialization compatibility
3372              segments = (Segment<K,V>[])
# Line 3396 | Line 3390 | public class ConcurrentHashMapV8<K, V>
3390       * Reconstitutes the instance from a stream (that is, deserializes it).
3391       * @param s the stream
3392       */
3393 <    @SuppressWarnings("unchecked")
3400 <        private void readObject(java.io.ObjectInputStream s)
3393 >    @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s)
3394          throws java.io.IOException, ClassNotFoundException {
3395          s.defaultReadObject();
3396          this.segments = null; // unneeded
# Line 3518 | Line 3511 | public class ConcurrentHashMapV8<K, V>
3511      // -------------------------------------------------------
3512  
3513      /**
3514 <     * Returns an extended {@link Parallel} view of this map using the
3522 <     * given executor for bulk parallel operations.
3514 >     * Performs the given action for each (key, value).
3515       *
3516 <     * @param executor the executor
3525 <     * @return a parallel view
3516 >     * @param action the action
3517       */
3518 <    public Parallel parallel(ForkJoinPool executor)  {
3519 <        return new Parallel(executor);
3518 >    public void forEach(BiAction<K,V> action) {
3519 >        ForkJoinTasks.forEach
3520 >            (this, action).invoke();
3521      }
3522  
3523      /**
3524 <     * An extended view of a ConcurrentHashMap supporting bulk
3525 <     * parallel operations. These operations are designed to be
3526 <     * safely, and often sensibly, applied even with maps that are
3527 <     * being concurrently updated by other threads; for example, when
3528 <     * computing a snapshot summary of the values in a shared
3529 <     * registry.  There are three kinds of operation, each with four
3530 <     * forms, accepting functions with Keys, Values, Entries, and
3531 <     * (Key, Value) arguments and/or return values. Because the
3532 <     * elements of a ConcurrentHashMap are not ordered in any
3533 <     * particular way, and may be processed in different orders in
3534 <     * different parallel executions, the correctness of supplied
3535 <     * functions should not depend on any ordering, or on any other
3536 <     * objects or values that may transiently change while computation
3537 <     * is in progress; and except for forEach actions, should ideally
3538 <     * be side-effect-free.
3539 <     *
3540 <     * <ul>
3541 <     * <li> forEach: Perform a given action on each element.
3542 <     * A variant form applies a given transformation on each element
3543 <     * before performing the action.</li>
3544 <     *
3545 <     * <li> search: Return the first available non-null result of
3546 <     * applying a given function on each element; skipping further
3547 <     * search when a result is found.</li>
3548 <     *
3549 <     * <li> reduce: Accumulate each element.  The supplied reduction
3550 <     * function cannot rely on ordering (more formally, it should be
3551 <     * both associative and commutative).  There are five variants:
3552 <     *
3553 <     * <ul>
3554 <     *
3555 <     * <li> Plain reductions. (There is not a form of this method for
3556 <     * (key, value) function arguments since there is no corresponding
3557 <     * return type.)</li>
3558 <     *
3559 <     * <li> Mapped reductions that accumulate the results of a given
3560 <     * function applied to each element.</li>
3561 <     *
3562 <     * <li> Reductions to scalar doubles, longs, and ints, using a
3563 <     * given basis value.</li>
3564 <     *
3565 <     * </li>
3566 <     * </ul>
3567 <     * </ul>
3568 <     *
3569 <     * <p>The concurrency properties of the bulk operations follow
3570 <     * from those of ConcurrentHashMap: Any non-null result returned
3571 <     * from {@code get(key)} and related access methods bears a
3572 <     * happens-before relation with the associated insertion or
3573 <     * update.  The result of any bulk operation reflects the
3574 <     * composition of these per-element relations (but is not
3575 <     * necessarily atomic with respect to the map as a whole unless it
3576 <     * is somehow known to be quiescent).  Conversely, because keys
3577 <     * and values in the map are never null, null serves as a reliable
3578 <     * atomic indicator of the current lack of any result.  To
3579 <     * maintain this property, null serves as an implicit basis for
3580 <     * all non-scalar reduction operations. For the double, long, and
3581 <     * int versions, the basis should be one that, when combined with
3582 <     * any other value, returns that other value (more formally, it
3583 <     * should be the identity element for the reduction). Most common
3584 <     * reductions have these properties; for example, computing a sum
3585 <     * with basis 0 or a minimum with basis MAX_VALUE.
3586 <     *
3587 <     * <p>Search and transformation functions provided as arguments
3588 <     * should similarly return null to indicate the lack of any result
3589 <     * (in which case it is not used). In the case of mapped
3590 <     * reductions, this also enables transformations to serve as
3591 <     * filters, returning null (or, in the case of primitive
3592 <     * specializations, the identity basis) if the element should not
3593 <     * be combined. You can create compound transformations and
3594 <     * filterings by composing them yourself under this "null means
3595 <     * there is nothing there now" rule before using them in search or
3596 <     * reduce operations.
3597 <     *
3598 <     * <p>Methods accepting and/or returning Entry arguments maintain
3599 <     * key-value associations. They may be useful for example when
3600 <     * finding the key for the greatest value. Note that "plain" Entry
3601 <     * arguments can be supplied using {@code new
3602 <     * AbstractMap.SimpleEntry(k,v)}.
3603 <     *
3604 <     * <p> Bulk operations may complete abruptly, throwing an
3605 <     * exception encountered in the application of a supplied
3606 <     * function. Bear in mind when handling such exceptions that other
3607 <     * concurrently executing functions could also have thrown
3608 <     * exceptions, or would have done so if the first exception had
3609 <     * not occurred.
3610 <     *
3611 <     * <p>Parallel speedups compared to sequential processing are
3612 <     * common but not guaranteed.  Operations involving brief
3613 <     * functions on small maps may execute more slowly than sequential
3614 <     * loops if the underlying work to parallelize the computation is
3615 <     * more expensive than the computation itself. Similarly,
3616 <     * parallelization may not lead to much actual parallelism if all
3617 <     * processors are busy performing unrelated tasks.
3618 <     *
3619 <     * <p> All arguments to all task methods must be non-null.
3620 <     *
3621 <     * <p><em>jsr166e note: During transition, this class
3622 <     * uses nested functional interfaces with different names but the
3623 <     * same forms as those expected for JDK8.<em>
3624 <     */
3625 <    public class Parallel {
3626 <        final ForkJoinPool fjp;
3627 <
3628 <        /**
3629 <         * Returns an extended view of this map using the given
3630 <         * executor for bulk parallel operations.
3631 <         *
3632 <         * @param executor the executor
3633 <         */
3634 <        public Parallel(ForkJoinPool executor)  {
3635 <            this.fjp = executor;
3636 <        }
3524 >     * Performs the given action for each non-null transformation
3525 >     * of each (key, value).
3526 >     *
3527 >     * @param transformer a function returning the transformation
3528 >     * for an element, or null of there is no transformation (in
3529 >     * which case the action is not applied).
3530 >     * @param action the action
3531 >     */
3532 >    public <U> void forEach(BiFun<? super K, ? super V, ? extends U> transformer,
3533 >                            Action<U> action) {
3534 >        ForkJoinTasks.forEach
3535 >            (this, transformer, action).invoke();
3536 >    }
3537 >
3538 >    /**
3539 >     * Returns a non-null result from applying the given search
3540 >     * function on each (key, value), or null if none.  Upon
3541 >     * success, further element processing is suppressed and the
3542 >     * results of any other parallel invocations of the search
3543 >     * function are ignored.
3544 >     *
3545 >     * @param searchFunction a function returning a non-null
3546 >     * result on success, else null
3547 >     * @return a non-null result from applying the given search
3548 >     * function on each (key, value), or null if none
3549 >     */
3550 >    public <U> U search(BiFun<? super K, ? super V, ? extends U> searchFunction) {
3551 >        return ForkJoinTasks.search
3552 >            (this, searchFunction).invoke();
3553 >    }
3554 >
3555 >    /**
3556 >     * Returns the result of accumulating the given transformation
3557 >     * of all (key, value) pairs using the given reducer to
3558 >     * combine values, or null if none.
3559 >     *
3560 >     * @param transformer a function returning the transformation
3561 >     * for an element, or null of there is no transformation (in
3562 >     * which case it is not combined).
3563 >     * @param reducer a commutative associative combining function
3564 >     * @return the result of accumulating the given transformation
3565 >     * of all (key, value) pairs
3566 >     */
3567 >    public <U> U reduce(BiFun<? super K, ? super V, ? extends U> transformer,
3568 >                        BiFun<? super U, ? super U, ? extends U> reducer) {
3569 >        return ForkJoinTasks.reduce
3570 >            (this, transformer, reducer).invoke();
3571 >    }
3572 >
3573 >    /**
3574 >     * Returns the result of accumulating the given transformation
3575 >     * of all (key, value) pairs using the given reducer to
3576 >     * combine values, and the given basis as an identity value.
3577 >     *
3578 >     * @param transformer a function returning the transformation
3579 >     * for an element
3580 >     * @param basis the identity (initial default value) for the reduction
3581 >     * @param reducer a commutative associative combining function
3582 >     * @return the result of accumulating the given transformation
3583 >     * of all (key, value) pairs
3584 >     */
3585 >    public double reduceToDouble(ObjectByObjectToDouble<? super K, ? super V> transformer,
3586 >                                 double basis,
3587 >                                 DoubleByDoubleToDouble reducer) {
3588 >        return ForkJoinTasks.reduceToDouble
3589 >            (this, transformer, basis, reducer).invoke();
3590 >    }
3591 >
3592 >    /**
3593 >     * Returns the result of accumulating the given transformation
3594 >     * of all (key, value) pairs using the given reducer to
3595 >     * combine values, and the given basis as an identity value.
3596 >     *
3597 >     * @param transformer a function returning the transformation
3598 >     * for an element
3599 >     * @param basis the identity (initial default value) for the reduction
3600 >     * @param reducer a commutative associative combining function
3601 >     * @return the result of accumulating the given transformation
3602 >     * of all (key, value) pairs
3603 >     */
3604 >    public long reduceToLong(ObjectByObjectToLong<? super K, ? super V> transformer,
3605 >                             long basis,
3606 >                             LongByLongToLong reducer) {
3607 >        return ForkJoinTasks.reduceToLong
3608 >            (this, transformer, basis, reducer).invoke();
3609 >    }
3610 >
3611 >    /**
3612 >     * Returns the result of accumulating the given transformation
3613 >     * of all (key, value) pairs using the given reducer to
3614 >     * combine values, and the given basis as an identity value.
3615 >     *
3616 >     * @param transformer a function returning the transformation
3617 >     * for an element
3618 >     * @param basis the identity (initial default value) for the reduction
3619 >     * @param reducer a commutative associative combining function
3620 >     * @return the result of accumulating the given transformation
3621 >     * of all (key, value) pairs
3622 >     */
3623 >    public int reduceToInt(ObjectByObjectToInt<? super K, ? super V> transformer,
3624 >                           int basis,
3625 >                           IntByIntToInt reducer) {
3626 >        return ForkJoinTasks.reduceToInt
3627 >            (this, transformer, basis, reducer).invoke();
3628 >    }
3629 >
3630 >    /**
3631 >     * Performs the given action for each key.
3632 >     *
3633 >     * @param action the action
3634 >     */
3635 >    public void forEachKey(Action<K> action) {
3636 >        ForkJoinTasks.forEachKey
3637 >            (this, action).invoke();
3638 >    }
3639 >
3640 >    /**
3641 >     * Performs the given action for each non-null transformation
3642 >     * of each key.
3643 >     *
3644 >     * @param transformer a function returning the transformation
3645 >     * for an element, or null of there is no transformation (in
3646 >     * which case the action is not applied).
3647 >     * @param action the action
3648 >     */
3649 >    public <U> void forEachKey(Fun<? super K, ? extends U> transformer,
3650 >                               Action<U> action) {
3651 >        ForkJoinTasks.forEachKey
3652 >            (this, transformer, action).invoke();
3653 >    }
3654 >
3655 >    /**
3656 >     * Returns a non-null result from applying the given search
3657 >     * function on each key, or null if none. Upon success,
3658 >     * further element processing is suppressed and the results of
3659 >     * any other parallel invocations of the search function are
3660 >     * ignored.
3661 >     *
3662 >     * @param searchFunction a function returning a non-null
3663 >     * result on success, else null
3664 >     * @return a non-null result from applying the given search
3665 >     * function on each key, or null if none
3666 >     */
3667 >    public <U> U searchKeys(Fun<? super K, ? extends U> searchFunction) {
3668 >        return ForkJoinTasks.searchKeys
3669 >            (this, searchFunction).invoke();
3670 >    }
3671 >
3672 >    /**
3673 >     * Returns the result of accumulating all keys using the given
3674 >     * reducer to combine values, or null if none.
3675 >     *
3676 >     * @param reducer a commutative associative combining function
3677 >     * @return the result of accumulating all keys using the given
3678 >     * reducer to combine values, or null if none
3679 >     */
3680 >    public K reduceKeys(BiFun<? super K, ? super K, ? extends K> reducer) {
3681 >        return ForkJoinTasks.reduceKeys
3682 >            (this, reducer).invoke();
3683 >    }
3684 >
3685 >    /**
3686 >     * Returns the result of accumulating the given transformation
3687 >     * of all keys using the given reducer to combine values, or
3688 >     * null if none.
3689 >     *
3690 >     * @param transformer a function returning the transformation
3691 >     * for an element, or null of there is no transformation (in
3692 >     * which case it is not combined).
3693 >     * @param reducer a commutative associative combining function
3694 >     * @return the result of accumulating the given transformation
3695 >     * of all keys
3696 >     */
3697 >    public <U> U reduceKeys(Fun<? super K, ? extends U> transformer,
3698 >                            BiFun<? super U, ? super U, ? extends U> reducer) {
3699 >        return ForkJoinTasks.reduceKeys
3700 >            (this, transformer, reducer).invoke();
3701 >    }
3702 >
3703 >    /**
3704 >     * Returns the result of accumulating the given transformation
3705 >     * of all keys using the given reducer to combine values, and
3706 >     * the given basis as an identity value.
3707 >     *
3708 >     * @param transformer a function returning the transformation
3709 >     * for an element
3710 >     * @param basis the identity (initial default value) for the reduction
3711 >     * @param reducer a commutative associative combining function
3712 >     * @return  the result of accumulating the given transformation
3713 >     * of all keys
3714 >     */
3715 >    public double reduceKeysToDouble(ObjectToDouble<? super K> transformer,
3716 >                                     double basis,
3717 >                                     DoubleByDoubleToDouble reducer) {
3718 >        return ForkJoinTasks.reduceKeysToDouble
3719 >            (this, transformer, basis, reducer).invoke();
3720 >    }
3721 >
3722 >    /**
3723 >     * Returns the result of accumulating the given transformation
3724 >     * of all keys using the given reducer to combine values, and
3725 >     * the given basis as an identity value.
3726 >     *
3727 >     * @param transformer a function returning the transformation
3728 >     * for an element
3729 >     * @param basis the identity (initial default value) for the reduction
3730 >     * @param reducer a commutative associative combining function
3731 >     * @return the result of accumulating the given transformation
3732 >     * of all keys
3733 >     */
3734 >    public long reduceKeysToLong(ObjectToLong<? super K> transformer,
3735 >                                 long basis,
3736 >                                 LongByLongToLong reducer) {
3737 >        return ForkJoinTasks.reduceKeysToLong
3738 >            (this, transformer, basis, reducer).invoke();
3739 >    }
3740 >
3741 >    /**
3742 >     * Returns the result of accumulating the given transformation
3743 >     * of all keys using the given reducer to combine values, and
3744 >     * the given basis as an identity value.
3745 >     *
3746 >     * @param transformer a function returning the transformation
3747 >     * for an element
3748 >     * @param basis the identity (initial default value) for the reduction
3749 >     * @param reducer a commutative associative combining function
3750 >     * @return the result of accumulating the given transformation
3751 >     * of all keys
3752 >     */
3753 >    public int reduceKeysToInt(ObjectToInt<? super K> transformer,
3754 >                               int basis,
3755 >                               IntByIntToInt reducer) {
3756 >        return ForkJoinTasks.reduceKeysToInt
3757 >            (this, transformer, basis, reducer).invoke();
3758 >    }
3759 >
3760 >    /**
3761 >     * Performs the given action for each value.
3762 >     *
3763 >     * @param action the action
3764 >     */
3765 >    public void forEachValue(Action<V> action) {
3766 >        ForkJoinTasks.forEachValue
3767 >            (this, action).invoke();
3768 >    }
3769 >
3770 >    /**
3771 >     * Performs the given action for each non-null transformation
3772 >     * of each value.
3773 >     *
3774 >     * @param transformer a function returning the transformation
3775 >     * for an element, or null of there is no transformation (in
3776 >     * which case the action is not applied).
3777 >     */
3778 >    public <U> void forEachValue(Fun<? super V, ? extends U> transformer,
3779 >                                 Action<U> action) {
3780 >        ForkJoinTasks.forEachValue
3781 >            (this, transformer, action).invoke();
3782 >    }
3783 >
3784 >    /**
3785 >     * Returns a non-null result from applying the given search
3786 >     * function on each value, or null if none.  Upon success,
3787 >     * further element processing is suppressed and the results of
3788 >     * any other parallel invocations of the search function are
3789 >     * ignored.
3790 >     *
3791 >     * @param searchFunction a function returning a non-null
3792 >     * result on success, else null
3793 >     * @return a non-null result from applying the given search
3794 >     * function on each value, or null if none
3795 >     *
3796 >     */
3797 >    public <U> U searchValues(Fun<? super V, ? extends U> searchFunction) {
3798 >        return ForkJoinTasks.searchValues
3799 >            (this, searchFunction).invoke();
3800 >    }
3801 >
3802 >    /**
3803 >     * Returns the result of accumulating all values using the
3804 >     * given reducer to combine values, or null if none.
3805 >     *
3806 >     * @param reducer a commutative associative combining function
3807 >     * @return  the result of accumulating all values
3808 >     */
3809 >    public V reduceValues(BiFun<? super V, ? super V, ? extends V> reducer) {
3810 >        return ForkJoinTasks.reduceValues
3811 >            (this, reducer).invoke();
3812 >    }
3813 >
3814 >    /**
3815 >     * Returns the result of accumulating the given transformation
3816 >     * of all values using the given reducer to combine values, or
3817 >     * null if none.
3818 >     *
3819 >     * @param transformer a function returning the transformation
3820 >     * for an element, or null of there is no transformation (in
3821 >     * which case it is not combined).
3822 >     * @param reducer a commutative associative combining function
3823 >     * @return the result of accumulating the given transformation
3824 >     * of all values
3825 >     */
3826 >    public <U> U reduceValues(Fun<? super V, ? extends U> transformer,
3827 >                              BiFun<? super U, ? super U, ? extends U> reducer) {
3828 >        return ForkJoinTasks.reduceValues
3829 >            (this, transformer, reducer).invoke();
3830 >    }
3831 >
3832 >    /**
3833 >     * Returns the result of accumulating the given transformation
3834 >     * of all values using the given reducer to combine values,
3835 >     * and the given basis as an identity value.
3836 >     *
3837 >     * @param transformer a function returning the transformation
3838 >     * for an element
3839 >     * @param basis the identity (initial default value) for the reduction
3840 >     * @param reducer a commutative associative combining function
3841 >     * @return the result of accumulating the given transformation
3842 >     * of all values
3843 >     */
3844 >    public double reduceValuesToDouble(ObjectToDouble<? super V> transformer,
3845 >                                       double basis,
3846 >                                       DoubleByDoubleToDouble reducer) {
3847 >        return ForkJoinTasks.reduceValuesToDouble
3848 >            (this, transformer, basis, reducer).invoke();
3849 >    }
3850 >
3851 >    /**
3852 >     * Returns the result of accumulating the given transformation
3853 >     * of all values using the given reducer to combine values,
3854 >     * and the given basis as an identity value.
3855 >     *
3856 >     * @param transformer a function returning the transformation
3857 >     * for an element
3858 >     * @param basis the identity (initial default value) for the reduction
3859 >     * @param reducer a commutative associative combining function
3860 >     * @return the result of accumulating the given transformation
3861 >     * of all values
3862 >     */
3863 >    public long reduceValuesToLong(ObjectToLong<? super V> transformer,
3864 >                                   long basis,
3865 >                                   LongByLongToLong reducer) {
3866 >        return ForkJoinTasks.reduceValuesToLong
3867 >            (this, transformer, basis, reducer).invoke();
3868 >    }
3869 >
3870 >    /**
3871 >     * Returns the result of accumulating the given transformation
3872 >     * of all values using the given reducer to combine values,
3873 >     * and the given basis as an identity value.
3874 >     *
3875 >     * @param transformer a function returning the transformation
3876 >     * for an element
3877 >     * @param basis the identity (initial default value) for the reduction
3878 >     * @param reducer a commutative associative combining function
3879 >     * @return the result of accumulating the given transformation
3880 >     * of all values
3881 >     */
3882 >    public int reduceValuesToInt(ObjectToInt<? super V> transformer,
3883 >                                 int basis,
3884 >                                 IntByIntToInt reducer) {
3885 >        return ForkJoinTasks.reduceValuesToInt
3886 >            (this, transformer, basis, reducer).invoke();
3887 >    }
3888 >
3889 >    /**
3890 >     * Performs the given action for each entry.
3891 >     *
3892 >     * @param action the action
3893 >     */
3894 >    public void forEachEntry(Action<Map.Entry<K,V>> action) {
3895 >        ForkJoinTasks.forEachEntry
3896 >            (this, action).invoke();
3897 >    }
3898 >
3899 >    /**
3900 >     * Performs the given action for each non-null transformation
3901 >     * of each entry.
3902 >     *
3903 >     * @param transformer a function returning the transformation
3904 >     * for an element, or null of there is no transformation (in
3905 >     * which case the action is not applied).
3906 >     * @param action the action
3907 >     */
3908 >    public <U> void forEachEntry(Fun<Map.Entry<K,V>, ? extends U> transformer,
3909 >                                 Action<U> action) {
3910 >        ForkJoinTasks.forEachEntry
3911 >            (this, transformer, action).invoke();
3912 >    }
3913 >
3914 >    /**
3915 >     * Returns a non-null result from applying the given search
3916 >     * function on each entry, or null if none.  Upon success,
3917 >     * further element processing is suppressed and the results of
3918 >     * any other parallel invocations of the search function are
3919 >     * ignored.
3920 >     *
3921 >     * @param searchFunction a function returning a non-null
3922 >     * result on success, else null
3923 >     * @return a non-null result from applying the given search
3924 >     * function on each entry, or null if none
3925 >     */
3926 >    public <U> U searchEntries(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
3927 >        return ForkJoinTasks.searchEntries
3928 >            (this, searchFunction).invoke();
3929 >    }
3930 >
3931 >    /**
3932 >     * Returns the result of accumulating all entries using the
3933 >     * given reducer to combine values, or null if none.
3934 >     *
3935 >     * @param reducer a commutative associative combining function
3936 >     * @return the result of accumulating all entries
3937 >     */
3938 >    public Map.Entry<K,V> reduceEntries(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
3939 >        return ForkJoinTasks.reduceEntries
3940 >            (this, reducer).invoke();
3941 >    }
3942 >
3943 >    /**
3944 >     * Returns the result of accumulating the given transformation
3945 >     * of all entries using the given reducer to combine values,
3946 >     * or null if none.
3947 >     *
3948 >     * @param transformer a function returning the transformation
3949 >     * for an element, or null of there is no transformation (in
3950 >     * which case it is not combined).
3951 >     * @param reducer a commutative associative combining function
3952 >     * @return the result of accumulating the given transformation
3953 >     * of all entries
3954 >     */
3955 >    public <U> U reduceEntries(Fun<Map.Entry<K,V>, ? extends U> transformer,
3956 >                               BiFun<? super U, ? super U, ? extends U> reducer) {
3957 >        return ForkJoinTasks.reduceEntries
3958 >            (this, transformer, reducer).invoke();
3959 >    }
3960 >
3961 >    /**
3962 >     * Returns the result of accumulating the given transformation
3963 >     * of all entries using the given reducer to combine values,
3964 >     * and the given basis as an identity value.
3965 >     *
3966 >     * @param transformer a function returning the transformation
3967 >     * for an element
3968 >     * @param basis the identity (initial default value) for the reduction
3969 >     * @param reducer a commutative associative combining function
3970 >     * @return the result of accumulating the given transformation
3971 >     * of all entries
3972 >     */
3973 >    public double reduceEntriesToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
3974 >                                        double basis,
3975 >                                        DoubleByDoubleToDouble reducer) {
3976 >        return ForkJoinTasks.reduceEntriesToDouble
3977 >            (this, transformer, basis, reducer).invoke();
3978 >    }
3979 >
3980 >    /**
3981 >     * Returns the result of accumulating the given transformation
3982 >     * of all entries using the given reducer to combine values,
3983 >     * and the given basis as an identity value.
3984 >     *
3985 >     * @param transformer a function returning the transformation
3986 >     * for an element
3987 >     * @param basis the identity (initial default value) for the reduction
3988 >     * @param reducer a commutative associative combining function
3989 >     * @return  the result of accumulating the given transformation
3990 >     * of all entries
3991 >     */
3992 >    public long reduceEntriesToLong(ObjectToLong<Map.Entry<K,V>> transformer,
3993 >                                    long basis,
3994 >                                    LongByLongToLong reducer) {
3995 >        return ForkJoinTasks.reduceEntriesToLong
3996 >            (this, transformer, basis, reducer).invoke();
3997 >    }
3998 >
3999 >    /**
4000 >     * Returns the result of accumulating the given transformation
4001 >     * of all entries using the given reducer to combine values,
4002 >     * and the given basis as an identity value.
4003 >     *
4004 >     * @param transformer a function returning the transformation
4005 >     * for an element
4006 >     * @param basis the identity (initial default value) for the reduction
4007 >     * @param reducer a commutative associative combining function
4008 >     * @return the result of accumulating the given transformation
4009 >     * of all entries
4010 >     */
4011 >    public int reduceEntriesToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4012 >                                  int basis,
4013 >                                  IntByIntToInt reducer) {
4014 >        return ForkJoinTasks.reduceEntriesToInt
4015 >            (this, transformer, basis, reducer).invoke();
4016 >    }
4017 >
4018 >    /* ----------------Views -------------- */
4019 >
4020 >    /**
4021 >     * Base class for views.
4022 >     */
4023 >    static abstract class CHMView<K, V> {
4024 >        final ConcurrentHashMapV8<K, V> map;
4025 >        CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
4026  
4027          /**
4028 <         * Performs the given action for each (key, value).
4028 >         * Returns the map backing this view.
4029           *
4030 <         * @param action the action
4030 >         * @return the map backing this view
4031           */
4032 <        public void forEach(BiAction<K,V> action) {
4033 <            fjp.invoke(ForkJoinTasks.forEach
4034 <                       (ConcurrentHashMapV8.this, action));
4032 >        public ConcurrentHashMapV8<K,V> getMap() { return map; }
4033 >
4034 >        public final int size()                 { return map.size(); }
4035 >        public final boolean isEmpty()          { return map.isEmpty(); }
4036 >        public final void clear()               { map.clear(); }
4037 >
4038 >        // implementations below rely on concrete classes supplying these
4039 >        abstract public Iterator<?> iterator();
4040 >        abstract public boolean contains(Object o);
4041 >        abstract public boolean remove(Object o);
4042 >
4043 >        private static final String oomeMsg = "Required array size too large";
4044 >
4045 >        public final Object[] toArray() {
4046 >            long sz = map.mappingCount();
4047 >            if (sz > (long)(MAX_ARRAY_SIZE))
4048 >                throw new OutOfMemoryError(oomeMsg);
4049 >            int n = (int)sz;
4050 >            Object[] r = new Object[n];
4051 >            int i = 0;
4052 >            Iterator<?> it = iterator();
4053 >            while (it.hasNext()) {
4054 >                if (i == n) {
4055 >                    if (n >= MAX_ARRAY_SIZE)
4056 >                        throw new OutOfMemoryError(oomeMsg);
4057 >                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4058 >                        n = MAX_ARRAY_SIZE;
4059 >                    else
4060 >                        n += (n >>> 1) + 1;
4061 >                    r = Arrays.copyOf(r, n);
4062 >                }
4063 >                r[i++] = it.next();
4064 >            }
4065 >            return (i == n) ? r : Arrays.copyOf(r, i);
4066          }
4067  
4068 <        /**
4069 <         * Performs the given action for each non-null transformation
4070 <         * of each (key, value).
4071 <         *
4072 <         * @param transformer a function returning the transformation
4073 <         * for an element, or null of there is no transformation (in
4074 <         * which case the action is not applied).
4075 <         * @param action the action
4076 <         */
4077 <        public <U> void forEach(BiFun<? super K, ? super V, ? extends U> transformer,
4078 <                                Action<U> action) {
4079 <            fjp.invoke(ForkJoinTasks.forEach
4080 <                       (ConcurrentHashMapV8.this, transformer, action));
4068 >        @SuppressWarnings("unchecked") public final <T> T[] toArray(T[] a) {
4069 >            long sz = map.mappingCount();
4070 >            if (sz > (long)(MAX_ARRAY_SIZE))
4071 >                throw new OutOfMemoryError(oomeMsg);
4072 >            int m = (int)sz;
4073 >            T[] r = (a.length >= m) ? a :
4074 >                (T[])java.lang.reflect.Array
4075 >                .newInstance(a.getClass().getComponentType(), m);
4076 >            int n = r.length;
4077 >            int i = 0;
4078 >            Iterator<?> it = iterator();
4079 >            while (it.hasNext()) {
4080 >                if (i == n) {
4081 >                    if (n >= MAX_ARRAY_SIZE)
4082 >                        throw new OutOfMemoryError(oomeMsg);
4083 >                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4084 >                        n = MAX_ARRAY_SIZE;
4085 >                    else
4086 >                        n += (n >>> 1) + 1;
4087 >                    r = Arrays.copyOf(r, n);
4088 >                }
4089 >                r[i++] = (T)it.next();
4090 >            }
4091 >            if (a == r && i < n) {
4092 >                r[i] = null; // null-terminate
4093 >                return r;
4094 >            }
4095 >            return (i == n) ? r : Arrays.copyOf(r, i);
4096          }
4097  
4098 <        /**
4099 <         * Returns a non-null result from applying the given search
4100 <         * function on each (key, value), or null if none.  Upon
4101 <         * success, further element processing is suppressed and the
4102 <         * results of any other parallel invocations of the search
3676 <         * function are ignored.
3677 <         *
3678 <         * @param searchFunction a function returning a non-null
3679 <         * result on success, else null
3680 <         * @return a non-null result from applying the given search
3681 <         * function on each (key, value), or null if none
3682 <         */
3683 <        public <U> U search(BiFun<? super K, ? super V, ? extends U> searchFunction) {
3684 <            return fjp.invoke(ForkJoinTasks.search
3685 <                              (ConcurrentHashMapV8.this, searchFunction));
4098 >        public final int hashCode() {
4099 >            int h = 0;
4100 >            for (Iterator<?> it = iterator(); it.hasNext();)
4101 >                h += it.next().hashCode();
4102 >            return h;
4103          }
4104  
4105 <        /**
4106 <         * Returns the result of accumulating the given transformation
4107 <         * of all (key, value) pairs using the given reducer to
4108 <         * combine values, or null if none.
4109 <         *
4110 <         * @param transformer a function returning the transformation
4111 <         * for an element, or null of there is no transformation (in
4112 <         * which case it is not combined).
4113 <         * @param reducer a commutative associative combining function
4114 <         * @return the result of accumulating the given transformation
4115 <         * of all (key, value) pairs
4116 <         */
4117 <        public <U> U reduce(BiFun<? super K, ? super V, ? extends U> transformer,
4118 <                            BiFun<? super U, ? super U, ? extends U> reducer) {
3702 <            return fjp.invoke(ForkJoinTasks.reduce
3703 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4105 >        public final String toString() {
4106 >            StringBuilder sb = new StringBuilder();
4107 >            sb.append('[');
4108 >            Iterator<?> it = iterator();
4109 >            if (it.hasNext()) {
4110 >                for (;;) {
4111 >                    Object e = it.next();
4112 >                    sb.append(e == this ? "(this Collection)" : e);
4113 >                    if (!it.hasNext())
4114 >                        break;
4115 >                    sb.append(',').append(' ');
4116 >                }
4117 >            }
4118 >            return sb.append(']').toString();
4119          }
4120  
4121 <        /**
4122 <         * Returns the result of accumulating the given transformation
4123 <         * of all (key, value) pairs using the given reducer to
4124 <         * combine values, and the given basis as an identity value.
4125 <         *
4126 <         * @param transformer a function returning the transformation
4127 <         * for an element
4128 <         * @param basis the identity (initial default value) for the reduction
4129 <         * @param reducer a commutative associative combining function
4130 <         * @return the result of accumulating the given transformation
4131 <         * of all (key, value) pairs
4132 <         */
4133 <        public double reduceToDouble(ObjectByObjectToDouble<? super K, ? super V> transformer,
4134 <                                     double basis,
4135 <                                     DoubleByDoubleToDouble reducer) {
4136 <            return fjp.invoke(ForkJoinTasks.reduceToDouble
4137 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4121 >        public final boolean containsAll(Collection<?> c) {
4122 >            if (c != this) {
4123 >                for (Iterator<?> it = c.iterator(); it.hasNext();) {
4124 >                    Object e = it.next();
4125 >                    if (e == null || !contains(e))
4126 >                        return false;
4127 >                }
4128 >            }
4129 >            return true;
4130 >        }
4131 >
4132 >        public final boolean removeAll(Collection<?> c) {
4133 >            boolean modified = false;
4134 >            for (Iterator<?> it = iterator(); it.hasNext();) {
4135 >                if (c.contains(it.next())) {
4136 >                    it.remove();
4137 >                    modified = true;
4138 >                }
4139 >            }
4140 >            return modified;
4141 >        }
4142 >
4143 >        public final boolean retainAll(Collection<?> c) {
4144 >            boolean modified = false;
4145 >            for (Iterator<?> it = iterator(); it.hasNext();) {
4146 >                if (!c.contains(it.next())) {
4147 >                    it.remove();
4148 >                    modified = true;
4149 >                }
4150 >            }
4151 >            return modified;
4152 >        }
4153 >
4154 >    }
4155 >
4156 >    /**
4157 >     * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in
4158 >     * which additions may optionally be enabled by mapping to a
4159 >     * common value.  This class cannot be directly instantiated. See
4160 >     * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
4161 >     * {@link #newKeySet(int)}.
4162 >     */
4163 >    public static class KeySetView<K,V> extends CHMView<K,V> implements Set<K>, java.io.Serializable {
4164 >        private static final long serialVersionUID = 7249069246763182397L;
4165 >        private final V value;
4166 >        KeySetView(ConcurrentHashMapV8<K, V> map, V value) {  // non-public
4167 >            super(map);
4168 >            this.value = value;
4169          }
4170  
4171          /**
4172 <         * Returns the result of accumulating the given transformation
4173 <         * of all (key, value) pairs using the given reducer to
3728 <         * combine values, and the given basis as an identity value.
4172 >         * Returns the default mapped value for additions,
4173 >         * or {@code null} if additions are not supported.
4174           *
4175 <         * @param transformer a function returning the transformation
4176 <         * for an element
3732 <         * @param basis the identity (initial default value) for the reduction
3733 <         * @param reducer a commutative associative combining function
3734 <         * @return the result of accumulating the given transformation
3735 <         * of all (key, value) pairs
4175 >         * @return the default mapped value for additions, or {@code null}
4176 >         * if not supported.
4177           */
4178 <        public long reduceToLong(ObjectByObjectToLong<? super K, ? super V> transformer,
4179 <                                 long basis,
4180 <                                 LongByLongToLong reducer) {
4181 <            return fjp.invoke(ForkJoinTasks.reduceToLong
4182 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4183 <        }
4178 >        public V getMappedValue() { return value; }
4179 >
4180 >        // implement Set API
4181 >
4182 >        public boolean contains(Object o) { return map.containsKey(o); }
4183 >        public boolean remove(Object o)   { return map.remove(o) != null; }
4184  
4185          /**
4186 <         * Returns the result of accumulating the given transformation
4187 <         * of all (key, value) pairs using the given reducer to
4188 <         * combine values, and the given basis as an identity value.
4186 >         * Returns a "weakly consistent" iterator that will never
4187 >         * throw {@link ConcurrentModificationException}, and
4188 >         * guarantees to traverse elements as they existed upon
4189 >         * construction of the iterator, and may (but is not
4190 >         * guaranteed to) reflect any modifications subsequent to
4191 >         * construction.
4192           *
4193 <         * @param transformer a function returning the transformation
3750 <         * for an element
3751 <         * @param basis the identity (initial default value) for the reduction
3752 <         * @param reducer a commutative associative combining function
3753 <         * @return the result of accumulating the given transformation
3754 <         * of all (key, value) pairs
4193 >         * @return an iterator over the keys of this map
4194           */
4195 <        public int reduceToInt(ObjectByObjectToInt<? super K, ? super V> transformer,
4196 <                               int basis,
4197 <                               IntByIntToInt reducer) {
4198 <            return fjp.invoke(ForkJoinTasks.reduceToInt
4199 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4195 >        public Iterator<K> iterator()     { return new KeyIterator<K,V>(map); }
4196 >        public boolean add(K e) {
4197 >            V v;
4198 >            if ((v = value) == null)
4199 >                throw new UnsupportedOperationException();
4200 >            if (e == null)
4201 >                throw new NullPointerException();
4202 >            return map.internalPutIfAbsent(e, v) == null;
4203 >        }
4204 >        public boolean addAll(Collection<? extends K> c) {
4205 >            boolean added = false;
4206 >            V v;
4207 >            if ((v = value) == null)
4208 >                throw new UnsupportedOperationException();
4209 >            for (K e : c) {
4210 >                if (e == null)
4211 >                    throw new NullPointerException();
4212 >                if (map.internalPutIfAbsent(e, v) == null)
4213 >                    added = true;
4214 >            }
4215 >            return added;
4216 >        }
4217 >        public boolean equals(Object o) {
4218 >            Set<?> c;
4219 >            return ((o instanceof Set) &&
4220 >                    ((c = (Set<?>)o) == this ||
4221 >                     (containsAll(c) && c.containsAll(this))));
4222          }
4223  
4224          /**
# Line 3765 | Line 4226 | public class ConcurrentHashMapV8<K, V>
4226           *
4227           * @param action the action
4228           */
4229 <        public void forEachKey(Action<K> action) {
4230 <            fjp.invoke(ForkJoinTasks.forEachKey
4231 <                       (ConcurrentHashMapV8.this, action));
4229 >        public void forEach(Action<K> action) {
4230 >            ForkJoinTasks.forEachKey
4231 >                (map, action).invoke();
4232          }
4233  
4234          /**
# Line 3779 | Line 4240 | public class ConcurrentHashMapV8<K, V>
4240           * which case the action is not applied).
4241           * @param action the action
4242           */
4243 <        public <U> void forEachKey(Fun<? super K, ? extends U> transformer,
4244 <                                   Action<U> action) {
4245 <            fjp.invoke(ForkJoinTasks.forEachKey
4246 <                       (ConcurrentHashMapV8.this, transformer, action));
4243 >        public <U> void forEach(Fun<? super K, ? extends U> transformer,
4244 >                                Action<U> action) {
4245 >            ForkJoinTasks.forEachKey
4246 >                (map, transformer, action).invoke();
4247          }
4248  
4249          /**
# Line 3797 | Line 4258 | public class ConcurrentHashMapV8<K, V>
4258           * @return a non-null result from applying the given search
4259           * function on each key, or null if none
4260           */
4261 <        public <U> U searchKeys(Fun<? super K, ? extends U> searchFunction) {
4262 <            return fjp.invoke(ForkJoinTasks.searchKeys
4263 <                              (ConcurrentHashMapV8.this, searchFunction));
4261 >        public <U> U search(Fun<? super K, ? extends U> searchFunction) {
4262 >            return ForkJoinTasks.searchKeys
4263 >                (map, searchFunction).invoke();
4264          }
4265  
4266          /**
# Line 3810 | Line 4271 | public class ConcurrentHashMapV8<K, V>
4271           * @return the result of accumulating all keys using the given
4272           * reducer to combine values, or null if none
4273           */
4274 <        public K reduceKeys(BiFun<? super K, ? super K, ? extends K> reducer) {
4275 <            return fjp.invoke(ForkJoinTasks.reduceKeys
4276 <                              (ConcurrentHashMapV8.this, reducer));
3816 <        }
3817 <
3818 <        /**
3819 <         * Returns the result of accumulating the given transformation
3820 <         * of all keys using the given reducer to combine values, or
3821 <         * null if none.
3822 <         *
3823 <         * @param transformer a function returning the transformation
3824 <         * for an element, or null of there is no transformation (in
3825 <         * which case it is not combined).
3826 <         * @param reducer a commutative associative combining function
3827 <         * @return the result of accumulating the given transformation
3828 <         * of all keys
3829 <         */
3830 <        public <U> U reduceKeys(Fun<? super K, ? extends U> transformer,
3831 <                                BiFun<? super U, ? super U, ? extends U> reducer) {
3832 <            return fjp.invoke(ForkJoinTasks.reduceKeys
3833 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4274 >        public K reduce(BiFun<? super K, ? super K, ? extends K> reducer) {
4275 >            return ForkJoinTasks.reduceKeys
4276 >                (map, reducer).invoke();
4277          }
4278  
4279          /**
# Line 3845 | Line 4288 | public class ConcurrentHashMapV8<K, V>
4288           * @return  the result of accumulating the given transformation
4289           * of all keys
4290           */
4291 <        public double reduceKeysToDouble(ObjectToDouble<? super K> transformer,
4292 <                                         double basis,
4293 <                                         DoubleByDoubleToDouble reducer) {
4294 <            return fjp.invoke(ForkJoinTasks.reduceKeysToDouble
4295 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4291 >        public double reduceToDouble(ObjectToDouble<? super K> transformer,
4292 >                                     double basis,
4293 >                                     DoubleByDoubleToDouble reducer) {
4294 >            return ForkJoinTasks.reduceKeysToDouble
4295 >                (map, transformer, basis, reducer).invoke();
4296          }
4297  
4298 +
4299          /**
4300           * Returns the result of accumulating the given transformation
4301           * of all keys using the given reducer to combine values, and
# Line 3864 | Line 4308 | public class ConcurrentHashMapV8<K, V>
4308           * @return the result of accumulating the given transformation
4309           * of all keys
4310           */
4311 <        public long reduceKeysToLong(ObjectToLong<? super K> transformer,
4312 <                                     long basis,
4313 <                                     LongByLongToLong reducer) {
4314 <            return fjp.invoke(ForkJoinTasks.reduceKeysToLong
4315 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4311 >        public long reduceToLong(ObjectToLong<? super K> transformer,
4312 >                                 long basis,
4313 >                                 LongByLongToLong reducer) {
4314 >            return ForkJoinTasks.reduceKeysToLong
4315 >                (map, transformer, basis, reducer).invoke();
4316          }
4317  
4318          /**
# Line 3883 | Line 4327 | public class ConcurrentHashMapV8<K, V>
4327           * @return the result of accumulating the given transformation
4328           * of all keys
4329           */
4330 <        public int reduceKeysToInt(ObjectToInt<? super K> transformer,
4331 <                                   int basis,
4332 <                                   IntByIntToInt reducer) {
4333 <            return fjp.invoke(ForkJoinTasks.reduceKeysToInt
4334 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4330 >        public int reduceToInt(ObjectToInt<? super K> transformer,
4331 >                               int basis,
4332 >                               IntByIntToInt reducer) {
4333 >            return ForkJoinTasks.reduceKeysToInt
4334 >                (map, transformer, basis, reducer).invoke();
4335 >        }
4336 >
4337 >    }
4338 >
4339 >    /**
4340 >     * A view of a ConcurrentHashMapV8 as a {@link Collection} of
4341 >     * values, in which additions are disabled. This class cannot be
4342 >     * directly instantiated. See {@link #values},
4343 >     *
4344 >     * <p>The view's {@code iterator} is a "weakly consistent" iterator
4345 >     * that will never throw {@link ConcurrentModificationException},
4346 >     * and guarantees to traverse elements as they existed upon
4347 >     * construction of the iterator, and may (but is not guaranteed to)
4348 >     * reflect any modifications subsequent to construction.
4349 >     */
4350 >    public static final class ValuesView<K,V> extends CHMView<K,V>
4351 >        implements Collection<V> {
4352 >        ValuesView(ConcurrentHashMapV8<K, V> map)   { super(map); }
4353 >        public final boolean contains(Object o) { return map.containsValue(o); }
4354 >        public final boolean remove(Object o) {
4355 >            if (o != null) {
4356 >                Iterator<V> it = new ValueIterator<K,V>(map);
4357 >                while (it.hasNext()) {
4358 >                    if (o.equals(it.next())) {
4359 >                        it.remove();
4360 >                        return true;
4361 >                    }
4362 >                }
4363 >            }
4364 >            return false;
4365 >        }
4366 >
4367 >        /**
4368 >         * Returns a "weakly consistent" iterator that will never
4369 >         * throw {@link ConcurrentModificationException}, and
4370 >         * guarantees to traverse elements as they existed upon
4371 >         * construction of the iterator, and may (but is not
4372 >         * guaranteed to) reflect any modifications subsequent to
4373 >         * construction.
4374 >         *
4375 >         * @return an iterator over the values of this map
4376 >         */
4377 >        public final Iterator<V> iterator() {
4378 >            return new ValueIterator<K,V>(map);
4379 >        }
4380 >        public final boolean add(V e) {
4381 >            throw new UnsupportedOperationException();
4382 >        }
4383 >        public final boolean addAll(Collection<? extends V> c) {
4384 >            throw new UnsupportedOperationException();
4385          }
4386  
4387          /**
# Line 3895 | Line 4389 | public class ConcurrentHashMapV8<K, V>
4389           *
4390           * @param action the action
4391           */
4392 <        public void forEachValue(Action<V> action) {
4393 <            fjp.invoke(ForkJoinTasks.forEachValue
4394 <                       (ConcurrentHashMapV8.this, action));
4392 >        public void forEach(Action<V> action) {
4393 >            ForkJoinTasks.forEachValue
4394 >                (map, action).invoke();
4395          }
4396  
4397          /**
# Line 3908 | Line 4402 | public class ConcurrentHashMapV8<K, V>
4402           * for an element, or null of there is no transformation (in
4403           * which case the action is not applied).
4404           */
4405 <        public <U> void forEachValue(Fun<? super V, ? extends U> transformer,
4405 >        public <U> void forEach(Fun<? super V, ? extends U> transformer,
4406                                       Action<U> action) {
4407 <            fjp.invoke(ForkJoinTasks.forEachValue
4408 <                       (ConcurrentHashMapV8.this, transformer, action));
4407 >            ForkJoinTasks.forEachValue
4408 >                (map, transformer, action).invoke();
4409          }
4410  
4411          /**
# Line 3927 | Line 4421 | public class ConcurrentHashMapV8<K, V>
4421           * function on each value, or null if none
4422           *
4423           */
4424 <        public <U> U searchValues(Fun<? super V, ? extends U> searchFunction) {
4425 <            return fjp.invoke(ForkJoinTasks.searchValues
4426 <                              (ConcurrentHashMapV8.this, searchFunction));
4424 >        public <U> U search(Fun<? super V, ? extends U> searchFunction) {
4425 >            return ForkJoinTasks.searchValues
4426 >                (map, searchFunction).invoke();
4427          }
4428  
4429          /**
# Line 3939 | Line 4433 | public class ConcurrentHashMapV8<K, V>
4433           * @param reducer a commutative associative combining function
4434           * @return  the result of accumulating all values
4435           */
4436 <        public V reduceValues(BiFun<? super V, ? super V, ? extends V> reducer) {
4437 <            return fjp.invoke(ForkJoinTasks.reduceValues
4438 <                              (ConcurrentHashMapV8.this, reducer));
4436 >        public V reduce(BiFun<? super V, ? super V, ? extends V> reducer) {
4437 >            return ForkJoinTasks.reduceValues
4438 >                (map, reducer).invoke();
4439          }
4440  
4441          /**
# Line 3956 | Line 4450 | public class ConcurrentHashMapV8<K, V>
4450           * @return the result of accumulating the given transformation
4451           * of all values
4452           */
4453 <        public <U> U reduceValues(Fun<? super V, ? extends U> transformer,
4454 <                                  BiFun<? super U, ? super U, ? extends U> reducer) {
4455 <            return fjp.invoke(ForkJoinTasks.reduceValues
4456 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4453 >        public <U> U reduce(Fun<? super V, ? extends U> transformer,
4454 >                            BiFun<? super U, ? super U, ? extends U> reducer) {
4455 >            return ForkJoinTasks.reduceValues
4456 >                (map, transformer, reducer).invoke();
4457          }
4458  
4459          /**
# Line 3974 | Line 4468 | public class ConcurrentHashMapV8<K, V>
4468           * @return the result of accumulating the given transformation
4469           * of all values
4470           */
4471 <        public double reduceValuesToDouble(ObjectToDouble<? super V> transformer,
4472 <                                           double basis,
4473 <                                           DoubleByDoubleToDouble reducer) {
4474 <            return fjp.invoke(ForkJoinTasks.reduceValuesToDouble
4475 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4471 >        public double reduceToDouble(ObjectToDouble<? super V> transformer,
4472 >                                     double basis,
4473 >                                     DoubleByDoubleToDouble reducer) {
4474 >            return ForkJoinTasks.reduceValuesToDouble
4475 >                (map, transformer, basis, reducer).invoke();
4476          }
4477  
4478          /**
# Line 3993 | Line 4487 | public class ConcurrentHashMapV8<K, V>
4487           * @return the result of accumulating the given transformation
4488           * of all values
4489           */
4490 <        public long reduceValuesToLong(ObjectToLong<? super V> transformer,
4491 <                                       long basis,
4492 <                                       LongByLongToLong reducer) {
4493 <            return fjp.invoke(ForkJoinTasks.reduceValuesToLong
4494 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4490 >        public long reduceToLong(ObjectToLong<? super V> transformer,
4491 >                                 long basis,
4492 >                                 LongByLongToLong reducer) {
4493 >            return ForkJoinTasks.reduceValuesToLong
4494 >                (map, transformer, basis, reducer).invoke();
4495          }
4496  
4497          /**
# Line 4012 | Line 4506 | public class ConcurrentHashMapV8<K, V>
4506           * @return the result of accumulating the given transformation
4507           * of all values
4508           */
4509 <        public int reduceValuesToInt(ObjectToInt<? super V> transformer,
4510 <                                     int basis,
4511 <                                     IntByIntToInt reducer) {
4512 <            return fjp.invoke(ForkJoinTasks.reduceValuesToInt
4513 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4509 >        public int reduceToInt(ObjectToInt<? super V> transformer,
4510 >                               int basis,
4511 >                               IntByIntToInt reducer) {
4512 >            return ForkJoinTasks.reduceValuesToInt
4513 >                (map, transformer, basis, reducer).invoke();
4514 >        }
4515 >
4516 >    }
4517 >
4518 >    /**
4519 >     * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value)
4520 >     * entries.  This class cannot be directly instantiated. See
4521 >     * {@link #entrySet}.
4522 >     */
4523 >    public static final class EntrySetView<K,V> extends CHMView<K,V>
4524 >        implements Set<Map.Entry<K,V>> {
4525 >        EntrySetView(ConcurrentHashMapV8<K, V> map) { super(map); }
4526 >        public final boolean contains(Object o) {
4527 >            Object k, v, r; Map.Entry<?,?> e;
4528 >            return ((o instanceof Map.Entry) &&
4529 >                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
4530 >                    (r = map.get(k)) != null &&
4531 >                    (v = e.getValue()) != null &&
4532 >                    (v == r || v.equals(r)));
4533 >        }
4534 >        public final boolean remove(Object o) {
4535 >            Object k, v; Map.Entry<?,?> e;
4536 >            return ((o instanceof Map.Entry) &&
4537 >                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
4538 >                    (v = e.getValue()) != null &&
4539 >                    map.remove(k, v));
4540 >        }
4541 >
4542 >        /**
4543 >         * Returns a "weakly consistent" iterator that will never
4544 >         * throw {@link ConcurrentModificationException}, and
4545 >         * guarantees to traverse elements as they existed upon
4546 >         * construction of the iterator, and may (but is not
4547 >         * guaranteed to) reflect any modifications subsequent to
4548 >         * construction.
4549 >         *
4550 >         * @return an iterator over the entries of this map
4551 >         */
4552 >        public final Iterator<Map.Entry<K,V>> iterator() {
4553 >            return new EntryIterator<K,V>(map);
4554 >        }
4555 >
4556 >        public final boolean add(Entry<K,V> e) {
4557 >            K key = e.getKey();
4558 >            V value = e.getValue();
4559 >            if (key == null || value == null)
4560 >                throw new NullPointerException();
4561 >            return map.internalPut(key, value) == null;
4562 >        }
4563 >        public final boolean addAll(Collection<? extends Entry<K,V>> c) {
4564 >            boolean added = false;
4565 >            for (Entry<K,V> e : c) {
4566 >                if (add(e))
4567 >                    added = true;
4568 >            }
4569 >            return added;
4570 >        }
4571 >        public boolean equals(Object o) {
4572 >            Set<?> c;
4573 >            return ((o instanceof Set) &&
4574 >                    ((c = (Set<?>)o) == this ||
4575 >                     (containsAll(c) && c.containsAll(this))));
4576          }
4577  
4578          /**
# Line 4024 | Line 4580 | public class ConcurrentHashMapV8<K, V>
4580           *
4581           * @param action the action
4582           */
4583 <        public void forEachEntry(Action<Map.Entry<K,V>> action) {
4584 <            fjp.invoke(ForkJoinTasks.forEachEntry
4585 <                       (ConcurrentHashMapV8.this, action));
4583 >        public void forEach(Action<Map.Entry<K,V>> action) {
4584 >            ForkJoinTasks.forEachEntry
4585 >                (map, action).invoke();
4586          }
4587  
4588          /**
# Line 4038 | Line 4594 | public class ConcurrentHashMapV8<K, V>
4594           * which case the action is not applied).
4595           * @param action the action
4596           */
4597 <        public <U> void forEachEntry(Fun<Map.Entry<K,V>, ? extends U> transformer,
4598 <                                     Action<U> action) {
4599 <            fjp.invoke(ForkJoinTasks.forEachEntry
4600 <                       (ConcurrentHashMapV8.this, transformer, action));
4597 >        public <U> void forEach(Fun<Map.Entry<K,V>, ? extends U> transformer,
4598 >                                Action<U> action) {
4599 >            ForkJoinTasks.forEachEntry
4600 >                (map, transformer, action).invoke();
4601          }
4602  
4603          /**
# Line 4056 | Line 4612 | public class ConcurrentHashMapV8<K, V>
4612           * @return a non-null result from applying the given search
4613           * function on each entry, or null if none
4614           */
4615 <        public <U> U searchEntries(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4616 <            return fjp.invoke(ForkJoinTasks.searchEntries
4617 <                              (ConcurrentHashMapV8.this, searchFunction));
4615 >        public <U> U search(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4616 >            return ForkJoinTasks.searchEntries
4617 >                (map, searchFunction).invoke();
4618          }
4619  
4620          /**
# Line 4068 | Line 4624 | public class ConcurrentHashMapV8<K, V>
4624           * @param reducer a commutative associative combining function
4625           * @return the result of accumulating all entries
4626           */
4627 <        public Map.Entry<K,V> reduceEntries(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4628 <            return fjp.invoke(ForkJoinTasks.reduceEntries
4629 <                              (ConcurrentHashMapV8.this, reducer));
4627 >        public Map.Entry<K,V> reduce(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4628 >            return ForkJoinTasks.reduceEntries
4629 >                (map, reducer).invoke();
4630          }
4631  
4632          /**
# Line 4085 | Line 4641 | public class ConcurrentHashMapV8<K, V>
4641           * @return the result of accumulating the given transformation
4642           * of all entries
4643           */
4644 <        public <U> U reduceEntries(Fun<Map.Entry<K,V>, ? extends U> transformer,
4645 <                                   BiFun<? super U, ? super U, ? extends U> reducer) {
4646 <            return fjp.invoke(ForkJoinTasks.reduceEntries
4647 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4644 >        public <U> U reduce(Fun<Map.Entry<K,V>, ? extends U> transformer,
4645 >                            BiFun<? super U, ? super U, ? extends U> reducer) {
4646 >            return ForkJoinTasks.reduceEntries
4647 >                (map, transformer, reducer).invoke();
4648          }
4649  
4650          /**
# Line 4103 | Line 4659 | public class ConcurrentHashMapV8<K, V>
4659           * @return the result of accumulating the given transformation
4660           * of all entries
4661           */
4662 <        public double reduceEntriesToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
4663 <                                            double basis,
4664 <                                            DoubleByDoubleToDouble reducer) {
4665 <            return fjp.invoke(ForkJoinTasks.reduceEntriesToDouble
4666 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4662 >        public double reduceToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
4663 >                                     double basis,
4664 >                                     DoubleByDoubleToDouble reducer) {
4665 >            return ForkJoinTasks.reduceEntriesToDouble
4666 >                (map, transformer, basis, reducer).invoke();
4667          }
4668  
4669          /**
# Line 4122 | Line 4678 | public class ConcurrentHashMapV8<K, V>
4678           * @return  the result of accumulating the given transformation
4679           * of all entries
4680           */
4681 <        public long reduceEntriesToLong(ObjectToLong<Map.Entry<K,V>> transformer,
4682 <                                        long basis,
4683 <                                        LongByLongToLong reducer) {
4684 <            return fjp.invoke(ForkJoinTasks.reduceEntriesToLong
4685 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4681 >        public long reduceToLong(ObjectToLong<Map.Entry<K,V>> transformer,
4682 >                                 long basis,
4683 >                                 LongByLongToLong reducer) {
4684 >            return ForkJoinTasks.reduceEntriesToLong
4685 >                (map, transformer, basis, reducer).invoke();
4686          }
4687  
4688          /**
# Line 4141 | Line 4697 | public class ConcurrentHashMapV8<K, V>
4697           * @return the result of accumulating the given transformation
4698           * of all entries
4699           */
4700 <        public int reduceEntriesToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4701 <                                      int basis,
4702 <                                      IntByIntToInt reducer) {
4703 <            return fjp.invoke(ForkJoinTasks.reduceEntriesToInt
4704 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4700 >        public int reduceToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4701 >                               int basis,
4702 >                               IntByIntToInt reducer) {
4703 >            return ForkJoinTasks.reduceEntriesToInt
4704 >                (map, transformer, basis, reducer).invoke();
4705          }
4706 +
4707      }
4708  
4709      // ---------------------------------------------------------------------
4710  
4711      /**
4712       * Predefined tasks for performing bulk parallel operations on
4713 <     * ConcurrentHashMaps. These tasks follow the forms and rules used
4714 <     * in class {@link Parallel}. Each method has the same name, but
4715 <     * returns a task rather than invoking it. These methods may be
4716 <     * useful in custom applications such as submitting a task without
4717 <     * waiting for completion, or combining with other tasks.
4713 >     * ConcurrentHashMapV8s. These tasks follow the forms and rules used
4714 >     * for bulk operations. Each method has the same name, but returns
4715 >     * a task rather than invoking it. These methods may be useful in
4716 >     * custom applications such as submitting a task without waiting
4717 >     * for completion, using a custom pool, or combining with other
4718 >     * tasks.
4719       */
4720      public static class ForkJoinTasks {
4721          private ForkJoinTasks() {}
# Line 4174 | Line 4732 | public class ConcurrentHashMapV8<K, V>
4732              (ConcurrentHashMapV8<K,V> map,
4733               BiAction<K,V> action) {
4734              if (action == null) throw new NullPointerException();
4735 <            return new ForEachMappingTask<K,V>(map, action);
4735 >            return new ForEachMappingTask<K,V>(map, null, -1, action);
4736          }
4737  
4738          /**
# Line 4183 | Line 4741 | public class ConcurrentHashMapV8<K, V>
4741           *
4742           * @param map the map
4743           * @param transformer a function returning the transformation
4744 <         * for an element, or null of there is no transformation (in
4745 <         * which case the action is not applied).
4744 >         * for an element, or null if there is no transformation (in
4745 >         * which case the action is not applied)
4746           * @param action the action
4747           * @return the task
4748           */
# Line 4195 | Line 4753 | public class ConcurrentHashMapV8<K, V>
4753              if (transformer == null || action == null)
4754                  throw new NullPointerException();
4755              return new ForEachTransformedMappingTask<K,V,U>
4756 <                (map, transformer, action);
4756 >                (map, null, -1, transformer, action);
4757          }
4758  
4759          /**
# Line 4215 | Line 4773 | public class ConcurrentHashMapV8<K, V>
4773               BiFun<? super K, ? super V, ? extends U> searchFunction) {
4774              if (searchFunction == null) throw new NullPointerException();
4775              return new SearchMappingsTask<K,V,U>
4776 <                (map, searchFunction,
4776 >                (map, null, -1, searchFunction,
4777                   new AtomicReference<U>());
4778          }
4779  
# Line 4226 | Line 4784 | public class ConcurrentHashMapV8<K, V>
4784           *
4785           * @param map the map
4786           * @param transformer a function returning the transformation
4787 <         * for an element, or null of there is no transformation (in
4787 >         * for an element, or null if there is no transformation (in
4788           * which case it is not combined).
4789           * @param reducer a commutative associative combining function
4790           * @return the task
# Line 4238 | Line 4796 | public class ConcurrentHashMapV8<K, V>
4796              if (transformer == null || reducer == null)
4797                  throw new NullPointerException();
4798              return new MapReduceMappingsTask<K,V,U>
4799 <                (map, transformer, reducer);
4799 >                (map, null, -1, null, transformer, reducer);
4800          }
4801  
4802          /**
# Line 4262 | Line 4820 | public class ConcurrentHashMapV8<K, V>
4820              if (transformer == null || reducer == null)
4821                  throw new NullPointerException();
4822              return new MapReduceMappingsToDoubleTask<K,V>
4823 <                (map, transformer, basis, reducer);
4823 >                (map, null, -1, null, transformer, basis, reducer);
4824          }
4825  
4826          /**
# Line 4286 | Line 4844 | public class ConcurrentHashMapV8<K, V>
4844              if (transformer == null || reducer == null)
4845                  throw new NullPointerException();
4846              return new MapReduceMappingsToLongTask<K,V>
4847 <                (map, transformer, basis, reducer);
4847 >                (map, null, -1, null, transformer, basis, reducer);
4848          }
4849  
4850          /**
# Line 4309 | Line 4867 | public class ConcurrentHashMapV8<K, V>
4867              if (transformer == null || reducer == null)
4868                  throw new NullPointerException();
4869              return new MapReduceMappingsToIntTask<K,V>
4870 <                (map, transformer, basis, reducer);
4870 >                (map, null, -1, null, transformer, basis, reducer);
4871          }
4872  
4873          /**
# Line 4324 | Line 4882 | public class ConcurrentHashMapV8<K, V>
4882              (ConcurrentHashMapV8<K,V> map,
4883               Action<K> action) {
4884              if (action == null) throw new NullPointerException();
4885 <            return new ForEachKeyTask<K,V>(map, action);
4885 >            return new ForEachKeyTask<K,V>(map, null, -1, action);
4886          }
4887  
4888          /**
# Line 4333 | Line 4891 | public class ConcurrentHashMapV8<K, V>
4891           *
4892           * @param map the map
4893           * @param transformer a function returning the transformation
4894 <         * for an element, or null of there is no transformation (in
4895 <         * which case the action is not applied).
4894 >         * for an element, or null if there is no transformation (in
4895 >         * which case the action is not applied)
4896           * @param action the action
4897           * @return the task
4898           */
# Line 4345 | Line 4903 | public class ConcurrentHashMapV8<K, V>
4903              if (transformer == null || action == null)
4904                  throw new NullPointerException();
4905              return new ForEachTransformedKeyTask<K,V,U>
4906 <                (map, transformer, action);
4906 >                (map, null, -1, transformer, action);
4907          }
4908  
4909          /**
# Line 4365 | Line 4923 | public class ConcurrentHashMapV8<K, V>
4923               Fun<? super K, ? extends U> searchFunction) {
4924              if (searchFunction == null) throw new NullPointerException();
4925              return new SearchKeysTask<K,V,U>
4926 <                (map, searchFunction,
4926 >                (map, null, -1, searchFunction,
4927                   new AtomicReference<U>());
4928          }
4929  
# Line 4383 | Line 4941 | public class ConcurrentHashMapV8<K, V>
4941               BiFun<? super K, ? super K, ? extends K> reducer) {
4942              if (reducer == null) throw new NullPointerException();
4943              return new ReduceKeysTask<K,V>
4944 <                (map, reducer);
4944 >                (map, null, -1, null, reducer);
4945          }
4946  
4947          /**
# Line 4393 | Line 4951 | public class ConcurrentHashMapV8<K, V>
4951           *
4952           * @param map the map
4953           * @param transformer a function returning the transformation
4954 <         * for an element, or null of there is no transformation (in
4954 >         * for an element, or null if there is no transformation (in
4955           * which case it is not combined).
4956           * @param reducer a commutative associative combining function
4957           * @return the task
# Line 4405 | Line 4963 | public class ConcurrentHashMapV8<K, V>
4963              if (transformer == null || reducer == null)
4964                  throw new NullPointerException();
4965              return new MapReduceKeysTask<K,V,U>
4966 <                (map, transformer, reducer);
4966 >                (map, null, -1, null, transformer, reducer);
4967          }
4968  
4969          /**
# Line 4429 | Line 4987 | public class ConcurrentHashMapV8<K, V>
4987              if (transformer == null || reducer == null)
4988                  throw new NullPointerException();
4989              return new MapReduceKeysToDoubleTask<K,V>
4990 <                (map, transformer, basis, reducer);
4990 >                (map, null, -1, null, transformer, basis, reducer);
4991          }
4992  
4993          /**
# Line 4453 | Line 5011 | public class ConcurrentHashMapV8<K, V>
5011              if (transformer == null || reducer == null)
5012                  throw new NullPointerException();
5013              return new MapReduceKeysToLongTask<K,V>
5014 <                (map, transformer, basis, reducer);
5014 >                (map, null, -1, null, transformer, basis, reducer);
5015          }
5016  
5017          /**
# Line 4477 | Line 5035 | public class ConcurrentHashMapV8<K, V>
5035              if (transformer == null || reducer == null)
5036                  throw new NullPointerException();
5037              return new MapReduceKeysToIntTask<K,V>
5038 <                (map, transformer, basis, reducer);
5038 >                (map, null, -1, null, transformer, basis, reducer);
5039          }
5040  
5041          /**
# Line 4491 | Line 5049 | public class ConcurrentHashMapV8<K, V>
5049              (ConcurrentHashMapV8<K,V> map,
5050               Action<V> action) {
5051              if (action == null) throw new NullPointerException();
5052 <            return new ForEachValueTask<K,V>(map, action);
5052 >            return new ForEachValueTask<K,V>(map, null, -1, action);
5053          }
5054  
5055          /**
# Line 4500 | Line 5058 | public class ConcurrentHashMapV8<K, V>
5058           *
5059           * @param map the map
5060           * @param transformer a function returning the transformation
5061 <         * for an element, or null of there is no transformation (in
5062 <         * which case the action is not applied).
5061 >         * for an element, or null if there is no transformation (in
5062 >         * which case the action is not applied)
5063           * @param action the action
5064           */
5065          public static <K,V,U> ForkJoinTask<Void> forEachValue
# Line 4511 | Line 5069 | public class ConcurrentHashMapV8<K, V>
5069              if (transformer == null || action == null)
5070                  throw new NullPointerException();
5071              return new ForEachTransformedValueTask<K,V,U>
5072 <                (map, transformer, action);
5072 >                (map, null, -1, transformer, action);
5073          }
5074  
5075          /**
# Line 4525 | Line 5083 | public class ConcurrentHashMapV8<K, V>
5083           * @param searchFunction a function returning a non-null
5084           * result on success, else null
5085           * @return the task
4528         *
5086           */
5087          public static <K,V,U> ForkJoinTask<U> searchValues
5088              (ConcurrentHashMapV8<K,V> map,
5089               Fun<? super V, ? extends U> searchFunction) {
5090              if (searchFunction == null) throw new NullPointerException();
5091              return new SearchValuesTask<K,V,U>
5092 <                (map, searchFunction,
5092 >                (map, null, -1, searchFunction,
5093                   new AtomicReference<U>());
5094          }
5095  
# Line 4550 | Line 5107 | public class ConcurrentHashMapV8<K, V>
5107               BiFun<? super V, ? super V, ? extends V> reducer) {
5108              if (reducer == null) throw new NullPointerException();
5109              return new ReduceValuesTask<K,V>
5110 <                (map, reducer);
5110 >                (map, null, -1, null, reducer);
5111          }
5112  
5113          /**
# Line 4560 | Line 5117 | public class ConcurrentHashMapV8<K, V>
5117           *
5118           * @param map the map
5119           * @param transformer a function returning the transformation
5120 <         * for an element, or null of there is no transformation (in
5120 >         * for an element, or null if there is no transformation (in
5121           * which case it is not combined).
5122           * @param reducer a commutative associative combining function
5123           * @return the task
# Line 4572 | Line 5129 | public class ConcurrentHashMapV8<K, V>
5129              if (transformer == null || reducer == null)
5130                  throw new NullPointerException();
5131              return new MapReduceValuesTask<K,V,U>
5132 <                (map, transformer, reducer);
5132 >                (map, null, -1, null, transformer, reducer);
5133          }
5134  
5135          /**
# Line 4596 | Line 5153 | public class ConcurrentHashMapV8<K, V>
5153              if (transformer == null || reducer == null)
5154                  throw new NullPointerException();
5155              return new MapReduceValuesToDoubleTask<K,V>
5156 <                (map, transformer, basis, reducer);
5156 >                (map, null, -1, null, transformer, basis, reducer);
5157          }
5158  
5159          /**
# Line 4620 | Line 5177 | public class ConcurrentHashMapV8<K, V>
5177              if (transformer == null || reducer == null)
5178                  throw new NullPointerException();
5179              return new MapReduceValuesToLongTask<K,V>
5180 <                (map, transformer, basis, reducer);
5180 >                (map, null, -1, null, transformer, basis, reducer);
5181          }
5182  
5183          /**
# Line 4644 | Line 5201 | public class ConcurrentHashMapV8<K, V>
5201              if (transformer == null || reducer == null)
5202                  throw new NullPointerException();
5203              return new MapReduceValuesToIntTask<K,V>
5204 <                (map, transformer, basis, reducer);
5204 >                (map, null, -1, null, transformer, basis, reducer);
5205          }
5206  
5207          /**
# Line 4658 | Line 5215 | public class ConcurrentHashMapV8<K, V>
5215              (ConcurrentHashMapV8<K,V> map,
5216               Action<Map.Entry<K,V>> action) {
5217              if (action == null) throw new NullPointerException();
5218 <            return new ForEachEntryTask<K,V>(map, action);
5218 >            return new ForEachEntryTask<K,V>(map, null, -1, action);
5219          }
5220  
5221          /**
# Line 4667 | Line 5224 | public class ConcurrentHashMapV8<K, V>
5224           *
5225           * @param map the map
5226           * @param transformer a function returning the transformation
5227 <         * for an element, or null of there is no transformation (in
5228 <         * which case the action is not applied).
5227 >         * for an element, or null if there is no transformation (in
5228 >         * which case the action is not applied)
5229           * @param action the action
5230           */
5231          public static <K,V,U> ForkJoinTask<Void> forEachEntry
# Line 4678 | Line 5235 | public class ConcurrentHashMapV8<K, V>
5235              if (transformer == null || action == null)
5236                  throw new NullPointerException();
5237              return new ForEachTransformedEntryTask<K,V,U>
5238 <                (map, transformer, action);
5238 >                (map, null, -1, transformer, action);
5239          }
5240  
5241          /**
# Line 4692 | Line 5249 | public class ConcurrentHashMapV8<K, V>
5249           * @param searchFunction a function returning a non-null
5250           * result on success, else null
5251           * @return the task
4695         *
5252           */
5253          public static <K,V,U> ForkJoinTask<U> searchEntries
5254              (ConcurrentHashMapV8<K,V> map,
5255               Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
5256              if (searchFunction == null) throw new NullPointerException();
5257              return new SearchEntriesTask<K,V,U>
5258 <                (map, searchFunction,
5258 >                (map, null, -1, searchFunction,
5259                   new AtomicReference<U>());
5260          }
5261  
# Line 4717 | Line 5273 | public class ConcurrentHashMapV8<K, V>
5273               BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5274              if (reducer == null) throw new NullPointerException();
5275              return new ReduceEntriesTask<K,V>
5276 <                (map, reducer);
5276 >                (map, null, -1, null, reducer);
5277          }
5278  
5279          /**
# Line 4727 | Line 5283 | public class ConcurrentHashMapV8<K, V>
5283           *
5284           * @param map the map
5285           * @param transformer a function returning the transformation
5286 <         * for an element, or null of there is no transformation (in
5286 >         * for an element, or null if there is no transformation (in
5287           * which case it is not combined).
5288           * @param reducer a commutative associative combining function
5289           * @return the task
# Line 4739 | Line 5295 | public class ConcurrentHashMapV8<K, V>
5295              if (transformer == null || reducer == null)
5296                  throw new NullPointerException();
5297              return new MapReduceEntriesTask<K,V,U>
5298 <                (map, transformer, reducer);
5298 >                (map, null, -1, null, transformer, reducer);
5299          }
5300  
5301          /**
# Line 4763 | Line 5319 | public class ConcurrentHashMapV8<K, V>
5319              if (transformer == null || reducer == null)
5320                  throw new NullPointerException();
5321              return new MapReduceEntriesToDoubleTask<K,V>
5322 <                (map, transformer, basis, reducer);
5322 >                (map, null, -1, null, transformer, basis, reducer);
5323          }
5324  
5325          /**
# Line 4787 | Line 5343 | public class ConcurrentHashMapV8<K, V>
5343              if (transformer == null || reducer == null)
5344                  throw new NullPointerException();
5345              return new MapReduceEntriesToLongTask<K,V>
5346 <                (map, transformer, basis, reducer);
5346 >                (map, null, -1, null, transformer, basis, reducer);
5347          }
5348  
5349          /**
# Line 4811 | Line 5367 | public class ConcurrentHashMapV8<K, V>
5367              if (transformer == null || reducer == null)
5368                  throw new NullPointerException();
5369              return new MapReduceEntriesToIntTask<K,V>
5370 <                (map, transformer, basis, reducer);
5370 >                (map, null, -1, null, transformer, basis, reducer);
5371          }
5372      }
5373  
5374      // -------------------------------------------------------
5375  
4820    /**
4821     * Base for FJ tasks for bulk operations. This adds a variant of
4822     * CountedCompleters and some split and merge bookkeeping to
4823     * iterator functionality. The forEach and reduce methods are
4824     * similar to those illustrated in CountedCompleter documentation,
4825     * except that bottom-up reduction completions perform them within
4826     * their compute methods. The search methods are like forEach
4827     * except they continually poll for success and exit early.  Also,
4828     * exceptions are handled in a simpler manner, by just trying to
4829     * complete root task exceptionally.
4830     */
4831    @SuppressWarnings("serial")
4832    static abstract class BulkTask<K,V,R> extends Traverser<K,V,R> {
4833        final BulkTask<K,V,?> parent;  // completion target
4834        int batch;                     // split control
4835        int pending;                   // completion control
4836
4837        /** Constructor for root tasks */
4838        BulkTask(ConcurrentHashMapV8<K,V> map) {
4839            super(map);
4840            this.parent = null;
4841            this.batch = -1; // force call to batch() on execution
4842        }
4843
4844        /** Constructor for subtasks */
4845        BulkTask(BulkTask<K,V,?> parent, int batch, boolean split) {
4846            super(parent, split);
4847            this.parent = parent;
4848            this.batch = batch;
4849        }
4850
4851        // FJ methods
4852
4853        /**
4854         * Propagates completion. Note that all reduce actions
4855         * bypass this method to combine while completing.
4856         */
4857        final void tryComplete() {
4858            BulkTask<K,V,?> a = this, s = a;
4859            for (int c;;) {
4860                if ((c = a.pending) == 0) {
4861                    if ((a = (s = a).parent) == null) {
4862                        s.quietlyComplete();
4863                        break;
4864                    }
4865                }
4866                else if (U.compareAndSwapInt(a, PENDING, c, c - 1))
4867                    break;
4868            }
4869        }
4870
4871        /**
4872         * Forces root task to throw exception unless already complete.
4873         */
4874        final void tryAbortComputation(Throwable ex) {
4875            for (BulkTask<K,V,?> a = this;;) {
4876                BulkTask<K,V,?> p = a.parent;
4877                if (p == null) {
4878                    a.completeExceptionally(ex);
4879                    break;
4880                }
4881                a = p;
4882            }
4883        }
4884
4885        public final boolean exec() {
4886            try {
4887                compute();
4888            }
4889            catch (Throwable ex) {
4890                tryAbortComputation(ex);
4891            }
4892            return false;
4893        }
4894
4895        public abstract void compute();
4896
4897        // utilities
4898
4899        /** CompareAndSet pending count */
4900        final boolean casPending(int cmp, int val) {
4901            return U.compareAndSwapInt(this, PENDING, cmp, val);
4902        }
4903
4904        /**
4905         * Returns approx exp2 of the number of times (minus one) to
4906         * split task by two before executing leaf action. This value
4907         * is faster to compute and more convenient to use as a guide
4908         * to splitting than is the depth, since it is used while
4909         * dividing by two anyway.
4910         */
4911        final int batch() {
4912            int b = batch;
4913            if (b < 0) {
4914                long n = map.counter.sum();
4915                int sp = getPool().getParallelism() << 3; // slack of 8
4916                b = batch = (n <= 0L) ? 0 : (n < (long)sp) ? (int)n : sp;
4917            }
4918            return b;
4919        }
4920
4921        /**
4922         * Error message for hoisted null checks of functions
4923         */
4924        static final String NullFunctionMessage =
4925            "Unexpected null function";
4926
4927        /**
4928         * Returns exportable snapshot entry.
4929         */
4930        static <K,V> AbstractMap.SimpleEntry<K,V> entryFor(K k, V v) {
4931            return new AbstractMap.SimpleEntry<K,V>(k, v);
4932        }
4933
4934        // Unsafe mechanics
4935        private static final sun.misc.Unsafe U;
4936        private static final long PENDING;
4937        static {
4938            try {
4939                U = getUnsafe();
4940                PENDING = U.objectFieldOffset
4941                    (BulkTask.class.getDeclaredField("pending"));
4942            } catch (Exception e) {
4943                throw new Error(e);
4944            }
4945        }
4946    }
4947
5376      /*
5377       * Task classes. Coded in a regular but ugly format/style to
5378       * simplify checks that each variant differs in the right way from
5379       * others.
5380       */
5381  
5382 <    @SuppressWarnings("serial")
5383 <    static final class ForEachKeyTask<K,V>
4956 <        extends BulkTask<K,V,Void> {
5382 >    @SuppressWarnings("serial") static final class ForEachKeyTask<K,V>
5383 >        extends Traverser<K,V,Void> {
5384          final Action<K> action;
5385          ForEachKeyTask
5386 <            (ConcurrentHashMapV8<K,V> m,
4960 <             Action<K> action) {
4961 <            super(m);
4962 <            this.action = action;
4963 <        }
4964 <        ForEachKeyTask
4965 <            (BulkTask<K,V,?> p, int b, boolean split,
5386 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5387               Action<K> action) {
5388 <            super(p, b, split);
5388 >            super(m, p, b);
5389              this.action = action;
5390          }
5391          @SuppressWarnings("unchecked") public final void compute() {
5392 <            final Action<K> action = this.action;
5393 <            if (action == null)
5394 <                throw new Error(NullFunctionMessage);
5395 <            int b = batch(), c;
5396 <            while (b > 1 && baseIndex != baseLimit) {
4976 <                do {} while (!casPending(c = pending, c+1));
4977 <                new ForEachKeyTask<K,V>(this, b >>>= 1, true, action).fork();
4978 <            }
5392 >            final Action<K> action;
5393 >            if ((action = this.action) == null)
5394 >                throw new NullPointerException();
5395 >            for (int b; (b = preSplit()) > 0;)
5396 >                new ForEachKeyTask<K,V>(map, this, b, action).fork();
5397              while (advance() != null)
5398                  action.apply((K)nextKey);
5399 <            tryComplete();
5399 >            propagateCompletion();
5400          }
5401      }
5402  
5403 <    @SuppressWarnings("serial")
5404 <    static final class ForEachValueTask<K,V>
4987 <        extends BulkTask<K,V,Void> {
5403 >    @SuppressWarnings("serial") static final class ForEachValueTask<K,V>
5404 >        extends Traverser<K,V,Void> {
5405          final Action<V> action;
5406          ForEachValueTask
5407 <            (ConcurrentHashMapV8<K,V> m,
5407 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5408               Action<V> action) {
5409 <            super(m);
4993 <            this.action = action;
4994 <        }
4995 <        ForEachValueTask
4996 <            (BulkTask<K,V,?> p, int b, boolean split,
4997 <             Action<V> action) {
4998 <            super(p, b, split);
5409 >            super(m, p, b);
5410              this.action = action;
5411          }
5412          @SuppressWarnings("unchecked") public final void compute() {
5413 <            final Action<V> action = this.action;
5414 <            if (action == null)
5415 <                throw new Error(NullFunctionMessage);
5416 <            int b = batch(), c;
5417 <            while (b > 1 && baseIndex != baseLimit) {
5007 <                do {} while (!casPending(c = pending, c+1));
5008 <                new ForEachValueTask<K,V>(this, b >>>= 1, true, action).fork();
5009 <            }
5413 >            final Action<V> action;
5414 >            if ((action = this.action) == null)
5415 >                throw new NullPointerException();
5416 >            for (int b; (b = preSplit()) > 0;)
5417 >                new ForEachValueTask<K,V>(map, this, b, action).fork();
5418              Object v;
5419              while ((v = advance()) != null)
5420                  action.apply((V)v);
5421 <            tryComplete();
5421 >            propagateCompletion();
5422          }
5423      }
5424  
5425 <    @SuppressWarnings("serial")
5426 <    static final class ForEachEntryTask<K,V>
5019 <        extends BulkTask<K,V,Void> {
5425 >    @SuppressWarnings("serial") static final class ForEachEntryTask<K,V>
5426 >        extends Traverser<K,V,Void> {
5427          final Action<Entry<K,V>> action;
5428          ForEachEntryTask
5429 <            (ConcurrentHashMapV8<K,V> m,
5429 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5430               Action<Entry<K,V>> action) {
5431 <            super(m);
5025 <            this.action = action;
5026 <        }
5027 <        ForEachEntryTask
5028 <            (BulkTask<K,V,?> p, int b, boolean split,
5029 <             Action<Entry<K,V>> action) {
5030 <            super(p, b, split);
5431 >            super(m, p, b);
5432              this.action = action;
5433          }
5434          @SuppressWarnings("unchecked") public final void compute() {
5435 <            final Action<Entry<K,V>> action = this.action;
5436 <            if (action == null)
5437 <                throw new Error(NullFunctionMessage);
5438 <            int b = batch(), c;
5439 <            while (b > 1 && baseIndex != baseLimit) {
5039 <                do {} while (!casPending(c = pending, c+1));
5040 <                new ForEachEntryTask<K,V>(this, b >>>= 1, true, action).fork();
5041 <            }
5435 >            final Action<Entry<K,V>> action;
5436 >            if ((action = this.action) == null)
5437 >                throw new NullPointerException();
5438 >            for (int b; (b = preSplit()) > 0;)
5439 >                new ForEachEntryTask<K,V>(map, this, b, action).fork();
5440              Object v;
5441              while ((v = advance()) != null)
5442                  action.apply(entryFor((K)nextKey, (V)v));
5443 <            tryComplete();
5443 >            propagateCompletion();
5444          }
5445      }
5446  
5447 <    @SuppressWarnings("serial")
5448 <    static final class ForEachMappingTask<K,V>
5051 <        extends BulkTask<K,V,Void> {
5447 >    @SuppressWarnings("serial") static final class ForEachMappingTask<K,V>
5448 >        extends Traverser<K,V,Void> {
5449          final BiAction<K,V> action;
5450          ForEachMappingTask
5451 <            (ConcurrentHashMapV8<K,V> m,
5055 <             BiAction<K,V> action) {
5056 <            super(m);
5057 <            this.action = action;
5058 <        }
5059 <        ForEachMappingTask
5060 <            (BulkTask<K,V,?> p, int b, boolean split,
5451 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5452               BiAction<K,V> action) {
5453 <            super(p, b, split);
5453 >            super(m, p, b);
5454              this.action = action;
5455          }
5065
5456          @SuppressWarnings("unchecked") public final void compute() {
5457 <            final BiAction<K,V> action = this.action;
5458 <            if (action == null)
5459 <                throw new Error(NullFunctionMessage);
5460 <            int b = batch(), c;
5461 <            while (b > 1 && baseIndex != baseLimit) {
5072 <                do {} while (!casPending(c = pending, c+1));
5073 <                new ForEachMappingTask<K,V>(this, b >>>= 1, true,
5074 <                                            action).fork();
5075 <            }
5457 >            final BiAction<K,V> action;
5458 >            if ((action = this.action) == null)
5459 >                throw new NullPointerException();
5460 >            for (int b; (b = preSplit()) > 0;)
5461 >                new ForEachMappingTask<K,V>(map, this, b, action).fork();
5462              Object v;
5463              while ((v = advance()) != null)
5464                  action.apply((K)nextKey, (V)v);
5465 <            tryComplete();
5465 >            propagateCompletion();
5466          }
5467      }
5468  
5469 <    @SuppressWarnings("serial")
5470 <    static final class ForEachTransformedKeyTask<K,V,U>
5085 <        extends BulkTask<K,V,Void> {
5469 >    @SuppressWarnings("serial") static final class ForEachTransformedKeyTask<K,V,U>
5470 >        extends Traverser<K,V,Void> {
5471          final Fun<? super K, ? extends U> transformer;
5472          final Action<U> action;
5473          ForEachTransformedKeyTask
5474 <            (ConcurrentHashMapV8<K,V> m,
5475 <             Fun<? super K, ? extends U> transformer,
5476 <             Action<U> action) {
5477 <            super(m);
5093 <            this.transformer = transformer;
5094 <            this.action = action;
5095 <
5096 <        }
5097 <        ForEachTransformedKeyTask
5098 <            (BulkTask<K,V,?> p, int b, boolean split,
5099 <             Fun<? super K, ? extends U> transformer,
5100 <             Action<U> action) {
5101 <            super(p, b, split);
5102 <            this.transformer = transformer;
5103 <            this.action = action;
5474 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5475 >             Fun<? super K, ? extends U> transformer, Action<U> action) {
5476 >            super(m, p, b);
5477 >            this.transformer = transformer; this.action = action;
5478          }
5479          @SuppressWarnings("unchecked") public final void compute() {
5480 <            final Fun<? super K, ? extends U> transformer =
5481 <                this.transformer;
5482 <            final Action<U> action = this.action;
5483 <            if (transformer == null || action == null)
5484 <                throw new Error(NullFunctionMessage);
5485 <            int b = batch(), c;
5112 <            while (b > 1 && baseIndex != baseLimit) {
5113 <                do {} while (!casPending(c = pending, c+1));
5480 >            final Fun<? super K, ? extends U> transformer;
5481 >            final Action<U> action;
5482 >            if ((transformer = this.transformer) == null ||
5483 >                (action = this.action) == null)
5484 >                throw new NullPointerException();
5485 >            for (int b; (b = preSplit()) > 0;)
5486                  new ForEachTransformedKeyTask<K,V,U>
5487 <                    (this, b >>>= 1, true, transformer, action).fork();
5116 <            }
5487 >                     (map, this, b, transformer, action).fork();
5488              U u;
5489              while (advance() != null) {
5490                  if ((u = transformer.apply((K)nextKey)) != null)
5491                      action.apply(u);
5492              }
5493 <            tryComplete();
5493 >            propagateCompletion();
5494          }
5495      }
5496  
5497 <    @SuppressWarnings("serial")
5498 <    static final class ForEachTransformedValueTask<K,V,U>
5128 <        extends BulkTask<K,V,Void> {
5497 >    @SuppressWarnings("serial") static final class ForEachTransformedValueTask<K,V,U>
5498 >        extends Traverser<K,V,Void> {
5499          final Fun<? super V, ? extends U> transformer;
5500          final Action<U> action;
5501          ForEachTransformedValueTask
5502 <            (ConcurrentHashMapV8<K,V> m,
5503 <             Fun<? super V, ? extends U> transformer,
5504 <             Action<U> action) {
5505 <            super(m);
5136 <            this.transformer = transformer;
5137 <            this.action = action;
5138 <
5139 <        }
5140 <        ForEachTransformedValueTask
5141 <            (BulkTask<K,V,?> p, int b, boolean split,
5142 <             Fun<? super V, ? extends U> transformer,
5143 <             Action<U> action) {
5144 <            super(p, b, split);
5145 <            this.transformer = transformer;
5146 <            this.action = action;
5502 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5503 >             Fun<? super V, ? extends U> transformer, Action<U> action) {
5504 >            super(m, p, b);
5505 >            this.transformer = transformer; this.action = action;
5506          }
5507          @SuppressWarnings("unchecked") public final void compute() {
5508 <            final Fun<? super V, ? extends U> transformer =
5509 <                this.transformer;
5510 <            final Action<U> action = this.action;
5511 <            if (transformer == null || action == null)
5512 <                throw new Error(NullFunctionMessage);
5513 <            int b = batch(), c;
5155 <            while (b > 1 && baseIndex != baseLimit) {
5156 <                do {} while (!casPending(c = pending, c+1));
5508 >            final Fun<? super V, ? extends U> transformer;
5509 >            final Action<U> action;
5510 >            if ((transformer = this.transformer) == null ||
5511 >                (action = this.action) == null)
5512 >                throw new NullPointerException();
5513 >            for (int b; (b = preSplit()) > 0;)
5514                  new ForEachTransformedValueTask<K,V,U>
5515 <                    (this, b >>>= 1, true, transformer, action).fork();
5159 <            }
5515 >                    (map, this, b, transformer, action).fork();
5516              Object v; U u;
5517              while ((v = advance()) != null) {
5518                  if ((u = transformer.apply((V)v)) != null)
5519                      action.apply(u);
5520              }
5521 <            tryComplete();
5521 >            propagateCompletion();
5522          }
5523      }
5524  
5525 <    @SuppressWarnings("serial")
5526 <    static final class ForEachTransformedEntryTask<K,V,U>
5171 <        extends BulkTask<K,V,Void> {
5525 >    @SuppressWarnings("serial") static final class ForEachTransformedEntryTask<K,V,U>
5526 >        extends Traverser<K,V,Void> {
5527          final Fun<Map.Entry<K,V>, ? extends U> transformer;
5528          final Action<U> action;
5529          ForEachTransformedEntryTask
5530 <            (ConcurrentHashMapV8<K,V> m,
5531 <             Fun<Map.Entry<K,V>, ? extends U> transformer,
5532 <             Action<U> action) {
5533 <            super(m);
5179 <            this.transformer = transformer;
5180 <            this.action = action;
5181 <
5182 <        }
5183 <        ForEachTransformedEntryTask
5184 <            (BulkTask<K,V,?> p, int b, boolean split,
5185 <             Fun<Map.Entry<K,V>, ? extends U> transformer,
5186 <             Action<U> action) {
5187 <            super(p, b, split);
5188 <            this.transformer = transformer;
5189 <            this.action = action;
5530 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5531 >             Fun<Map.Entry<K,V>, ? extends U> transformer, Action<U> action) {
5532 >            super(m, p, b);
5533 >            this.transformer = transformer; this.action = action;
5534          }
5535          @SuppressWarnings("unchecked") public final void compute() {
5536 <            final Fun<Map.Entry<K,V>, ? extends U> transformer =
5537 <                this.transformer;
5538 <            final Action<U> action = this.action;
5539 <            if (transformer == null || action == null)
5540 <                throw new Error(NullFunctionMessage);
5541 <            int b = batch(), c;
5198 <            while (b > 1 && baseIndex != baseLimit) {
5199 <                do {} while (!casPending(c = pending, c+1));
5536 >            final Fun<Map.Entry<K,V>, ? extends U> transformer;
5537 >            final Action<U> action;
5538 >            if ((transformer = this.transformer) == null ||
5539 >                (action = this.action) == null)
5540 >                throw new NullPointerException();
5541 >            for (int b; (b = preSplit()) > 0;)
5542                  new ForEachTransformedEntryTask<K,V,U>
5543 <                    (this, b >>>= 1, true, transformer, action).fork();
5202 <            }
5543 >                    (map, this, b, transformer, action).fork();
5544              Object v; U u;
5545              while ((v = advance()) != null) {
5546                  if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
5547                      action.apply(u);
5548              }
5549 <            tryComplete();
5549 >            propagateCompletion();
5550          }
5551      }
5552  
5553 <    @SuppressWarnings("serial")
5554 <    static final class ForEachTransformedMappingTask<K,V,U>
5214 <        extends BulkTask<K,V,Void> {
5553 >    @SuppressWarnings("serial") static final class ForEachTransformedMappingTask<K,V,U>
5554 >        extends Traverser<K,V,Void> {
5555          final BiFun<? super K, ? super V, ? extends U> transformer;
5556          final Action<U> action;
5557          ForEachTransformedMappingTask
5558 <            (ConcurrentHashMapV8<K,V> m,
5219 <             BiFun<? super K, ? super V, ? extends U> transformer,
5220 <             Action<U> action) {
5221 <            super(m);
5222 <            this.transformer = transformer;
5223 <            this.action = action;
5224 <
5225 <        }
5226 <        ForEachTransformedMappingTask
5227 <            (BulkTask<K,V,?> p, int b, boolean split,
5558 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5559               BiFun<? super K, ? super V, ? extends U> transformer,
5560               Action<U> action) {
5561 <            super(p, b, split);
5562 <            this.transformer = transformer;
5232 <            this.action = action;
5561 >            super(m, p, b);
5562 >            this.transformer = transformer; this.action = action;
5563          }
5564          @SuppressWarnings("unchecked") public final void compute() {
5565 <            final BiFun<? super K, ? super V, ? extends U> transformer =
5566 <                this.transformer;
5567 <            final Action<U> action = this.action;
5568 <            if (transformer == null || action == null)
5569 <                throw new Error(NullFunctionMessage);
5570 <            int b = batch(), c;
5241 <            while (b > 1 && baseIndex != baseLimit) {
5242 <                do {} while (!casPending(c = pending, c+1));
5565 >            final BiFun<? super K, ? super V, ? extends U> transformer;
5566 >            final Action<U> action;
5567 >            if ((transformer = this.transformer) == null ||
5568 >                (action = this.action) == null)
5569 >                throw new NullPointerException();
5570 >            for (int b; (b = preSplit()) > 0;)
5571                  new ForEachTransformedMappingTask<K,V,U>
5572 <                    (this, b >>>= 1, true, transformer, action).fork();
5245 <            }
5572 >                    (map, this, b, transformer, action).fork();
5573              Object v; U u;
5574              while ((v = advance()) != null) {
5575                  if ((u = transformer.apply((K)nextKey, (V)v)) != null)
5576                      action.apply(u);
5577              }
5578 <            tryComplete();
5578 >            propagateCompletion();
5579          }
5580      }
5581  
5582 <    @SuppressWarnings("serial")
5583 <    static final class SearchKeysTask<K,V,U>
5257 <        extends BulkTask<K,V,U> {
5582 >    @SuppressWarnings("serial") static final class SearchKeysTask<K,V,U>
5583 >        extends Traverser<K,V,U> {
5584          final Fun<? super K, ? extends U> searchFunction;
5585          final AtomicReference<U> result;
5586          SearchKeysTask
5587 <            (ConcurrentHashMapV8<K,V> m,
5587 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5588               Fun<? super K, ? extends U> searchFunction,
5589               AtomicReference<U> result) {
5590 <            super(m);
5265 <            this.searchFunction = searchFunction; this.result = result;
5266 <        }
5267 <        SearchKeysTask
5268 <            (BulkTask<K,V,?> p, int b, boolean split,
5269 <             Fun<? super K, ? extends U> searchFunction,
5270 <             AtomicReference<U> result) {
5271 <            super(p, b, split);
5590 >            super(m, p, b);
5591              this.searchFunction = searchFunction; this.result = result;
5592          }
5593 +        public final U getRawResult() { return result.get(); }
5594          @SuppressWarnings("unchecked") public final void compute() {
5595 <            AtomicReference<U> result = this.result;
5596 <            final Fun<? super K, ? extends U> searchFunction =
5597 <                this.searchFunction;
5598 <            if (searchFunction == null || result == null)
5599 <                throw new Error(NullFunctionMessage);
5600 <            int b = batch(), c;
5601 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5602 <                do {} while (!casPending(c = pending, c+1));
5603 <                new SearchKeysTask<K,V,U>(this, b >>>= 1, true,
5604 <                                          searchFunction, result).fork();
5595 >            final Fun<? super K, ? extends U> searchFunction;
5596 >            final AtomicReference<U> result;
5597 >            if ((searchFunction = this.searchFunction) == null ||
5598 >                (result = this.result) == null)
5599 >                throw new NullPointerException();
5600 >            for (int b;;) {
5601 >                if (result.get() != null)
5602 >                    return;
5603 >                if ((b = preSplit()) <= 0)
5604 >                    break;
5605 >                new SearchKeysTask<K,V,U>
5606 >                    (map, this, b, searchFunction, result).fork();
5607              }
5608 <            U u;
5609 <            while (result.get() == null && advance() != null) {
5608 >            while (result.get() == null) {
5609 >                U u;
5610 >                if (advance() == null) {
5611 >                    propagateCompletion();
5612 >                    break;
5613 >                }
5614                  if ((u = searchFunction.apply((K)nextKey)) != null) {
5615 <                    if (result.compareAndSet(null, u)) {
5616 <                        for (BulkTask<K,V,?> a = this, p;;) {
5291 <                            if ((p = a.parent) == null) {
5292 <                                a.quietlyComplete();
5293 <                                break;
5294 <                            }
5295 <                            a = p;
5296 <                        }
5297 <                    }
5615 >                    if (result.compareAndSet(null, u))
5616 >                        quietlyCompleteRoot();
5617                      break;
5618                  }
5619              }
5301            tryComplete();
5620          }
5303        public final U getRawResult() { return result.get(); }
5621      }
5622  
5623 <    @SuppressWarnings("serial")
5624 <    static final class SearchValuesTask<K,V,U>
5308 <        extends BulkTask<K,V,U> {
5623 >    @SuppressWarnings("serial") static final class SearchValuesTask<K,V,U>
5624 >        extends Traverser<K,V,U> {
5625          final Fun<? super V, ? extends U> searchFunction;
5626          final AtomicReference<U> result;
5627          SearchValuesTask
5628 <            (ConcurrentHashMapV8<K,V> m,
5313 <             Fun<? super V, ? extends U> searchFunction,
5314 <             AtomicReference<U> result) {
5315 <            super(m);
5316 <            this.searchFunction = searchFunction; this.result = result;
5317 <        }
5318 <        SearchValuesTask
5319 <            (BulkTask<K,V,?> p, int b, boolean split,
5628 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5629               Fun<? super V, ? extends U> searchFunction,
5630               AtomicReference<U> result) {
5631 <            super(p, b, split);
5631 >            super(m, p, b);
5632              this.searchFunction = searchFunction; this.result = result;
5633          }
5634 +        public final U getRawResult() { return result.get(); }
5635          @SuppressWarnings("unchecked") public final void compute() {
5636 <            AtomicReference<U> result = this.result;
5637 <            final Fun<? super V, ? extends U> searchFunction =
5638 <                this.searchFunction;
5639 <            if (searchFunction == null || result == null)
5640 <                throw new Error(NullFunctionMessage);
5641 <            int b = batch(), c;
5642 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5643 <                do {} while (!casPending(c = pending, c+1));
5644 <                new SearchValuesTask<K,V,U>(this, b >>>= 1, true,
5645 <                                            searchFunction, result).fork();
5636 >            final Fun<? super V, ? extends U> searchFunction;
5637 >            final AtomicReference<U> result;
5638 >            if ((searchFunction = this.searchFunction) == null ||
5639 >                (result = this.result) == null)
5640 >                throw new NullPointerException();
5641 >            for (int b;;) {
5642 >                if (result.get() != null)
5643 >                    return;
5644 >                if ((b = preSplit()) <= 0)
5645 >                    break;
5646 >                new SearchValuesTask<K,V,U>
5647 >                    (map, this, b, searchFunction, result).fork();
5648              }
5649 <            Object v; U u;
5650 <            while (result.get() == null && (v = advance()) != null) {
5649 >            while (result.get() == null) {
5650 >                Object v; U u;
5651 >                if ((v = advance()) == null) {
5652 >                    propagateCompletion();
5653 >                    break;
5654 >                }
5655                  if ((u = searchFunction.apply((V)v)) != null) {
5656 <                    if (result.compareAndSet(null, u)) {
5657 <                        for (BulkTask<K,V,?> a = this, p;;) {
5342 <                            if ((p = a.parent) == null) {
5343 <                                a.quietlyComplete();
5344 <                                break;
5345 <                            }
5346 <                            a = p;
5347 <                        }
5348 <                    }
5656 >                    if (result.compareAndSet(null, u))
5657 >                        quietlyCompleteRoot();
5658                      break;
5659                  }
5660              }
5352            tryComplete();
5661          }
5354        public final U getRawResult() { return result.get(); }
5662      }
5663  
5664 <    @SuppressWarnings("serial")
5665 <    static final class SearchEntriesTask<K,V,U>
5359 <        extends BulkTask<K,V,U> {
5664 >    @SuppressWarnings("serial") static final class SearchEntriesTask<K,V,U>
5665 >        extends Traverser<K,V,U> {
5666          final Fun<Entry<K,V>, ? extends U> searchFunction;
5667          final AtomicReference<U> result;
5668          SearchEntriesTask
5669 <            (ConcurrentHashMapV8<K,V> m,
5364 <             Fun<Entry<K,V>, ? extends U> searchFunction,
5365 <             AtomicReference<U> result) {
5366 <            super(m);
5367 <            this.searchFunction = searchFunction; this.result = result;
5368 <        }
5369 <        SearchEntriesTask
5370 <            (BulkTask<K,V,?> p, int b, boolean split,
5669 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5670               Fun<Entry<K,V>, ? extends U> searchFunction,
5671               AtomicReference<U> result) {
5672 <            super(p, b, split);
5672 >            super(m, p, b);
5673              this.searchFunction = searchFunction; this.result = result;
5674          }
5675 +        public final U getRawResult() { return result.get(); }
5676          @SuppressWarnings("unchecked") public final void compute() {
5677 <            AtomicReference<U> result = this.result;
5678 <            final Fun<Entry<K,V>, ? extends U> searchFunction =
5679 <                this.searchFunction;
5680 <            if (searchFunction == null || result == null)
5681 <                throw new Error(NullFunctionMessage);
5682 <            int b = batch(), c;
5683 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5684 <                do {} while (!casPending(c = pending, c+1));
5685 <                new SearchEntriesTask<K,V,U>(this, b >>>= 1, true,
5686 <                                             searchFunction, result).fork();
5677 >            final Fun<Entry<K,V>, ? extends U> searchFunction;
5678 >            final AtomicReference<U> result;
5679 >            if ((searchFunction = this.searchFunction) == null ||
5680 >                (result = this.result) == null)
5681 >                throw new NullPointerException();
5682 >            for (int b;;) {
5683 >                if (result.get() != null)
5684 >                    return;
5685 >                if ((b = preSplit()) <= 0)
5686 >                    break;
5687 >                new SearchEntriesTask<K,V,U>
5688 >                    (map, this, b, searchFunction, result).fork();
5689              }
5690 <            Object v; U u;
5691 <            while (result.get() == null && (v = advance()) != null) {
5692 <                if ((u = searchFunction.apply(entryFor((K)nextKey, (V)v))) != null) {
5693 <                    if (result.compareAndSet(null, u)) {
5392 <                        for (BulkTask<K,V,?> a = this, p;;) {
5393 <                            if ((p = a.parent) == null) {
5394 <                                a.quietlyComplete();
5395 <                                break;
5396 <                            }
5397 <                            a = p;
5398 <                        }
5399 <                    }
5690 >            while (result.get() == null) {
5691 >                Object v; U u;
5692 >                if ((v = advance()) == null) {
5693 >                    propagateCompletion();
5694                      break;
5695                  }
5696 +                if ((u = searchFunction.apply(entryFor((K)nextKey, (V)v))) != null) {
5697 +                    if (result.compareAndSet(null, u))
5698 +                        quietlyCompleteRoot();
5699 +                    return;
5700 +                }
5701              }
5403            tryComplete();
5702          }
5405        public final U getRawResult() { return result.get(); }
5703      }
5704  
5705 <    @SuppressWarnings("serial")
5706 <    static final class SearchMappingsTask<K,V,U>
5410 <        extends BulkTask<K,V,U> {
5705 >    @SuppressWarnings("serial") static final class SearchMappingsTask<K,V,U>
5706 >        extends Traverser<K,V,U> {
5707          final BiFun<? super K, ? super V, ? extends U> searchFunction;
5708          final AtomicReference<U> result;
5709          SearchMappingsTask
5710 <            (ConcurrentHashMapV8<K,V> m,
5415 <             BiFun<? super K, ? super V, ? extends U> searchFunction,
5416 <             AtomicReference<U> result) {
5417 <            super(m);
5418 <            this.searchFunction = searchFunction; this.result = result;
5419 <        }
5420 <        SearchMappingsTask
5421 <            (BulkTask<K,V,?> p, int b, boolean split,
5710 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5711               BiFun<? super K, ? super V, ? extends U> searchFunction,
5712               AtomicReference<U> result) {
5713 <            super(p, b, split);
5713 >            super(m, p, b);
5714              this.searchFunction = searchFunction; this.result = result;
5715          }
5716 +        public final U getRawResult() { return result.get(); }
5717          @SuppressWarnings("unchecked") public final void compute() {
5718 <            AtomicReference<U> result = this.result;
5719 <            final BiFun<? super K, ? super V, ? extends U> searchFunction =
5720 <                this.searchFunction;
5721 <            if (searchFunction == null || result == null)
5722 <                throw new Error(NullFunctionMessage);
5723 <            int b = batch(), c;
5724 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5725 <                do {} while (!casPending(c = pending, c+1));
5726 <                new SearchMappingsTask<K,V,U>(this, b >>>= 1, true,
5727 <                                              searchFunction, result).fork();
5718 >            final BiFun<? super K, ? super V, ? extends U> searchFunction;
5719 >            final AtomicReference<U> result;
5720 >            if ((searchFunction = this.searchFunction) == null ||
5721 >                (result = this.result) == null)
5722 >                throw new NullPointerException();
5723 >            for (int b;;) {
5724 >                if (result.get() != null)
5725 >                    return;
5726 >                if ((b = preSplit()) <= 0)
5727 >                    break;
5728 >                new SearchMappingsTask<K,V,U>
5729 >                    (map, this, b, searchFunction, result).fork();
5730              }
5731 <            Object v; U u;
5732 <            while (result.get() == null && (v = advance()) != null) {
5731 >            while (result.get() == null) {
5732 >                Object v; U u;
5733 >                if ((v = advance()) == null) {
5734 >                    propagateCompletion();
5735 >                    break;
5736 >                }
5737                  if ((u = searchFunction.apply((K)nextKey, (V)v)) != null) {
5738 <                    if (result.compareAndSet(null, u)) {
5739 <                        for (BulkTask<K,V,?> a = this, p;;) {
5444 <                            if ((p = a.parent) == null) {
5445 <                                a.quietlyComplete();
5446 <                                break;
5447 <                            }
5448 <                            a = p;
5449 <                        }
5450 <                    }
5738 >                    if (result.compareAndSet(null, u))
5739 >                        quietlyCompleteRoot();
5740                      break;
5741                  }
5742              }
5454            tryComplete();
5743          }
5456        public final U getRawResult() { return result.get(); }
5744      }
5745  
5746 <    @SuppressWarnings("serial")
5747 <    static final class ReduceKeysTask<K,V>
5461 <        extends BulkTask<K,V,K> {
5746 >    @SuppressWarnings("serial") static final class ReduceKeysTask<K,V>
5747 >        extends Traverser<K,V,K> {
5748          final BiFun<? super K, ? super K, ? extends K> reducer;
5749          K result;
5750 <        ReduceKeysTask<K,V> sibling;
5465 <        ReduceKeysTask
5466 <            (ConcurrentHashMapV8<K,V> m,
5467 <             BiFun<? super K, ? super K, ? extends K> reducer) {
5468 <            super(m);
5469 <            this.reducer = reducer;
5470 <        }
5750 >        ReduceKeysTask<K,V> rights, nextRight;
5751          ReduceKeysTask
5752 <            (BulkTask<K,V,?> p, int b, boolean split,
5752 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5753 >             ReduceKeysTask<K,V> nextRight,
5754               BiFun<? super K, ? super K, ? extends K> reducer) {
5755 <            super(p, b, split);
5755 >            super(m, p, b); this.nextRight = nextRight;
5756              this.reducer = reducer;
5757          }
5758 <
5758 >        public final K getRawResult() { return result; }
5759          @SuppressWarnings("unchecked") public final void compute() {
5479            ReduceKeysTask<K,V> t = this;
5760              final BiFun<? super K, ? super K, ? extends K> reducer =
5761                  this.reducer;
5762              if (reducer == null)
5763 <                throw new Error(NullFunctionMessage);
5764 <            int b = batch();
5765 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5766 <                b >>>= 1;
5487 <                t.pending = 1;
5488 <                ReduceKeysTask<K,V> rt =
5489 <                    new ReduceKeysTask<K,V>
5490 <                    (t, b, true, reducer);
5491 <                t = new ReduceKeysTask<K,V>
5492 <                    (t, b, false, reducer);
5493 <                t.sibling = rt;
5494 <                rt.sibling = t;
5495 <                rt.fork();
5496 <            }
5763 >                throw new NullPointerException();
5764 >            for (int b; (b = preSplit()) > 0;)
5765 >                (rights = new ReduceKeysTask<K,V>
5766 >                 (map, this, b, rights, reducer)).fork();
5767              K r = null;
5768 <            while (t.advance() != null) {
5769 <                K u = (K)t.nextKey;
5768 >            while (advance() != null) {
5769 >                K u = (K)nextKey;
5770                  r = (r == null) ? u : reducer.apply(r, u);
5771              }
5772 <            t.result = r;
5773 <            for (;;) {
5774 <                int c; BulkTask<K,V,?> par; ReduceKeysTask<K,V> s, p; K u;
5775 <                if ((par = t.parent) == null ||
5776 <                    !(par instanceof ReduceKeysTask)) {
5777 <                    t.quietlyComplete();
5778 <                    break;
5779 <                }
5780 <                else if ((c = (p = (ReduceKeysTask<K,V>)par).pending) == 0) {
5781 <                    if ((s = t.sibling) != null && (u = s.result) != null)
5782 <                        r = (r == null) ? u : reducer.apply(r, u);
5783 <                    (t = p).result = r;
5772 >            result = r;
5773 >            CountedCompleter<?> c;
5774 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
5775 >                ReduceKeysTask<K,V>
5776 >                    t = (ReduceKeysTask<K,V>)c,
5777 >                    s = t.rights;
5778 >                while (s != null) {
5779 >                    K tr, sr;
5780 >                    if ((sr = s.result) != null)
5781 >                        t.result = (((tr = t.result) == null) ? sr :
5782 >                                    reducer.apply(tr, sr));
5783 >                    s = t.rights = s.nextRight;
5784                  }
5515                else if (p.casPending(c, 0))
5516                    break;
5785              }
5786          }
5519        public final K getRawResult() { return result; }
5787      }
5788  
5789 <    @SuppressWarnings("serial")
5790 <    static final class ReduceValuesTask<K,V>
5524 <        extends BulkTask<K,V,V> {
5789 >    @SuppressWarnings("serial") static final class ReduceValuesTask<K,V>
5790 >        extends Traverser<K,V,V> {
5791          final BiFun<? super V, ? super V, ? extends V> reducer;
5792          V result;
5793 <        ReduceValuesTask<K,V> sibling;
5528 <        ReduceValuesTask
5529 <            (ConcurrentHashMapV8<K,V> m,
5530 <             BiFun<? super V, ? super V, ? extends V> reducer) {
5531 <            super(m);
5532 <            this.reducer = reducer;
5533 <        }
5793 >        ReduceValuesTask<K,V> rights, nextRight;
5794          ReduceValuesTask
5795 <            (BulkTask<K,V,?> p, int b, boolean split,
5795 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5796 >             ReduceValuesTask<K,V> nextRight,
5797               BiFun<? super V, ? super V, ? extends V> reducer) {
5798 <            super(p, b, split);
5798 >            super(m, p, b); this.nextRight = nextRight;
5799              this.reducer = reducer;
5800          }
5801 <
5801 >        public final V getRawResult() { return result; }
5802          @SuppressWarnings("unchecked") public final void compute() {
5542            ReduceValuesTask<K,V> t = this;
5803              final BiFun<? super V, ? super V, ? extends V> reducer =
5804                  this.reducer;
5805              if (reducer == null)
5806 <                throw new Error(NullFunctionMessage);
5807 <            int b = batch();
5808 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5809 <                b >>>= 1;
5550 <                t.pending = 1;
5551 <                ReduceValuesTask<K,V> rt =
5552 <                    new ReduceValuesTask<K,V>
5553 <                    (t, b, true, reducer);
5554 <                t = new ReduceValuesTask<K,V>
5555 <                    (t, b, false, reducer);
5556 <                t.sibling = rt;
5557 <                rt.sibling = t;
5558 <                rt.fork();
5559 <            }
5806 >                throw new NullPointerException();
5807 >            for (int b; (b = preSplit()) > 0;)
5808 >                (rights = new ReduceValuesTask<K,V>
5809 >                 (map, this, b, rights, reducer)).fork();
5810              V r = null;
5811              Object v;
5812 <            while ((v = t.advance()) != null) {
5812 >            while ((v = advance()) != null) {
5813                  V u = (V)v;
5814                  r = (r == null) ? u : reducer.apply(r, u);
5815              }
5816 <            t.result = r;
5817 <            for (;;) {
5818 <                int c; BulkTask<K,V,?> par; ReduceValuesTask<K,V> s, p; V u;
5819 <                if ((par = t.parent) == null ||
5820 <                    !(par instanceof ReduceValuesTask)) {
5821 <                    t.quietlyComplete();
5822 <                    break;
5816 >            result = r;
5817 >            CountedCompleter<?> c;
5818 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
5819 >                ReduceValuesTask<K,V>
5820 >                    t = (ReduceValuesTask<K,V>)c,
5821 >                    s = t.rights;
5822 >                while (s != null) {
5823 >                    V tr, sr;
5824 >                    if ((sr = s.result) != null)
5825 >                        t.result = (((tr = t.result) == null) ? sr :
5826 >                                    reducer.apply(tr, sr));
5827 >                    s = t.rights = s.nextRight;
5828                  }
5574                else if ((c = (p = (ReduceValuesTask<K,V>)par).pending) == 0) {
5575                    if ((s = t.sibling) != null && (u = s.result) != null)
5576                        r = (r == null) ? u : reducer.apply(r, u);
5577                    (t = p).result = r;
5578                }
5579                else if (p.casPending(c, 0))
5580                    break;
5829              }
5830          }
5583        public final V getRawResult() { return result; }
5831      }
5832  
5833 <    @SuppressWarnings("serial")
5834 <    static final class ReduceEntriesTask<K,V>
5588 <        extends BulkTask<K,V,Map.Entry<K,V>> {
5833 >    @SuppressWarnings("serial") static final class ReduceEntriesTask<K,V>
5834 >        extends Traverser<K,V,Map.Entry<K,V>> {
5835          final BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer;
5836          Map.Entry<K,V> result;
5837 <        ReduceEntriesTask<K,V> sibling;
5837 >        ReduceEntriesTask<K,V> rights, nextRight;
5838          ReduceEntriesTask
5839 <            (ConcurrentHashMapV8<K,V> m,
5839 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5840 >             ReduceEntriesTask<K,V> nextRight,
5841               BiFun<Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5842 <            super(m);
5596 <            this.reducer = reducer;
5597 <        }
5598 <        ReduceEntriesTask
5599 <            (BulkTask<K,V,?> p, int b, boolean split,
5600 <             BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5601 <            super(p, b, split);
5842 >            super(m, p, b); this.nextRight = nextRight;
5843              this.reducer = reducer;
5844          }
5845 <
5845 >        public final Map.Entry<K,V> getRawResult() { return result; }
5846          @SuppressWarnings("unchecked") public final void compute() {
5606            ReduceEntriesTask<K,V> t = this;
5847              final BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer =
5848                  this.reducer;
5849              if (reducer == null)
5850 <                throw new Error(NullFunctionMessage);
5851 <            int b = batch();
5852 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5853 <                b >>>= 1;
5614 <                t.pending = 1;
5615 <                ReduceEntriesTask<K,V> rt =
5616 <                    new ReduceEntriesTask<K,V>
5617 <                    (t, b, true, reducer);
5618 <                t = new ReduceEntriesTask<K,V>
5619 <                    (t, b, false, reducer);
5620 <                t.sibling = rt;
5621 <                rt.sibling = t;
5622 <                rt.fork();
5623 <            }
5850 >                throw new NullPointerException();
5851 >            for (int b; (b = preSplit()) > 0;)
5852 >                (rights = new ReduceEntriesTask<K,V>
5853 >                 (map, this, b, rights, reducer)).fork();
5854              Map.Entry<K,V> r = null;
5855              Object v;
5856 <            while ((v = t.advance()) != null) {
5857 <                Map.Entry<K,V> u = entryFor((K)t.nextKey, (V)v);
5856 >            while ((v = advance()) != null) {
5857 >                Map.Entry<K,V> u = entryFor((K)nextKey, (V)v);
5858                  r = (r == null) ? u : reducer.apply(r, u);
5859              }
5860 <            t.result = r;
5861 <            for (;;) {
5862 <                int c; BulkTask<K,V,?> par; ReduceEntriesTask<K,V> s, p;
5863 <                Map.Entry<K,V> u;
5864 <                if ((par = t.parent) == null ||
5865 <                    !(par instanceof ReduceEntriesTask)) {
5866 <                    t.quietlyComplete();
5867 <                    break;
5868 <                }
5869 <                else if ((c = (p = (ReduceEntriesTask<K,V>)par).pending) == 0) {
5870 <                    if ((s = t.sibling) != null && (u = s.result) != null)
5871 <                        r = (r == null) ? u : reducer.apply(r, u);
5642 <                    (t = p).result = r;
5860 >            result = r;
5861 >            CountedCompleter<?> c;
5862 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
5863 >                ReduceEntriesTask<K,V>
5864 >                    t = (ReduceEntriesTask<K,V>)c,
5865 >                    s = t.rights;
5866 >                while (s != null) {
5867 >                    Map.Entry<K,V> tr, sr;
5868 >                    if ((sr = s.result) != null)
5869 >                        t.result = (((tr = t.result) == null) ? sr :
5870 >                                    reducer.apply(tr, sr));
5871 >                    s = t.rights = s.nextRight;
5872                  }
5644                else if (p.casPending(c, 0))
5645                    break;
5873              }
5874          }
5648        public final Map.Entry<K,V> getRawResult() { return result; }
5875      }
5876  
5877 <    @SuppressWarnings("serial")
5878 <    static final class MapReduceKeysTask<K,V,U>
5653 <        extends BulkTask<K,V,U> {
5877 >    @SuppressWarnings("serial") static final class MapReduceKeysTask<K,V,U>
5878 >        extends Traverser<K,V,U> {
5879          final Fun<? super K, ? extends U> transformer;
5880          final BiFun<? super U, ? super U, ? extends U> reducer;
5881          U result;
5882 <        MapReduceKeysTask<K,V,U> sibling;
5882 >        MapReduceKeysTask<K,V,U> rights, nextRight;
5883          MapReduceKeysTask
5884 <            (ConcurrentHashMapV8<K,V> m,
5884 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5885 >             MapReduceKeysTask<K,V,U> nextRight,
5886               Fun<? super K, ? extends U> transformer,
5887               BiFun<? super U, ? super U, ? extends U> reducer) {
5888 <            super(m);
5663 <            this.transformer = transformer;
5664 <            this.reducer = reducer;
5665 <        }
5666 <        MapReduceKeysTask
5667 <            (BulkTask<K,V,?> p, int b, boolean split,
5668 <             Fun<? super K, ? extends U> transformer,
5669 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5670 <            super(p, b, split);
5888 >            super(m, p, b); this.nextRight = nextRight;
5889              this.transformer = transformer;
5890              this.reducer = reducer;
5891          }
5892 +        public final U getRawResult() { return result; }
5893          @SuppressWarnings("unchecked") public final void compute() {
5675            MapReduceKeysTask<K,V,U> t = this;
5894              final Fun<? super K, ? extends U> transformer =
5895                  this.transformer;
5896              final BiFun<? super U, ? super U, ? extends U> reducer =
5897                  this.reducer;
5898              if (transformer == null || reducer == null)
5899 <                throw new Error(NullFunctionMessage);
5900 <            int b = batch();
5901 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5902 <                b >>>= 1;
5685 <                t.pending = 1;
5686 <                MapReduceKeysTask<K,V,U> rt =
5687 <                    new MapReduceKeysTask<K,V,U>
5688 <                    (t, b, true, transformer, reducer);
5689 <                t = new MapReduceKeysTask<K,V,U>
5690 <                    (t, b, false, transformer, reducer);
5691 <                t.sibling = rt;
5692 <                rt.sibling = t;
5693 <                rt.fork();
5694 <            }
5899 >                throw new NullPointerException();
5900 >            for (int b; (b = preSplit()) > 0;)
5901 >                (rights = new MapReduceKeysTask<K,V,U>
5902 >                 (map, this, b, rights, transformer, reducer)).fork();
5903              U r = null, u;
5904 <            while (t.advance() != null) {
5905 <                if ((u = transformer.apply((K)t.nextKey)) != null)
5904 >            while (advance() != null) {
5905 >                if ((u = transformer.apply((K)nextKey)) != null)
5906                      r = (r == null) ? u : reducer.apply(r, u);
5907              }
5908 <            t.result = r;
5909 <            for (;;) {
5910 <                int c; BulkTask<K,V,?> par; MapReduceKeysTask<K,V,U> s, p;
5911 <                if ((par = t.parent) == null ||
5912 <                    !(par instanceof MapReduceKeysTask)) {
5913 <                    t.quietlyComplete();
5914 <                    break;
5908 >            result = r;
5909 >            CountedCompleter<?> c;
5910 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
5911 >                MapReduceKeysTask<K,V,U>
5912 >                    t = (MapReduceKeysTask<K,V,U>)c,
5913 >                    s = t.rights;
5914 >                while (s != null) {
5915 >                    U tr, sr;
5916 >                    if ((sr = s.result) != null)
5917 >                        t.result = (((tr = t.result) == null) ? sr :
5918 >                                    reducer.apply(tr, sr));
5919 >                    s = t.rights = s.nextRight;
5920                  }
5708                else if ((c = (p = (MapReduceKeysTask<K,V,U>)par).pending) == 0) {
5709                    if ((s = t.sibling) != null && (u = s.result) != null)
5710                        r = (r == null) ? u : reducer.apply(r, u);
5711                    (t = p).result = r;
5712                }
5713                else if (p.casPending(c, 0))
5714                    break;
5921              }
5922          }
5717        public final U getRawResult() { return result; }
5923      }
5924  
5925 <    @SuppressWarnings("serial")
5926 <    static final class MapReduceValuesTask<K,V,U>
5722 <        extends BulkTask<K,V,U> {
5925 >    @SuppressWarnings("serial") static final class MapReduceValuesTask<K,V,U>
5926 >        extends Traverser<K,V,U> {
5927          final Fun<? super V, ? extends U> transformer;
5928          final BiFun<? super U, ? super U, ? extends U> reducer;
5929          U result;
5930 <        MapReduceValuesTask<K,V,U> sibling;
5930 >        MapReduceValuesTask<K,V,U> rights, nextRight;
5931          MapReduceValuesTask
5932 <            (ConcurrentHashMapV8<K,V> m,
5932 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5933 >             MapReduceValuesTask<K,V,U> nextRight,
5934               Fun<? super V, ? extends U> transformer,
5935               BiFun<? super U, ? super U, ? extends U> reducer) {
5936 <            super(m);
5732 <            this.transformer = transformer;
5733 <            this.reducer = reducer;
5734 <        }
5735 <        MapReduceValuesTask
5736 <            (BulkTask<K,V,?> p, int b, boolean split,
5737 <             Fun<? super V, ? extends U> transformer,
5738 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5739 <            super(p, b, split);
5936 >            super(m, p, b); this.nextRight = nextRight;
5937              this.transformer = transformer;
5938              this.reducer = reducer;
5939          }
5940 +        public final U getRawResult() { return result; }
5941          @SuppressWarnings("unchecked") public final void compute() {
5744            MapReduceValuesTask<K,V,U> t = this;
5942              final Fun<? super V, ? extends U> transformer =
5943                  this.transformer;
5944              final BiFun<? super U, ? super U, ? extends U> reducer =
5945                  this.reducer;
5946              if (transformer == null || reducer == null)
5947 <                throw new Error(NullFunctionMessage);
5948 <            int b = batch();
5949 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5950 <                b >>>= 1;
5754 <                t.pending = 1;
5755 <                MapReduceValuesTask<K,V,U> rt =
5756 <                    new MapReduceValuesTask<K,V,U>
5757 <                    (t, b, true, transformer, reducer);
5758 <                t = new MapReduceValuesTask<K,V,U>
5759 <                    (t, b, false, transformer, reducer);
5760 <                t.sibling = rt;
5761 <                rt.sibling = t;
5762 <                rt.fork();
5763 <            }
5947 >                throw new NullPointerException();
5948 >            for (int b; (b = preSplit()) > 0;)
5949 >                (rights = new MapReduceValuesTask<K,V,U>
5950 >                 (map, this, b, rights, transformer, reducer)).fork();
5951              U r = null, u;
5952              Object v;
5953 <            while ((v = t.advance()) != null) {
5953 >            while ((v = advance()) != null) {
5954                  if ((u = transformer.apply((V)v)) != null)
5955                      r = (r == null) ? u : reducer.apply(r, u);
5956              }
5957 <            t.result = r;
5958 <            for (;;) {
5959 <                int c; BulkTask<K,V,?> par; MapReduceValuesTask<K,V,U> s, p;
5960 <                if ((par = t.parent) == null ||
5961 <                    !(par instanceof MapReduceValuesTask)) {
5962 <                    t.quietlyComplete();
5963 <                    break;
5964 <                }
5965 <                else if ((c = (p = (MapReduceValuesTask<K,V,U>)par).pending) == 0) {
5966 <                    if ((s = t.sibling) != null && (u = s.result) != null)
5967 <                        r = (r == null) ? u : reducer.apply(r, u);
5968 <                    (t = p).result = r;
5957 >            result = r;
5958 >            CountedCompleter<?> c;
5959 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
5960 >                MapReduceValuesTask<K,V,U>
5961 >                    t = (MapReduceValuesTask<K,V,U>)c,
5962 >                    s = t.rights;
5963 >                while (s != null) {
5964 >                    U tr, sr;
5965 >                    if ((sr = s.result) != null)
5966 >                        t.result = (((tr = t.result) == null) ? sr :
5967 >                                    reducer.apply(tr, sr));
5968 >                    s = t.rights = s.nextRight;
5969                  }
5783                else if (p.casPending(c, 0))
5784                    break;
5970              }
5971          }
5787        public final U getRawResult() { return result; }
5972      }
5973  
5974 <    @SuppressWarnings("serial")
5975 <    static final class MapReduceEntriesTask<K,V,U>
5792 <        extends BulkTask<K,V,U> {
5974 >    @SuppressWarnings("serial") static final class MapReduceEntriesTask<K,V,U>
5975 >        extends Traverser<K,V,U> {
5976          final Fun<Map.Entry<K,V>, ? extends U> transformer;
5977          final BiFun<? super U, ? super U, ? extends U> reducer;
5978          U result;
5979 <        MapReduceEntriesTask<K,V,U> sibling;
5979 >        MapReduceEntriesTask<K,V,U> rights, nextRight;
5980          MapReduceEntriesTask
5981 <            (ConcurrentHashMapV8<K,V> m,
5981 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5982 >             MapReduceEntriesTask<K,V,U> nextRight,
5983               Fun<Map.Entry<K,V>, ? extends U> transformer,
5984               BiFun<? super U, ? super U, ? extends U> reducer) {
5985 <            super(m);
5802 <            this.transformer = transformer;
5803 <            this.reducer = reducer;
5804 <        }
5805 <        MapReduceEntriesTask
5806 <            (BulkTask<K,V,?> p, int b, boolean split,
5807 <             Fun<Map.Entry<K,V>, ? extends U> transformer,
5808 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5809 <            super(p, b, split);
5985 >            super(m, p, b); this.nextRight = nextRight;
5986              this.transformer = transformer;
5987              this.reducer = reducer;
5988          }
5989 +        public final U getRawResult() { return result; }
5990          @SuppressWarnings("unchecked") public final void compute() {
5814            MapReduceEntriesTask<K,V,U> t = this;
5991              final Fun<Map.Entry<K,V>, ? extends U> transformer =
5992                  this.transformer;
5993              final BiFun<? super U, ? super U, ? extends U> reducer =
5994                  this.reducer;
5995              if (transformer == null || reducer == null)
5996 <                throw new Error(NullFunctionMessage);
5997 <            int b = batch();
5998 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5999 <                b >>>= 1;
5824 <                t.pending = 1;
5825 <                MapReduceEntriesTask<K,V,U> rt =
5826 <                    new MapReduceEntriesTask<K,V,U>
5827 <                    (t, b, true, transformer, reducer);
5828 <                t = new MapReduceEntriesTask<K,V,U>
5829 <                    (t, b, false, transformer, reducer);
5830 <                t.sibling = rt;
5831 <                rt.sibling = t;
5832 <                rt.fork();
5833 <            }
5996 >                throw new NullPointerException();
5997 >            for (int b; (b = preSplit()) > 0;)
5998 >                (rights = new MapReduceEntriesTask<K,V,U>
5999 >                 (map, this, b, rights, transformer, reducer)).fork();
6000              U r = null, u;
6001              Object v;
6002 <            while ((v = t.advance()) != null) {
6003 <                if ((u = transformer.apply(entryFor((K)t.nextKey, (V)v))) != null)
6002 >            while ((v = advance()) != null) {
6003 >                if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
6004                      r = (r == null) ? u : reducer.apply(r, u);
6005              }
6006 <            t.result = r;
6007 <            for (;;) {
6008 <                int c; BulkTask<K,V,?> par; MapReduceEntriesTask<K,V,U> s, p;
6009 <                if ((par = t.parent) == null ||
6010 <                    !(par instanceof MapReduceEntriesTask)) {
6011 <                    t.quietlyComplete();
6012 <                    break;
6006 >            result = r;
6007 >            CountedCompleter<?> c;
6008 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6009 >                MapReduceEntriesTask<K,V,U>
6010 >                    t = (MapReduceEntriesTask<K,V,U>)c,
6011 >                    s = t.rights;
6012 >                while (s != null) {
6013 >                    U tr, sr;
6014 >                    if ((sr = s.result) != null)
6015 >                        t.result = (((tr = t.result) == null) ? sr :
6016 >                                    reducer.apply(tr, sr));
6017 >                    s = t.rights = s.nextRight;
6018                  }
5848                else if ((c = (p = (MapReduceEntriesTask<K,V,U>)par).pending) == 0) {
5849                    if ((s = t.sibling) != null && (u = s.result) != null)
5850                        r = (r == null) ? u : reducer.apply(r, u);
5851                    (t = p).result = r;
5852                }
5853                else if (p.casPending(c, 0))
5854                    break;
6019              }
6020          }
5857        public final U getRawResult() { return result; }
6021      }
6022  
6023 <    @SuppressWarnings("serial")
6024 <    static final class MapReduceMappingsTask<K,V,U>
5862 <        extends BulkTask<K,V,U> {
6023 >    @SuppressWarnings("serial") static final class MapReduceMappingsTask<K,V,U>
6024 >        extends Traverser<K,V,U> {
6025          final BiFun<? super K, ? super V, ? extends U> transformer;
6026          final BiFun<? super U, ? super U, ? extends U> reducer;
6027          U result;
6028 <        MapReduceMappingsTask<K,V,U> sibling;
6028 >        MapReduceMappingsTask<K,V,U> rights, nextRight;
6029          MapReduceMappingsTask
6030 <            (ConcurrentHashMapV8<K,V> m,
6030 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6031 >             MapReduceMappingsTask<K,V,U> nextRight,
6032               BiFun<? super K, ? super V, ? extends U> transformer,
6033               BiFun<? super U, ? super U, ? extends U> reducer) {
6034 <            super(m);
5872 <            this.transformer = transformer;
5873 <            this.reducer = reducer;
5874 <        }
5875 <        MapReduceMappingsTask
5876 <            (BulkTask<K,V,?> p, int b, boolean split,
5877 <             BiFun<? super K, ? super V, ? extends U> transformer,
5878 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5879 <            super(p, b, split);
6034 >            super(m, p, b); this.nextRight = nextRight;
6035              this.transformer = transformer;
6036              this.reducer = reducer;
6037          }
6038 +        public final U getRawResult() { return result; }
6039          @SuppressWarnings("unchecked") public final void compute() {
5884            MapReduceMappingsTask<K,V,U> t = this;
6040              final BiFun<? super K, ? super V, ? extends U> transformer =
6041                  this.transformer;
6042              final BiFun<? super U, ? super U, ? extends U> reducer =
6043                  this.reducer;
6044              if (transformer == null || reducer == null)
6045 <                throw new Error(NullFunctionMessage);
6046 <            int b = batch();
6047 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6048 <                b >>>= 1;
5894 <                t.pending = 1;
5895 <                MapReduceMappingsTask<K,V,U> rt =
5896 <                    new MapReduceMappingsTask<K,V,U>
5897 <                    (t, b, true, transformer, reducer);
5898 <                t = new MapReduceMappingsTask<K,V,U>
5899 <                    (t, b, false, transformer, reducer);
5900 <                t.sibling = rt;
5901 <                rt.sibling = t;
5902 <                rt.fork();
5903 <            }
6045 >                throw new NullPointerException();
6046 >            for (int b; (b = preSplit()) > 0;)
6047 >                (rights = new MapReduceMappingsTask<K,V,U>
6048 >                 (map, this, b, rights, transformer, reducer)).fork();
6049              U r = null, u;
6050              Object v;
6051 <            while ((v = t.advance()) != null) {
6052 <                if ((u = transformer.apply((K)t.nextKey, (V)v)) != null)
6051 >            while ((v = advance()) != null) {
6052 >                if ((u = transformer.apply((K)nextKey, (V)v)) != null)
6053                      r = (r == null) ? u : reducer.apply(r, u);
6054              }
6055 <            for (;;) {
6056 <                int c; BulkTask<K,V,?> par; MapReduceMappingsTask<K,V,U> s, p;
6057 <                if ((par = t.parent) == null ||
6058 <                    !(par instanceof MapReduceMappingsTask)) {
6059 <                    t.quietlyComplete();
6060 <                    break;
6061 <                }
6062 <                else if ((c = (p = (MapReduceMappingsTask<K,V,U>)par).pending) == 0) {
6063 <                    if ((s = t.sibling) != null && (u = s.result) != null)
6064 <                        r = (r == null) ? u : reducer.apply(r, u);
6065 <                    (t = p).result = r;
6055 >            result = r;
6056 >            CountedCompleter<?> c;
6057 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6058 >                MapReduceMappingsTask<K,V,U>
6059 >                    t = (MapReduceMappingsTask<K,V,U>)c,
6060 >                    s = t.rights;
6061 >                while (s != null) {
6062 >                    U tr, sr;
6063 >                    if ((sr = s.result) != null)
6064 >                        t.result = (((tr = t.result) == null) ? sr :
6065 >                                    reducer.apply(tr, sr));
6066 >                    s = t.rights = s.nextRight;
6067                  }
5922                else if (p.casPending(c, 0))
5923                    break;
6068              }
6069          }
5926        public final U getRawResult() { return result; }
6070      }
6071  
6072 <    @SuppressWarnings("serial")
6073 <    static final class MapReduceKeysToDoubleTask<K,V>
5931 <        extends BulkTask<K,V,Double> {
6072 >    @SuppressWarnings("serial") static final class MapReduceKeysToDoubleTask<K,V>
6073 >        extends Traverser<K,V,Double> {
6074          final ObjectToDouble<? super K> transformer;
6075          final DoubleByDoubleToDouble reducer;
6076          final double basis;
6077          double result;
6078 <        MapReduceKeysToDoubleTask<K,V> sibling;
5937 <        MapReduceKeysToDoubleTask
5938 <            (ConcurrentHashMapV8<K,V> m,
5939 <             ObjectToDouble<? super K> transformer,
5940 <             double basis,
5941 <             DoubleByDoubleToDouble reducer) {
5942 <            super(m);
5943 <            this.transformer = transformer;
5944 <            this.basis = basis; this.reducer = reducer;
5945 <        }
6078 >        MapReduceKeysToDoubleTask<K,V> rights, nextRight;
6079          MapReduceKeysToDoubleTask
6080 <            (BulkTask<K,V,?> p, int b, boolean split,
6080 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6081 >             MapReduceKeysToDoubleTask<K,V> nextRight,
6082               ObjectToDouble<? super K> transformer,
6083               double basis,
6084               DoubleByDoubleToDouble reducer) {
6085 <            super(p, b, split);
6085 >            super(m, p, b); this.nextRight = nextRight;
6086              this.transformer = transformer;
6087              this.basis = basis; this.reducer = reducer;
6088          }
6089 +        public final Double getRawResult() { return result; }
6090          @SuppressWarnings("unchecked") public final void compute() {
5956            MapReduceKeysToDoubleTask<K,V> t = this;
6091              final ObjectToDouble<? super K> transformer =
6092                  this.transformer;
6093              final DoubleByDoubleToDouble reducer = this.reducer;
6094              if (transformer == null || reducer == null)
6095 <                throw new Error(NullFunctionMessage);
6096 <            final double id = this.basis;
6097 <            int b = batch();
6098 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6099 <                b >>>= 1;
6100 <                t.pending = 1;
6101 <                MapReduceKeysToDoubleTask<K,V> rt =
6102 <                    new MapReduceKeysToDoubleTask<K,V>
6103 <                    (t, b, true, transformer, id, reducer);
6104 <                t = new MapReduceKeysToDoubleTask<K,V>
6105 <                    (t, b, false, transformer, id, reducer);
6106 <                t.sibling = rt;
6107 <                rt.sibling = t;
6108 <                rt.fork();
6109 <            }
6110 <            double r = id;
5977 <            while (t.advance() != null)
5978 <                r = reducer.apply(r, transformer.apply((K)t.nextKey));
5979 <            t.result = r;
5980 <            for (;;) {
5981 <                int c; BulkTask<K,V,?> par; MapReduceKeysToDoubleTask<K,V> s, p;
5982 <                if ((par = t.parent) == null ||
5983 <                    !(par instanceof MapReduceKeysToDoubleTask)) {
5984 <                    t.quietlyComplete();
5985 <                    break;
5986 <                }
5987 <                else if ((c = (p = (MapReduceKeysToDoubleTask<K,V>)par).pending) == 0) {
5988 <                    if ((s = t.sibling) != null)
5989 <                        r = reducer.apply(r, s.result);
5990 <                    (t = p).result = r;
6095 >                throw new NullPointerException();
6096 >            double r = this.basis;
6097 >            for (int b; (b = preSplit()) > 0;)
6098 >                (rights = new MapReduceKeysToDoubleTask<K,V>
6099 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6100 >            while (advance() != null)
6101 >                r = reducer.apply(r, transformer.apply((K)nextKey));
6102 >            result = r;
6103 >            CountedCompleter<?> c;
6104 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6105 >                MapReduceKeysToDoubleTask<K,V>
6106 >                    t = (MapReduceKeysToDoubleTask<K,V>)c,
6107 >                    s = t.rights;
6108 >                while (s != null) {
6109 >                    t.result = reducer.apply(t.result, s.result);
6110 >                    s = t.rights = s.nextRight;
6111                  }
5992                else if (p.casPending(c, 0))
5993                    break;
6112              }
6113          }
5996        public final Double getRawResult() { return result; }
6114      }
6115  
6116 <    @SuppressWarnings("serial")
6117 <    static final class MapReduceValuesToDoubleTask<K,V>
6001 <        extends BulkTask<K,V,Double> {
6116 >    @SuppressWarnings("serial") static final class MapReduceValuesToDoubleTask<K,V>
6117 >        extends Traverser<K,V,Double> {
6118          final ObjectToDouble<? super V> transformer;
6119          final DoubleByDoubleToDouble reducer;
6120          final double basis;
6121          double result;
6122 <        MapReduceValuesToDoubleTask<K,V> sibling;
6007 <        MapReduceValuesToDoubleTask
6008 <            (ConcurrentHashMapV8<K,V> m,
6009 <             ObjectToDouble<? super V> transformer,
6010 <             double basis,
6011 <             DoubleByDoubleToDouble reducer) {
6012 <            super(m);
6013 <            this.transformer = transformer;
6014 <            this.basis = basis; this.reducer = reducer;
6015 <        }
6122 >        MapReduceValuesToDoubleTask<K,V> rights, nextRight;
6123          MapReduceValuesToDoubleTask
6124 <            (BulkTask<K,V,?> p, int b, boolean split,
6124 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6125 >             MapReduceValuesToDoubleTask<K,V> nextRight,
6126               ObjectToDouble<? super V> transformer,
6127               double basis,
6128               DoubleByDoubleToDouble reducer) {
6129 <            super(p, b, split);
6129 >            super(m, p, b); this.nextRight = nextRight;
6130              this.transformer = transformer;
6131              this.basis = basis; this.reducer = reducer;
6132          }
6133 +        public final Double getRawResult() { return result; }
6134          @SuppressWarnings("unchecked") public final void compute() {
6026            MapReduceValuesToDoubleTask<K,V> t = this;
6135              final ObjectToDouble<? super V> transformer =
6136                  this.transformer;
6137              final DoubleByDoubleToDouble reducer = this.reducer;
6138              if (transformer == null || reducer == null)
6139 <                throw new Error(NullFunctionMessage);
6140 <            final double id = this.basis;
6141 <            int b = batch();
6142 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6143 <                b >>>= 1;
6036 <                t.pending = 1;
6037 <                MapReduceValuesToDoubleTask<K,V> rt =
6038 <                    new MapReduceValuesToDoubleTask<K,V>
6039 <                    (t, b, true, transformer, id, reducer);
6040 <                t = new MapReduceValuesToDoubleTask<K,V>
6041 <                    (t, b, false, transformer, id, reducer);
6042 <                t.sibling = rt;
6043 <                rt.sibling = t;
6044 <                rt.fork();
6045 <            }
6046 <            double r = id;
6139 >                throw new NullPointerException();
6140 >            double r = this.basis;
6141 >            for (int b; (b = preSplit()) > 0;)
6142 >                (rights = new MapReduceValuesToDoubleTask<K,V>
6143 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6144              Object v;
6145 <            while ((v = t.advance()) != null)
6145 >            while ((v = advance()) != null)
6146                  r = reducer.apply(r, transformer.apply((V)v));
6147 <            t.result = r;
6148 <            for (;;) {
6149 <                int c; BulkTask<K,V,?> par; MapReduceValuesToDoubleTask<K,V> s, p;
6150 <                if ((par = t.parent) == null ||
6151 <                    !(par instanceof MapReduceValuesToDoubleTask)) {
6152 <                    t.quietlyComplete();
6153 <                    break;
6147 >            result = r;
6148 >            CountedCompleter<?> c;
6149 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6150 >                MapReduceValuesToDoubleTask<K,V>
6151 >                    t = (MapReduceValuesToDoubleTask<K,V>)c,
6152 >                    s = t.rights;
6153 >                while (s != null) {
6154 >                    t.result = reducer.apply(t.result, s.result);
6155 >                    s = t.rights = s.nextRight;
6156                  }
6058                else if ((c = (p = (MapReduceValuesToDoubleTask<K,V>)par).pending) == 0) {
6059                    if ((s = t.sibling) != null)
6060                        r = reducer.apply(r, s.result);
6061                    (t = p).result = r;
6062                }
6063                else if (p.casPending(c, 0))
6064                    break;
6157              }
6158          }
6067        public final Double getRawResult() { return result; }
6159      }
6160  
6161 <    @SuppressWarnings("serial")
6162 <    static final class MapReduceEntriesToDoubleTask<K,V>
6072 <        extends BulkTask<K,V,Double> {
6161 >    @SuppressWarnings("serial") static final class MapReduceEntriesToDoubleTask<K,V>
6162 >        extends Traverser<K,V,Double> {
6163          final ObjectToDouble<Map.Entry<K,V>> transformer;
6164          final DoubleByDoubleToDouble reducer;
6165          final double basis;
6166          double result;
6167 <        MapReduceEntriesToDoubleTask<K,V> sibling;
6167 >        MapReduceEntriesToDoubleTask<K,V> rights, nextRight;
6168          MapReduceEntriesToDoubleTask
6169 <            (ConcurrentHashMapV8<K,V> m,
6169 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6170 >             MapReduceEntriesToDoubleTask<K,V> nextRight,
6171               ObjectToDouble<Map.Entry<K,V>> transformer,
6172               double basis,
6173               DoubleByDoubleToDouble reducer) {
6174 <            super(m);
6084 <            this.transformer = transformer;
6085 <            this.basis = basis; this.reducer = reducer;
6086 <        }
6087 <        MapReduceEntriesToDoubleTask
6088 <            (BulkTask<K,V,?> p, int b, boolean split,
6089 <             ObjectToDouble<Map.Entry<K,V>> transformer,
6090 <             double basis,
6091 <             DoubleByDoubleToDouble reducer) {
6092 <            super(p, b, split);
6174 >            super(m, p, b); this.nextRight = nextRight;
6175              this.transformer = transformer;
6176              this.basis = basis; this.reducer = reducer;
6177          }
6178 +        public final Double getRawResult() { return result; }
6179          @SuppressWarnings("unchecked") public final void compute() {
6097            MapReduceEntriesToDoubleTask<K,V> t = this;
6180              final ObjectToDouble<Map.Entry<K,V>> transformer =
6181                  this.transformer;
6182              final DoubleByDoubleToDouble reducer = this.reducer;
6183              if (transformer == null || reducer == null)
6184 <                throw new Error(NullFunctionMessage);
6185 <            final double id = this.basis;
6186 <            int b = batch();
6187 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6188 <                b >>>= 1;
6107 <                t.pending = 1;
6108 <                MapReduceEntriesToDoubleTask<K,V> rt =
6109 <                    new MapReduceEntriesToDoubleTask<K,V>
6110 <                    (t, b, true, transformer, id, reducer);
6111 <                t = new MapReduceEntriesToDoubleTask<K,V>
6112 <                    (t, b, false, transformer, id, reducer);
6113 <                t.sibling = rt;
6114 <                rt.sibling = t;
6115 <                rt.fork();
6116 <            }
6117 <            double r = id;
6184 >                throw new NullPointerException();
6185 >            double r = this.basis;
6186 >            for (int b; (b = preSplit()) > 0;)
6187 >                (rights = new MapReduceEntriesToDoubleTask<K,V>
6188 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6189              Object v;
6190 <            while ((v = t.advance()) != null)
6191 <                r = reducer.apply(r, transformer.apply(entryFor((K)t.nextKey, (V)v)));
6192 <            t.result = r;
6193 <            for (;;) {
6194 <                int c; BulkTask<K,V,?> par; MapReduceEntriesToDoubleTask<K,V> s, p;
6195 <                if ((par = t.parent) == null ||
6196 <                    !(par instanceof MapReduceEntriesToDoubleTask)) {
6197 <                    t.quietlyComplete();
6198 <                    break;
6199 <                }
6200 <                else if ((c = (p = (MapReduceEntriesToDoubleTask<K,V>)par).pending) == 0) {
6130 <                    if ((s = t.sibling) != null)
6131 <                        r = reducer.apply(r, s.result);
6132 <                    (t = p).result = r;
6190 >            while ((v = advance()) != null)
6191 >                r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6192 >            result = r;
6193 >            CountedCompleter<?> c;
6194 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6195 >                MapReduceEntriesToDoubleTask<K,V>
6196 >                    t = (MapReduceEntriesToDoubleTask<K,V>)c,
6197 >                    s = t.rights;
6198 >                while (s != null) {
6199 >                    t.result = reducer.apply(t.result, s.result);
6200 >                    s = t.rights = s.nextRight;
6201                  }
6134                else if (p.casPending(c, 0))
6135                    break;
6202              }
6203          }
6138        public final Double getRawResult() { return result; }
6204      }
6205  
6206 <    @SuppressWarnings("serial")
6207 <    static final class MapReduceMappingsToDoubleTask<K,V>
6143 <        extends BulkTask<K,V,Double> {
6206 >    @SuppressWarnings("serial") static final class MapReduceMappingsToDoubleTask<K,V>
6207 >        extends Traverser<K,V,Double> {
6208          final ObjectByObjectToDouble<? super K, ? super V> transformer;
6209          final DoubleByDoubleToDouble reducer;
6210          final double basis;
6211          double result;
6212 <        MapReduceMappingsToDoubleTask<K,V> sibling;
6212 >        MapReduceMappingsToDoubleTask<K,V> rights, nextRight;
6213          MapReduceMappingsToDoubleTask
6214 <            (ConcurrentHashMapV8<K,V> m,
6214 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6215 >             MapReduceMappingsToDoubleTask<K,V> nextRight,
6216               ObjectByObjectToDouble<? super K, ? super V> transformer,
6217               double basis,
6218               DoubleByDoubleToDouble reducer) {
6219 <            super(m);
6155 <            this.transformer = transformer;
6156 <            this.basis = basis; this.reducer = reducer;
6157 <        }
6158 <        MapReduceMappingsToDoubleTask
6159 <            (BulkTask<K,V,?> p, int b, boolean split,
6160 <             ObjectByObjectToDouble<? super K, ? super V> transformer,
6161 <             double basis,
6162 <             DoubleByDoubleToDouble reducer) {
6163 <            super(p, b, split);
6219 >            super(m, p, b); this.nextRight = nextRight;
6220              this.transformer = transformer;
6221              this.basis = basis; this.reducer = reducer;
6222          }
6223 +        public final Double getRawResult() { return result; }
6224          @SuppressWarnings("unchecked") public final void compute() {
6168            MapReduceMappingsToDoubleTask<K,V> t = this;
6225              final ObjectByObjectToDouble<? super K, ? super V> transformer =
6226                  this.transformer;
6227              final DoubleByDoubleToDouble reducer = this.reducer;
6228              if (transformer == null || reducer == null)
6229 <                throw new Error(NullFunctionMessage);
6230 <            final double id = this.basis;
6231 <            int b = batch();
6232 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6233 <                b >>>= 1;
6178 <                t.pending = 1;
6179 <                MapReduceMappingsToDoubleTask<K,V> rt =
6180 <                    new MapReduceMappingsToDoubleTask<K,V>
6181 <                    (t, b, true, transformer, id, reducer);
6182 <                t = new MapReduceMappingsToDoubleTask<K,V>
6183 <                    (t, b, false, transformer, id, reducer);
6184 <                t.sibling = rt;
6185 <                rt.sibling = t;
6186 <                rt.fork();
6187 <            }
6188 <            double r = id;
6229 >                throw new NullPointerException();
6230 >            double r = this.basis;
6231 >            for (int b; (b = preSplit()) > 0;)
6232 >                (rights = new MapReduceMappingsToDoubleTask<K,V>
6233 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6234              Object v;
6235 <            while ((v = t.advance()) != null)
6236 <                r = reducer.apply(r, transformer.apply((K)t.nextKey, (V)v));
6237 <            t.result = r;
6238 <            for (;;) {
6239 <                int c; BulkTask<K,V,?> par; MapReduceMappingsToDoubleTask<K,V> s, p;
6240 <                if ((par = t.parent) == null ||
6241 <                    !(par instanceof MapReduceMappingsToDoubleTask)) {
6242 <                    t.quietlyComplete();
6243 <                    break;
6244 <                }
6245 <                else if ((c = (p = (MapReduceMappingsToDoubleTask<K,V>)par).pending) == 0) {
6201 <                    if ((s = t.sibling) != null)
6202 <                        r = reducer.apply(r, s.result);
6203 <                    (t = p).result = r;
6235 >            while ((v = advance()) != null)
6236 >                r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6237 >            result = r;
6238 >            CountedCompleter<?> c;
6239 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6240 >                MapReduceMappingsToDoubleTask<K,V>
6241 >                    t = (MapReduceMappingsToDoubleTask<K,V>)c,
6242 >                    s = t.rights;
6243 >                while (s != null) {
6244 >                    t.result = reducer.apply(t.result, s.result);
6245 >                    s = t.rights = s.nextRight;
6246                  }
6205                else if (p.casPending(c, 0))
6206                    break;
6247              }
6248          }
6209        public final Double getRawResult() { return result; }
6249      }
6250  
6251 <    @SuppressWarnings("serial")
6252 <    static final class MapReduceKeysToLongTask<K,V>
6214 <        extends BulkTask<K,V,Long> {
6251 >    @SuppressWarnings("serial") static final class MapReduceKeysToLongTask<K,V>
6252 >        extends Traverser<K,V,Long> {
6253          final ObjectToLong<? super K> transformer;
6254          final LongByLongToLong reducer;
6255          final long basis;
6256          long result;
6257 <        MapReduceKeysToLongTask<K,V> sibling;
6257 >        MapReduceKeysToLongTask<K,V> rights, nextRight;
6258          MapReduceKeysToLongTask
6259 <            (ConcurrentHashMapV8<K,V> m,
6259 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6260 >             MapReduceKeysToLongTask<K,V> nextRight,
6261               ObjectToLong<? super K> transformer,
6262               long basis,
6263               LongByLongToLong reducer) {
6264 <            super(m);
6226 <            this.transformer = transformer;
6227 <            this.basis = basis; this.reducer = reducer;
6228 <        }
6229 <        MapReduceKeysToLongTask
6230 <            (BulkTask<K,V,?> p, int b, boolean split,
6231 <             ObjectToLong<? super K> transformer,
6232 <             long basis,
6233 <             LongByLongToLong reducer) {
6234 <            super(p, b, split);
6264 >            super(m, p, b); this.nextRight = nextRight;
6265              this.transformer = transformer;
6266              this.basis = basis; this.reducer = reducer;
6267          }
6268 +        public final Long getRawResult() { return result; }
6269          @SuppressWarnings("unchecked") public final void compute() {
6239            MapReduceKeysToLongTask<K,V> t = this;
6270              final ObjectToLong<? super K> transformer =
6271                  this.transformer;
6272              final LongByLongToLong reducer = this.reducer;
6273              if (transformer == null || reducer == null)
6274 <                throw new Error(NullFunctionMessage);
6275 <            final long id = this.basis;
6276 <            int b = batch();
6277 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6278 <                b >>>= 1;
6279 <                t.pending = 1;
6280 <                MapReduceKeysToLongTask<K,V> rt =
6281 <                    new MapReduceKeysToLongTask<K,V>
6282 <                    (t, b, true, transformer, id, reducer);
6283 <                t = new MapReduceKeysToLongTask<K,V>
6284 <                    (t, b, false, transformer, id, reducer);
6285 <                t.sibling = rt;
6286 <                rt.sibling = t;
6287 <                rt.fork();
6288 <            }
6289 <            long r = id;
6260 <            while (t.advance() != null)
6261 <                r = reducer.apply(r, transformer.apply((K)t.nextKey));
6262 <            t.result = r;
6263 <            for (;;) {
6264 <                int c; BulkTask<K,V,?> par; MapReduceKeysToLongTask<K,V> s, p;
6265 <                if ((par = t.parent) == null ||
6266 <                    !(par instanceof MapReduceKeysToLongTask)) {
6267 <                    t.quietlyComplete();
6268 <                    break;
6269 <                }
6270 <                else if ((c = (p = (MapReduceKeysToLongTask<K,V>)par).pending) == 0) {
6271 <                    if ((s = t.sibling) != null)
6272 <                        r = reducer.apply(r, s.result);
6273 <                    (t = p).result = r;
6274 >                throw new NullPointerException();
6275 >            long r = this.basis;
6276 >            for (int b; (b = preSplit()) > 0;)
6277 >                (rights = new MapReduceKeysToLongTask<K,V>
6278 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6279 >            while (advance() != null)
6280 >                r = reducer.apply(r, transformer.apply((K)nextKey));
6281 >            result = r;
6282 >            CountedCompleter<?> c;
6283 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6284 >                MapReduceKeysToLongTask<K,V>
6285 >                    t = (MapReduceKeysToLongTask<K,V>)c,
6286 >                    s = t.rights;
6287 >                while (s != null) {
6288 >                    t.result = reducer.apply(t.result, s.result);
6289 >                    s = t.rights = s.nextRight;
6290                  }
6275                else if (p.casPending(c, 0))
6276                    break;
6291              }
6292          }
6279        public final Long getRawResult() { return result; }
6293      }
6294  
6295 <    @SuppressWarnings("serial")
6296 <    static final class MapReduceValuesToLongTask<K,V>
6284 <        extends BulkTask<K,V,Long> {
6295 >    @SuppressWarnings("serial") static final class MapReduceValuesToLongTask<K,V>
6296 >        extends Traverser<K,V,Long> {
6297          final ObjectToLong<? super V> transformer;
6298          final LongByLongToLong reducer;
6299          final long basis;
6300          long result;
6301 <        MapReduceValuesToLongTask<K,V> sibling;
6290 <        MapReduceValuesToLongTask
6291 <            (ConcurrentHashMapV8<K,V> m,
6292 <             ObjectToLong<? super V> transformer,
6293 <             long basis,
6294 <             LongByLongToLong reducer) {
6295 <            super(m);
6296 <            this.transformer = transformer;
6297 <            this.basis = basis; this.reducer = reducer;
6298 <        }
6301 >        MapReduceValuesToLongTask<K,V> rights, nextRight;
6302          MapReduceValuesToLongTask
6303 <            (BulkTask<K,V,?> p, int b, boolean split,
6303 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6304 >             MapReduceValuesToLongTask<K,V> nextRight,
6305               ObjectToLong<? super V> transformer,
6306               long basis,
6307               LongByLongToLong reducer) {
6308 <            super(p, b, split);
6308 >            super(m, p, b); this.nextRight = nextRight;
6309              this.transformer = transformer;
6310              this.basis = basis; this.reducer = reducer;
6311          }
6312 +        public final Long getRawResult() { return result; }
6313          @SuppressWarnings("unchecked") public final void compute() {
6309            MapReduceValuesToLongTask<K,V> t = this;
6314              final ObjectToLong<? super V> transformer =
6315                  this.transformer;
6316              final LongByLongToLong reducer = this.reducer;
6317              if (transformer == null || reducer == null)
6318 <                throw new Error(NullFunctionMessage);
6319 <            final long id = this.basis;
6320 <            int b = batch();
6321 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6322 <                b >>>= 1;
6319 <                t.pending = 1;
6320 <                MapReduceValuesToLongTask<K,V> rt =
6321 <                    new MapReduceValuesToLongTask<K,V>
6322 <                    (t, b, true, transformer, id, reducer);
6323 <                t = new MapReduceValuesToLongTask<K,V>
6324 <                    (t, b, false, transformer, id, reducer);
6325 <                t.sibling = rt;
6326 <                rt.sibling = t;
6327 <                rt.fork();
6328 <            }
6329 <            long r = id;
6318 >                throw new NullPointerException();
6319 >            long r = this.basis;
6320 >            for (int b; (b = preSplit()) > 0;)
6321 >                (rights = new MapReduceValuesToLongTask<K,V>
6322 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6323              Object v;
6324 <            while ((v = t.advance()) != null)
6324 >            while ((v = advance()) != null)
6325                  r = reducer.apply(r, transformer.apply((V)v));
6326 <            t.result = r;
6327 <            for (;;) {
6328 <                int c; BulkTask<K,V,?> par; MapReduceValuesToLongTask<K,V> s, p;
6329 <                if ((par = t.parent) == null ||
6330 <                    !(par instanceof MapReduceValuesToLongTask)) {
6331 <                    t.quietlyComplete();
6332 <                    break;
6333 <                }
6334 <                else if ((c = (p = (MapReduceValuesToLongTask<K,V>)par).pending) == 0) {
6342 <                    if ((s = t.sibling) != null)
6343 <                        r = reducer.apply(r, s.result);
6344 <                    (t = p).result = r;
6326 >            result = r;
6327 >            CountedCompleter<?> c;
6328 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6329 >                MapReduceValuesToLongTask<K,V>
6330 >                    t = (MapReduceValuesToLongTask<K,V>)c,
6331 >                    s = t.rights;
6332 >                while (s != null) {
6333 >                    t.result = reducer.apply(t.result, s.result);
6334 >                    s = t.rights = s.nextRight;
6335                  }
6346                else if (p.casPending(c, 0))
6347                    break;
6336              }
6337          }
6350        public final Long getRawResult() { return result; }
6338      }
6339  
6340 <    @SuppressWarnings("serial")
6341 <    static final class MapReduceEntriesToLongTask<K,V>
6355 <        extends BulkTask<K,V,Long> {
6340 >    @SuppressWarnings("serial") static final class MapReduceEntriesToLongTask<K,V>
6341 >        extends Traverser<K,V,Long> {
6342          final ObjectToLong<Map.Entry<K,V>> transformer;
6343          final LongByLongToLong reducer;
6344          final long basis;
6345          long result;
6346 <        MapReduceEntriesToLongTask<K,V> sibling;
6361 <        MapReduceEntriesToLongTask
6362 <            (ConcurrentHashMapV8<K,V> m,
6363 <             ObjectToLong<Map.Entry<K,V>> transformer,
6364 <             long basis,
6365 <             LongByLongToLong reducer) {
6366 <            super(m);
6367 <            this.transformer = transformer;
6368 <            this.basis = basis; this.reducer = reducer;
6369 <        }
6346 >        MapReduceEntriesToLongTask<K,V> rights, nextRight;
6347          MapReduceEntriesToLongTask
6348 <            (BulkTask<K,V,?> p, int b, boolean split,
6348 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6349 >             MapReduceEntriesToLongTask<K,V> nextRight,
6350               ObjectToLong<Map.Entry<K,V>> transformer,
6351               long basis,
6352               LongByLongToLong reducer) {
6353 <            super(p, b, split);
6353 >            super(m, p, b); this.nextRight = nextRight;
6354              this.transformer = transformer;
6355              this.basis = basis; this.reducer = reducer;
6356          }
6357 +        public final Long getRawResult() { return result; }
6358          @SuppressWarnings("unchecked") public final void compute() {
6380            MapReduceEntriesToLongTask<K,V> t = this;
6359              final ObjectToLong<Map.Entry<K,V>> transformer =
6360                  this.transformer;
6361              final LongByLongToLong reducer = this.reducer;
6362              if (transformer == null || reducer == null)
6363 <                throw new Error(NullFunctionMessage);
6364 <            final long id = this.basis;
6365 <            int b = batch();
6366 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6367 <                b >>>= 1;
6390 <                t.pending = 1;
6391 <                MapReduceEntriesToLongTask<K,V> rt =
6392 <                    new MapReduceEntriesToLongTask<K,V>
6393 <                    (t, b, true, transformer, id, reducer);
6394 <                t = new MapReduceEntriesToLongTask<K,V>
6395 <                    (t, b, false, transformer, id, reducer);
6396 <                t.sibling = rt;
6397 <                rt.sibling = t;
6398 <                rt.fork();
6399 <            }
6400 <            long r = id;
6363 >                throw new NullPointerException();
6364 >            long r = this.basis;
6365 >            for (int b; (b = preSplit()) > 0;)
6366 >                (rights = new MapReduceEntriesToLongTask<K,V>
6367 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6368              Object v;
6369 <            while ((v = t.advance()) != null)
6370 <                r = reducer.apply(r, transformer.apply(entryFor((K)t.nextKey, (V)v)));
6371 <            t.result = r;
6372 <            for (;;) {
6373 <                int c; BulkTask<K,V,?> par; MapReduceEntriesToLongTask<K,V> s, p;
6374 <                if ((par = t.parent) == null ||
6375 <                    !(par instanceof MapReduceEntriesToLongTask)) {
6376 <                    t.quietlyComplete();
6377 <                    break;
6378 <                }
6379 <                else if ((c = (p = (MapReduceEntriesToLongTask<K,V>)par).pending) == 0) {
6413 <                    if ((s = t.sibling) != null)
6414 <                        r = reducer.apply(r, s.result);
6415 <                    (t = p).result = r;
6369 >            while ((v = advance()) != null)
6370 >                r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6371 >            result = r;
6372 >            CountedCompleter<?> c;
6373 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6374 >                MapReduceEntriesToLongTask<K,V>
6375 >                    t = (MapReduceEntriesToLongTask<K,V>)c,
6376 >                    s = t.rights;
6377 >                while (s != null) {
6378 >                    t.result = reducer.apply(t.result, s.result);
6379 >                    s = t.rights = s.nextRight;
6380                  }
6417                else if (p.casPending(c, 0))
6418                    break;
6381              }
6382          }
6421        public final Long getRawResult() { return result; }
6383      }
6384  
6385 <    @SuppressWarnings("serial")
6386 <    static final class MapReduceMappingsToLongTask<K,V>
6426 <        extends BulkTask<K,V,Long> {
6385 >    @SuppressWarnings("serial") static final class MapReduceMappingsToLongTask<K,V>
6386 >        extends Traverser<K,V,Long> {
6387          final ObjectByObjectToLong<? super K, ? super V> transformer;
6388          final LongByLongToLong reducer;
6389          final long basis;
6390          long result;
6391 <        MapReduceMappingsToLongTask<K,V> sibling;
6391 >        MapReduceMappingsToLongTask<K,V> rights, nextRight;
6392          MapReduceMappingsToLongTask
6393 <            (ConcurrentHashMapV8<K,V> m,
6393 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6394 >             MapReduceMappingsToLongTask<K,V> nextRight,
6395               ObjectByObjectToLong<? super K, ? super V> transformer,
6396               long basis,
6397               LongByLongToLong reducer) {
6398 <            super(m);
6438 <            this.transformer = transformer;
6439 <            this.basis = basis; this.reducer = reducer;
6440 <        }
6441 <        MapReduceMappingsToLongTask
6442 <            (BulkTask<K,V,?> p, int b, boolean split,
6443 <             ObjectByObjectToLong<? super K, ? super V> transformer,
6444 <             long basis,
6445 <             LongByLongToLong reducer) {
6446 <            super(p, b, split);
6398 >            super(m, p, b); this.nextRight = nextRight;
6399              this.transformer = transformer;
6400              this.basis = basis; this.reducer = reducer;
6401          }
6402 +        public final Long getRawResult() { return result; }
6403          @SuppressWarnings("unchecked") public final void compute() {
6451            MapReduceMappingsToLongTask<K,V> t = this;
6404              final ObjectByObjectToLong<? super K, ? super V> transformer =
6405                  this.transformer;
6406              final LongByLongToLong reducer = this.reducer;
6407              if (transformer == null || reducer == null)
6408 <                throw new Error(NullFunctionMessage);
6409 <            final long id = this.basis;
6410 <            int b = batch();
6411 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6412 <                b >>>= 1;
6461 <                t.pending = 1;
6462 <                MapReduceMappingsToLongTask<K,V> rt =
6463 <                    new MapReduceMappingsToLongTask<K,V>
6464 <                    (t, b, true, transformer, id, reducer);
6465 <                t = new MapReduceMappingsToLongTask<K,V>
6466 <                    (t, b, false, transformer, id, reducer);
6467 <                t.sibling = rt;
6468 <                rt.sibling = t;
6469 <                rt.fork();
6470 <            }
6471 <            long r = id;
6408 >                throw new NullPointerException();
6409 >            long r = this.basis;
6410 >            for (int b; (b = preSplit()) > 0;)
6411 >                (rights = new MapReduceMappingsToLongTask<K,V>
6412 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6413              Object v;
6414 <            while ((v = t.advance()) != null)
6415 <                r = reducer.apply(r, transformer.apply((K)t.nextKey, (V)v));
6416 <            t.result = r;
6417 <            for (;;) {
6418 <                int c; BulkTask<K,V,?> par; MapReduceMappingsToLongTask<K,V> s, p;
6419 <                if ((par = t.parent) == null ||
6420 <                    !(par instanceof MapReduceMappingsToLongTask)) {
6421 <                    t.quietlyComplete();
6422 <                    break;
6423 <                }
6424 <                else if ((c = (p = (MapReduceMappingsToLongTask<K,V>)par).pending) == 0) {
6484 <                    if ((s = t.sibling) != null)
6485 <                        r = reducer.apply(r, s.result);
6486 <                    (t = p).result = r;
6414 >            while ((v = advance()) != null)
6415 >                r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6416 >            result = r;
6417 >            CountedCompleter<?> c;
6418 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6419 >                MapReduceMappingsToLongTask<K,V>
6420 >                    t = (MapReduceMappingsToLongTask<K,V>)c,
6421 >                    s = t.rights;
6422 >                while (s != null) {
6423 >                    t.result = reducer.apply(t.result, s.result);
6424 >                    s = t.rights = s.nextRight;
6425                  }
6488                else if (p.casPending(c, 0))
6489                    break;
6426              }
6427          }
6492        public final Long getRawResult() { return result; }
6428      }
6429  
6430 <    @SuppressWarnings("serial")
6431 <    static final class MapReduceKeysToIntTask<K,V>
6497 <        extends BulkTask<K,V,Integer> {
6430 >    @SuppressWarnings("serial") static final class MapReduceKeysToIntTask<K,V>
6431 >        extends Traverser<K,V,Integer> {
6432          final ObjectToInt<? super K> transformer;
6433          final IntByIntToInt reducer;
6434          final int basis;
6435          int result;
6436 <        MapReduceKeysToIntTask<K,V> sibling;
6436 >        MapReduceKeysToIntTask<K,V> rights, nextRight;
6437          MapReduceKeysToIntTask
6438 <            (ConcurrentHashMapV8<K,V> m,
6438 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6439 >             MapReduceKeysToIntTask<K,V> nextRight,
6440               ObjectToInt<? super K> transformer,
6441               int basis,
6442               IntByIntToInt reducer) {
6443 <            super(m);
6509 <            this.transformer = transformer;
6510 <            this.basis = basis; this.reducer = reducer;
6511 <        }
6512 <        MapReduceKeysToIntTask
6513 <            (BulkTask<K,V,?> p, int b, boolean split,
6514 <             ObjectToInt<? super K> transformer,
6515 <             int basis,
6516 <             IntByIntToInt reducer) {
6517 <            super(p, b, split);
6443 >            super(m, p, b); this.nextRight = nextRight;
6444              this.transformer = transformer;
6445              this.basis = basis; this.reducer = reducer;
6446          }
6447 +        public final Integer getRawResult() { return result; }
6448          @SuppressWarnings("unchecked") public final void compute() {
6522            MapReduceKeysToIntTask<K,V> t = this;
6449              final ObjectToInt<? super K> transformer =
6450                  this.transformer;
6451              final IntByIntToInt reducer = this.reducer;
6452              if (transformer == null || reducer == null)
6453 <                throw new Error(NullFunctionMessage);
6454 <            final int id = this.basis;
6455 <            int b = batch();
6456 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6457 <                b >>>= 1;
6458 <                t.pending = 1;
6459 <                MapReduceKeysToIntTask<K,V> rt =
6460 <                    new MapReduceKeysToIntTask<K,V>
6461 <                    (t, b, true, transformer, id, reducer);
6462 <                t = new MapReduceKeysToIntTask<K,V>
6463 <                    (t, b, false, transformer, id, reducer);
6464 <                t.sibling = rt;
6465 <                rt.sibling = t;
6466 <                rt.fork();
6467 <            }
6468 <            int r = id;
6543 <            while (t.advance() != null)
6544 <                r = reducer.apply(r, transformer.apply((K)t.nextKey));
6545 <            t.result = r;
6546 <            for (;;) {
6547 <                int c; BulkTask<K,V,?> par; MapReduceKeysToIntTask<K,V> s, p;
6548 <                if ((par = t.parent) == null ||
6549 <                    !(par instanceof MapReduceKeysToIntTask)) {
6550 <                    t.quietlyComplete();
6551 <                    break;
6552 <                }
6553 <                else if ((c = (p = (MapReduceKeysToIntTask<K,V>)par).pending) == 0) {
6554 <                    if ((s = t.sibling) != null)
6555 <                        r = reducer.apply(r, s.result);
6556 <                    (t = p).result = r;
6453 >                throw new NullPointerException();
6454 >            int r = this.basis;
6455 >            for (int b; (b = preSplit()) > 0;)
6456 >                (rights = new MapReduceKeysToIntTask<K,V>
6457 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6458 >            while (advance() != null)
6459 >                r = reducer.apply(r, transformer.apply((K)nextKey));
6460 >            result = r;
6461 >            CountedCompleter<?> c;
6462 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6463 >                MapReduceKeysToIntTask<K,V>
6464 >                    t = (MapReduceKeysToIntTask<K,V>)c,
6465 >                    s = t.rights;
6466 >                while (s != null) {
6467 >                    t.result = reducer.apply(t.result, s.result);
6468 >                    s = t.rights = s.nextRight;
6469                  }
6558                else if (p.casPending(c, 0))
6559                    break;
6470              }
6471          }
6562        public final Integer getRawResult() { return result; }
6472      }
6473  
6474 <    @SuppressWarnings("serial")
6475 <    static final class MapReduceValuesToIntTask<K,V>
6567 <        extends BulkTask<K,V,Integer> {
6474 >    @SuppressWarnings("serial") static final class MapReduceValuesToIntTask<K,V>
6475 >        extends Traverser<K,V,Integer> {
6476          final ObjectToInt<? super V> transformer;
6477          final IntByIntToInt reducer;
6478          final int basis;
6479          int result;
6480 <        MapReduceValuesToIntTask<K,V> sibling;
6573 <        MapReduceValuesToIntTask
6574 <            (ConcurrentHashMapV8<K,V> m,
6575 <             ObjectToInt<? super V> transformer,
6576 <             int basis,
6577 <             IntByIntToInt reducer) {
6578 <            super(m);
6579 <            this.transformer = transformer;
6580 <            this.basis = basis; this.reducer = reducer;
6581 <        }
6480 >        MapReduceValuesToIntTask<K,V> rights, nextRight;
6481          MapReduceValuesToIntTask
6482 <            (BulkTask<K,V,?> p, int b, boolean split,
6482 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6483 >             MapReduceValuesToIntTask<K,V> nextRight,
6484               ObjectToInt<? super V> transformer,
6485               int basis,
6486               IntByIntToInt reducer) {
6487 <            super(p, b, split);
6487 >            super(m, p, b); this.nextRight = nextRight;
6488              this.transformer = transformer;
6489              this.basis = basis; this.reducer = reducer;
6490          }
6491 +        public final Integer getRawResult() { return result; }
6492          @SuppressWarnings("unchecked") public final void compute() {
6592            MapReduceValuesToIntTask<K,V> t = this;
6493              final ObjectToInt<? super V> transformer =
6494                  this.transformer;
6495              final IntByIntToInt reducer = this.reducer;
6496              if (transformer == null || reducer == null)
6497 <                throw new Error(NullFunctionMessage);
6498 <            final int id = this.basis;
6499 <            int b = batch();
6500 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6501 <                b >>>= 1;
6602 <                t.pending = 1;
6603 <                MapReduceValuesToIntTask<K,V> rt =
6604 <                    new MapReduceValuesToIntTask<K,V>
6605 <                    (t, b, true, transformer, id, reducer);
6606 <                t = new MapReduceValuesToIntTask<K,V>
6607 <                    (t, b, false, transformer, id, reducer);
6608 <                t.sibling = rt;
6609 <                rt.sibling = t;
6610 <                rt.fork();
6611 <            }
6612 <            int r = id;
6497 >                throw new NullPointerException();
6498 >            int r = this.basis;
6499 >            for (int b; (b = preSplit()) > 0;)
6500 >                (rights = new MapReduceValuesToIntTask<K,V>
6501 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6502              Object v;
6503 <            while ((v = t.advance()) != null)
6503 >            while ((v = advance()) != null)
6504                  r = reducer.apply(r, transformer.apply((V)v));
6505 <            t.result = r;
6506 <            for (;;) {
6507 <                int c; BulkTask<K,V,?> par; MapReduceValuesToIntTask<K,V> s, p;
6508 <                if ((par = t.parent) == null ||
6509 <                    !(par instanceof MapReduceValuesToIntTask)) {
6510 <                    t.quietlyComplete();
6511 <                    break;
6512 <                }
6513 <                else if ((c = (p = (MapReduceValuesToIntTask<K,V>)par).pending) == 0) {
6625 <                    if ((s = t.sibling) != null)
6626 <                        r = reducer.apply(r, s.result);
6627 <                    (t = p).result = r;
6505 >            result = r;
6506 >            CountedCompleter<?> c;
6507 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6508 >                MapReduceValuesToIntTask<K,V>
6509 >                    t = (MapReduceValuesToIntTask<K,V>)c,
6510 >                    s = t.rights;
6511 >                while (s != null) {
6512 >                    t.result = reducer.apply(t.result, s.result);
6513 >                    s = t.rights = s.nextRight;
6514                  }
6629                else if (p.casPending(c, 0))
6630                    break;
6515              }
6516          }
6633        public final Integer getRawResult() { return result; }
6517      }
6518  
6519 <    @SuppressWarnings("serial")
6520 <    static final class MapReduceEntriesToIntTask<K,V>
6638 <        extends BulkTask<K,V,Integer> {
6519 >    @SuppressWarnings("serial") static final class MapReduceEntriesToIntTask<K,V>
6520 >        extends Traverser<K,V,Integer> {
6521          final ObjectToInt<Map.Entry<K,V>> transformer;
6522          final IntByIntToInt reducer;
6523          final int basis;
6524          int result;
6525 <        MapReduceEntriesToIntTask<K,V> sibling;
6644 <        MapReduceEntriesToIntTask
6645 <            (ConcurrentHashMapV8<K,V> m,
6646 <             ObjectToInt<Map.Entry<K,V>> transformer,
6647 <             int basis,
6648 <             IntByIntToInt reducer) {
6649 <            super(m);
6650 <            this.transformer = transformer;
6651 <            this.basis = basis; this.reducer = reducer;
6652 <        }
6525 >        MapReduceEntriesToIntTask<K,V> rights, nextRight;
6526          MapReduceEntriesToIntTask
6527 <            (BulkTask<K,V,?> p, int b, boolean split,
6527 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6528 >             MapReduceEntriesToIntTask<K,V> nextRight,
6529               ObjectToInt<Map.Entry<K,V>> transformer,
6530               int basis,
6531               IntByIntToInt reducer) {
6532 <            super(p, b, split);
6532 >            super(m, p, b); this.nextRight = nextRight;
6533              this.transformer = transformer;
6534              this.basis = basis; this.reducer = reducer;
6535          }
6536 +        public final Integer getRawResult() { return result; }
6537          @SuppressWarnings("unchecked") public final void compute() {
6663            MapReduceEntriesToIntTask<K,V> t = this;
6538              final ObjectToInt<Map.Entry<K,V>> transformer =
6539                  this.transformer;
6540              final IntByIntToInt reducer = this.reducer;
6541              if (transformer == null || reducer == null)
6542 <                throw new Error(NullFunctionMessage);
6543 <            final int id = this.basis;
6544 <            int b = batch();
6545 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6546 <                b >>>= 1;
6673 <                t.pending = 1;
6674 <                MapReduceEntriesToIntTask<K,V> rt =
6675 <                    new MapReduceEntriesToIntTask<K,V>
6676 <                    (t, b, true, transformer, id, reducer);
6677 <                t = new MapReduceEntriesToIntTask<K,V>
6678 <                    (t, b, false, transformer, id, reducer);
6679 <                t.sibling = rt;
6680 <                rt.sibling = t;
6681 <                rt.fork();
6682 <            }
6683 <            int r = id;
6542 >                throw new NullPointerException();
6543 >            int r = this.basis;
6544 >            for (int b; (b = preSplit()) > 0;)
6545 >                (rights = new MapReduceEntriesToIntTask<K,V>
6546 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6547              Object v;
6548 <            while ((v = t.advance()) != null)
6549 <                r = reducer.apply(r, transformer.apply(entryFor((K)t.nextKey, (V)v)));
6550 <            t.result = r;
6551 <            for (;;) {
6552 <                int c; BulkTask<K,V,?> par; MapReduceEntriesToIntTask<K,V> s, p;
6553 <                if ((par = t.parent) == null ||
6554 <                    !(par instanceof MapReduceEntriesToIntTask)) {
6555 <                    t.quietlyComplete();
6556 <                    break;
6557 <                }
6558 <                else if ((c = (p = (MapReduceEntriesToIntTask<K,V>)par).pending) == 0) {
6696 <                    if ((s = t.sibling) != null)
6697 <                        r = reducer.apply(r, s.result);
6698 <                    (t = p).result = r;
6548 >            while ((v = advance()) != null)
6549 >                r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6550 >            result = r;
6551 >            CountedCompleter<?> c;
6552 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6553 >                MapReduceEntriesToIntTask<K,V>
6554 >                    t = (MapReduceEntriesToIntTask<K,V>)c,
6555 >                    s = t.rights;
6556 >                while (s != null) {
6557 >                    t.result = reducer.apply(t.result, s.result);
6558 >                    s = t.rights = s.nextRight;
6559                  }
6700                else if (p.casPending(c, 0))
6701                    break;
6560              }
6561          }
6704        public final Integer getRawResult() { return result; }
6562      }
6563  
6564 <    @SuppressWarnings("serial")
6565 <    static final class MapReduceMappingsToIntTask<K,V>
6709 <        extends BulkTask<K,V,Integer> {
6564 >    @SuppressWarnings("serial") static final class MapReduceMappingsToIntTask<K,V>
6565 >        extends Traverser<K,V,Integer> {
6566          final ObjectByObjectToInt<? super K, ? super V> transformer;
6567          final IntByIntToInt reducer;
6568          final int basis;
6569          int result;
6570 <        MapReduceMappingsToIntTask<K,V> sibling;
6715 <        MapReduceMappingsToIntTask
6716 <            (ConcurrentHashMapV8<K,V> m,
6717 <             ObjectByObjectToInt<? super K, ? super V> transformer,
6718 <             int basis,
6719 <             IntByIntToInt reducer) {
6720 <            super(m);
6721 <            this.transformer = transformer;
6722 <            this.basis = basis; this.reducer = reducer;
6723 <        }
6570 >        MapReduceMappingsToIntTask<K,V> rights, nextRight;
6571          MapReduceMappingsToIntTask
6572 <            (BulkTask<K,V,?> p, int b, boolean split,
6572 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6573 >             MapReduceMappingsToIntTask<K,V> nextRight,
6574               ObjectByObjectToInt<? super K, ? super V> transformer,
6575               int basis,
6576               IntByIntToInt reducer) {
6577 <            super(p, b, split);
6577 >            super(m, p, b); this.nextRight = nextRight;
6578              this.transformer = transformer;
6579              this.basis = basis; this.reducer = reducer;
6580          }
6581 +        public final Integer getRawResult() { return result; }
6582          @SuppressWarnings("unchecked") public final void compute() {
6734            MapReduceMappingsToIntTask<K,V> t = this;
6583              final ObjectByObjectToInt<? super K, ? super V> transformer =
6584                  this.transformer;
6585              final IntByIntToInt reducer = this.reducer;
6586              if (transformer == null || reducer == null)
6587 <                throw new Error(NullFunctionMessage);
6588 <            final int id = this.basis;
6589 <            int b = batch();
6590 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6591 <                b >>>= 1;
6744 <                t.pending = 1;
6745 <                MapReduceMappingsToIntTask<K,V> rt =
6746 <                    new MapReduceMappingsToIntTask<K,V>
6747 <                    (t, b, true, transformer, id, reducer);
6748 <                t = new MapReduceMappingsToIntTask<K,V>
6749 <                    (t, b, false, transformer, id, reducer);
6750 <                t.sibling = rt;
6751 <                rt.sibling = t;
6752 <                rt.fork();
6753 <            }
6754 <            int r = id;
6587 >                throw new NullPointerException();
6588 >            int r = this.basis;
6589 >            for (int b; (b = preSplit()) > 0;)
6590 >                (rights = new MapReduceMappingsToIntTask<K,V>
6591 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6592              Object v;
6593 <            while ((v = t.advance()) != null)
6594 <                r = reducer.apply(r, transformer.apply((K)t.nextKey, (V)v));
6595 <            t.result = r;
6596 <            for (;;) {
6597 <                int c; BulkTask<K,V,?> par; MapReduceMappingsToIntTask<K,V> s, p;
6598 <                if ((par = t.parent) == null ||
6599 <                    !(par instanceof MapReduceMappingsToIntTask)) {
6600 <                    t.quietlyComplete();
6601 <                    break;
6602 <                }
6603 <                else if ((c = (p = (MapReduceMappingsToIntTask<K,V>)par).pending) == 0) {
6767 <                    if ((s = t.sibling) != null)
6768 <                        r = reducer.apply(r, s.result);
6769 <                    (t = p).result = r;
6593 >            while ((v = advance()) != null)
6594 >                r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6595 >            result = r;
6596 >            CountedCompleter<?> c;
6597 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6598 >                MapReduceMappingsToIntTask<K,V>
6599 >                    t = (MapReduceMappingsToIntTask<K,V>)c,
6600 >                    s = t.rights;
6601 >                while (s != null) {
6602 >                    t.result = reducer.apply(t.result, s.result);
6603 >                    s = t.rights = s.nextRight;
6604                  }
6771                else if (p.casPending(c, 0))
6772                    break;
6605              }
6606          }
6775        public final Integer getRawResult() { return result; }
6607      }
6608  
6778
6609      // Unsafe mechanics
6610      private static final sun.misc.Unsafe UNSAFE;
6611      private static final long counterOffset;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines