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.58 by jsr166, Tue Aug 14 05:55:08 2012 UTC vs.
Revision 1.81 by dl, Sat Dec 8 14:10:38 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
69 < * onset.  For aggregate operations such as {@code putAll} and {@code
70 < * clear}, concurrent retrievals may reflect insertion or removal of
71 < * only some entries.  Similarly, Iterators and Enumerations return
72 < * elements reflecting the state of the hash table at some point at or
73 < * since the creation of the iterator/enumeration.  They do
74 < * <em>not</em> throw {@link ConcurrentModificationException}.
75 < * However, iterators are designed to be used by only one thread at a
76 < * time.  Bear in mind that the results of aggregate status methods
77 < * including {@code size}, {@code isEmpty}, and {@code containsValue}
78 < * are typically useful only when a map is not undergoing concurrent
79 < * updates in other threads.  Otherwise the results of these methods
80 < * reflect transient states that may be adequate for monitoring
81 < * or estimation purposes, but not for program control.
69 > * onset. (More formally, an update operation for a given key bears a
70 > * <em>happens-before</em> relation with any (non-null) retrieval for
71 > * that key reporting the updated value.)  For aggregate operations
72 > * such as {@code putAll} and {@code clear}, concurrent retrievals may
73 > * reflect insertion or removal of only some entries.  Similarly,
74 > * Iterators and Enumerations return elements reflecting the state of
75 > * the hash table at some point at or since the creation of the
76 > * iterator/enumeration.  They do <em>not</em> throw {@link
77 > * ConcurrentModificationException}.  However, iterators are designed
78 > * to be used by only one thread at a time.  Bear in mind that the
79 > * results of aggregate status methods including {@code size}, {@code
80 > * isEmpty}, and {@code containsValue} are typically useful only when
81 > * a map is not undergoing concurrent updates in other threads.
82 > * Otherwise the results of these methods reflect transient states
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 82 | 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   *
96 * <p><em>jsr166e note: This class is a candidate replacement for
97 * java.util.concurrent.ConcurrentHashMap.  During transition, this
98 * class declares and uses nested functional interfaces with different
99 * names but the same forms as those expected for JDK8.<em>
100 *
234   * @since 1.5
235   * @author Doug Lea
236   * @param <K> the type of keys maintained by this map
# Line 114 | 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 176 | Line 309 | public class ConcurrentHashMapV8<K, V>
309          Spliterator<T> split();
310      }
311  
312 +
313      /*
314       * Overview:
315       *
# Line 458 | 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 537 | 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 555 | 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 715 | 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 726 | Line 867 | public class ConcurrentHashMapV8<K, V>
867                      if (c != (pc = pk.getClass()) ||
868                          !(k instanceof Comparable) ||
869                          (dir = ((Comparable)k).compareTo((Comparable)pk)) == 0) {
870 <                        dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName());
871 <                        TreeNode r = null, s = null, pl, pr;
872 <                        if (dir >= 0) {
873 <                            if ((pl = p.left) != null && h <= pl.hash)
874 <                                s = pl;
870 >                        if ((dir = (c == pc) ? 0 :
871 >                             c.getName().compareTo(pc.getName())) == 0) {
872 >                            TreeNode r = null, pl, pr; // check both sides
873 >                            if ((pr = p.right) != null && h >= pr.hash &&
874 >                                (r = getTreeNode(h, k, pr)) != null)
875 >                                return r;
876 >                            else if ((pl = p.left) != null && h <= pl.hash)
877 >                                dir = -1;
878 >                            else // nothing there
879 >                                return null;
880                          }
735                        else if ((pr = p.right) != null && h >= pr.hash)
736                            s = pr;
737                        if (s != null && (r = getTreeNode(h, k, s)) != null)
738                            return r;
881                      }
882                  }
883                  else
# Line 776 | Line 918 | public class ConcurrentHashMapV8<K, V>
918           * Finds or adds a node.
919           * @return null if added
920           */
921 <        @SuppressWarnings("unchecked") // suppress Comparable cast warning
922 <            final TreeNode putTreeNode(int h, Object k, Object v) {
921 >        @SuppressWarnings("unchecked") final TreeNode putTreeNode
922 >            (int h, Object k, Object v) {
923              Class<?> c = k.getClass();
924              TreeNode pp = root, p = null;
925              int dir = 0;
# Line 790 | Line 932 | public class ConcurrentHashMapV8<K, V>
932                      if (c != (pc = pk.getClass()) ||
933                          !(k instanceof Comparable) ||
934                          (dir = ((Comparable)k).compareTo((Comparable)pk)) == 0) {
935 <                        dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName());
936 <                        TreeNode r = null, s = null, pl, pr;
937 <                        if (dir >= 0) {
938 <                            if ((pl = p.left) != null && h <= pl.hash)
939 <                                s = pl;
935 >                        TreeNode s = null, r = null, pr;
936 >                        if ((dir = (c == pc) ? 0 :
937 >                             c.getName().compareTo(pc.getName())) == 0) {
938 >                            if ((pr = p.right) != null && h >= pr.hash &&
939 >                                (r = getTreeNode(h, k, pr)) != null)
940 >                                return r;
941 >                            else // continue left
942 >                                dir = -1;
943                          }
944                          else if ((pr = p.right) != null && h >= pr.hash)
945                              s = pr;
# Line 1204 | Line 1349 | public class ConcurrentHashMapV8<K, V>
1349      }
1350  
1351      /*
1352 <     * Internal versions of the five insertion methods, each a
1352 >     * Internal versions of the six insertion methods, each a
1353       * little more complicated than the last. All have
1354       * the same basic structure as the first (internalPut):
1355       *  1. If table uninitialized, create
# Line 1222 | Line 1367 | public class ConcurrentHashMapV8<K, V>
1367       *    returns from function call.
1368       *  * compute uses the same function-call mechanics, but without
1369       *    the prescans
1370 +     *  * merge acts as putIfAbsent in the absent case, but invokes the
1371 +     *    update function if present
1372       *  * putAll attempts to pre-allocate enough table space
1373       *    and more lazily performs count updates and checks.
1374       *
# Line 1545 | Line 1692 | public class ConcurrentHashMapV8<K, V>
1692      }
1693  
1694      /** Implementation for compute */
1695 <    @SuppressWarnings("unchecked")
1696 <        private final Object internalCompute(K k, boolean onlyIfPresent,
1550 <                                             BiFun<? super K, ? super V, ? extends V> mf) {
1695 >    @SuppressWarnings("unchecked") private final Object internalCompute
1696 >        (K k, boolean onlyIfPresent, BiFun<? super K, ? super V, ? extends V> mf) {
1697          int h = spread(k.hashCode());
1698          Object val = null;
1699          int delta = 0;
# Line 1670 | Line 1816 | public class ConcurrentHashMapV8<K, V>
1816          return val;
1817      }
1818  
1819 <    private final Object internalMerge(K k, V v,
1820 <                                       BiFun<? super V, ? super V, ? extends V> mf) {
1819 >    /** Implementation for merge */
1820 >    @SuppressWarnings("unchecked") private final Object internalMerge
1821 >        (K k, V v, BiFun<? super V, ? super V, ? extends V> mf) {
1822          int h = spread(k.hashCode());
1823          Object val = null;
1824          int delta = 0;
# Line 2001 | Line 2148 | public class ConcurrentHashMapV8<K, V>
2148          for (int i = bin;;) {      // start upwards sweep
2149              int fh; Node f;
2150              if ((f = tabAt(tab, i)) == null) {
2151 <                if (bin >= 0) {    // no lock needed (or available)
2151 >                if (bin >= 0) {    // Unbuffered; no lock needed (or available)
2152                      if (!casTabAt(tab, i, f, fwd))
2153                          continue;
2154                  }
# Line 2177 | Line 2324 | public class ConcurrentHashMapV8<K, V>
2324                      try {
2325                          if (tabAt(tab, i) == f) {
2326                              for (Node p = t.first; p != null; p = p.next) {
2327 <                                p.val = null;
2328 <                                --delta;
2327 >                                if (p.val != null) { // (currently always true)
2328 >                                    p.val = null;
2329 >                                    --delta;
2330 >                                }
2331                              }
2332                              t.first = null;
2333                              t.root = null;
# Line 2200 | Line 2349 | public class ConcurrentHashMapV8<K, V>
2349                  try {
2350                      if (tabAt(tab, i) == f) {
2351                          for (Node e = f; e != null; e = e.next) {
2352 <                            e.val = null;
2353 <                            --delta;
2352 >                            if (e.val != null) {  // (currently always true)
2353 >                                e.val = null;
2354 >                                --delta;
2355 >                            }
2356                          }
2357                          setTabAt(tab, i, null);
2358                          ++i;
# Line 2222 | Line 2373 | public class ConcurrentHashMapV8<K, V>
2373  
2374      /**
2375       * Encapsulates traversal for methods such as containsValue; also
2376 <     * serves as a base class for other iterators.
2376 >     * serves as a base class for other iterators and bulk tasks.
2377       *
2378       * At each step, the iterator snapshots the key ("nextKey") and
2379       * value ("nextVal") of a valid node (i.e., one that, at point of
# Line 2230 | Line 2381 | public class ConcurrentHashMapV8<K, V>
2381       * change (including to null, indicating deletion), field nextVal
2382       * might not be accurate at point of use, but still maintains the
2383       * weak consistency property of holding a value that was once
2384 <     * valid.
2384 >     * valid. To support iterator.remove, the nextKey field is not
2385 >     * updated (nulled out) when the iterator cannot advance.
2386       *
2387       * Internal traversals directly access these fields, as in:
2388       * {@code while (it.advance() != null) { process(it.nextKey); }}
# Line 2257 | Line 2409 | public class ConcurrentHashMapV8<K, V>
2409       * across threads, iteration terminates if a bounds checks fails
2410       * for a table read.
2411       *
2412 <     * This class extends ForkJoinTask to streamline parallel
2413 <     * iteration in bulk operations (see BulkTask). This adds only an
2414 <     * int of space overhead, which is close enough to negligible in
2415 <     * cases where it is not needed to not worry about it.
2412 >     * This class extends CountedCompleter to streamline parallel
2413 >     * iteration in bulk operations. This adds only a few fields of
2414 >     * space overhead, which is small enough in cases where it is not
2415 >     * needed to not worry about it.  Because CountedCompleter is
2416 >     * Serializable, but iterators need not be, we need to add warning
2417 >     * suppressions.
2418       */
2419 <    static class Traverser<K,V,R> extends ForkJoinTask<R> {
2419 >    @SuppressWarnings("serial") static class Traverser<K,V,R> extends CountedCompleter<R> {
2420          final ConcurrentHashMapV8<K, V> map;
2421          Node next;           // the next entry to use
2268        Node last;           // the last entry used
2422          Object nextKey;      // cached key field of next
2423          Object nextVal;      // cached val field of next
2424          Node[] tab;          // current table; updated if resized
2425          int index;           // index of bin to use next
2426          int baseIndex;       // current index of initial table
2427          int baseLimit;       // index bound for initial table
2428 <        final int baseSize;  // initial table size
2428 >        int baseSize;        // initial table size
2429 >        int batch;           // split control
2430  
2431          /** Creates iterator for all entries in the table. */
2432          Traverser(ConcurrentHashMapV8<K, V> map) {
2433 <            this.tab = (this.map = map).table;
2280 <            baseLimit = baseSize = (tab == null) ? 0 : tab.length;
2433 >            this.map = map;
2434          }
2435  
2436 <        /** Creates iterator for split() methods */
2437 <        Traverser(Traverser<K,V,?> it, boolean split) {
2438 <            this.map = it.map;
2439 <            this.tab = it.tab;
2440 <            this.baseSize = it.baseSize;
2441 <            int lo = it.baseIndex;
2442 <            int hi = this.baseLimit = it.baseLimit;
2443 <            int i;
2444 <            if (split) // adjust parent
2445 <                i = it.baseLimit = (lo + hi + 1) >>> 1;
2446 <            else       // clone parent
2447 <                i = lo;
2448 <            this.index = this.baseIndex = i;
2436 >        /** Creates iterator for split() methods and task constructors */
2437 >        Traverser(ConcurrentHashMapV8<K,V> map, Traverser<K,V,?> it, int batch) {
2438 >            super(it);
2439 >            this.batch = batch;
2440 >            if ((this.map = map) != null && it != null) { // split parent
2441 >                Node[] t;
2442 >                if ((t = it.tab) == null &&
2443 >                    (t = it.tab = map.table) != null)
2444 >                    it.baseLimit = it.baseSize = t.length;
2445 >                this.tab = t;
2446 >                this.baseSize = it.baseSize;
2447 >                int hi = this.baseLimit = it.baseLimit;
2448 >                it.baseLimit = this.index = this.baseIndex =
2449 >                    (hi + it.baseIndex + 1) >>> 1;
2450 >            }
2451          }
2452  
2453          /**
# Line 2300 | Line 2455 | public class ConcurrentHashMapV8<K, V>
2455           * See above for explanation.
2456           */
2457          final Object advance() {
2458 <            Node e = last = next;
2458 >            Node e = next;
2459              Object ev = null;
2460              outer: do {
2461                  if (e != null)                  // advance past used/skipped node
2462                      e = e.next;
2463                  while (e == null) {             // get to next non-null bin
2464 +                    ConcurrentHashMapV8<K, V> m;
2465                      Node[] t; int b, i, n; Object ek; // checks must use locals
2466 <                    if ((b = baseIndex) >= baseLimit || (i = index) < 0 ||
2467 <                        (t = tab) == null || i >= (n = t.length))
2466 >                    if ((t = tab) != null)
2467 >                        n = t.length;
2468 >                    else if ((m = map) != null && (t = tab = m.table) != null)
2469 >                        n = baseLimit = baseSize = t.length;
2470 >                    else
2471                          break outer;
2472 <                    else if ((e = tabAt(t, i)) != null && e.hash == MOVED) {
2472 >                    if ((b = baseIndex) >= baseLimit ||
2473 >                        (i = index) < 0 || i >= n)
2474 >                        break outer;
2475 >                    if ((e = tabAt(t, i)) != null && e.hash == MOVED) {
2476                          if ((ek = e.key) instanceof TreeBin)
2477                              e = ((TreeBin)ek).first;
2478                          else {
# Line 2327 | Line 2489 | public class ConcurrentHashMapV8<K, V>
2489          }
2490  
2491          public final void remove() {
2492 <            if (nextVal == null && last == null)
2493 <                advance();
2332 <            Node e = last;
2333 <            if (e == null)
2492 >            Object k = nextKey;
2493 >            if (k == null && (advance() == null || (k = nextKey) == null))
2494                  throw new IllegalStateException();
2495 <            last = null;
2336 <            map.remove(e.key);
2495 >            map.internalReplace(k, null, null);
2496          }
2497  
2498          public final boolean hasNext() {
# Line 2341 | Line 2500 | public class ConcurrentHashMapV8<K, V>
2500          }
2501  
2502          public final boolean hasMoreElements() { return hasNext(); }
2503 <        public final void setRawResult(Object x) { }
2504 <        public R getRawResult() { return null; }
2505 <        public boolean exec() { return true; }
2503 >
2504 >        public void compute() { } // default no-op CountedCompleter body
2505 >
2506 >        /**
2507 >         * Returns a batch value > 0 if this task should (and must) be
2508 >         * split, if so, adding to pending count, and in any case
2509 >         * updating batch value. The initial batch value is approx
2510 >         * exp2 of the number of times (minus one) to split task by
2511 >         * two before executing leaf action. This value is faster to
2512 >         * compute and more convenient to use as a guide to splitting
2513 >         * than is the depth, since it is used while dividing by two
2514 >         * anyway.
2515 >         */
2516 >        final int preSplit() {
2517 >            ConcurrentHashMapV8<K, V> m; int b; Node[] t;  ForkJoinPool pool;
2518 >            if ((b = batch) < 0 && (m = map) != null) { // force initialization
2519 >                if ((t = tab) == null && (t = tab = m.table) != null)
2520 >                    baseLimit = baseSize = t.length;
2521 >                if (t != null) {
2522 >                    long n = m.counter.sum();
2523 >                    int par = ((pool = getPool()) == null) ?
2524 >                        ForkJoinPool.getCommonPoolParallelism() :
2525 >                        pool.getParallelism();
2526 >                    int sp = par << 3; // slack of 8
2527 >                    b = (n <= 0L) ? 0 : (n < (long)sp) ? (int)n : sp;
2528 >                }
2529 >            }
2530 >            b = (b <= 1 || baseIndex == baseLimit) ? 0 : (b >>> 1);
2531 >            if ((batch = b) > 0)
2532 >                addToPendingCount(1);
2533 >            return b;
2534 >        }
2535 >
2536      }
2537  
2538      /* ---------------- Public operations -------------- */
# Line 2437 | Line 2626 | public class ConcurrentHashMapV8<K, V>
2626      }
2627  
2628      /**
2629 +     * Creates a new {@link Set} backed by a ConcurrentHashMapV8
2630 +     * from the given type to {@code Boolean.TRUE}.
2631 +     *
2632 +     * @return the new set
2633 +     */
2634 +    public static <K> KeySetView<K,Boolean> newKeySet() {
2635 +        return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(),
2636 +                                      Boolean.TRUE);
2637 +    }
2638 +
2639 +    /**
2640 +     * Creates a new {@link Set} backed by a ConcurrentHashMapV8
2641 +     * from the given type to {@code Boolean.TRUE}.
2642 +     *
2643 +     * @param initialCapacity The implementation performs internal
2644 +     * sizing to accommodate this many elements.
2645 +     * @throws IllegalArgumentException if the initial capacity of
2646 +     * elements is negative
2647 +     * @return the new set
2648 +     */
2649 +    public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) {
2650 +        return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(initialCapacity),
2651 +                                      Boolean.TRUE);
2652 +    }
2653 +
2654 +    /**
2655       * {@inheritDoc}
2656       */
2657      public boolean isEmpty() {
# Line 2455 | Line 2670 | public class ConcurrentHashMapV8<K, V>
2670  
2671      /**
2672       * Returns the number of mappings. This method should be used
2673 <     * instead of {@link #size} because a ConcurrentHashMap may
2673 >     * instead of {@link #size} because a ConcurrentHashMapV8 may
2674       * contain more mappings than can be represented as an int. The
2675 <     * value returned is a snapshot; the actual count may differ if
2676 <     * there are ongoing concurrent insertions of removals.
2675 >     * value returned is an estimate; the actual count may differ if
2676 >     * there are concurrent insertions or removals.
2677       *
2678       * @return the number of mappings
2679       */
2680      public long mappingCount() {
2681          long n = counter.sum();
2682 <        return (n < 0L) ? 0L : n;
2682 >        return (n < 0L) ? 0L : n; // ignore transient negative values
2683      }
2684  
2685      /**
# Line 2478 | Line 2693 | public class ConcurrentHashMapV8<K, V>
2693       *
2694       * @throws NullPointerException if the specified key is null
2695       */
2696 <    @SuppressWarnings("unchecked")
2482 <        public V get(Object key) {
2696 >    @SuppressWarnings("unchecked") public V get(Object key) {
2697          if (key == null)
2698              throw new NullPointerException();
2699          return (V)internalGet(key);
2700      }
2701  
2702      /**
2703 +     * Returns the value to which the specified key is mapped,
2704 +     * or the given defaultValue if this map contains no mapping for the key.
2705 +     *
2706 +     * @param key the key
2707 +     * @param defaultValue the value to return if this map contains
2708 +     * no mapping for the given key
2709 +     * @return the mapping for the key, if present; else the defaultValue
2710 +     * @throws NullPointerException if the specified key is null
2711 +     */
2712 +    @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) {
2713 +        if (key == null)
2714 +            throw new NullPointerException();
2715 +        V v = (V) internalGet(key);
2716 +        return v == null ? defaultValue : v;
2717 +    }
2718 +
2719 +    /**
2720       * Tests if the specified object is a key in this table.
2721       *
2722       * @param  key   possible key
# Line 2545 | Line 2776 | public class ConcurrentHashMapV8<K, V>
2776       * Maps the specified key to the specified value in this table.
2777       * Neither the key nor the value can be null.
2778       *
2779 <     * <p> The value can be retrieved by calling the {@code get} method
2779 >     * <p>The value can be retrieved by calling the {@code get} method
2780       * with a key that is equal to the original key.
2781       *
2782       * @param key key with which the specified value is to be associated
# Line 2554 | Line 2785 | public class ConcurrentHashMapV8<K, V>
2785       *         {@code null} if there was no mapping for {@code key}
2786       * @throws NullPointerException if the specified key or value is null
2787       */
2788 <    @SuppressWarnings("unchecked")
2558 <        public V put(K key, V value) {
2788 >    @SuppressWarnings("unchecked") public V put(K key, V value) {
2789          if (key == null || value == null)
2790              throw new NullPointerException();
2791          return (V)internalPut(key, value);
# Line 2568 | Line 2798 | public class ConcurrentHashMapV8<K, V>
2798       *         or {@code null} if there was no mapping for the key
2799       * @throws NullPointerException if the specified key or value is null
2800       */
2801 <    @SuppressWarnings("unchecked")
2572 <        public V putIfAbsent(K key, V value) {
2801 >    @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) {
2802          if (key == null || value == null)
2803              throw new NullPointerException();
2804          return (V)internalPutIfAbsent(key, value);
# Line 2616 | Line 2845 | public class ConcurrentHashMapV8<K, V>
2845       * @param key key with which the specified value is to be associated
2846       * @param mappingFunction the function to compute a value
2847       * @return the current (existing or computed) value associated with
2848 <     *         the specified key, or null if the computed value is null.
2848 >     *         the specified key, or null if the computed value is null
2849       * @throws NullPointerException if the specified key or mappingFunction
2850       *         is null
2851       * @throws IllegalStateException if the computation detectably
# Line 2625 | Line 2854 | public class ConcurrentHashMapV8<K, V>
2854       * @throws RuntimeException or Error if the mappingFunction does so,
2855       *         in which case the mapping is left unestablished
2856       */
2857 <    @SuppressWarnings("unchecked")
2858 <        public V computeIfAbsent(K key, Fun<? super K, ? extends V> mappingFunction) {
2857 >    @SuppressWarnings("unchecked") public V computeIfAbsent
2858 >        (K key, Fun<? super K, ? extends V> mappingFunction) {
2859          if (key == null || mappingFunction == null)
2860              throw new NullPointerException();
2861          return (V)internalComputeIfAbsent(key, mappingFunction);
# Line 2666 | Line 2895 | public class ConcurrentHashMapV8<K, V>
2895       * @throws RuntimeException or Error if the remappingFunction does so,
2896       *         in which case the mapping is unchanged
2897       */
2898 <    public V computeIfPresent(K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2898 >    @SuppressWarnings("unchecked") public V computeIfPresent
2899 >        (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2900          if (key == null || remappingFunction == null)
2901              throw new NullPointerException();
2902          return (V)internalCompute(key, true, remappingFunction);
# Line 2712 | Line 2942 | public class ConcurrentHashMapV8<K, V>
2942       * @throws RuntimeException or Error if the remappingFunction does so,
2943       *         in which case the mapping is unchanged
2944       */
2945 <    //    @SuppressWarnings("unchecked")
2946 <    public V compute(K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2945 >    @SuppressWarnings("unchecked") public V compute
2946 >        (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2947          if (key == null || remappingFunction == null)
2948              throw new NullPointerException();
2949          return (V)internalCompute(key, false, remappingFunction);
# Line 2744 | Line 2974 | public class ConcurrentHashMapV8<K, V>
2974       * so the computation should be short and simple, and must not
2975       * attempt to update any other mappings of this Map.
2976       */
2977 <    //    @SuppressWarnings("unchecked")
2978 <    public V merge(K key, V value, BiFun<? super V, ? super V, ? extends V> remappingFunction) {
2977 >    @SuppressWarnings("unchecked") public V merge
2978 >        (K key, V value, BiFun<? super V, ? super V, ? extends V> remappingFunction) {
2979          if (key == null || value == null || remappingFunction == null)
2980              throw new NullPointerException();
2981          return (V)internalMerge(key, value, remappingFunction);
# Line 2760 | Line 2990 | public class ConcurrentHashMapV8<K, V>
2990       *         {@code null} if there was no mapping for {@code key}
2991       * @throws NullPointerException if the specified key is null
2992       */
2993 <    @SuppressWarnings("unchecked")
2764 <        public V remove(Object key) {
2993 >    @SuppressWarnings("unchecked") public V remove(Object key) {
2994          if (key == null)
2995              throw new NullPointerException();
2996          return (V)internalReplace(key, null, null);
# Line 2798 | Line 3027 | public class ConcurrentHashMapV8<K, V>
3027       *         or {@code null} if there was no mapping for the key
3028       * @throws NullPointerException if the specified key or value is null
3029       */
3030 <    @SuppressWarnings("unchecked")
2802 <        public V replace(K key, V value) {
3030 >    @SuppressWarnings("unchecked") public V replace(K key, V value) {
3031          if (key == null || value == null)
3032              throw new NullPointerException();
3033          return (V)internalReplace(key, value, null);
# Line 2815 | Line 3043 | public class ConcurrentHashMapV8<K, V>
3043      /**
3044       * Returns a {@link Set} view of the keys contained in this map.
3045       * The set is backed by the map, so changes to the map are
3046 <     * reflected in the set, and vice-versa.  The set supports element
2819 <     * removal, which removes the corresponding mapping from this map,
2820 <     * via the {@code Iterator.remove}, {@code Set.remove},
2821 <     * {@code removeAll}, {@code retainAll}, and {@code clear}
2822 <     * operations.  It does not support the {@code add} or
2823 <     * {@code addAll} operations.
3046 >     * reflected in the set, and vice-versa.
3047       *
3048 <     * <p>The view's {@code iterator} is a "weakly consistent" iterator
2826 <     * that will never throw {@link ConcurrentModificationException},
2827 <     * and guarantees to traverse elements as they existed upon
2828 <     * construction of the iterator, and may (but is not guaranteed to)
2829 <     * reflect any modifications subsequent to construction.
3048 >     * @return the set view
3049       */
3050 <    public Set<K> keySet() {
3051 <        KeySet<K,V> ks = keySet;
3052 <        return (ks != null) ? ks : (keySet = new KeySet<K,V>(this));
3050 >    public KeySetView<K,V> keySet() {
3051 >        KeySetView<K,V> ks = keySet;
3052 >        return (ks != null) ? ks : (keySet = new KeySetView<K,V>(this, null));
3053 >    }
3054 >
3055 >    /**
3056 >     * Returns a {@link Set} view of the keys in this map, using the
3057 >     * given common mapped value for any additions (i.e., {@link
3058 >     * Collection#add} and {@link Collection#addAll}). This is of
3059 >     * course only appropriate if it is acceptable to use the same
3060 >     * value for all additions from this view.
3061 >     *
3062 >     * @param mappedValue the mapped value to use for any
3063 >     * additions.
3064 >     * @return the set view
3065 >     * @throws NullPointerException if the mappedValue is null
3066 >     */
3067 >    public KeySetView<K,V> keySet(V mappedValue) {
3068 >        if (mappedValue == null)
3069 >            throw new NullPointerException();
3070 >        return new KeySetView<K,V>(this, mappedValue);
3071      }
3072  
3073      /**
3074       * Returns a {@link Collection} view of the values contained in this map.
3075       * The collection is backed by the map, so changes to the map are
3076 <     * reflected in the collection, and vice-versa.  The collection
2840 <     * supports element removal, which removes the corresponding
2841 <     * mapping from this map, via the {@code Iterator.remove},
2842 <     * {@code Collection.remove}, {@code removeAll},
2843 <     * {@code retainAll}, and {@code clear} operations.  It does not
2844 <     * support the {@code add} or {@code addAll} operations.
2845 <     *
2846 <     * <p>The view's {@code iterator} is a "weakly consistent" iterator
2847 <     * that will never throw {@link ConcurrentModificationException},
2848 <     * and guarantees to traverse elements as they existed upon
2849 <     * construction of the iterator, and may (but is not guaranteed to)
2850 <     * reflect any modifications subsequent to construction.
3076 >     * reflected in the collection, and vice-versa.
3077       */
3078 <    public Collection<V> values() {
3079 <        Values<K,V> vs = values;
3080 <        return (vs != null) ? vs : (values = new Values<K,V>(this));
3078 >    public ValuesView<K,V> values() {
3079 >        ValuesView<K,V> vs = values;
3080 >        return (vs != null) ? vs : (values = new ValuesView<K,V>(this));
3081      }
3082  
3083      /**
# Line 2871 | Line 3097 | public class ConcurrentHashMapV8<K, V>
3097       * reflect any modifications subsequent to construction.
3098       */
3099      public Set<Map.Entry<K,V>> entrySet() {
3100 <        EntrySet<K,V> es = entrySet;
3101 <        return (es != null) ? es : (entrySet = new EntrySet<K,V>(this));
3100 >        EntrySetView<K,V> es = entrySet;
3101 >        return (es != null) ? es : (entrySet = new EntrySetView<K,V>(this));
3102      }
3103  
3104      /**
# Line 3005 | Line 3231 | public class ConcurrentHashMapV8<K, V>
3231  
3232      /* ----------------Iterators -------------- */
3233  
3234 <    static final class KeyIterator<K,V> extends Traverser<K,V,Object>
3234 >    @SuppressWarnings("serial") static final class KeyIterator<K,V> extends Traverser<K,V,Object>
3235          implements Spliterator<K>, Enumeration<K> {
3236          KeyIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3237 <        KeyIterator(Traverser<K,V,Object> it, boolean split) {
3238 <            super(it, split);
3237 >        KeyIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3238 >            super(map, it, -1);
3239          }
3240          public KeyIterator<K,V> split() {
3241 <            if (last != null || (next != null && nextVal == null))
3241 >            if (nextKey != null)
3242                  throw new IllegalStateException();
3243 <            return new KeyIterator<K,V>(this, true);
3243 >            return new KeyIterator<K,V>(map, this);
3244          }
3245 <        @SuppressWarnings("unchecked")
3020 <            public final K next() {
3245 >        @SuppressWarnings("unchecked") public final K next() {
3246              if (nextVal == null && advance() == null)
3247                  throw new NoSuchElementException();
3248              Object k = nextKey;
# Line 3028 | Line 3253 | public class ConcurrentHashMapV8<K, V>
3253          public final K nextElement() { return next(); }
3254      }
3255  
3256 <    static final class ValueIterator<K,V> extends Traverser<K,V,Object>
3256 >    @SuppressWarnings("serial") static final class ValueIterator<K,V> extends Traverser<K,V,Object>
3257          implements Spliterator<V>, Enumeration<V> {
3258          ValueIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3259 <        ValueIterator(Traverser<K,V,Object> it, boolean split) {
3260 <            super(it, split);
3259 >        ValueIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3260 >            super(map, it, -1);
3261          }
3262          public ValueIterator<K,V> split() {
3263 <            if (last != null || (next != null && nextVal == null))
3263 >            if (nextKey != null)
3264                  throw new IllegalStateException();
3265 <            return new ValueIterator<K,V>(this, true);
3265 >            return new ValueIterator<K,V>(map, this);
3266          }
3267  
3268 <        @SuppressWarnings("unchecked")
3044 <            public final V next() {
3268 >        @SuppressWarnings("unchecked") public final V next() {
3269              Object v;
3270              if ((v = nextVal) == null && (v = advance()) == null)
3271                  throw new NoSuchElementException();
# Line 3052 | Line 3276 | public class ConcurrentHashMapV8<K, V>
3276          public final V nextElement() { return next(); }
3277      }
3278  
3279 <    static final class EntryIterator<K,V> extends Traverser<K,V,Object>
3279 >    @SuppressWarnings("serial") static final class EntryIterator<K,V> extends Traverser<K,V,Object>
3280          implements Spliterator<Map.Entry<K,V>> {
3281          EntryIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3282 <        EntryIterator(Traverser<K,V,Object> it, boolean split) {
3283 <            super(it, split);
3282 >        EntryIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3283 >            super(map, it, -1);
3284          }
3285          public EntryIterator<K,V> split() {
3286 <            if (last != null || (next != null && nextVal == null))
3286 >            if (nextKey != null)
3287                  throw new IllegalStateException();
3288 <            return new EntryIterator<K,V>(this, true);
3288 >            return new EntryIterator<K,V>(map, this);
3289          }
3290  
3291 <        @SuppressWarnings("unchecked")
3068 <            public final Map.Entry<K,V> next() {
3291 >        @SuppressWarnings("unchecked") public final Map.Entry<K,V> next() {
3292              Object v;
3293              if ((v = nextVal) == null && (v = advance()) == null)
3294                  throw new NoSuchElementException();
# Line 3118 | Line 3341 | public class ConcurrentHashMapV8<K, V>
3341          }
3342      }
3343  
3121    /* ----------------Views -------------- */
3122
3344      /**
3345 <     * Base class for views.
3345 >     * Returns exportable snapshot entry for the given key and value
3346 >     * when write-through can't or shouldn't be used.
3347       */
3348 <    static abstract class CHMView<K, V> {
3349 <        final ConcurrentHashMapV8<K, V> map;
3128 <        CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
3129 <        public final int size()                 { return map.size(); }
3130 <        public final boolean isEmpty()          { return map.isEmpty(); }
3131 <        public final void clear()               { map.clear(); }
3132 <
3133 <        // implementations below rely on concrete classes supplying these
3134 <        abstract public Iterator<?> iterator();
3135 <        abstract public boolean contains(Object o);
3136 <        abstract public boolean remove(Object o);
3137 <
3138 <        private static final String oomeMsg = "Required array size too large";
3139 <
3140 <        public final Object[] toArray() {
3141 <            long sz = map.mappingCount();
3142 <            if (sz > (long)(MAX_ARRAY_SIZE))
3143 <                throw new OutOfMemoryError(oomeMsg);
3144 <            int n = (int)sz;
3145 <            Object[] r = new Object[n];
3146 <            int i = 0;
3147 <            Iterator<?> it = iterator();
3148 <            while (it.hasNext()) {
3149 <                if (i == n) {
3150 <                    if (n >= MAX_ARRAY_SIZE)
3151 <                        throw new OutOfMemoryError(oomeMsg);
3152 <                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3153 <                        n = MAX_ARRAY_SIZE;
3154 <                    else
3155 <                        n += (n >>> 1) + 1;
3156 <                    r = Arrays.copyOf(r, n);
3157 <                }
3158 <                r[i++] = it.next();
3159 <            }
3160 <            return (i == n) ? r : Arrays.copyOf(r, i);
3161 <        }
3162 <
3163 <        @SuppressWarnings("unchecked")
3164 <            public final <T> T[] toArray(T[] a) {
3165 <            long sz = map.mappingCount();
3166 <            if (sz > (long)(MAX_ARRAY_SIZE))
3167 <                throw new OutOfMemoryError(oomeMsg);
3168 <            int m = (int)sz;
3169 <            T[] r = (a.length >= m) ? a :
3170 <                (T[])java.lang.reflect.Array
3171 <                .newInstance(a.getClass().getComponentType(), m);
3172 <            int n = r.length;
3173 <            int i = 0;
3174 <            Iterator<?> it = iterator();
3175 <            while (it.hasNext()) {
3176 <                if (i == n) {
3177 <                    if (n >= MAX_ARRAY_SIZE)
3178 <                        throw new OutOfMemoryError(oomeMsg);
3179 <                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3180 <                        n = MAX_ARRAY_SIZE;
3181 <                    else
3182 <                        n += (n >>> 1) + 1;
3183 <                    r = Arrays.copyOf(r, n);
3184 <                }
3185 <                r[i++] = (T)it.next();
3186 <            }
3187 <            if (a == r && i < n) {
3188 <                r[i] = null; // null-terminate
3189 <                return r;
3190 <            }
3191 <            return (i == n) ? r : Arrays.copyOf(r, i);
3192 <        }
3193 <
3194 <        public final int hashCode() {
3195 <            int h = 0;
3196 <            for (Iterator<?> it = iterator(); it.hasNext();)
3197 <                h += it.next().hashCode();
3198 <            return h;
3199 <        }
3200 <
3201 <        public final String toString() {
3202 <            StringBuilder sb = new StringBuilder();
3203 <            sb.append('[');
3204 <            Iterator<?> it = iterator();
3205 <            if (it.hasNext()) {
3206 <                for (;;) {
3207 <                    Object e = it.next();
3208 <                    sb.append(e == this ? "(this Collection)" : e);
3209 <                    if (!it.hasNext())
3210 <                        break;
3211 <                    sb.append(',').append(' ');
3212 <                }
3213 <            }
3214 <            return sb.append(']').toString();
3215 <        }
3216 <
3217 <        public final boolean containsAll(Collection<?> c) {
3218 <            if (c != this) {
3219 <                for (Iterator<?> it = c.iterator(); it.hasNext();) {
3220 <                    Object e = it.next();
3221 <                    if (e == null || !contains(e))
3222 <                        return false;
3223 <                }
3224 <            }
3225 <            return true;
3226 <        }
3227 <
3228 <        public final boolean removeAll(Collection<?> c) {
3229 <            boolean modified = false;
3230 <            for (Iterator<?> it = iterator(); it.hasNext();) {
3231 <                if (c.contains(it.next())) {
3232 <                    it.remove();
3233 <                    modified = true;
3234 <                }
3235 <            }
3236 <            return modified;
3237 <        }
3238 <
3239 <        public final boolean retainAll(Collection<?> c) {
3240 <            boolean modified = false;
3241 <            for (Iterator<?> it = iterator(); it.hasNext();) {
3242 <                if (!c.contains(it.next())) {
3243 <                    it.remove();
3244 <                    modified = true;
3245 <                }
3246 <            }
3247 <            return modified;
3248 <        }
3249 <
3250 <    }
3251 <
3252 <    static final class KeySet<K,V> extends CHMView<K,V> implements Set<K> {
3253 <        KeySet(ConcurrentHashMapV8<K, V> map)  {
3254 <            super(map);
3255 <        }
3256 <        public final boolean contains(Object o) { return map.containsKey(o); }
3257 <        public final boolean remove(Object o)   { return map.remove(o) != null; }
3258 <        public final Iterator<K> iterator() {
3259 <            return new KeyIterator<K,V>(map);
3260 <        }
3261 <        public final boolean add(K e) {
3262 <            throw new UnsupportedOperationException();
3263 <        }
3264 <        public final boolean addAll(Collection<? extends K> c) {
3265 <            throw new UnsupportedOperationException();
3266 <        }
3267 <        public boolean equals(Object o) {
3268 <            Set<?> c;
3269 <            return ((o instanceof Set) &&
3270 <                    ((c = (Set<?>)o) == this ||
3271 <                     (containsAll(c) && c.containsAll(this))));
3272 <        }
3273 <    }
3274 <
3275 <
3276 <    static final class Values<K,V> extends CHMView<K,V>
3277 <        implements Collection<V> {
3278 <        Values(ConcurrentHashMapV8<K, V> map)   { super(map); }
3279 <        public final boolean contains(Object o) { return map.containsValue(o); }
3280 <        public final boolean remove(Object o) {
3281 <            if (o != null) {
3282 <                Iterator<V> it = new ValueIterator<K,V>(map);
3283 <                while (it.hasNext()) {
3284 <                    if (o.equals(it.next())) {
3285 <                        it.remove();
3286 <                        return true;
3287 <                    }
3288 <                }
3289 <            }
3290 <            return false;
3291 <        }
3292 <        public final Iterator<V> iterator() {
3293 <            return new ValueIterator<K,V>(map);
3294 <        }
3295 <        public final boolean add(V e) {
3296 <            throw new UnsupportedOperationException();
3297 <        }
3298 <        public final boolean addAll(Collection<? extends V> c) {
3299 <            throw new UnsupportedOperationException();
3300 <        }
3301 <
3302 <    }
3303 <
3304 <    static final class EntrySet<K,V> extends CHMView<K,V>
3305 <        implements Set<Map.Entry<K,V>> {
3306 <        EntrySet(ConcurrentHashMapV8<K, V> map) { super(map); }
3307 <        public final boolean contains(Object o) {
3308 <            Object k, v, r; Map.Entry<?,?> e;
3309 <            return ((o instanceof Map.Entry) &&
3310 <                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
3311 <                    (r = map.get(k)) != null &&
3312 <                    (v = e.getValue()) != null &&
3313 <                    (v == r || v.equals(r)));
3314 <        }
3315 <        public final boolean remove(Object o) {
3316 <            Object k, v; Map.Entry<?,?> e;
3317 <            return ((o instanceof Map.Entry) &&
3318 <                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
3319 <                    (v = e.getValue()) != null &&
3320 <                    map.remove(k, v));
3321 <        }
3322 <        public final Iterator<Map.Entry<K,V>> iterator() {
3323 <            return new EntryIterator<K,V>(map);
3324 <        }
3325 <        public final boolean add(Entry<K,V> e) {
3326 <            throw new UnsupportedOperationException();
3327 <        }
3328 <        public final boolean addAll(Collection<? extends Entry<K,V>> c) {
3329 <            throw new UnsupportedOperationException();
3330 <        }
3331 <        public boolean equals(Object o) {
3332 <            Set<?> c;
3333 <            return ((o instanceof Set) &&
3334 <                    ((c = (Set<?>)o) == this ||
3335 <                     (containsAll(c) && c.containsAll(this))));
3336 <        }
3348 >    static <K,V> AbstractMap.SimpleEntry<K,V> entryFor(K k, V v) {
3349 >        return new AbstractMap.SimpleEntry<K,V>(k, v);
3350      }
3351  
3352      /* ---------------- Serialization Support -------------- */
# Line 3357 | Line 3370 | public class ConcurrentHashMapV8<K, V>
3370       * for each key-value mapping, followed by a null pair.
3371       * The key-value mappings are emitted in no particular order.
3372       */
3373 <    @SuppressWarnings("unchecked")
3361 <        private void writeObject(java.io.ObjectOutputStream s)
3373 >    @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s)
3374          throws java.io.IOException {
3375          if (segments == null) { // for serialization compatibility
3376              segments = (Segment<K,V>[])
# Line 3382 | Line 3394 | public class ConcurrentHashMapV8<K, V>
3394       * Reconstitutes the instance from a stream (that is, deserializes it).
3395       * @param s the stream
3396       */
3397 <    @SuppressWarnings("unchecked")
3386 <        private void readObject(java.io.ObjectInputStream s)
3397 >    @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s)
3398          throws java.io.IOException, ClassNotFoundException {
3399          s.defaultReadObject();
3400          this.segments = null; // unneeded
# Line 3504 | Line 3515 | public class ConcurrentHashMapV8<K, V>
3515      // -------------------------------------------------------
3516  
3517      /**
3518 <     * Returns an extended {@link Parallel} view of this map using the
3508 <     * given executor for bulk parallel operations.
3518 >     * Performs the given action for each (key, value).
3519       *
3520 <     * @param executor the executor
3511 <     * @return a parallel view
3520 >     * @param action the action
3521       */
3522 <    public Parallel parallel(ForkJoinPool executor)  {
3523 <        return new Parallel(executor);
3522 >    public void forEach(BiAction<K,V> action) {
3523 >        ForkJoinTasks.forEach
3524 >            (this, action).invoke();
3525      }
3526  
3527      /**
3528 <     * An extended view of a ConcurrentHashMap supporting bulk
3529 <     * parallel operations. These operations are designed to be
3530 <     * safely, and often sensibly, applied even with maps that are
3531 <     * being concurrently updated by other threads; for example, when
3532 <     * computing a snapshot summary of the values in a shared
3533 <     * registry.  There are three kinds of operation, each with four
3534 <     * forms, accepting functions with Keys, Values, Entries, and
3535 <     * (Key, Value) arguments and/or return values. Because the
3536 <     * elements of a ConcurrentHashMap are not ordered in any
3537 <     * particular way, and may be processed in different orders in
3538 <     * different parallel executions, the correctness of supplied
3539 <     * functions should not depend on any ordering, or on any other
3540 <     * objects or values that may transiently change while computation
3541 <     * is in progress; and except for forEach actions, should ideally
3542 <     * be side-effect-free.
3543 <     *
3544 <     * <ul>
3545 <     * <li> forEach: Perform a given action on each element.
3546 <     * A variant form applies a given transformation on each element
3547 <     * before performing the action.</li>
3548 <     *
3549 <     * <li> search: Return the first available non-null result of
3550 <     * applying a given function on each element; skipping further
3551 <     * search when a result is found.</li>
3552 <     *
3553 <     * <li> reduce: Accumulate each element.  The supplied reduction
3554 <     * function cannot rely on ordering (more formally, it should be
3555 <     * both associative and commutative).  There are five variants:
3556 <     *
3557 <     * <ul>
3558 <     *
3559 <     * <li> Plain reductions. (There is not a form of this method for
3560 <     * (key, value) function arguments since there is no corresponding
3561 <     * return type.)</li>
3562 <     *
3563 <     * <li> Mapped reductions that accumulate the results of a given
3564 <     * function applied to each element.</li>
3565 <     *
3566 <     * <li> Reductions to scalar doubles, longs, and ints, using a
3567 <     * given basis value.</li>
3568 <     *
3569 <     * </li>
3570 <     * </ul>
3571 <     * </ul>
3572 <     *
3573 <     * <p>The concurrency properties of the bulk operations follow
3574 <     * from those of ConcurrentHashMap: Any non-null result returned
3575 <     * from {@code get(key)} and related access methods bears a
3576 <     * happens-before relation with the associated insertion or
3577 <     * update.  The result of any bulk operation reflects the
3578 <     * composition of these per-element relations (but is not
3579 <     * necessarily atomic with respect to the map as a whole unless it
3580 <     * is somehow known to be quiescent).  Conversely, because keys
3581 <     * and values in the map are never null, null serves as a reliable
3582 <     * atomic indicator of the current lack of any result.  To
3583 <     * maintain this property, null serves as an implicit basis for
3584 <     * all non-scalar reduction operations. For the double, long, and
3585 <     * int versions, the basis should be one that, when combined with
3586 <     * any other value, returns that other value (more formally, it
3587 <     * should be the identity element for the reduction). Most common
3588 <     * reductions have these properties; for example, computing a sum
3589 <     * with basis 0 or a minimum with basis MAX_VALUE.
3590 <     *
3591 <     * <p>Search and transformation functions provided as arguments
3592 <     * should similarly return null to indicate the lack of any result
3593 <     * (in which case it is not used). In the case of mapped
3594 <     * reductions, this also enables transformations to serve as
3595 <     * filters, returning null (or, in the case of primitive
3596 <     * specializations, the identity basis) if the element should not
3597 <     * be combined. You can create compound transformations and
3598 <     * filterings by composing them yourself under this "null means
3599 <     * there is nothing there now" rule before using them in search or
3600 <     * reduce operations.
3601 <     *
3602 <     * <p>Methods accepting and/or returning Entry arguments maintain
3603 <     * key-value associations. They may be useful for example when
3604 <     * finding the key for the greatest value. Note that "plain" Entry
3605 <     * arguments can be supplied using {@code new
3606 <     * AbstractMap.SimpleEntry(k,v)}.
3607 <     *
3608 <     * <p> Bulk operations may complete abruptly, throwing an
3609 <     * exception encountered in the application of a supplied
3610 <     * function. Bear in mind when handling such exceptions that other
3611 <     * concurrently executing functions could also have thrown
3612 <     * exceptions, or would have done so if the first exception had
3613 <     * not occurred.
3614 <     *
3615 <     * <p>Parallel speedups compared to sequential processing are
3616 <     * common but not guaranteed.  Operations involving brief
3617 <     * functions on small maps may execute more slowly than sequential
3618 <     * loops if the underlying work to parallelize the computation is
3619 <     * more expensive than the computation itself. Similarly,
3620 <     * parallelization may not lead to much actual parallelism if all
3621 <     * processors are busy performing unrelated tasks.
3622 <     *
3623 <     * <p> All arguments to all task methods must be non-null.
3624 <     *
3625 <     * <p><em>jsr166e note: During transition, this class
3626 <     * uses nested functional interfaces with different names but the
3627 <     * same forms as those expected for JDK8.<em>
3628 <     */
3629 <    public class Parallel {
3630 <        final ForkJoinPool fjp;
3631 <
3632 <        /**
3633 <         * Returns an extended view of this map using the given
3634 <         * executor for bulk parallel operations.
3635 <         *
3636 <         * @param executor the executor
3637 <         */
3638 <        public Parallel(ForkJoinPool executor)  {
3639 <            this.fjp = executor;
3640 <        }
3528 >     * Performs the given action for each non-null transformation
3529 >     * of each (key, value).
3530 >     *
3531 >     * @param transformer a function returning the transformation
3532 >     * for an element, or null of there is no transformation (in
3533 >     * which case the action is not applied).
3534 >     * @param action the action
3535 >     */
3536 >    public <U> void forEach(BiFun<? super K, ? super V, ? extends U> transformer,
3537 >                            Action<U> action) {
3538 >        ForkJoinTasks.forEach
3539 >            (this, transformer, action).invoke();
3540 >    }
3541 >
3542 >    /**
3543 >     * Returns a non-null result from applying the given search
3544 >     * function on each (key, value), or null if none.  Upon
3545 >     * success, further element processing is suppressed and the
3546 >     * results of any other parallel invocations of the search
3547 >     * function are ignored.
3548 >     *
3549 >     * @param searchFunction a function returning a non-null
3550 >     * result on success, else null
3551 >     * @return a non-null result from applying the given search
3552 >     * function on each (key, value), or null if none
3553 >     */
3554 >    public <U> U search(BiFun<? super K, ? super V, ? extends U> searchFunction) {
3555 >        return ForkJoinTasks.search
3556 >            (this, searchFunction).invoke();
3557 >    }
3558 >
3559 >    /**
3560 >     * Returns the result of accumulating the given transformation
3561 >     * of all (key, value) pairs using the given reducer to
3562 >     * combine values, or null if none.
3563 >     *
3564 >     * @param transformer a function returning the transformation
3565 >     * for an element, or null of there is no transformation (in
3566 >     * which case it is not combined).
3567 >     * @param reducer a commutative associative combining function
3568 >     * @return the result of accumulating the given transformation
3569 >     * of all (key, value) pairs
3570 >     */
3571 >    public <U> U reduce(BiFun<? super K, ? super V, ? extends U> transformer,
3572 >                        BiFun<? super U, ? super U, ? extends U> reducer) {
3573 >        return ForkJoinTasks.reduce
3574 >            (this, transformer, reducer).invoke();
3575 >    }
3576 >
3577 >    /**
3578 >     * Returns the result of accumulating the given transformation
3579 >     * of all (key, value) pairs using the given reducer to
3580 >     * combine values, and the given basis as an identity value.
3581 >     *
3582 >     * @param transformer a function returning the transformation
3583 >     * for an element
3584 >     * @param basis the identity (initial default value) for the reduction
3585 >     * @param reducer a commutative associative combining function
3586 >     * @return the result of accumulating the given transformation
3587 >     * of all (key, value) pairs
3588 >     */
3589 >    public double reduceToDouble(ObjectByObjectToDouble<? super K, ? super V> transformer,
3590 >                                 double basis,
3591 >                                 DoubleByDoubleToDouble reducer) {
3592 >        return ForkJoinTasks.reduceToDouble
3593 >            (this, transformer, basis, reducer).invoke();
3594 >    }
3595 >
3596 >    /**
3597 >     * Returns the result of accumulating the given transformation
3598 >     * of all (key, value) pairs using the given reducer to
3599 >     * combine values, and the given basis as an identity value.
3600 >     *
3601 >     * @param transformer a function returning the transformation
3602 >     * for an element
3603 >     * @param basis the identity (initial default value) for the reduction
3604 >     * @param reducer a commutative associative combining function
3605 >     * @return the result of accumulating the given transformation
3606 >     * of all (key, value) pairs
3607 >     */
3608 >    public long reduceToLong(ObjectByObjectToLong<? super K, ? super V> transformer,
3609 >                             long basis,
3610 >                             LongByLongToLong reducer) {
3611 >        return ForkJoinTasks.reduceToLong
3612 >            (this, transformer, basis, reducer).invoke();
3613 >    }
3614 >
3615 >    /**
3616 >     * Returns the result of accumulating the given transformation
3617 >     * of all (key, value) pairs using the given reducer to
3618 >     * combine values, and the given basis as an identity value.
3619 >     *
3620 >     * @param transformer a function returning the transformation
3621 >     * for an element
3622 >     * @param basis the identity (initial default value) for the reduction
3623 >     * @param reducer a commutative associative combining function
3624 >     * @return the result of accumulating the given transformation
3625 >     * of all (key, value) pairs
3626 >     */
3627 >    public int reduceToInt(ObjectByObjectToInt<? super K, ? super V> transformer,
3628 >                           int basis,
3629 >                           IntByIntToInt reducer) {
3630 >        return ForkJoinTasks.reduceToInt
3631 >            (this, transformer, basis, reducer).invoke();
3632 >    }
3633 >
3634 >    /**
3635 >     * Performs the given action for each key.
3636 >     *
3637 >     * @param action the action
3638 >     */
3639 >    public void forEachKey(Action<K> action) {
3640 >        ForkJoinTasks.forEachKey
3641 >            (this, action).invoke();
3642 >    }
3643 >
3644 >    /**
3645 >     * Performs the given action for each non-null transformation
3646 >     * of each key.
3647 >     *
3648 >     * @param transformer a function returning the transformation
3649 >     * for an element, or null of there is no transformation (in
3650 >     * which case the action is not applied).
3651 >     * @param action the action
3652 >     */
3653 >    public <U> void forEachKey(Fun<? super K, ? extends U> transformer,
3654 >                               Action<U> action) {
3655 >        ForkJoinTasks.forEachKey
3656 >            (this, transformer, action).invoke();
3657 >    }
3658 >
3659 >    /**
3660 >     * Returns a non-null result from applying the given search
3661 >     * function on each key, or null if none. Upon success,
3662 >     * further element processing is suppressed and the results of
3663 >     * any other parallel invocations of the search function are
3664 >     * ignored.
3665 >     *
3666 >     * @param searchFunction a function returning a non-null
3667 >     * result on success, else null
3668 >     * @return a non-null result from applying the given search
3669 >     * function on each key, or null if none
3670 >     */
3671 >    public <U> U searchKeys(Fun<? super K, ? extends U> searchFunction) {
3672 >        return ForkJoinTasks.searchKeys
3673 >            (this, searchFunction).invoke();
3674 >    }
3675 >
3676 >    /**
3677 >     * Returns the result of accumulating all keys using the given
3678 >     * reducer to combine values, or null if none.
3679 >     *
3680 >     * @param reducer a commutative associative combining function
3681 >     * @return the result of accumulating all keys using the given
3682 >     * reducer to combine values, or null if none
3683 >     */
3684 >    public K reduceKeys(BiFun<? super K, ? super K, ? extends K> reducer) {
3685 >        return ForkJoinTasks.reduceKeys
3686 >            (this, reducer).invoke();
3687 >    }
3688 >
3689 >    /**
3690 >     * Returns the result of accumulating the given transformation
3691 >     * of all keys using the given reducer to combine values, or
3692 >     * null if none.
3693 >     *
3694 >     * @param transformer a function returning the transformation
3695 >     * for an element, or null of there is no transformation (in
3696 >     * which case it is not combined).
3697 >     * @param reducer a commutative associative combining function
3698 >     * @return the result of accumulating the given transformation
3699 >     * of all keys
3700 >     */
3701 >    public <U> U reduceKeys(Fun<? super K, ? extends U> transformer,
3702 >                            BiFun<? super U, ? super U, ? extends U> reducer) {
3703 >        return ForkJoinTasks.reduceKeys
3704 >            (this, transformer, reducer).invoke();
3705 >    }
3706 >
3707 >    /**
3708 >     * Returns the result of accumulating the given transformation
3709 >     * of all keys using the given reducer to combine values, and
3710 >     * the given basis as an identity value.
3711 >     *
3712 >     * @param transformer a function returning the transformation
3713 >     * for an element
3714 >     * @param basis the identity (initial default value) for the reduction
3715 >     * @param reducer a commutative associative combining function
3716 >     * @return  the result of accumulating the given transformation
3717 >     * of all keys
3718 >     */
3719 >    public double reduceKeysToDouble(ObjectToDouble<? super K> transformer,
3720 >                                     double basis,
3721 >                                     DoubleByDoubleToDouble reducer) {
3722 >        return ForkJoinTasks.reduceKeysToDouble
3723 >            (this, transformer, basis, reducer).invoke();
3724 >    }
3725 >
3726 >    /**
3727 >     * Returns the result of accumulating the given transformation
3728 >     * of all keys using the given reducer to combine values, and
3729 >     * the given basis as an identity value.
3730 >     *
3731 >     * @param transformer a function returning the transformation
3732 >     * for an element
3733 >     * @param basis the identity (initial default value) for the reduction
3734 >     * @param reducer a commutative associative combining function
3735 >     * @return the result of accumulating the given transformation
3736 >     * of all keys
3737 >     */
3738 >    public long reduceKeysToLong(ObjectToLong<? super K> transformer,
3739 >                                 long basis,
3740 >                                 LongByLongToLong reducer) {
3741 >        return ForkJoinTasks.reduceKeysToLong
3742 >            (this, transformer, basis, reducer).invoke();
3743 >    }
3744 >
3745 >    /**
3746 >     * Returns the result of accumulating the given transformation
3747 >     * of all keys using the given reducer to combine values, and
3748 >     * the given basis as an identity value.
3749 >     *
3750 >     * @param transformer a function returning the transformation
3751 >     * for an element
3752 >     * @param basis the identity (initial default value) for the reduction
3753 >     * @param reducer a commutative associative combining function
3754 >     * @return the result of accumulating the given transformation
3755 >     * of all keys
3756 >     */
3757 >    public int reduceKeysToInt(ObjectToInt<? super K> transformer,
3758 >                               int basis,
3759 >                               IntByIntToInt reducer) {
3760 >        return ForkJoinTasks.reduceKeysToInt
3761 >            (this, transformer, basis, reducer).invoke();
3762 >    }
3763 >
3764 >    /**
3765 >     * Performs the given action for each value.
3766 >     *
3767 >     * @param action the action
3768 >     */
3769 >    public void forEachValue(Action<V> action) {
3770 >        ForkJoinTasks.forEachValue
3771 >            (this, action).invoke();
3772 >    }
3773 >
3774 >    /**
3775 >     * Performs the given action for each non-null transformation
3776 >     * of each value.
3777 >     *
3778 >     * @param transformer a function returning the transformation
3779 >     * for an element, or null of there is no transformation (in
3780 >     * which case the action is not applied).
3781 >     */
3782 >    public <U> void forEachValue(Fun<? super V, ? extends U> transformer,
3783 >                                 Action<U> action) {
3784 >        ForkJoinTasks.forEachValue
3785 >            (this, transformer, action).invoke();
3786 >    }
3787 >
3788 >    /**
3789 >     * Returns a non-null result from applying the given search
3790 >     * function on each value, or null if none.  Upon success,
3791 >     * further element processing is suppressed and the results of
3792 >     * any other parallel invocations of the search function are
3793 >     * ignored.
3794 >     *
3795 >     * @param searchFunction a function returning a non-null
3796 >     * result on success, else null
3797 >     * @return a non-null result from applying the given search
3798 >     * function on each value, or null if none
3799 >     *
3800 >     */
3801 >    public <U> U searchValues(Fun<? super V, ? extends U> searchFunction) {
3802 >        return ForkJoinTasks.searchValues
3803 >            (this, searchFunction).invoke();
3804 >    }
3805 >
3806 >    /**
3807 >     * Returns the result of accumulating all values using the
3808 >     * given reducer to combine values, or null if none.
3809 >     *
3810 >     * @param reducer a commutative associative combining function
3811 >     * @return  the result of accumulating all values
3812 >     */
3813 >    public V reduceValues(BiFun<? super V, ? super V, ? extends V> reducer) {
3814 >        return ForkJoinTasks.reduceValues
3815 >            (this, reducer).invoke();
3816 >    }
3817 >
3818 >    /**
3819 >     * Returns the result of accumulating the given transformation
3820 >     * of all values 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 values
3829 >     */
3830 >    public <U> U reduceValues(Fun<? super V, ? extends U> transformer,
3831 >                              BiFun<? super U, ? super U, ? extends U> reducer) {
3832 >        return ForkJoinTasks.reduceValues
3833 >            (this, transformer, reducer).invoke();
3834 >    }
3835 >
3836 >    /**
3837 >     * Returns the result of accumulating the given transformation
3838 >     * of all values using the given reducer to combine values,
3839 >     * and the given basis as an identity value.
3840 >     *
3841 >     * @param transformer a function returning the transformation
3842 >     * for an element
3843 >     * @param basis the identity (initial default value) for the reduction
3844 >     * @param reducer a commutative associative combining function
3845 >     * @return the result of accumulating the given transformation
3846 >     * of all values
3847 >     */
3848 >    public double reduceValuesToDouble(ObjectToDouble<? super V> transformer,
3849 >                                       double basis,
3850 >                                       DoubleByDoubleToDouble reducer) {
3851 >        return ForkJoinTasks.reduceValuesToDouble
3852 >            (this, transformer, basis, reducer).invoke();
3853 >    }
3854 >
3855 >    /**
3856 >     * Returns the result of accumulating the given transformation
3857 >     * of all values using the given reducer to combine values,
3858 >     * and the given basis as an identity value.
3859 >     *
3860 >     * @param transformer a function returning the transformation
3861 >     * for an element
3862 >     * @param basis the identity (initial default value) for the reduction
3863 >     * @param reducer a commutative associative combining function
3864 >     * @return the result of accumulating the given transformation
3865 >     * of all values
3866 >     */
3867 >    public long reduceValuesToLong(ObjectToLong<? super V> transformer,
3868 >                                   long basis,
3869 >                                   LongByLongToLong reducer) {
3870 >        return ForkJoinTasks.reduceValuesToLong
3871 >            (this, transformer, basis, reducer).invoke();
3872 >    }
3873 >
3874 >    /**
3875 >     * Returns the result of accumulating the given transformation
3876 >     * of all values using the given reducer to combine values,
3877 >     * and the given basis as an identity value.
3878 >     *
3879 >     * @param transformer a function returning the transformation
3880 >     * for an element
3881 >     * @param basis the identity (initial default value) for the reduction
3882 >     * @param reducer a commutative associative combining function
3883 >     * @return the result of accumulating the given transformation
3884 >     * of all values
3885 >     */
3886 >    public int reduceValuesToInt(ObjectToInt<? super V> transformer,
3887 >                                 int basis,
3888 >                                 IntByIntToInt reducer) {
3889 >        return ForkJoinTasks.reduceValuesToInt
3890 >            (this, transformer, basis, reducer).invoke();
3891 >    }
3892 >
3893 >    /**
3894 >     * Performs the given action for each entry.
3895 >     *
3896 >     * @param action the action
3897 >     */
3898 >    public void forEachEntry(Action<Map.Entry<K,V>> action) {
3899 >        ForkJoinTasks.forEachEntry
3900 >            (this, action).invoke();
3901 >    }
3902 >
3903 >    /**
3904 >     * Performs the given action for each non-null transformation
3905 >     * of each entry.
3906 >     *
3907 >     * @param transformer a function returning the transformation
3908 >     * for an element, or null of there is no transformation (in
3909 >     * which case the action is not applied).
3910 >     * @param action the action
3911 >     */
3912 >    public <U> void forEachEntry(Fun<Map.Entry<K,V>, ? extends U> transformer,
3913 >                                 Action<U> action) {
3914 >        ForkJoinTasks.forEachEntry
3915 >            (this, transformer, action).invoke();
3916 >    }
3917 >
3918 >    /**
3919 >     * Returns a non-null result from applying the given search
3920 >     * function on each entry, or null if none.  Upon success,
3921 >     * further element processing is suppressed and the results of
3922 >     * any other parallel invocations of the search function are
3923 >     * ignored.
3924 >     *
3925 >     * @param searchFunction a function returning a non-null
3926 >     * result on success, else null
3927 >     * @return a non-null result from applying the given search
3928 >     * function on each entry, or null if none
3929 >     */
3930 >    public <U> U searchEntries(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
3931 >        return ForkJoinTasks.searchEntries
3932 >            (this, searchFunction).invoke();
3933 >    }
3934 >
3935 >    /**
3936 >     * Returns the result of accumulating all entries using the
3937 >     * given reducer to combine values, or null if none.
3938 >     *
3939 >     * @param reducer a commutative associative combining function
3940 >     * @return the result of accumulating all entries
3941 >     */
3942 >    public Map.Entry<K,V> reduceEntries(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
3943 >        return ForkJoinTasks.reduceEntries
3944 >            (this, reducer).invoke();
3945 >    }
3946 >
3947 >    /**
3948 >     * Returns the result of accumulating the given transformation
3949 >     * of all entries using the given reducer to combine values,
3950 >     * or null if none.
3951 >     *
3952 >     * @param transformer a function returning the transformation
3953 >     * for an element, or null of there is no transformation (in
3954 >     * which case it is not combined).
3955 >     * @param reducer a commutative associative combining function
3956 >     * @return the result of accumulating the given transformation
3957 >     * of all entries
3958 >     */
3959 >    public <U> U reduceEntries(Fun<Map.Entry<K,V>, ? extends U> transformer,
3960 >                               BiFun<? super U, ? super U, ? extends U> reducer) {
3961 >        return ForkJoinTasks.reduceEntries
3962 >            (this, transformer, reducer).invoke();
3963 >    }
3964 >
3965 >    /**
3966 >     * Returns the result of accumulating the given transformation
3967 >     * of all entries using the given reducer to combine values,
3968 >     * and the given basis as an identity value.
3969 >     *
3970 >     * @param transformer a function returning the transformation
3971 >     * for an element
3972 >     * @param basis the identity (initial default value) for the reduction
3973 >     * @param reducer a commutative associative combining function
3974 >     * @return the result of accumulating the given transformation
3975 >     * of all entries
3976 >     */
3977 >    public double reduceEntriesToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
3978 >                                        double basis,
3979 >                                        DoubleByDoubleToDouble reducer) {
3980 >        return ForkJoinTasks.reduceEntriesToDouble
3981 >            (this, transformer, basis, reducer).invoke();
3982 >    }
3983 >
3984 >    /**
3985 >     * Returns the result of accumulating the given transformation
3986 >     * of all entries using the given reducer to combine values,
3987 >     * and the given basis as an identity value.
3988 >     *
3989 >     * @param transformer a function returning the transformation
3990 >     * for an element
3991 >     * @param basis the identity (initial default value) for the reduction
3992 >     * @param reducer a commutative associative combining function
3993 >     * @return  the result of accumulating the given transformation
3994 >     * of all entries
3995 >     */
3996 >    public long reduceEntriesToLong(ObjectToLong<Map.Entry<K,V>> transformer,
3997 >                                    long basis,
3998 >                                    LongByLongToLong reducer) {
3999 >        return ForkJoinTasks.reduceEntriesToLong
4000 >            (this, transformer, basis, reducer).invoke();
4001 >    }
4002 >
4003 >    /**
4004 >     * Returns the result of accumulating the given transformation
4005 >     * of all entries using the given reducer to combine values,
4006 >     * and the given basis as an identity value.
4007 >     *
4008 >     * @param transformer a function returning the transformation
4009 >     * for an element
4010 >     * @param basis the identity (initial default value) for the reduction
4011 >     * @param reducer a commutative associative combining function
4012 >     * @return the result of accumulating the given transformation
4013 >     * of all entries
4014 >     */
4015 >    public int reduceEntriesToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4016 >                                  int basis,
4017 >                                  IntByIntToInt reducer) {
4018 >        return ForkJoinTasks.reduceEntriesToInt
4019 >            (this, transformer, basis, reducer).invoke();
4020 >    }
4021 >
4022 >    /* ----------------Views -------------- */
4023 >
4024 >    /**
4025 >     * Base class for views.
4026 >     */
4027 >    static abstract class CHMView<K, V> {
4028 >        final ConcurrentHashMapV8<K, V> map;
4029 >        CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
4030  
4031          /**
4032 <         * Performs the given action for each (key, value).
4032 >         * Returns the map backing this view.
4033           *
4034 <         * @param action the action
4034 >         * @return the map backing this view
4035           */
4036 <        public void forEach(BiAction<K,V> action) {
4037 <            fjp.invoke(ForkJoinTasks.forEach
4038 <                       (ConcurrentHashMapV8.this, action));
4036 >        public ConcurrentHashMapV8<K,V> getMap() { return map; }
4037 >
4038 >        public final int size()                 { return map.size(); }
4039 >        public final boolean isEmpty()          { return map.isEmpty(); }
4040 >        public final void clear()               { map.clear(); }
4041 >
4042 >        // implementations below rely on concrete classes supplying these
4043 >        abstract public Iterator<?> iterator();
4044 >        abstract public boolean contains(Object o);
4045 >        abstract public boolean remove(Object o);
4046 >
4047 >        private static final String oomeMsg = "Required array size too large";
4048 >
4049 >        public final Object[] toArray() {
4050 >            long sz = map.mappingCount();
4051 >            if (sz > (long)(MAX_ARRAY_SIZE))
4052 >                throw new OutOfMemoryError(oomeMsg);
4053 >            int n = (int)sz;
4054 >            Object[] r = new Object[n];
4055 >            int i = 0;
4056 >            Iterator<?> it = iterator();
4057 >            while (it.hasNext()) {
4058 >                if (i == n) {
4059 >                    if (n >= MAX_ARRAY_SIZE)
4060 >                        throw new OutOfMemoryError(oomeMsg);
4061 >                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4062 >                        n = MAX_ARRAY_SIZE;
4063 >                    else
4064 >                        n += (n >>> 1) + 1;
4065 >                    r = Arrays.copyOf(r, n);
4066 >                }
4067 >                r[i++] = it.next();
4068 >            }
4069 >            return (i == n) ? r : Arrays.copyOf(r, i);
4070          }
4071  
4072 <        /**
4073 <         * Performs the given action for each non-null transformation
4074 <         * of each (key, value).
4075 <         *
4076 <         * @param transformer a function returning the transformation
4077 <         * for an element, or null of there is no transformation (in
4078 <         * which case the action is not applied).
4079 <         * @param action the action
4080 <         */
4081 <        public <U> void forEach(BiFun<? super K, ? super V, ? extends U> transformer,
4082 <                                Action<U> action) {
4083 <            fjp.invoke(ForkJoinTasks.forEach
4084 <                       (ConcurrentHashMapV8.this, transformer, action));
4072 >        @SuppressWarnings("unchecked") public final <T> T[] toArray(T[] a) {
4073 >            long sz = map.mappingCount();
4074 >            if (sz > (long)(MAX_ARRAY_SIZE))
4075 >                throw new OutOfMemoryError(oomeMsg);
4076 >            int m = (int)sz;
4077 >            T[] r = (a.length >= m) ? a :
4078 >                (T[])java.lang.reflect.Array
4079 >                .newInstance(a.getClass().getComponentType(), m);
4080 >            int n = r.length;
4081 >            int i = 0;
4082 >            Iterator<?> it = iterator();
4083 >            while (it.hasNext()) {
4084 >                if (i == n) {
4085 >                    if (n >= MAX_ARRAY_SIZE)
4086 >                        throw new OutOfMemoryError(oomeMsg);
4087 >                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4088 >                        n = MAX_ARRAY_SIZE;
4089 >                    else
4090 >                        n += (n >>> 1) + 1;
4091 >                    r = Arrays.copyOf(r, n);
4092 >                }
4093 >                r[i++] = (T)it.next();
4094 >            }
4095 >            if (a == r && i < n) {
4096 >                r[i] = null; // null-terminate
4097 >                return r;
4098 >            }
4099 >            return (i == n) ? r : Arrays.copyOf(r, i);
4100          }
4101  
4102 <        /**
4103 <         * Returns a non-null result from applying the given search
4104 <         * function on each (key, value), or null if none.  Further
4105 <         * element processing is suppressed upon success. However,
4106 <         * this method does not return until other in-progress
3662 <         * parallel invocations of the search function also complete.
3663 <         *
3664 <         * @param searchFunction a function returning a non-null
3665 <         * result on success, else null
3666 <         * @return a non-null result from applying the given search
3667 <         * function on each (key, value), or null if none
3668 <         */
3669 <        public <U> U search(BiFun<? super K, ? super V, ? extends U> searchFunction) {
3670 <            return fjp.invoke(ForkJoinTasks.search
3671 <                              (ConcurrentHashMapV8.this, searchFunction));
4102 >        public final int hashCode() {
4103 >            int h = 0;
4104 >            for (Iterator<?> it = iterator(); it.hasNext();)
4105 >                h += it.next().hashCode();
4106 >            return h;
4107          }
4108  
4109 <        /**
4110 <         * Returns the result of accumulating the given transformation
4111 <         * of all (key, value) pairs using the given reducer to
4112 <         * combine values, or null if none.
4113 <         *
4114 <         * @param transformer a function returning the transformation
4115 <         * for an element, or null of there is no transformation (in
4116 <         * which case it is not combined).
4117 <         * @param reducer a commutative associative combining function
4118 <         * @return the result of accumulating the given transformation
4119 <         * of all (key, value) pairs
4120 <         */
4121 <        public <U> U reduce(BiFun<? super K, ? super V, ? extends U> transformer,
4122 <                            BiFun<? super U, ? super U, ? extends U> reducer) {
3688 <            return fjp.invoke(ForkJoinTasks.reduce
3689 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4109 >        public final String toString() {
4110 >            StringBuilder sb = new StringBuilder();
4111 >            sb.append('[');
4112 >            Iterator<?> it = iterator();
4113 >            if (it.hasNext()) {
4114 >                for (;;) {
4115 >                    Object e = it.next();
4116 >                    sb.append(e == this ? "(this Collection)" : e);
4117 >                    if (!it.hasNext())
4118 >                        break;
4119 >                    sb.append(',').append(' ');
4120 >                }
4121 >            }
4122 >            return sb.append(']').toString();
4123          }
4124  
4125 <        /**
4126 <         * Returns the result of accumulating the given transformation
4127 <         * of all (key, value) pairs using the given reducer to
4128 <         * combine values, and the given basis as an identity value.
4129 <         *
4130 <         * @param transformer a function returning the transformation
4131 <         * for an element
4132 <         * @param basis the identity (initial default value) for the reduction
4133 <         * @param reducer a commutative associative combining function
4134 <         * @return the result of accumulating the given transformation
4135 <         * of all (key, value) pairs
4136 <         */
4137 <        public double reduceToDouble(ObjectByObjectToDouble<? super K, ? super V> transformer,
4138 <                                     double basis,
4139 <                                     DoubleByDoubleToDouble reducer) {
4140 <            return fjp.invoke(ForkJoinTasks.reduceToDouble
4141 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4125 >        public final boolean containsAll(Collection<?> c) {
4126 >            if (c != this) {
4127 >                for (Iterator<?> it = c.iterator(); it.hasNext();) {
4128 >                    Object e = it.next();
4129 >                    if (e == null || !contains(e))
4130 >                        return false;
4131 >                }
4132 >            }
4133 >            return true;
4134 >        }
4135 >
4136 >        public final boolean removeAll(Collection<?> c) {
4137 >            boolean modified = false;
4138 >            for (Iterator<?> it = iterator(); it.hasNext();) {
4139 >                if (c.contains(it.next())) {
4140 >                    it.remove();
4141 >                    modified = true;
4142 >                }
4143 >            }
4144 >            return modified;
4145 >        }
4146 >
4147 >        public final boolean retainAll(Collection<?> c) {
4148 >            boolean modified = false;
4149 >            for (Iterator<?> it = iterator(); it.hasNext();) {
4150 >                if (!c.contains(it.next())) {
4151 >                    it.remove();
4152 >                    modified = true;
4153 >                }
4154 >            }
4155 >            return modified;
4156 >        }
4157 >
4158 >    }
4159 >
4160 >    /**
4161 >     * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in
4162 >     * which additions may optionally be enabled by mapping to a
4163 >     * common value.  This class cannot be directly instantiated. See
4164 >     * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
4165 >     * {@link #newKeySet(int)}.
4166 >     */
4167 >    public static class KeySetView<K,V> extends CHMView<K,V> implements Set<K>, java.io.Serializable {
4168 >        private static final long serialVersionUID = 7249069246763182397L;
4169 >        private final V value;
4170 >        KeySetView(ConcurrentHashMapV8<K, V> map, V value) {  // non-public
4171 >            super(map);
4172 >            this.value = value;
4173          }
4174  
4175          /**
4176 <         * Returns the result of accumulating the given transformation
4177 <         * of all (key, value) pairs using the given reducer to
3714 <         * combine values, and the given basis as an identity value.
4176 >         * Returns the default mapped value for additions,
4177 >         * or {@code null} if additions are not supported.
4178           *
4179 <         * @param transformer a function returning the transformation
4180 <         * for an element
3718 <         * @param basis the identity (initial default value) for the reduction
3719 <         * @param reducer a commutative associative combining function
3720 <         * @return the result of accumulating the given transformation
3721 <         * of all (key, value) pairs using the given reducer to
3722 <         * combine values, and the given basis as an identity value.
4179 >         * @return the default mapped value for additions, or {@code null}
4180 >         * if not supported.
4181           */
4182 <        public long reduceToLong(ObjectByObjectToLong<? super K, ? super V> transformer,
4183 <                                 long basis,
4184 <                                 LongByLongToLong reducer) {
4185 <            return fjp.invoke(ForkJoinTasks.reduceToLong
4186 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4187 <        }
4182 >        public V getMappedValue() { return value; }
4183 >
4184 >        // implement Set API
4185 >
4186 >        public boolean contains(Object o) { return map.containsKey(o); }
4187 >        public boolean remove(Object o)   { return map.remove(o) != null; }
4188  
4189          /**
4190 <         * Returns the result of accumulating the given transformation
4191 <         * of all (key, value) pairs using the given reducer to
4192 <         * combine values, and the given basis as an identity value.
4190 >         * Returns a "weakly consistent" iterator that will never
4191 >         * throw {@link ConcurrentModificationException}, and
4192 >         * guarantees to traverse elements as they existed upon
4193 >         * construction of the iterator, and may (but is not
4194 >         * guaranteed to) reflect any modifications subsequent to
4195 >         * construction.
4196           *
4197 <         * @param transformer a function returning the transformation
3737 <         * for an element
3738 <         * @param basis the identity (initial default value) for the reduction
3739 <         * @param reducer a commutative associative combining function
3740 <         * @return the result of accumulating the given transformation
3741 <         * of all (key, value) pairs
4197 >         * @return an iterator over the keys of this map
4198           */
4199 <        public int reduceToInt(ObjectByObjectToInt<? super K, ? super V> transformer,
4200 <                               int basis,
4201 <                               IntByIntToInt reducer) {
4202 <            return fjp.invoke(ForkJoinTasks.reduceToInt
4203 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4199 >        public Iterator<K> iterator()     { return new KeyIterator<K,V>(map); }
4200 >        public boolean add(K e) {
4201 >            V v;
4202 >            if ((v = value) == null)
4203 >                throw new UnsupportedOperationException();
4204 >            if (e == null)
4205 >                throw new NullPointerException();
4206 >            return map.internalPutIfAbsent(e, v) == null;
4207 >        }
4208 >        public boolean addAll(Collection<? extends K> c) {
4209 >            boolean added = false;
4210 >            V v;
4211 >            if ((v = value) == null)
4212 >                throw new UnsupportedOperationException();
4213 >            for (K e : c) {
4214 >                if (e == null)
4215 >                    throw new NullPointerException();
4216 >                if (map.internalPutIfAbsent(e, v) == null)
4217 >                    added = true;
4218 >            }
4219 >            return added;
4220 >        }
4221 >        public boolean equals(Object o) {
4222 >            Set<?> c;
4223 >            return ((o instanceof Set) &&
4224 >                    ((c = (Set<?>)o) == this ||
4225 >                     (containsAll(c) && c.containsAll(this))));
4226          }
4227  
4228          /**
# Line 3752 | Line 4230 | public class ConcurrentHashMapV8<K, V>
4230           *
4231           * @param action the action
4232           */
4233 <        public void forEachKey(Action<K> action) {
4234 <            fjp.invoke(ForkJoinTasks.forEachKey
4235 <                       (ConcurrentHashMapV8.this, action));
4233 >        public void forEach(Action<K> action) {
4234 >            ForkJoinTasks.forEachKey
4235 >                (map, action).invoke();
4236          }
4237  
4238          /**
# Line 3766 | Line 4244 | public class ConcurrentHashMapV8<K, V>
4244           * which case the action is not applied).
4245           * @param action the action
4246           */
4247 <        public <U> void forEachKey(Fun<? super K, ? extends U> transformer,
4248 <                                   Action<U> action) {
4249 <            fjp.invoke(ForkJoinTasks.forEachKey
4250 <                       (ConcurrentHashMapV8.this, transformer, action));
4247 >        public <U> void forEach(Fun<? super K, ? extends U> transformer,
4248 >                                Action<U> action) {
4249 >            ForkJoinTasks.forEachKey
4250 >                (map, transformer, action).invoke();
4251          }
4252  
4253          /**
4254           * Returns a non-null result from applying the given search
4255 <         * function on each key, or null if none.  Further element
4256 <         * processing is suppressed upon success. However, this method
4257 <         * does not return until other in-progress parallel
4258 <         * invocations of the search function also complete.
4255 >         * function on each key, or null if none. Upon success,
4256 >         * further element processing is suppressed and the results of
4257 >         * any other parallel invocations of the search function are
4258 >         * ignored.
4259           *
4260           * @param searchFunction a function returning a non-null
4261           * result on success, else null
4262           * @return a non-null result from applying the given search
4263           * function on each key, or null if none
4264           */
4265 <        public <U> U searchKeys(Fun<? super K, ? extends U> searchFunction) {
4266 <            return fjp.invoke(ForkJoinTasks.searchKeys
4267 <                              (ConcurrentHashMapV8.this, searchFunction));
4265 >        public <U> U search(Fun<? super K, ? extends U> searchFunction) {
4266 >            return ForkJoinTasks.searchKeys
4267 >                (map, searchFunction).invoke();
4268          }
4269  
4270          /**
# Line 3797 | Line 4275 | public class ConcurrentHashMapV8<K, V>
4275           * @return the result of accumulating all keys using the given
4276           * reducer to combine values, or null if none
4277           */
4278 <        public K reduceKeys(BiFun<? super K, ? super K, ? extends K> reducer) {
4279 <            return fjp.invoke(ForkJoinTasks.reduceKeys
4280 <                              (ConcurrentHashMapV8.this, reducer));
3803 <        }
3804 <
3805 <        /**
3806 <         * Returns the result of accumulating the given transformation
3807 <         * of all keys using the given reducer to combine values, or
3808 <         * null if none.
3809 <         *
3810 <         * @param transformer a function returning the transformation
3811 <         * for an element, or null of there is no transformation (in
3812 <         * which case it is not combined).
3813 <         * @param reducer a commutative associative combining function
3814 <         * @return the result of accumulating the given transformation
3815 <         * of all keys
3816 <         */
3817 <        public <U> U reduceKeys(Fun<? super K, ? extends U> transformer,
3818 <                                BiFun<? super U, ? super U, ? extends U> reducer) {
3819 <            return fjp.invoke(ForkJoinTasks.reduceKeys
3820 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4278 >        public K reduce(BiFun<? super K, ? super K, ? extends K> reducer) {
4279 >            return ForkJoinTasks.reduceKeys
4280 >                (map, reducer).invoke();
4281          }
4282  
4283          /**
# Line 3832 | Line 4292 | public class ConcurrentHashMapV8<K, V>
4292           * @return  the result of accumulating the given transformation
4293           * of all keys
4294           */
4295 <        public double reduceKeysToDouble(ObjectToDouble<? super K> transformer,
4296 <                                         double basis,
4297 <                                         DoubleByDoubleToDouble reducer) {
4298 <            return fjp.invoke(ForkJoinTasks.reduceKeysToDouble
4299 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4295 >        public double reduceToDouble(ObjectToDouble<? super K> transformer,
4296 >                                     double basis,
4297 >                                     DoubleByDoubleToDouble reducer) {
4298 >            return ForkJoinTasks.reduceKeysToDouble
4299 >                (map, transformer, basis, reducer).invoke();
4300          }
4301  
4302 +
4303          /**
4304           * Returns the result of accumulating the given transformation
4305           * of all keys using the given reducer to combine values, and
# Line 3851 | Line 4312 | public class ConcurrentHashMapV8<K, V>
4312           * @return the result of accumulating the given transformation
4313           * of all keys
4314           */
4315 <        public long reduceKeysToLong(ObjectToLong<? super K> transformer,
4316 <                                     long basis,
4317 <                                     LongByLongToLong reducer) {
4318 <            return fjp.invoke(ForkJoinTasks.reduceKeysToLong
4319 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4315 >        public long reduceToLong(ObjectToLong<? super K> transformer,
4316 >                                 long basis,
4317 >                                 LongByLongToLong reducer) {
4318 >            return ForkJoinTasks.reduceKeysToLong
4319 >                (map, transformer, basis, reducer).invoke();
4320          }
4321  
4322          /**
# Line 3870 | Line 4331 | public class ConcurrentHashMapV8<K, V>
4331           * @return the result of accumulating the given transformation
4332           * of all keys
4333           */
4334 <        public int reduceKeysToInt(ObjectToInt<? super K> transformer,
4335 <                                   int basis,
4336 <                                   IntByIntToInt reducer) {
4337 <            return fjp.invoke(ForkJoinTasks.reduceKeysToInt
4338 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4334 >        public int reduceToInt(ObjectToInt<? super K> transformer,
4335 >                               int basis,
4336 >                               IntByIntToInt reducer) {
4337 >            return ForkJoinTasks.reduceKeysToInt
4338 >                (map, transformer, basis, reducer).invoke();
4339 >        }
4340 >
4341 >    }
4342 >
4343 >    /**
4344 >     * A view of a ConcurrentHashMapV8 as a {@link Collection} of
4345 >     * values, in which additions are disabled. This class cannot be
4346 >     * directly instantiated. See {@link #values},
4347 >     *
4348 >     * <p>The view's {@code iterator} is a "weakly consistent" iterator
4349 >     * that will never throw {@link ConcurrentModificationException},
4350 >     * and guarantees to traverse elements as they existed upon
4351 >     * construction of the iterator, and may (but is not guaranteed to)
4352 >     * reflect any modifications subsequent to construction.
4353 >     */
4354 >    public static final class ValuesView<K,V> extends CHMView<K,V>
4355 >        implements Collection<V> {
4356 >        ValuesView(ConcurrentHashMapV8<K, V> map)   { super(map); }
4357 >        public final boolean contains(Object o) { return map.containsValue(o); }
4358 >        public final boolean remove(Object o) {
4359 >            if (o != null) {
4360 >                Iterator<V> it = new ValueIterator<K,V>(map);
4361 >                while (it.hasNext()) {
4362 >                    if (o.equals(it.next())) {
4363 >                        it.remove();
4364 >                        return true;
4365 >                    }
4366 >                }
4367 >            }
4368 >            return false;
4369 >        }
4370 >
4371 >        /**
4372 >         * Returns a "weakly consistent" iterator that will never
4373 >         * throw {@link ConcurrentModificationException}, and
4374 >         * guarantees to traverse elements as they existed upon
4375 >         * construction of the iterator, and may (but is not
4376 >         * guaranteed to) reflect any modifications subsequent to
4377 >         * construction.
4378 >         *
4379 >         * @return an iterator over the values of this map
4380 >         */
4381 >        public final Iterator<V> iterator() {
4382 >            return new ValueIterator<K,V>(map);
4383 >        }
4384 >        public final boolean add(V e) {
4385 >            throw new UnsupportedOperationException();
4386 >        }
4387 >        public final boolean addAll(Collection<? extends V> c) {
4388 >            throw new UnsupportedOperationException();
4389          }
4390  
4391          /**
# Line 3882 | Line 4393 | public class ConcurrentHashMapV8<K, V>
4393           *
4394           * @param action the action
4395           */
4396 <        public void forEachValue(Action<V> action) {
4397 <            fjp.invoke(ForkJoinTasks.forEachValue
4398 <                       (ConcurrentHashMapV8.this, action));
4396 >        public void forEach(Action<V> action) {
4397 >            ForkJoinTasks.forEachValue
4398 >                (map, action).invoke();
4399          }
4400  
4401          /**
# Line 3895 | Line 4406 | public class ConcurrentHashMapV8<K, V>
4406           * for an element, or null of there is no transformation (in
4407           * which case the action is not applied).
4408           */
4409 <        public <U> void forEachValue(Fun<? super V, ? extends U> transformer,
4409 >        public <U> void forEach(Fun<? super V, ? extends U> transformer,
4410                                       Action<U> action) {
4411 <            fjp.invoke(ForkJoinTasks.forEachValue
4412 <                       (ConcurrentHashMapV8.this, transformer, action));
4411 >            ForkJoinTasks.forEachValue
4412 >                (map, transformer, action).invoke();
4413          }
4414  
4415          /**
4416           * Returns a non-null result from applying the given search
4417 <         * function on each value, or null if none.  Further element
4418 <         * processing is suppressed upon success. However, this method
4419 <         * does not return until other in-progress parallel
4420 <         * invocations of the search function also complete.
4417 >         * function on each value, or null if none.  Upon success,
4418 >         * further element processing is suppressed and the results of
4419 >         * any other parallel invocations of the search function are
4420 >         * ignored.
4421           *
4422           * @param searchFunction a function returning a non-null
4423           * result on success, else null
# Line 3914 | Line 4425 | public class ConcurrentHashMapV8<K, V>
4425           * function on each value, or null if none
4426           *
4427           */
4428 <        public <U> U searchValues(Fun<? super V, ? extends U> searchFunction) {
4429 <            return fjp.invoke(ForkJoinTasks.searchValues
4430 <                              (ConcurrentHashMapV8.this, searchFunction));
4428 >        public <U> U search(Fun<? super V, ? extends U> searchFunction) {
4429 >            return ForkJoinTasks.searchValues
4430 >                (map, searchFunction).invoke();
4431          }
4432  
4433          /**
# Line 3926 | Line 4437 | public class ConcurrentHashMapV8<K, V>
4437           * @param reducer a commutative associative combining function
4438           * @return  the result of accumulating all values
4439           */
4440 <        public V reduceValues(BiFun<? super V, ? super V, ? extends V> reducer) {
4441 <            return fjp.invoke(ForkJoinTasks.reduceValues
4442 <                              (ConcurrentHashMapV8.this, reducer));
4440 >        public V reduce(BiFun<? super V, ? super V, ? extends V> reducer) {
4441 >            return ForkJoinTasks.reduceValues
4442 >                (map, reducer).invoke();
4443          }
4444  
4445          /**
# Line 3943 | Line 4454 | public class ConcurrentHashMapV8<K, V>
4454           * @return the result of accumulating the given transformation
4455           * of all values
4456           */
4457 <        public <U> U reduceValues(Fun<? super V, ? extends U> transformer,
4458 <                                  BiFun<? super U, ? super U, ? extends U> reducer) {
4459 <            return fjp.invoke(ForkJoinTasks.reduceValues
4460 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4457 >        public <U> U reduce(Fun<? super V, ? extends U> transformer,
4458 >                            BiFun<? super U, ? super U, ? extends U> reducer) {
4459 >            return ForkJoinTasks.reduceValues
4460 >                (map, transformer, reducer).invoke();
4461          }
4462  
4463          /**
# Line 3961 | Line 4472 | public class ConcurrentHashMapV8<K, V>
4472           * @return the result of accumulating the given transformation
4473           * of all values
4474           */
4475 <        public double reduceValuesToDouble(ObjectToDouble<? super V> transformer,
4476 <                                           double basis,
4477 <                                           DoubleByDoubleToDouble reducer) {
4478 <            return fjp.invoke(ForkJoinTasks.reduceValuesToDouble
4479 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4475 >        public double reduceToDouble(ObjectToDouble<? super V> transformer,
4476 >                                     double basis,
4477 >                                     DoubleByDoubleToDouble reducer) {
4478 >            return ForkJoinTasks.reduceValuesToDouble
4479 >                (map, transformer, basis, reducer).invoke();
4480          }
4481  
4482          /**
# Line 3980 | Line 4491 | public class ConcurrentHashMapV8<K, V>
4491           * @return the result of accumulating the given transformation
4492           * of all values
4493           */
4494 <        public long reduceValuesToLong(ObjectToLong<? super V> transformer,
4495 <                                       long basis,
4496 <                                       LongByLongToLong reducer) {
4497 <            return fjp.invoke(ForkJoinTasks.reduceValuesToLong
4498 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4494 >        public long reduceToLong(ObjectToLong<? super V> transformer,
4495 >                                 long basis,
4496 >                                 LongByLongToLong reducer) {
4497 >            return ForkJoinTasks.reduceValuesToLong
4498 >                (map, transformer, basis, reducer).invoke();
4499          }
4500  
4501          /**
# Line 3999 | Line 4510 | public class ConcurrentHashMapV8<K, V>
4510           * @return the result of accumulating the given transformation
4511           * of all values
4512           */
4513 <        public int reduceValuesToInt(ObjectToInt<? super V> transformer,
4514 <                                     int basis,
4515 <                                     IntByIntToInt reducer) {
4516 <            return fjp.invoke(ForkJoinTasks.reduceValuesToInt
4517 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4513 >        public int reduceToInt(ObjectToInt<? super V> transformer,
4514 >                               int basis,
4515 >                               IntByIntToInt reducer) {
4516 >            return ForkJoinTasks.reduceValuesToInt
4517 >                (map, transformer, basis, reducer).invoke();
4518 >        }
4519 >
4520 >    }
4521 >
4522 >    /**
4523 >     * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value)
4524 >     * entries.  This class cannot be directly instantiated. See
4525 >     * {@link #entrySet}.
4526 >     */
4527 >    public static final class EntrySetView<K,V> extends CHMView<K,V>
4528 >        implements Set<Map.Entry<K,V>> {
4529 >        EntrySetView(ConcurrentHashMapV8<K, V> map) { super(map); }
4530 >        public final boolean contains(Object o) {
4531 >            Object k, v, r; Map.Entry<?,?> e;
4532 >            return ((o instanceof Map.Entry) &&
4533 >                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
4534 >                    (r = map.get(k)) != null &&
4535 >                    (v = e.getValue()) != null &&
4536 >                    (v == r || v.equals(r)));
4537 >        }
4538 >        public final boolean remove(Object o) {
4539 >            Object k, v; Map.Entry<?,?> e;
4540 >            return ((o instanceof Map.Entry) &&
4541 >                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
4542 >                    (v = e.getValue()) != null &&
4543 >                    map.remove(k, v));
4544 >        }
4545 >
4546 >        /**
4547 >         * Returns a "weakly consistent" iterator that will never
4548 >         * throw {@link ConcurrentModificationException}, and
4549 >         * guarantees to traverse elements as they existed upon
4550 >         * construction of the iterator, and may (but is not
4551 >         * guaranteed to) reflect any modifications subsequent to
4552 >         * construction.
4553 >         *
4554 >         * @return an iterator over the entries of this map
4555 >         */
4556 >        public final Iterator<Map.Entry<K,V>> iterator() {
4557 >            return new EntryIterator<K,V>(map);
4558 >        }
4559 >
4560 >        public final boolean add(Entry<K,V> e) {
4561 >            K key = e.getKey();
4562 >            V value = e.getValue();
4563 >            if (key == null || value == null)
4564 >                throw new NullPointerException();
4565 >            return map.internalPut(key, value) == null;
4566 >        }
4567 >        public final boolean addAll(Collection<? extends Entry<K,V>> c) {
4568 >            boolean added = false;
4569 >            for (Entry<K,V> e : c) {
4570 >                if (add(e))
4571 >                    added = true;
4572 >            }
4573 >            return added;
4574 >        }
4575 >        public boolean equals(Object o) {
4576 >            Set<?> c;
4577 >            return ((o instanceof Set) &&
4578 >                    ((c = (Set<?>)o) == this ||
4579 >                     (containsAll(c) && c.containsAll(this))));
4580          }
4581  
4582          /**
# Line 4011 | Line 4584 | public class ConcurrentHashMapV8<K, V>
4584           *
4585           * @param action the action
4586           */
4587 <        public void forEachEntry(Action<Map.Entry<K,V>> action) {
4588 <            fjp.invoke(ForkJoinTasks.forEachEntry
4589 <                       (ConcurrentHashMapV8.this, action));
4587 >        public void forEach(Action<Map.Entry<K,V>> action) {
4588 >            ForkJoinTasks.forEachEntry
4589 >                (map, action).invoke();
4590          }
4591  
4592          /**
# Line 4025 | Line 4598 | public class ConcurrentHashMapV8<K, V>
4598           * which case the action is not applied).
4599           * @param action the action
4600           */
4601 <        public <U> void forEachEntry(Fun<Map.Entry<K,V>, ? extends U> transformer,
4602 <                                     Action<U> action) {
4603 <            fjp.invoke(ForkJoinTasks.forEachEntry
4604 <                       (ConcurrentHashMapV8.this, transformer, action));
4601 >        public <U> void forEach(Fun<Map.Entry<K,V>, ? extends U> transformer,
4602 >                                Action<U> action) {
4603 >            ForkJoinTasks.forEachEntry
4604 >                (map, transformer, action).invoke();
4605          }
4606  
4607          /**
4608           * Returns a non-null result from applying the given search
4609 <         * function on each entry, or null if none.  Further element
4610 <         * processing is suppressed upon success. However, this method
4611 <         * does not return until other in-progress parallel
4612 <         * invocations of the search function also complete.
4609 >         * function on each entry, or null if none.  Upon success,
4610 >         * further element processing is suppressed and the results of
4611 >         * any other parallel invocations of the search function are
4612 >         * ignored.
4613           *
4614           * @param searchFunction a function returning a non-null
4615           * result on success, else null
4616           * @return a non-null result from applying the given search
4617           * function on each entry, or null if none
4618           */
4619 <        public <U> U searchEntries(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4620 <            return fjp.invoke(ForkJoinTasks.searchEntries
4621 <                              (ConcurrentHashMapV8.this, searchFunction));
4619 >        public <U> U search(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4620 >            return ForkJoinTasks.searchEntries
4621 >                (map, searchFunction).invoke();
4622          }
4623  
4624          /**
# Line 4055 | Line 4628 | public class ConcurrentHashMapV8<K, V>
4628           * @param reducer a commutative associative combining function
4629           * @return the result of accumulating all entries
4630           */
4631 <        public Map.Entry<K,V> reduceEntries(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4632 <            return fjp.invoke(ForkJoinTasks.reduceEntries
4633 <                              (ConcurrentHashMapV8.this, reducer));
4631 >        public Map.Entry<K,V> reduce(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4632 >            return ForkJoinTasks.reduceEntries
4633 >                (map, reducer).invoke();
4634          }
4635  
4636          /**
# Line 4072 | Line 4645 | public class ConcurrentHashMapV8<K, V>
4645           * @return the result of accumulating the given transformation
4646           * of all entries
4647           */
4648 <        public <U> U reduceEntries(Fun<Map.Entry<K,V>, ? extends U> transformer,
4649 <                                   BiFun<? super U, ? super U, ? extends U> reducer) {
4650 <            return fjp.invoke(ForkJoinTasks.reduceEntries
4651 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4648 >        public <U> U reduce(Fun<Map.Entry<K,V>, ? extends U> transformer,
4649 >                            BiFun<? super U, ? super U, ? extends U> reducer) {
4650 >            return ForkJoinTasks.reduceEntries
4651 >                (map, transformer, reducer).invoke();
4652          }
4653  
4654          /**
# Line 4090 | Line 4663 | public class ConcurrentHashMapV8<K, V>
4663           * @return the result of accumulating the given transformation
4664           * of all entries
4665           */
4666 <        public double reduceEntriesToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
4667 <                                            double basis,
4668 <                                            DoubleByDoubleToDouble reducer) {
4669 <            return fjp.invoke(ForkJoinTasks.reduceEntriesToDouble
4670 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4666 >        public double reduceToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
4667 >                                     double basis,
4668 >                                     DoubleByDoubleToDouble reducer) {
4669 >            return ForkJoinTasks.reduceEntriesToDouble
4670 >                (map, transformer, basis, reducer).invoke();
4671          }
4672  
4673          /**
# Line 4109 | Line 4682 | public class ConcurrentHashMapV8<K, V>
4682           * @return  the result of accumulating the given transformation
4683           * of all entries
4684           */
4685 <        public long reduceEntriesToLong(ObjectToLong<Map.Entry<K,V>> transformer,
4686 <                                        long basis,
4687 <                                        LongByLongToLong reducer) {
4688 <            return fjp.invoke(ForkJoinTasks.reduceEntriesToLong
4689 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4685 >        public long reduceToLong(ObjectToLong<Map.Entry<K,V>> transformer,
4686 >                                 long basis,
4687 >                                 LongByLongToLong reducer) {
4688 >            return ForkJoinTasks.reduceEntriesToLong
4689 >                (map, transformer, basis, reducer).invoke();
4690          }
4691  
4692          /**
# Line 4128 | Line 4701 | public class ConcurrentHashMapV8<K, V>
4701           * @return the result of accumulating the given transformation
4702           * of all entries
4703           */
4704 <        public int reduceEntriesToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4705 <                                      int basis,
4706 <                                      IntByIntToInt reducer) {
4707 <            return fjp.invoke(ForkJoinTasks.reduceEntriesToInt
4708 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4704 >        public int reduceToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4705 >                               int basis,
4706 >                               IntByIntToInt reducer) {
4707 >            return ForkJoinTasks.reduceEntriesToInt
4708 >                (map, transformer, basis, reducer).invoke();
4709          }
4710 +
4711      }
4712  
4713      // ---------------------------------------------------------------------
4714  
4715      /**
4716       * Predefined tasks for performing bulk parallel operations on
4717 <     * ConcurrentHashMaps. These tasks follow the forms and rules used
4718 <     * in class {@link Parallel}. Each method has the same name, but
4719 <     * returns a task rather than invoking it. These methods may be
4720 <     * useful in custom applications such as submitting a task without
4721 <     * waiting for completion, or combining with other tasks.
4717 >     * ConcurrentHashMapV8s. These tasks follow the forms and rules used
4718 >     * for bulk operations. Each method has the same name, but returns
4719 >     * a task rather than invoking it. These methods may be useful in
4720 >     * custom applications such as submitting a task without waiting
4721 >     * for completion, using a custom pool, or combining with other
4722 >     * tasks.
4723       */
4724      public static class ForkJoinTasks {
4725          private ForkJoinTasks() {}
# Line 4161 | Line 4736 | public class ConcurrentHashMapV8<K, V>
4736              (ConcurrentHashMapV8<K,V> map,
4737               BiAction<K,V> action) {
4738              if (action == null) throw new NullPointerException();
4739 <            return new ForEachMappingTask<K,V>(map, action);
4739 >            return new ForEachMappingTask<K,V>(map, null, -1, action);
4740          }
4741  
4742          /**
# Line 4170 | Line 4745 | public class ConcurrentHashMapV8<K, V>
4745           *
4746           * @param map the map
4747           * @param transformer a function returning the transformation
4748 <         * for an element, or null of there is no transformation (in
4749 <         * which case the action is not applied).
4748 >         * for an element, or null if there is no transformation (in
4749 >         * which case the action is not applied)
4750           * @param action the action
4751           * @return the task
4752           */
# Line 4182 | Line 4757 | public class ConcurrentHashMapV8<K, V>
4757              if (transformer == null || action == null)
4758                  throw new NullPointerException();
4759              return new ForEachTransformedMappingTask<K,V,U>
4760 <                (map, transformer, action);
4760 >                (map, null, -1, transformer, action);
4761          }
4762  
4763          /**
4764 <         * Returns a task that when invoked, returns a non-null
4765 <         * result from applying the given search function on each
4766 <         * (key, value), or null if none.  Further element processing
4767 <         * is suppressed upon success. However, this method does not
4768 <         * return until other in-progress parallel invocations of the
4194 <         * search function also complete.
4764 >         * Returns a task that when invoked, returns a non-null result
4765 >         * from applying the given search function on each (key,
4766 >         * value), or null if none. Upon success, further element
4767 >         * processing is suppressed and the results of any other
4768 >         * parallel invocations of the search function are ignored.
4769           *
4770           * @param map the map
4771           * @param searchFunction a function returning a non-null
# Line 4203 | Line 4777 | public class ConcurrentHashMapV8<K, V>
4777               BiFun<? super K, ? super V, ? extends U> searchFunction) {
4778              if (searchFunction == null) throw new NullPointerException();
4779              return new SearchMappingsTask<K,V,U>
4780 <                (map, searchFunction,
4780 >                (map, null, -1, searchFunction,
4781                   new AtomicReference<U>());
4782          }
4783  
# Line 4214 | Line 4788 | public class ConcurrentHashMapV8<K, V>
4788           *
4789           * @param map the map
4790           * @param transformer a function returning the transformation
4791 <         * for an element, or null of there is no transformation (in
4791 >         * for an element, or null if there is no transformation (in
4792           * which case it is not combined).
4793           * @param reducer a commutative associative combining function
4794           * @return the task
# Line 4226 | Line 4800 | public class ConcurrentHashMapV8<K, V>
4800              if (transformer == null || reducer == null)
4801                  throw new NullPointerException();
4802              return new MapReduceMappingsTask<K,V,U>
4803 <                (map, transformer, reducer);
4803 >                (map, null, -1, null, transformer, reducer);
4804          }
4805  
4806          /**
# Line 4250 | Line 4824 | public class ConcurrentHashMapV8<K, V>
4824              if (transformer == null || reducer == null)
4825                  throw new NullPointerException();
4826              return new MapReduceMappingsToDoubleTask<K,V>
4827 <                (map, transformer, basis, reducer);
4827 >                (map, null, -1, null, transformer, basis, reducer);
4828          }
4829  
4830          /**
# Line 4274 | Line 4848 | public class ConcurrentHashMapV8<K, V>
4848              if (transformer == null || reducer == null)
4849                  throw new NullPointerException();
4850              return new MapReduceMappingsToLongTask<K,V>
4851 <                (map, transformer, basis, reducer);
4851 >                (map, null, -1, null, transformer, basis, reducer);
4852          }
4853  
4854          /**
# Line 4297 | Line 4871 | public class ConcurrentHashMapV8<K, V>
4871              if (transformer == null || reducer == null)
4872                  throw new NullPointerException();
4873              return new MapReduceMappingsToIntTask<K,V>
4874 <                (map, transformer, basis, reducer);
4874 >                (map, null, -1, null, transformer, basis, reducer);
4875          }
4876  
4877          /**
# Line 4312 | Line 4886 | public class ConcurrentHashMapV8<K, V>
4886              (ConcurrentHashMapV8<K,V> map,
4887               Action<K> action) {
4888              if (action == null) throw new NullPointerException();
4889 <            return new ForEachKeyTask<K,V>(map, action);
4889 >            return new ForEachKeyTask<K,V>(map, null, -1, action);
4890          }
4891  
4892          /**
# Line 4321 | Line 4895 | public class ConcurrentHashMapV8<K, V>
4895           *
4896           * @param map the map
4897           * @param transformer a function returning the transformation
4898 <         * for an element, or null of there is no transformation (in
4899 <         * which case the action is not applied).
4898 >         * for an element, or null if there is no transformation (in
4899 >         * which case the action is not applied)
4900           * @param action the action
4901           * @return the task
4902           */
# Line 4333 | Line 4907 | public class ConcurrentHashMapV8<K, V>
4907              if (transformer == null || action == null)
4908                  throw new NullPointerException();
4909              return new ForEachTransformedKeyTask<K,V,U>
4910 <                (map, transformer, action);
4910 >                (map, null, -1, transformer, action);
4911          }
4912  
4913          /**
4914           * Returns a task that when invoked, returns a non-null result
4915           * from applying the given search function on each key, or
4916 <         * null if none.  Further element processing is suppressed
4917 <         * upon success. However, this method does not return until
4918 <         * other in-progress parallel invocations of the search
4345 <         * function also complete.
4916 >         * null if none.  Upon success, further element processing is
4917 >         * suppressed and the results of any other parallel
4918 >         * invocations of the search function are ignored.
4919           *
4920           * @param map the map
4921           * @param searchFunction a function returning a non-null
# Line 4354 | Line 4927 | public class ConcurrentHashMapV8<K, V>
4927               Fun<? super K, ? extends U> searchFunction) {
4928              if (searchFunction == null) throw new NullPointerException();
4929              return new SearchKeysTask<K,V,U>
4930 <                (map, searchFunction,
4930 >                (map, null, -1, searchFunction,
4931                   new AtomicReference<U>());
4932          }
4933  
# Line 4372 | Line 4945 | public class ConcurrentHashMapV8<K, V>
4945               BiFun<? super K, ? super K, ? extends K> reducer) {
4946              if (reducer == null) throw new NullPointerException();
4947              return new ReduceKeysTask<K,V>
4948 <                (map, reducer);
4948 >                (map, null, -1, null, reducer);
4949          }
4950  
4951          /**
# Line 4382 | Line 4955 | public class ConcurrentHashMapV8<K, V>
4955           *
4956           * @param map the map
4957           * @param transformer a function returning the transformation
4958 <         * for an element, or null of there is no transformation (in
4958 >         * for an element, or null if there is no transformation (in
4959           * which case it is not combined).
4960           * @param reducer a commutative associative combining function
4961           * @return the task
# Line 4394 | Line 4967 | public class ConcurrentHashMapV8<K, V>
4967              if (transformer == null || reducer == null)
4968                  throw new NullPointerException();
4969              return new MapReduceKeysTask<K,V,U>
4970 <                (map, transformer, reducer);
4970 >                (map, null, -1, null, transformer, reducer);
4971          }
4972  
4973          /**
# Line 4418 | Line 4991 | public class ConcurrentHashMapV8<K, V>
4991              if (transformer == null || reducer == null)
4992                  throw new NullPointerException();
4993              return new MapReduceKeysToDoubleTask<K,V>
4994 <                (map, transformer, basis, reducer);
4994 >                (map, null, -1, null, transformer, basis, reducer);
4995          }
4996  
4997          /**
# Line 4442 | Line 5015 | public class ConcurrentHashMapV8<K, V>
5015              if (transformer == null || reducer == null)
5016                  throw new NullPointerException();
5017              return new MapReduceKeysToLongTask<K,V>
5018 <                (map, transformer, basis, reducer);
5018 >                (map, null, -1, null, transformer, basis, reducer);
5019          }
5020  
5021          /**
# Line 4466 | Line 5039 | public class ConcurrentHashMapV8<K, V>
5039              if (transformer == null || reducer == null)
5040                  throw new NullPointerException();
5041              return new MapReduceKeysToIntTask<K,V>
5042 <                (map, transformer, basis, reducer);
5042 >                (map, null, -1, null, transformer, basis, reducer);
5043          }
5044  
5045          /**
# Line 4480 | Line 5053 | public class ConcurrentHashMapV8<K, V>
5053              (ConcurrentHashMapV8<K,V> map,
5054               Action<V> action) {
5055              if (action == null) throw new NullPointerException();
5056 <            return new ForEachValueTask<K,V>(map, action);
5056 >            return new ForEachValueTask<K,V>(map, null, -1, action);
5057          }
5058  
5059          /**
# Line 4489 | Line 5062 | public class ConcurrentHashMapV8<K, V>
5062           *
5063           * @param map the map
5064           * @param transformer a function returning the transformation
5065 <         * for an element, or null of there is no transformation (in
5066 <         * which case the action is not applied).
5065 >         * for an element, or null if there is no transformation (in
5066 >         * which case the action is not applied)
5067           * @param action the action
5068           */
5069          public static <K,V,U> ForkJoinTask<Void> forEachValue
# Line 4500 | Line 5073 | public class ConcurrentHashMapV8<K, V>
5073              if (transformer == null || action == null)
5074                  throw new NullPointerException();
5075              return new ForEachTransformedValueTask<K,V,U>
5076 <                (map, transformer, action);
5076 >                (map, null, -1, transformer, action);
5077          }
5078  
5079          /**
5080           * Returns a task that when invoked, returns a non-null result
5081           * from applying the given search function on each value, or
5082 <         * null if none.  Further element processing is suppressed
5083 <         * upon success. However, this method does not return until
5084 <         * other in-progress parallel invocations of the search
4512 <         * function also complete.
5082 >         * null if none.  Upon success, further element processing is
5083 >         * suppressed and the results of any other parallel
5084 >         * invocations of the search function are ignored.
5085           *
5086           * @param map the map
5087           * @param searchFunction a function returning a non-null
5088           * result on success, else null
5089           * @return the task
4518         *
5090           */
5091          public static <K,V,U> ForkJoinTask<U> searchValues
5092              (ConcurrentHashMapV8<K,V> map,
5093               Fun<? super V, ? extends U> searchFunction) {
5094              if (searchFunction == null) throw new NullPointerException();
5095              return new SearchValuesTask<K,V,U>
5096 <                (map, searchFunction,
5096 >                (map, null, -1, searchFunction,
5097                   new AtomicReference<U>());
5098          }
5099  
# Line 4540 | Line 5111 | public class ConcurrentHashMapV8<K, V>
5111               BiFun<? super V, ? super V, ? extends V> reducer) {
5112              if (reducer == null) throw new NullPointerException();
5113              return new ReduceValuesTask<K,V>
5114 <                (map, reducer);
5114 >                (map, null, -1, null, reducer);
5115          }
5116  
5117          /**
# Line 4550 | Line 5121 | public class ConcurrentHashMapV8<K, V>
5121           *
5122           * @param map the map
5123           * @param transformer a function returning the transformation
5124 <         * for an element, or null of there is no transformation (in
5124 >         * for an element, or null if there is no transformation (in
5125           * which case it is not combined).
5126           * @param reducer a commutative associative combining function
5127           * @return the task
# Line 4562 | Line 5133 | public class ConcurrentHashMapV8<K, V>
5133              if (transformer == null || reducer == null)
5134                  throw new NullPointerException();
5135              return new MapReduceValuesTask<K,V,U>
5136 <                (map, transformer, reducer);
5136 >                (map, null, -1, null, transformer, reducer);
5137          }
5138  
5139          /**
# Line 4586 | Line 5157 | public class ConcurrentHashMapV8<K, V>
5157              if (transformer == null || reducer == null)
5158                  throw new NullPointerException();
5159              return new MapReduceValuesToDoubleTask<K,V>
5160 <                (map, transformer, basis, reducer);
5160 >                (map, null, -1, null, transformer, basis, reducer);
5161          }
5162  
5163          /**
# Line 4610 | Line 5181 | public class ConcurrentHashMapV8<K, V>
5181              if (transformer == null || reducer == null)
5182                  throw new NullPointerException();
5183              return new MapReduceValuesToLongTask<K,V>
5184 <                (map, transformer, basis, reducer);
5184 >                (map, null, -1, null, transformer, basis, reducer);
5185          }
5186  
5187          /**
# Line 4634 | Line 5205 | public class ConcurrentHashMapV8<K, V>
5205              if (transformer == null || reducer == null)
5206                  throw new NullPointerException();
5207              return new MapReduceValuesToIntTask<K,V>
5208 <                (map, transformer, basis, reducer);
5208 >                (map, null, -1, null, transformer, basis, reducer);
5209          }
5210  
5211          /**
# Line 4648 | Line 5219 | public class ConcurrentHashMapV8<K, V>
5219              (ConcurrentHashMapV8<K,V> map,
5220               Action<Map.Entry<K,V>> action) {
5221              if (action == null) throw new NullPointerException();
5222 <            return new ForEachEntryTask<K,V>(map, action);
5222 >            return new ForEachEntryTask<K,V>(map, null, -1, action);
5223          }
5224  
5225          /**
# Line 4657 | Line 5228 | public class ConcurrentHashMapV8<K, V>
5228           *
5229           * @param map the map
5230           * @param transformer a function returning the transformation
5231 <         * for an element, or null of there is no transformation (in
5232 <         * which case the action is not applied).
5231 >         * for an element, or null if there is no transformation (in
5232 >         * which case the action is not applied)
5233           * @param action the action
5234           */
5235          public static <K,V,U> ForkJoinTask<Void> forEachEntry
# Line 4668 | Line 5239 | public class ConcurrentHashMapV8<K, V>
5239              if (transformer == null || action == null)
5240                  throw new NullPointerException();
5241              return new ForEachTransformedEntryTask<K,V,U>
5242 <                (map, transformer, action);
5242 >                (map, null, -1, transformer, action);
5243          }
5244  
5245          /**
5246           * Returns a task that when invoked, returns a non-null result
5247           * from applying the given search function on each entry, or
5248 <         * null if none.  Further element processing is suppressed
5249 <         * upon success. However, this method does not return until
5250 <         * other in-progress parallel invocations of the search
4680 <         * function also complete.
5248 >         * null if none.  Upon success, further element processing is
5249 >         * suppressed and the results of any other parallel
5250 >         * invocations of the search function are ignored.
5251           *
5252           * @param map the map
5253           * @param searchFunction a function returning a non-null
5254           * result on success, else null
5255           * @return the task
4686         *
5256           */
5257          public static <K,V,U> ForkJoinTask<U> searchEntries
5258              (ConcurrentHashMapV8<K,V> map,
5259               Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
5260              if (searchFunction == null) throw new NullPointerException();
5261              return new SearchEntriesTask<K,V,U>
5262 <                (map, searchFunction,
5262 >                (map, null, -1, searchFunction,
5263                   new AtomicReference<U>());
5264          }
5265  
# Line 4708 | Line 5277 | public class ConcurrentHashMapV8<K, V>
5277               BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5278              if (reducer == null) throw new NullPointerException();
5279              return new ReduceEntriesTask<K,V>
5280 <                (map, reducer);
5280 >                (map, null, -1, null, reducer);
5281          }
5282  
5283          /**
# Line 4718 | Line 5287 | public class ConcurrentHashMapV8<K, V>
5287           *
5288           * @param map the map
5289           * @param transformer a function returning the transformation
5290 <         * for an element, or null of there is no transformation (in
5290 >         * for an element, or null if there is no transformation (in
5291           * which case it is not combined).
5292           * @param reducer a commutative associative combining function
5293           * @return the task
# Line 4730 | Line 5299 | public class ConcurrentHashMapV8<K, V>
5299              if (transformer == null || reducer == null)
5300                  throw new NullPointerException();
5301              return new MapReduceEntriesTask<K,V,U>
5302 <                (map, transformer, reducer);
5302 >                (map, null, -1, null, transformer, reducer);
5303          }
5304  
5305          /**
# Line 4754 | Line 5323 | public class ConcurrentHashMapV8<K, V>
5323              if (transformer == null || reducer == null)
5324                  throw new NullPointerException();
5325              return new MapReduceEntriesToDoubleTask<K,V>
5326 <                (map, transformer, basis, reducer);
5326 >                (map, null, -1, null, transformer, basis, reducer);
5327          }
5328  
5329          /**
# Line 4778 | Line 5347 | public class ConcurrentHashMapV8<K, V>
5347              if (transformer == null || reducer == null)
5348                  throw new NullPointerException();
5349              return new MapReduceEntriesToLongTask<K,V>
5350 <                (map, transformer, basis, reducer);
5350 >                (map, null, -1, null, transformer, basis, reducer);
5351          }
5352  
5353          /**
# Line 4802 | Line 5371 | public class ConcurrentHashMapV8<K, V>
5371              if (transformer == null || reducer == null)
5372                  throw new NullPointerException();
5373              return new MapReduceEntriesToIntTask<K,V>
5374 <                (map, transformer, basis, reducer);
5374 >                (map, null, -1, null, transformer, basis, reducer);
5375          }
5376      }
5377  
5378      // -------------------------------------------------------
5379  
4811    /**
4812     * Base for FJ tasks for bulk operations. This adds a variant of
4813     * CountedCompleters and some split and merge bookkeeping to
4814     * iterator functionality. The forEach and reduce methods are
4815     * similar to those illustrated in CountedCompleter documentation,
4816     * except that bottom-up reduction completions perform them within
4817     * their compute methods. The search methods are like forEach
4818     * except they continually poll for success and exit early.  Also,
4819     * exceptions are handled in a simpler manner, by just trying to
4820     * complete root task exceptionally.
4821     */
4822    static abstract class BulkTask<K,V,R> extends Traverser<K,V,R> {
4823        final BulkTask<K,V,?> parent;  // completion target
4824        int batch;                     // split control
4825        int pending;                   // completion control
4826
4827        /** Constructor for root tasks */
4828        BulkTask(ConcurrentHashMapV8<K,V> map) {
4829            super(map);
4830            this.parent = null;
4831            this.batch = -1; // force call to batch() on execution
4832        }
4833
4834        /** Constructor for subtasks */
4835        BulkTask(BulkTask<K,V,?> parent, int batch, boolean split) {
4836            super(parent, split);
4837            this.parent = parent;
4838            this.batch = batch;
4839        }
4840
4841        // FJ methods
4842
4843        /**
4844         * Propagates completion. Note that all reduce actions
4845         * bypass this method to combine while completing.
4846         */
4847        final void tryComplete() {
4848            BulkTask<K,V,?> a = this, s = a;
4849            for (int c;;) {
4850                if ((c = a.pending) == 0) {
4851                    if ((a = (s = a).parent) == null) {
4852                        s.quietlyComplete();
4853                        break;
4854                    }
4855                }
4856                else if (U.compareAndSwapInt(a, PENDING, c, c - 1))
4857                    break;
4858            }
4859        }
4860
4861        /**
4862         * Forces root task to throw exception unless already complete.
4863         */
4864        final void tryAbortComputation(Throwable ex) {
4865            for (BulkTask<K,V,?> a = this;;) {
4866                BulkTask<K,V,?> p = a.parent;
4867                if (p == null) {
4868                    a.completeExceptionally(ex);
4869                    break;
4870                }
4871                a = p;
4872            }
4873        }
4874
4875        public final boolean exec() {
4876            try {
4877                compute();
4878            }
4879            catch (Throwable ex) {
4880                tryAbortComputation(ex);
4881            }
4882            return false;
4883        }
4884
4885        public abstract void compute();
4886
4887        // utilities
4888
4889        /** CompareAndSet pending count */
4890        final boolean casPending(int cmp, int val) {
4891            return U.compareAndSwapInt(this, PENDING, cmp, val);
4892        }
4893
4894        /**
4895         * Returns approx exp2 of the number of times (minus one) to
4896         * split task by two before executing leaf action. This value
4897         * is faster to compute and more convenient to use as a guide
4898         * to splitting than is the depth, since it is used while
4899         * dividing by two anyway.
4900         */
4901        final int batch() {
4902            int b = batch;
4903            if (b < 0) {
4904                long n = map.counter.sum();
4905                int sp = getPool().getParallelism() << 3; // slack of 8
4906                b = batch = (n <= 0L) ? 0 : (n < (long)sp) ? (int)n : sp;
4907            }
4908            return b;
4909        }
4910
4911        /**
4912         * Error message for hoisted null checks of functions
4913         */
4914        static final String NullFunctionMessage =
4915            "Unexpected null function";
4916
4917        /**
4918         * Returns exportable snapshot entry.
4919         */
4920        static <K,V> AbstractMap.SimpleEntry<K,V> entryFor(K k, V v) {
4921            return new AbstractMap.SimpleEntry(k, v);
4922        }
4923
4924        // Unsafe mechanics
4925        private static final sun.misc.Unsafe U;
4926        private static final long PENDING;
4927        static {
4928            try {
4929                U = sun.misc.Unsafe.getUnsafe();
4930                PENDING = U.objectFieldOffset
4931                    (BulkTask.class.getDeclaredField("pending"));
4932            } catch (Exception e) {
4933                throw new Error(e);
4934            }
4935        }
4936    }
4937
5380      /*
5381       * Task classes. Coded in a regular but ugly format/style to
5382       * simplify checks that each variant differs in the right way from
5383       * others.
5384       */
5385  
5386 <    static final class ForEachKeyTask<K,V>
5387 <        extends BulkTask<K,V,Void> {
5386 >    @SuppressWarnings("serial") static final class ForEachKeyTask<K,V>
5387 >        extends Traverser<K,V,Void> {
5388          final Action<K> action;
5389          ForEachKeyTask
5390 <            (ConcurrentHashMapV8<K,V> m,
4949 <             Action<K> action) {
4950 <            super(m);
4951 <            this.action = action;
4952 <        }
4953 <        ForEachKeyTask
4954 <            (BulkTask<K,V,?> p, int b, boolean split,
5390 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5391               Action<K> action) {
5392 <            super(p, b, split);
5392 >            super(m, p, b);
5393              this.action = action;
5394          }
5395 <        public final void compute() {
5396 <            final Action<K> action = this.action;
5397 <            if (action == null)
5398 <                throw new Error(NullFunctionMessage);
5399 <            int b = batch(), c;
5400 <            while (b > 1 && baseIndex != baseLimit) {
4965 <                do {} while (!casPending(c = pending, c+1));
4966 <                new ForEachKeyTask<K,V>(this, b >>>= 1, true, action).fork();
4967 <            }
5395 >        @SuppressWarnings("unchecked") public final void compute() {
5396 >            final Action<K> action;
5397 >            if ((action = this.action) == null)
5398 >                throw new NullPointerException();
5399 >            for (int b; (b = preSplit()) > 0;)
5400 >                new ForEachKeyTask<K,V>(map, this, b, action).fork();
5401              while (advance() != null)
5402                  action.apply((K)nextKey);
5403 <            tryComplete();
5403 >            propagateCompletion();
5404          }
5405      }
5406  
5407 <    static final class ForEachValueTask<K,V>
5408 <        extends BulkTask<K,V,Void> {
5407 >    @SuppressWarnings("serial") static final class ForEachValueTask<K,V>
5408 >        extends Traverser<K,V,Void> {
5409          final Action<V> action;
5410          ForEachValueTask
5411 <            (ConcurrentHashMapV8<K,V> m,
4979 <             Action<V> action) {
4980 <            super(m);
4981 <            this.action = action;
4982 <        }
4983 <        ForEachValueTask
4984 <            (BulkTask<K,V,?> p, int b, boolean split,
5411 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5412               Action<V> action) {
5413 <            super(p, b, split);
5413 >            super(m, p, b);
5414              this.action = action;
5415          }
5416 <        public final void compute() {
5417 <            final Action<V> action = this.action;
5418 <            if (action == null)
5419 <                throw new Error(NullFunctionMessage);
5420 <            int b = batch(), c;
5421 <            while (b > 1 && baseIndex != baseLimit) {
4995 <                do {} while (!casPending(c = pending, c+1));
4996 <                new ForEachValueTask<K,V>(this, b >>>= 1, true, action).fork();
4997 <            }
5416 >        @SuppressWarnings("unchecked") public final void compute() {
5417 >            final Action<V> action;
5418 >            if ((action = this.action) == null)
5419 >                throw new NullPointerException();
5420 >            for (int b; (b = preSplit()) > 0;)
5421 >                new ForEachValueTask<K,V>(map, this, b, action).fork();
5422              Object v;
5423              while ((v = advance()) != null)
5424                  action.apply((V)v);
5425 <            tryComplete();
5425 >            propagateCompletion();
5426          }
5427      }
5428  
5429 <    static final class ForEachEntryTask<K,V>
5430 <        extends BulkTask<K,V,Void> {
5429 >    @SuppressWarnings("serial") static final class ForEachEntryTask<K,V>
5430 >        extends Traverser<K,V,Void> {
5431          final Action<Entry<K,V>> action;
5432          ForEachEntryTask
5433 <            (ConcurrentHashMapV8<K,V> m,
5433 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5434               Action<Entry<K,V>> action) {
5435 <            super(m);
5435 >            super(m, p, b);
5436              this.action = action;
5437          }
5438 <        ForEachEntryTask
5439 <            (BulkTask<K,V,?> p, int b, boolean split,
5440 <             Action<Entry<K,V>> action) {
5441 <            super(p, b, split);
5442 <            this.action = action;
5443 <        }
5020 <        public final void compute() {
5021 <            final Action<Entry<K,V>> action = this.action;
5022 <            if (action == null)
5023 <                throw new Error(NullFunctionMessage);
5024 <            int b = batch(), c;
5025 <            while (b > 1 && baseIndex != baseLimit) {
5026 <                do {} while (!casPending(c = pending, c+1));
5027 <                new ForEachEntryTask<K,V>(this, b >>>= 1, true, action).fork();
5028 <            }
5438 >        @SuppressWarnings("unchecked") public final void compute() {
5439 >            final Action<Entry<K,V>> action;
5440 >            if ((action = this.action) == null)
5441 >                throw new NullPointerException();
5442 >            for (int b; (b = preSplit()) > 0;)
5443 >                new ForEachEntryTask<K,V>(map, this, b, action).fork();
5444              Object v;
5445              while ((v = advance()) != null)
5446                  action.apply(entryFor((K)nextKey, (V)v));
5447 <            tryComplete();
5447 >            propagateCompletion();
5448          }
5449      }
5450  
5451 <    static final class ForEachMappingTask<K,V>
5452 <        extends BulkTask<K,V,Void> {
5451 >    @SuppressWarnings("serial") static final class ForEachMappingTask<K,V>
5452 >        extends Traverser<K,V,Void> {
5453          final BiAction<K,V> action;
5454          ForEachMappingTask
5455 <            (ConcurrentHashMapV8<K,V> m,
5041 <             BiAction<K,V> action) {
5042 <            super(m);
5043 <            this.action = action;
5044 <        }
5045 <        ForEachMappingTask
5046 <            (BulkTask<K,V,?> p, int b, boolean split,
5455 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5456               BiAction<K,V> action) {
5457 <            super(p, b, split);
5457 >            super(m, p, b);
5458              this.action = action;
5459          }
5460 <
5461 <        public final void compute() {
5462 <            final BiAction<K,V> action = this.action;
5463 <            if (action == null)
5464 <                throw new Error(NullFunctionMessage);
5465 <            int b = batch(), c;
5057 <            while (b > 1 && baseIndex != baseLimit) {
5058 <                do {} while (!casPending(c = pending, c+1));
5059 <                new ForEachMappingTask<K,V>(this, b >>>= 1, true,
5060 <                                            action).fork();
5061 <            }
5460 >        @SuppressWarnings("unchecked") public final void compute() {
5461 >            final BiAction<K,V> action;
5462 >            if ((action = this.action) == null)
5463 >                throw new NullPointerException();
5464 >            for (int b; (b = preSplit()) > 0;)
5465 >                new ForEachMappingTask<K,V>(map, this, b, action).fork();
5466              Object v;
5467              while ((v = advance()) != null)
5468                  action.apply((K)nextKey, (V)v);
5469 <            tryComplete();
5469 >            propagateCompletion();
5470          }
5471      }
5472  
5473 <    static final class ForEachTransformedKeyTask<K,V,U>
5474 <        extends BulkTask<K,V,Void> {
5473 >    @SuppressWarnings("serial") static final class ForEachTransformedKeyTask<K,V,U>
5474 >        extends Traverser<K,V,Void> {
5475          final Fun<? super K, ? extends U> transformer;
5476          final Action<U> action;
5477          ForEachTransformedKeyTask
5478 <            (ConcurrentHashMapV8<K,V> m,
5479 <             Fun<? super K, ? extends U> transformer,
5480 <             Action<U> action) {
5481 <            super(m);
5482 <            this.transformer = transformer;
5483 <            this.action = action;
5484 <
5485 <        }
5486 <        ForEachTransformedKeyTask
5487 <            (BulkTask<K,V,?> p, int b, boolean split,
5488 <             Fun<? super K, ? extends U> transformer,
5489 <             Action<U> action) {
5086 <            super(p, b, split);
5087 <            this.transformer = transformer;
5088 <            this.action = action;
5089 <        }
5090 <        public final void compute() {
5091 <            final Fun<? super K, ? extends U> transformer =
5092 <                this.transformer;
5093 <            final Action<U> action = this.action;
5094 <            if (transformer == null || action == null)
5095 <                throw new Error(NullFunctionMessage);
5096 <            int b = batch(), c;
5097 <            while (b > 1 && baseIndex != baseLimit) {
5098 <                do {} while (!casPending(c = pending, c+1));
5478 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5479 >             Fun<? super K, ? extends U> transformer, Action<U> action) {
5480 >            super(m, p, b);
5481 >            this.transformer = transformer; this.action = action;
5482 >        }
5483 >        @SuppressWarnings("unchecked") public final void compute() {
5484 >            final Fun<? super K, ? extends U> transformer;
5485 >            final Action<U> action;
5486 >            if ((transformer = this.transformer) == null ||
5487 >                (action = this.action) == null)
5488 >                throw new NullPointerException();
5489 >            for (int b; (b = preSplit()) > 0;)
5490                  new ForEachTransformedKeyTask<K,V,U>
5491 <                    (this, b >>>= 1, true, transformer, action).fork();
5101 <            }
5491 >                     (map, this, b, transformer, action).fork();
5492              U u;
5493              while (advance() != null) {
5494                  if ((u = transformer.apply((K)nextKey)) != null)
5495                      action.apply(u);
5496              }
5497 <            tryComplete();
5497 >            propagateCompletion();
5498          }
5499      }
5500  
5501 <    static final class ForEachTransformedValueTask<K,V,U>
5502 <        extends BulkTask<K,V,Void> {
5501 >    @SuppressWarnings("serial") static final class ForEachTransformedValueTask<K,V,U>
5502 >        extends Traverser<K,V,Void> {
5503          final Fun<? super V, ? extends U> transformer;
5504          final Action<U> action;
5505          ForEachTransformedValueTask
5506 <            (ConcurrentHashMapV8<K,V> m,
5507 <             Fun<? super V, ? extends U> transformer,
5508 <             Action<U> action) {
5509 <            super(m);
5510 <            this.transformer = transformer;
5511 <            this.action = action;
5512 <
5513 <        }
5514 <        ForEachTransformedValueTask
5515 <            (BulkTask<K,V,?> p, int b, boolean split,
5516 <             Fun<? super V, ? extends U> transformer,
5517 <             Action<U> action) {
5128 <            super(p, b, split);
5129 <            this.transformer = transformer;
5130 <            this.action = action;
5131 <        }
5132 <        public final void compute() {
5133 <            final Fun<? super V, ? extends U> transformer =
5134 <                this.transformer;
5135 <            final Action<U> action = this.action;
5136 <            if (transformer == null || action == null)
5137 <                throw new Error(NullFunctionMessage);
5138 <            int b = batch(), c;
5139 <            while (b > 1 && baseIndex != baseLimit) {
5140 <                do {} while (!casPending(c = pending, c+1));
5506 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5507 >             Fun<? super V, ? extends U> transformer, Action<U> action) {
5508 >            super(m, p, b);
5509 >            this.transformer = transformer; this.action = action;
5510 >        }
5511 >        @SuppressWarnings("unchecked") public final void compute() {
5512 >            final Fun<? super V, ? extends U> transformer;
5513 >            final Action<U> action;
5514 >            if ((transformer = this.transformer) == null ||
5515 >                (action = this.action) == null)
5516 >                throw new NullPointerException();
5517 >            for (int b; (b = preSplit()) > 0;)
5518                  new ForEachTransformedValueTask<K,V,U>
5519 <                    (this, b >>>= 1, true, transformer, action).fork();
5143 <            }
5519 >                    (map, this, b, transformer, action).fork();
5520              Object v; U u;
5521              while ((v = advance()) != null) {
5522                  if ((u = transformer.apply((V)v)) != null)
5523                      action.apply(u);
5524              }
5525 <            tryComplete();
5525 >            propagateCompletion();
5526          }
5527      }
5528  
5529 <    static final class ForEachTransformedEntryTask<K,V,U>
5530 <        extends BulkTask<K,V,Void> {
5529 >    @SuppressWarnings("serial") static final class ForEachTransformedEntryTask<K,V,U>
5530 >        extends Traverser<K,V,Void> {
5531          final Fun<Map.Entry<K,V>, ? extends U> transformer;
5532          final Action<U> action;
5533          ForEachTransformedEntryTask
5534 <            (ConcurrentHashMapV8<K,V> m,
5535 <             Fun<Map.Entry<K,V>, ? extends U> transformer,
5536 <             Action<U> action) {
5537 <            super(m);
5538 <            this.transformer = transformer;
5539 <            this.action = action;
5540 <
5541 <        }
5542 <        ForEachTransformedEntryTask
5543 <            (BulkTask<K,V,?> p, int b, boolean split,
5544 <             Fun<Map.Entry<K,V>, ? extends U> transformer,
5545 <             Action<U> action) {
5170 <            super(p, b, split);
5171 <            this.transformer = transformer;
5172 <            this.action = action;
5173 <        }
5174 <        public final void compute() {
5175 <            final Fun<Map.Entry<K,V>, ? extends U> transformer =
5176 <                this.transformer;
5177 <            final Action<U> action = this.action;
5178 <            if (transformer == null || action == null)
5179 <                throw new Error(NullFunctionMessage);
5180 <            int b = batch(), c;
5181 <            while (b > 1 && baseIndex != baseLimit) {
5182 <                do {} while (!casPending(c = pending, c+1));
5534 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5535 >             Fun<Map.Entry<K,V>, ? extends U> transformer, Action<U> action) {
5536 >            super(m, p, b);
5537 >            this.transformer = transformer; this.action = action;
5538 >        }
5539 >        @SuppressWarnings("unchecked") public final void compute() {
5540 >            final Fun<Map.Entry<K,V>, ? extends U> transformer;
5541 >            final Action<U> action;
5542 >            if ((transformer = this.transformer) == null ||
5543 >                (action = this.action) == null)
5544 >                throw new NullPointerException();
5545 >            for (int b; (b = preSplit()) > 0;)
5546                  new ForEachTransformedEntryTask<K,V,U>
5547 <                    (this, b >>>= 1, true, transformer, action).fork();
5185 <            }
5547 >                    (map, this, b, transformer, action).fork();
5548              Object v; U u;
5549              while ((v = advance()) != null) {
5550                  if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
5551                      action.apply(u);
5552              }
5553 <            tryComplete();
5553 >            propagateCompletion();
5554          }
5555      }
5556  
5557 <    static final class ForEachTransformedMappingTask<K,V,U>
5558 <        extends BulkTask<K,V,Void> {
5557 >    @SuppressWarnings("serial") static final class ForEachTransformedMappingTask<K,V,U>
5558 >        extends Traverser<K,V,Void> {
5559          final BiFun<? super K, ? super V, ? extends U> transformer;
5560          final Action<U> action;
5561          ForEachTransformedMappingTask
5562 <            (ConcurrentHashMapV8<K,V> m,
5201 <             BiFun<? super K, ? super V, ? extends U> transformer,
5202 <             Action<U> action) {
5203 <            super(m);
5204 <            this.transformer = transformer;
5205 <            this.action = action;
5206 <
5207 <        }
5208 <        ForEachTransformedMappingTask
5209 <            (BulkTask<K,V,?> p, int b, boolean split,
5562 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5563               BiFun<? super K, ? super V, ? extends U> transformer,
5564               Action<U> action) {
5565 <            super(p, b, split);
5566 <            this.transformer = transformer;
5214 <            this.action = action;
5565 >            super(m, p, b);
5566 >            this.transformer = transformer; this.action = action;
5567          }
5568 <        public final void compute() {
5569 <            final BiFun<? super K, ? super V, ? extends U> transformer =
5570 <                this.transformer;
5571 <            final Action<U> action = this.action;
5572 <            if (transformer == null || action == null)
5573 <                throw new Error(NullFunctionMessage);
5574 <            int b = batch(), c;
5223 <            while (b > 1 && baseIndex != baseLimit) {
5224 <                do {} while (!casPending(c = pending, c+1));
5568 >        @SuppressWarnings("unchecked") public final void compute() {
5569 >            final BiFun<? super K, ? super V, ? extends U> transformer;
5570 >            final Action<U> action;
5571 >            if ((transformer = this.transformer) == null ||
5572 >                (action = this.action) == null)
5573 >                throw new NullPointerException();
5574 >            for (int b; (b = preSplit()) > 0;)
5575                  new ForEachTransformedMappingTask<K,V,U>
5576 <                    (this, b >>>= 1, true, transformer, action).fork();
5227 <            }
5576 >                    (map, this, b, transformer, action).fork();
5577              Object v; U u;
5578              while ((v = advance()) != null) {
5579                  if ((u = transformer.apply((K)nextKey, (V)v)) != null)
5580                      action.apply(u);
5581              }
5582 <            tryComplete();
5582 >            propagateCompletion();
5583          }
5584      }
5585  
5586 <    static final class SearchKeysTask<K,V,U>
5587 <        extends BulkTask<K,V,U> {
5586 >    @SuppressWarnings("serial") static final class SearchKeysTask<K,V,U>
5587 >        extends Traverser<K,V,U> {
5588          final Fun<? super K, ? extends U> searchFunction;
5589          final AtomicReference<U> result;
5590          SearchKeysTask
5591 <            (ConcurrentHashMapV8<K,V> m,
5243 <             Fun<? super K, ? extends U> searchFunction,
5244 <             AtomicReference<U> result) {
5245 <            super(m);
5246 <            this.searchFunction = searchFunction; this.result = result;
5247 <        }
5248 <        SearchKeysTask
5249 <            (BulkTask<K,V,?> p, int b, boolean split,
5591 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5592               Fun<? super K, ? extends U> searchFunction,
5593               AtomicReference<U> result) {
5594 <            super(p, b, split);
5594 >            super(m, p, b);
5595              this.searchFunction = searchFunction; this.result = result;
5596          }
5597 <        public final void compute() {
5598 <            AtomicReference<U> result = this.result;
5599 <            final Fun<? super K, ? extends U> searchFunction =
5600 <                this.searchFunction;
5601 <            if (searchFunction == null || result == null)
5602 <                throw new Error(NullFunctionMessage);
5603 <            int b = batch(), c;
5604 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5605 <                do {} while (!casPending(c = pending, c+1));
5606 <                new SearchKeysTask<K,V,U>(this, b >>>= 1, true,
5607 <                                          searchFunction, result).fork();
5597 >        public final U getRawResult() { return result.get(); }
5598 >        @SuppressWarnings("unchecked") public final void compute() {
5599 >            final Fun<? super K, ? extends U> searchFunction;
5600 >            final AtomicReference<U> result;
5601 >            if ((searchFunction = this.searchFunction) == null ||
5602 >                (result = this.result) == null)
5603 >                throw new NullPointerException();
5604 >            for (int b;;) {
5605 >                if (result.get() != null)
5606 >                    return;
5607 >                if ((b = preSplit()) <= 0)
5608 >                    break;
5609 >                new SearchKeysTask<K,V,U>
5610 >                    (map, this, b, searchFunction, result).fork();
5611              }
5612 <            U u;
5613 <            while (result.get() == null && advance() != null) {
5612 >            while (result.get() == null) {
5613 >                U u;
5614 >                if (advance() == null) {
5615 >                    propagateCompletion();
5616 >                    break;
5617 >                }
5618                  if ((u = searchFunction.apply((K)nextKey)) != null) {
5619 <                    result.compareAndSet(null, u);
5619 >                    if (result.compareAndSet(null, u))
5620 >                        quietlyCompleteRoot();
5621                      break;
5622                  }
5623              }
5274            tryComplete();
5624          }
5276        public final U getRawResult() { return result.get(); }
5625      }
5626  
5627 <    static final class SearchValuesTask<K,V,U>
5628 <        extends BulkTask<K,V,U> {
5627 >    @SuppressWarnings("serial") static final class SearchValuesTask<K,V,U>
5628 >        extends Traverser<K,V,U> {
5629          final Fun<? super V, ? extends U> searchFunction;
5630          final AtomicReference<U> result;
5631          SearchValuesTask
5632 <            (ConcurrentHashMapV8<K,V> m,
5285 <             Fun<? super V, ? extends U> searchFunction,
5286 <             AtomicReference<U> result) {
5287 <            super(m);
5288 <            this.searchFunction = searchFunction; this.result = result;
5289 <        }
5290 <        SearchValuesTask
5291 <            (BulkTask<K,V,?> p, int b, boolean split,
5632 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5633               Fun<? super V, ? extends U> searchFunction,
5634               AtomicReference<U> result) {
5635 <            super(p, b, split);
5635 >            super(m, p, b);
5636              this.searchFunction = searchFunction; this.result = result;
5637          }
5638 <        public final void compute() {
5639 <            AtomicReference<U> result = this.result;
5640 <            final Fun<? super V, ? extends U> searchFunction =
5641 <                this.searchFunction;
5642 <            if (searchFunction == null || result == null)
5643 <                throw new Error(NullFunctionMessage);
5644 <            int b = batch(), c;
5645 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5646 <                do {} while (!casPending(c = pending, c+1));
5647 <                new SearchValuesTask<K,V,U>(this, b >>>= 1, true,
5648 <                                            searchFunction, result).fork();
5638 >        public final U getRawResult() { return result.get(); }
5639 >        @SuppressWarnings("unchecked") public final void compute() {
5640 >            final Fun<? super V, ? extends U> searchFunction;
5641 >            final AtomicReference<U> result;
5642 >            if ((searchFunction = this.searchFunction) == null ||
5643 >                (result = this.result) == null)
5644 >                throw new NullPointerException();
5645 >            for (int b;;) {
5646 >                if (result.get() != null)
5647 >                    return;
5648 >                if ((b = preSplit()) <= 0)
5649 >                    break;
5650 >                new SearchValuesTask<K,V,U>
5651 >                    (map, this, b, searchFunction, result).fork();
5652              }
5653 <            Object v; U u;
5654 <            while (result.get() == null && (v = advance()) != null) {
5653 >            while (result.get() == null) {
5654 >                Object v; U u;
5655 >                if ((v = advance()) == null) {
5656 >                    propagateCompletion();
5657 >                    break;
5658 >                }
5659                  if ((u = searchFunction.apply((V)v)) != null) {
5660 <                    result.compareAndSet(null, u);
5660 >                    if (result.compareAndSet(null, u))
5661 >                        quietlyCompleteRoot();
5662                      break;
5663                  }
5664              }
5316            tryComplete();
5665          }
5318        public final U getRawResult() { return result.get(); }
5666      }
5667  
5668 <    static final class SearchEntriesTask<K,V,U>
5669 <        extends BulkTask<K,V,U> {
5668 >    @SuppressWarnings("serial") static final class SearchEntriesTask<K,V,U>
5669 >        extends Traverser<K,V,U> {
5670          final Fun<Entry<K,V>, ? extends U> searchFunction;
5671          final AtomicReference<U> result;
5672          SearchEntriesTask
5673 <            (ConcurrentHashMapV8<K,V> m,
5673 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5674               Fun<Entry<K,V>, ? extends U> searchFunction,
5675               AtomicReference<U> result) {
5676 <            super(m);
5676 >            super(m, p, b);
5677              this.searchFunction = searchFunction; this.result = result;
5678          }
5679 <        SearchEntriesTask
5680 <            (BulkTask<K,V,?> p, int b, boolean split,
5681 <             Fun<Entry<K,V>, ? extends U> searchFunction,
5682 <             AtomicReference<U> result) {
5683 <            super(p, b, split);
5684 <            this.searchFunction = searchFunction; this.result = result;
5685 <        }
5686 <        public final void compute() {
5687 <            AtomicReference<U> result = this.result;
5688 <            final Fun<Entry<K,V>, ? extends U> searchFunction =
5689 <                this.searchFunction;
5690 <            if (searchFunction == null || result == null)
5691 <                throw new Error(NullFunctionMessage);
5692 <            int b = batch(), c;
5346 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5347 <                do {} while (!casPending(c = pending, c+1));
5348 <                new SearchEntriesTask<K,V,U>(this, b >>>= 1, true,
5349 <                                             searchFunction, result).fork();
5679 >        public final U getRawResult() { return result.get(); }
5680 >        @SuppressWarnings("unchecked") public final void compute() {
5681 >            final Fun<Entry<K,V>, ? extends U> searchFunction;
5682 >            final AtomicReference<U> result;
5683 >            if ((searchFunction = this.searchFunction) == null ||
5684 >                (result = this.result) == null)
5685 >                throw new NullPointerException();
5686 >            for (int b;;) {
5687 >                if (result.get() != null)
5688 >                    return;
5689 >                if ((b = preSplit()) <= 0)
5690 >                    break;
5691 >                new SearchEntriesTask<K,V,U>
5692 >                    (map, this, b, searchFunction, result).fork();
5693              }
5694 <            Object v; U u;
5695 <            while (result.get() == null && (v = advance()) != null) {
5696 <                if ((u = searchFunction.apply(entryFor((K)nextKey, (V)v))) != null) {
5697 <                    result.compareAndSet(null, u);
5694 >            while (result.get() == null) {
5695 >                Object v; U u;
5696 >                if ((v = advance()) == null) {
5697 >                    propagateCompletion();
5698                      break;
5699                  }
5700 +                if ((u = searchFunction.apply(entryFor((K)nextKey, (V)v))) != null) {
5701 +                    if (result.compareAndSet(null, u))
5702 +                        quietlyCompleteRoot();
5703 +                    return;
5704 +                }
5705              }
5358            tryComplete();
5706          }
5360        public final U getRawResult() { return result.get(); }
5707      }
5708  
5709 <    static final class SearchMappingsTask<K,V,U>
5710 <        extends BulkTask<K,V,U> {
5709 >    @SuppressWarnings("serial") static final class SearchMappingsTask<K,V,U>
5710 >        extends Traverser<K,V,U> {
5711          final BiFun<? super K, ? super V, ? extends U> searchFunction;
5712          final AtomicReference<U> result;
5713          SearchMappingsTask
5714 <            (ConcurrentHashMapV8<K,V> m,
5369 <             BiFun<? super K, ? super V, ? extends U> searchFunction,
5370 <             AtomicReference<U> result) {
5371 <            super(m);
5372 <            this.searchFunction = searchFunction; this.result = result;
5373 <        }
5374 <        SearchMappingsTask
5375 <            (BulkTask<K,V,?> p, int b, boolean split,
5714 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5715               BiFun<? super K, ? super V, ? extends U> searchFunction,
5716               AtomicReference<U> result) {
5717 <            super(p, b, split);
5717 >            super(m, p, b);
5718              this.searchFunction = searchFunction; this.result = result;
5719          }
5720 <        public final void compute() {
5721 <            AtomicReference<U> result = this.result;
5722 <            final BiFun<? super K, ? super V, ? extends U> searchFunction =
5723 <                this.searchFunction;
5724 <            if (searchFunction == null || result == null)
5725 <                throw new Error(NullFunctionMessage);
5726 <            int b = batch(), c;
5727 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5728 <                do {} while (!casPending(c = pending, c+1));
5729 <                new SearchMappingsTask<K,V,U>(this, b >>>= 1, true,
5730 <                                              searchFunction, result).fork();
5720 >        public final U getRawResult() { return result.get(); }
5721 >        @SuppressWarnings("unchecked") public final void compute() {
5722 >            final BiFun<? super K, ? super V, ? extends U> searchFunction;
5723 >            final AtomicReference<U> result;
5724 >            if ((searchFunction = this.searchFunction) == null ||
5725 >                (result = this.result) == null)
5726 >                throw new NullPointerException();
5727 >            for (int b;;) {
5728 >                if (result.get() != null)
5729 >                    return;
5730 >                if ((b = preSplit()) <= 0)
5731 >                    break;
5732 >                new SearchMappingsTask<K,V,U>
5733 >                    (map, this, b, searchFunction, result).fork();
5734              }
5735 <            Object v; U u;
5736 <            while (result.get() == null && (v = advance()) != null) {
5735 >            while (result.get() == null) {
5736 >                Object v; U u;
5737 >                if ((v = advance()) == null) {
5738 >                    propagateCompletion();
5739 >                    break;
5740 >                }
5741                  if ((u = searchFunction.apply((K)nextKey, (V)v)) != null) {
5742 <                    result.compareAndSet(null, u);
5742 >                    if (result.compareAndSet(null, u))
5743 >                        quietlyCompleteRoot();
5744                      break;
5745                  }
5746              }
5400            tryComplete();
5747          }
5402        public final U getRawResult() { return result.get(); }
5748      }
5749  
5750 <    static final class ReduceKeysTask<K,V>
5751 <        extends BulkTask<K,V,K> {
5750 >    @SuppressWarnings("serial") static final class ReduceKeysTask<K,V>
5751 >        extends Traverser<K,V,K> {
5752          final BiFun<? super K, ? super K, ? extends K> reducer;
5753          K result;
5754 <        ReduceKeysTask<K,V> sibling;
5410 <        ReduceKeysTask
5411 <            (ConcurrentHashMapV8<K,V> m,
5412 <             BiFun<? super K, ? super K, ? extends K> reducer) {
5413 <            super(m);
5414 <            this.reducer = reducer;
5415 <        }
5754 >        ReduceKeysTask<K,V> rights, nextRight;
5755          ReduceKeysTask
5756 <            (BulkTask<K,V,?> p, int b, boolean split,
5756 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5757 >             ReduceKeysTask<K,V> nextRight,
5758               BiFun<? super K, ? super K, ? extends K> reducer) {
5759 <            super(p, b, split);
5759 >            super(m, p, b); this.nextRight = nextRight;
5760              this.reducer = reducer;
5761          }
5762 <
5763 <        public final void compute() {
5424 <            ReduceKeysTask<K,V> t = this;
5762 >        public final K getRawResult() { return result; }
5763 >        @SuppressWarnings("unchecked") public final void compute() {
5764              final BiFun<? super K, ? super K, ? extends K> reducer =
5765                  this.reducer;
5766              if (reducer == null)
5767 <                throw new Error(NullFunctionMessage);
5768 <            int b = batch();
5769 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5770 <                b >>>= 1;
5432 <                t.pending = 1;
5433 <                ReduceKeysTask<K,V> rt =
5434 <                    new ReduceKeysTask<K,V>
5435 <                    (t, b, true, reducer);
5436 <                t = new ReduceKeysTask<K,V>
5437 <                    (t, b, false, reducer);
5438 <                t.sibling = rt;
5439 <                rt.sibling = t;
5440 <                rt.fork();
5441 <            }
5767 >                throw new NullPointerException();
5768 >            for (int b; (b = preSplit()) > 0;)
5769 >                (rights = new ReduceKeysTask<K,V>
5770 >                 (map, this, b, rights, reducer)).fork();
5771              K r = null;
5772 <            while (t.advance() != null) {
5773 <                K u = (K)t.nextKey;
5772 >            while (advance() != null) {
5773 >                K u = (K)nextKey;
5774                  r = (r == null) ? u : reducer.apply(r, u);
5775              }
5776 <            t.result = r;
5777 <            for (;;) {
5778 <                int c; BulkTask<K,V,?> par; ReduceKeysTask<K,V> s, p; K u;
5779 <                if ((par = t.parent) == null ||
5780 <                    !(par instanceof ReduceKeysTask)) {
5781 <                    t.quietlyComplete();
5782 <                    break;
5783 <                }
5784 <                else if ((c = (p = (ReduceKeysTask<K,V>)par).pending) == 0) {
5785 <                    if ((s = t.sibling) != null && (u = s.result) != null)
5786 <                        r = (r == null) ? u : reducer.apply(r, u);
5787 <                    (t = p).result = r;
5776 >            result = r;
5777 >            CountedCompleter<?> c;
5778 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
5779 >                ReduceKeysTask<K,V>
5780 >                    t = (ReduceKeysTask<K,V>)c,
5781 >                    s = t.rights;
5782 >                while (s != null) {
5783 >                    K tr, sr;
5784 >                    if ((sr = s.result) != null)
5785 >                        t.result = (((tr = t.result) == null) ? sr :
5786 >                                    reducer.apply(tr, sr));
5787 >                    s = t.rights = s.nextRight;
5788                  }
5460                else if (p.casPending(c, 0))
5461                    break;
5789              }
5790          }
5464        public final K getRawResult() { return result; }
5791      }
5792  
5793 <    static final class ReduceValuesTask<K,V>
5794 <        extends BulkTask<K,V,V> {
5793 >    @SuppressWarnings("serial") static final class ReduceValuesTask<K,V>
5794 >        extends Traverser<K,V,V> {
5795          final BiFun<? super V, ? super V, ? extends V> reducer;
5796          V result;
5797 <        ReduceValuesTask<K,V> sibling;
5797 >        ReduceValuesTask<K,V> rights, nextRight;
5798          ReduceValuesTask
5799 <            (ConcurrentHashMapV8<K,V> m,
5799 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5800 >             ReduceValuesTask<K,V> nextRight,
5801               BiFun<? super V, ? super V, ? extends V> reducer) {
5802 <            super(m);
5802 >            super(m, p, b); this.nextRight = nextRight;
5803              this.reducer = reducer;
5804          }
5805 <        ReduceValuesTask
5806 <            (BulkTask<K,V,?> p, int b, boolean split,
5480 <             BiFun<? super V, ? super V, ? extends V> reducer) {
5481 <            super(p, b, split);
5482 <            this.reducer = reducer;
5483 <        }
5484 <
5485 <        public final void compute() {
5486 <            ReduceValuesTask<K,V> t = this;
5805 >        public final V getRawResult() { return result; }
5806 >        @SuppressWarnings("unchecked") public final void compute() {
5807              final BiFun<? super V, ? super V, ? extends V> reducer =
5808                  this.reducer;
5809              if (reducer == null)
5810 <                throw new Error(NullFunctionMessage);
5811 <            int b = batch();
5812 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5813 <                b >>>= 1;
5494 <                t.pending = 1;
5495 <                ReduceValuesTask<K,V> rt =
5496 <                    new ReduceValuesTask<K,V>
5497 <                    (t, b, true, reducer);
5498 <                t = new ReduceValuesTask<K,V>
5499 <                    (t, b, false, reducer);
5500 <                t.sibling = rt;
5501 <                rt.sibling = t;
5502 <                rt.fork();
5503 <            }
5810 >                throw new NullPointerException();
5811 >            for (int b; (b = preSplit()) > 0;)
5812 >                (rights = new ReduceValuesTask<K,V>
5813 >                 (map, this, b, rights, reducer)).fork();
5814              V r = null;
5815              Object v;
5816 <            while ((v = t.advance()) != null) {
5816 >            while ((v = advance()) != null) {
5817                  V u = (V)v;
5818                  r = (r == null) ? u : reducer.apply(r, u);
5819              }
5820 <            t.result = r;
5821 <            for (;;) {
5822 <                int c; BulkTask<K,V,?> par; ReduceValuesTask<K,V> s, p; V u;
5823 <                if ((par = t.parent) == null ||
5824 <                    !(par instanceof ReduceValuesTask)) {
5825 <                    t.quietlyComplete();
5826 <                    break;
5827 <                }
5828 <                else if ((c = (p = (ReduceValuesTask<K,V>)par).pending) == 0) {
5829 <                    if ((s = t.sibling) != null && (u = s.result) != null)
5830 <                        r = (r == null) ? u : reducer.apply(r, u);
5831 <                    (t = p).result = r;
5820 >            result = r;
5821 >            CountedCompleter<?> c;
5822 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
5823 >                ReduceValuesTask<K,V>
5824 >                    t = (ReduceValuesTask<K,V>)c,
5825 >                    s = t.rights;
5826 >                while (s != null) {
5827 >                    V tr, sr;
5828 >                    if ((sr = s.result) != null)
5829 >                        t.result = (((tr = t.result) == null) ? sr :
5830 >                                    reducer.apply(tr, sr));
5831 >                    s = t.rights = s.nextRight;
5832                  }
5523                else if (p.casPending(c, 0))
5524                    break;
5833              }
5834          }
5527        public final V getRawResult() { return result; }
5835      }
5836  
5837 <    static final class ReduceEntriesTask<K,V>
5838 <        extends BulkTask<K,V,Map.Entry<K,V>> {
5837 >    @SuppressWarnings("serial") static final class ReduceEntriesTask<K,V>
5838 >        extends Traverser<K,V,Map.Entry<K,V>> {
5839          final BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer;
5840          Map.Entry<K,V> result;
5841 <        ReduceEntriesTask<K,V> sibling;
5841 >        ReduceEntriesTask<K,V> rights, nextRight;
5842          ReduceEntriesTask
5843 <            (ConcurrentHashMapV8<K,V> m,
5843 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5844 >             ReduceEntriesTask<K,V> nextRight,
5845               BiFun<Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5846 <            super(m);
5539 <            this.reducer = reducer;
5540 <        }
5541 <        ReduceEntriesTask
5542 <            (BulkTask<K,V,?> p, int b, boolean split,
5543 <             BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5544 <            super(p, b, split);
5846 >            super(m, p, b); this.nextRight = nextRight;
5847              this.reducer = reducer;
5848          }
5849 <
5850 <        public final void compute() {
5549 <            ReduceEntriesTask<K,V> t = this;
5849 >        public final Map.Entry<K,V> getRawResult() { return result; }
5850 >        @SuppressWarnings("unchecked") public final void compute() {
5851              final BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer =
5852                  this.reducer;
5853              if (reducer == null)
5854 <                throw new Error(NullFunctionMessage);
5855 <            int b = batch();
5856 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5857 <                b >>>= 1;
5557 <                t.pending = 1;
5558 <                ReduceEntriesTask<K,V> rt =
5559 <                    new ReduceEntriesTask<K,V>
5560 <                    (t, b, true, reducer);
5561 <                t = new ReduceEntriesTask<K,V>
5562 <                    (t, b, false, reducer);
5563 <                t.sibling = rt;
5564 <                rt.sibling = t;
5565 <                rt.fork();
5566 <            }
5854 >                throw new NullPointerException();
5855 >            for (int b; (b = preSplit()) > 0;)
5856 >                (rights = new ReduceEntriesTask<K,V>
5857 >                 (map, this, b, rights, reducer)).fork();
5858              Map.Entry<K,V> r = null;
5859              Object v;
5860 <            while ((v = t.advance()) != null) {
5861 <                Map.Entry<K,V> u = entryFor((K)t.nextKey, (V)v);
5860 >            while ((v = advance()) != null) {
5861 >                Map.Entry<K,V> u = entryFor((K)nextKey, (V)v);
5862                  r = (r == null) ? u : reducer.apply(r, u);
5863              }
5864 <            t.result = r;
5865 <            for (;;) {
5866 <                int c; BulkTask<K,V,?> par; ReduceEntriesTask<K,V> s, p;
5867 <                Map.Entry<K,V> u;
5868 <                if ((par = t.parent) == null ||
5869 <                    !(par instanceof ReduceEntriesTask)) {
5870 <                    t.quietlyComplete();
5871 <                    break;
5864 >            result = r;
5865 >            CountedCompleter<?> c;
5866 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
5867 >                ReduceEntriesTask<K,V>
5868 >                    t = (ReduceEntriesTask<K,V>)c,
5869 >                    s = t.rights;
5870 >                while (s != null) {
5871 >                    Map.Entry<K,V> tr, sr;
5872 >                    if ((sr = s.result) != null)
5873 >                        t.result = (((tr = t.result) == null) ? sr :
5874 >                                    reducer.apply(tr, sr));
5875 >                    s = t.rights = s.nextRight;
5876                  }
5582                else if ((c = (p = (ReduceEntriesTask<K,V>)par).pending) == 0) {
5583                    if ((s = t.sibling) != null && (u = s.result) != null)
5584                        r = (r == null) ? u : reducer.apply(r, u);
5585                    (t = p).result = r;
5586                }
5587                else if (p.casPending(c, 0))
5588                    break;
5877              }
5878          }
5591        public final Map.Entry<K,V> getRawResult() { return result; }
5879      }
5880  
5881 <    static final class MapReduceKeysTask<K,V,U>
5882 <        extends BulkTask<K,V,U> {
5881 >    @SuppressWarnings("serial") static final class MapReduceKeysTask<K,V,U>
5882 >        extends Traverser<K,V,U> {
5883          final Fun<? super K, ? extends U> transformer;
5884          final BiFun<? super U, ? super U, ? extends U> reducer;
5885          U result;
5886 <        MapReduceKeysTask<K,V,U> sibling;
5600 <        MapReduceKeysTask
5601 <            (ConcurrentHashMapV8<K,V> m,
5602 <             Fun<? super K, ? extends U> transformer,
5603 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5604 <            super(m);
5605 <            this.transformer = transformer;
5606 <            this.reducer = reducer;
5607 <        }
5886 >        MapReduceKeysTask<K,V,U> rights, nextRight;
5887          MapReduceKeysTask
5888 <            (BulkTask<K,V,?> p, int b, boolean split,
5888 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5889 >             MapReduceKeysTask<K,V,U> nextRight,
5890               Fun<? super K, ? extends U> transformer,
5891               BiFun<? super U, ? super U, ? extends U> reducer) {
5892 <            super(p, b, split);
5892 >            super(m, p, b); this.nextRight = nextRight;
5893              this.transformer = transformer;
5894              this.reducer = reducer;
5895          }
5896 <        public final void compute() {
5897 <            MapReduceKeysTask<K,V,U> t = this;
5896 >        public final U getRawResult() { return result; }
5897 >        @SuppressWarnings("unchecked") public final void compute() {
5898              final Fun<? super K, ? extends U> transformer =
5899                  this.transformer;
5900              final BiFun<? super U, ? super U, ? extends U> reducer =
5901                  this.reducer;
5902              if (transformer == null || reducer == null)
5903 <                throw new Error(NullFunctionMessage);
5904 <            int b = batch();
5905 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5906 <                b >>>= 1;
5627 <                t.pending = 1;
5628 <                MapReduceKeysTask<K,V,U> rt =
5629 <                    new MapReduceKeysTask<K,V,U>
5630 <                    (t, b, true, transformer, reducer);
5631 <                t = new MapReduceKeysTask<K,V,U>
5632 <                    (t, b, false, transformer, reducer);
5633 <                t.sibling = rt;
5634 <                rt.sibling = t;
5635 <                rt.fork();
5636 <            }
5903 >                throw new NullPointerException();
5904 >            for (int b; (b = preSplit()) > 0;)
5905 >                (rights = new MapReduceKeysTask<K,V,U>
5906 >                 (map, this, b, rights, transformer, reducer)).fork();
5907              U r = null, u;
5908 <            while (t.advance() != null) {
5909 <                if ((u = transformer.apply((K)t.nextKey)) != null)
5908 >            while (advance() != null) {
5909 >                if ((u = transformer.apply((K)nextKey)) != null)
5910                      r = (r == null) ? u : reducer.apply(r, u);
5911              }
5912 <            t.result = r;
5913 <            for (;;) {
5914 <                int c; BulkTask<K,V,?> par; MapReduceKeysTask<K,V,U> s, p;
5915 <                if ((par = t.parent) == null ||
5916 <                    !(par instanceof MapReduceKeysTask)) {
5917 <                    t.quietlyComplete();
5918 <                    break;
5919 <                }
5920 <                else if ((c = (p = (MapReduceKeysTask<K,V,U>)par).pending) == 0) {
5921 <                    if ((s = t.sibling) != null && (u = s.result) != null)
5922 <                        r = (r == null) ? u : reducer.apply(r, u);
5923 <                    (t = p).result = r;
5912 >            result = r;
5913 >            CountedCompleter<?> c;
5914 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
5915 >                MapReduceKeysTask<K,V,U>
5916 >                    t = (MapReduceKeysTask<K,V,U>)c,
5917 >                    s = t.rights;
5918 >                while (s != null) {
5919 >                    U tr, sr;
5920 >                    if ((sr = s.result) != null)
5921 >                        t.result = (((tr = t.result) == null) ? sr :
5922 >                                    reducer.apply(tr, sr));
5923 >                    s = t.rights = s.nextRight;
5924                  }
5655                else if (p.casPending(c, 0))
5656                    break;
5925              }
5926          }
5659        public final U getRawResult() { return result; }
5927      }
5928  
5929 <    static final class MapReduceValuesTask<K,V,U>
5930 <        extends BulkTask<K,V,U> {
5929 >    @SuppressWarnings("serial") static final class MapReduceValuesTask<K,V,U>
5930 >        extends Traverser<K,V,U> {
5931          final Fun<? super V, ? extends U> transformer;
5932          final BiFun<? super U, ? super U, ? extends U> reducer;
5933          U result;
5934 <        MapReduceValuesTask<K,V,U> sibling;
5668 <        MapReduceValuesTask
5669 <            (ConcurrentHashMapV8<K,V> m,
5670 <             Fun<? super V, ? extends U> transformer,
5671 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5672 <            super(m);
5673 <            this.transformer = transformer;
5674 <            this.reducer = reducer;
5675 <        }
5934 >        MapReduceValuesTask<K,V,U> rights, nextRight;
5935          MapReduceValuesTask
5936 <            (BulkTask<K,V,?> p, int b, boolean split,
5936 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5937 >             MapReduceValuesTask<K,V,U> nextRight,
5938               Fun<? super V, ? extends U> transformer,
5939               BiFun<? super U, ? super U, ? extends U> reducer) {
5940 <            super(p, b, split);
5940 >            super(m, p, b); this.nextRight = nextRight;
5941              this.transformer = transformer;
5942              this.reducer = reducer;
5943          }
5944 <        public final void compute() {
5945 <            MapReduceValuesTask<K,V,U> t = this;
5944 >        public final U getRawResult() { return result; }
5945 >        @SuppressWarnings("unchecked") public final void compute() {
5946              final Fun<? super V, ? extends U> transformer =
5947                  this.transformer;
5948              final BiFun<? super U, ? super U, ? extends U> reducer =
5949                  this.reducer;
5950              if (transformer == null || reducer == null)
5951 <                throw new Error(NullFunctionMessage);
5952 <            int b = batch();
5953 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5954 <                b >>>= 1;
5695 <                t.pending = 1;
5696 <                MapReduceValuesTask<K,V,U> rt =
5697 <                    new MapReduceValuesTask<K,V,U>
5698 <                    (t, b, true, transformer, reducer);
5699 <                t = new MapReduceValuesTask<K,V,U>
5700 <                    (t, b, false, transformer, reducer);
5701 <                t.sibling = rt;
5702 <                rt.sibling = t;
5703 <                rt.fork();
5704 <            }
5951 >                throw new NullPointerException();
5952 >            for (int b; (b = preSplit()) > 0;)
5953 >                (rights = new MapReduceValuesTask<K,V,U>
5954 >                 (map, this, b, rights, transformer, reducer)).fork();
5955              U r = null, u;
5956              Object v;
5957 <            while ((v = t.advance()) != null) {
5957 >            while ((v = advance()) != null) {
5958                  if ((u = transformer.apply((V)v)) != null)
5959                      r = (r == null) ? u : reducer.apply(r, u);
5960              }
5961 <            t.result = r;
5962 <            for (;;) {
5963 <                int c; BulkTask<K,V,?> par; MapReduceValuesTask<K,V,U> s, p;
5964 <                if ((par = t.parent) == null ||
5965 <                    !(par instanceof MapReduceValuesTask)) {
5966 <                    t.quietlyComplete();
5967 <                    break;
5968 <                }
5969 <                else if ((c = (p = (MapReduceValuesTask<K,V,U>)par).pending) == 0) {
5970 <                    if ((s = t.sibling) != null && (u = s.result) != null)
5971 <                        r = (r == null) ? u : reducer.apply(r, u);
5972 <                    (t = p).result = r;
5961 >            result = r;
5962 >            CountedCompleter<?> c;
5963 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
5964 >                MapReduceValuesTask<K,V,U>
5965 >                    t = (MapReduceValuesTask<K,V,U>)c,
5966 >                    s = t.rights;
5967 >                while (s != null) {
5968 >                    U tr, sr;
5969 >                    if ((sr = s.result) != null)
5970 >                        t.result = (((tr = t.result) == null) ? sr :
5971 >                                    reducer.apply(tr, sr));
5972 >                    s = t.rights = s.nextRight;
5973                  }
5724                else if (p.casPending(c, 0))
5725                    break;
5974              }
5975          }
5728        public final U getRawResult() { return result; }
5976      }
5977  
5978 <    static final class MapReduceEntriesTask<K,V,U>
5979 <        extends BulkTask<K,V,U> {
5978 >    @SuppressWarnings("serial") static final class MapReduceEntriesTask<K,V,U>
5979 >        extends Traverser<K,V,U> {
5980          final Fun<Map.Entry<K,V>, ? extends U> transformer;
5981          final BiFun<? super U, ? super U, ? extends U> reducer;
5982          U result;
5983 <        MapReduceEntriesTask<K,V,U> sibling;
5737 <        MapReduceEntriesTask
5738 <            (ConcurrentHashMapV8<K,V> m,
5739 <             Fun<Map.Entry<K,V>, ? extends U> transformer,
5740 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5741 <            super(m);
5742 <            this.transformer = transformer;
5743 <            this.reducer = reducer;
5744 <        }
5983 >        MapReduceEntriesTask<K,V,U> rights, nextRight;
5984          MapReduceEntriesTask
5985 <            (BulkTask<K,V,?> p, int b, boolean split,
5985 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5986 >             MapReduceEntriesTask<K,V,U> nextRight,
5987               Fun<Map.Entry<K,V>, ? extends U> transformer,
5988               BiFun<? super U, ? super U, ? extends U> reducer) {
5989 <            super(p, b, split);
5989 >            super(m, p, b); this.nextRight = nextRight;
5990              this.transformer = transformer;
5991              this.reducer = reducer;
5992          }
5993 <        public final void compute() {
5994 <            MapReduceEntriesTask<K,V,U> t = this;
5993 >        public final U getRawResult() { return result; }
5994 >        @SuppressWarnings("unchecked") public final void compute() {
5995              final Fun<Map.Entry<K,V>, ? extends U> transformer =
5996                  this.transformer;
5997              final BiFun<? super U, ? super U, ? extends U> reducer =
5998                  this.reducer;
5999              if (transformer == null || reducer == null)
6000 <                throw new Error(NullFunctionMessage);
6001 <            int b = batch();
6002 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6003 <                b >>>= 1;
5764 <                t.pending = 1;
5765 <                MapReduceEntriesTask<K,V,U> rt =
5766 <                    new MapReduceEntriesTask<K,V,U>
5767 <                    (t, b, true, transformer, reducer);
5768 <                t = new MapReduceEntriesTask<K,V,U>
5769 <                    (t, b, false, transformer, reducer);
5770 <                t.sibling = rt;
5771 <                rt.sibling = t;
5772 <                rt.fork();
5773 <            }
6000 >                throw new NullPointerException();
6001 >            for (int b; (b = preSplit()) > 0;)
6002 >                (rights = new MapReduceEntriesTask<K,V,U>
6003 >                 (map, this, b, rights, transformer, reducer)).fork();
6004              U r = null, u;
6005              Object v;
6006 <            while ((v = t.advance()) != null) {
6007 <                if ((u = transformer.apply(entryFor((K)t.nextKey, (V)v))) != null)
6006 >            while ((v = advance()) != null) {
6007 >                if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
6008                      r = (r == null) ? u : reducer.apply(r, u);
6009              }
6010 <            t.result = r;
6011 <            for (;;) {
6012 <                int c; BulkTask<K,V,?> par; MapReduceEntriesTask<K,V,U> s, p;
6013 <                if ((par = t.parent) == null ||
6014 <                    !(par instanceof MapReduceEntriesTask)) {
6015 <                    t.quietlyComplete();
6016 <                    break;
6017 <                }
6018 <                else if ((c = (p = (MapReduceEntriesTask<K,V,U>)par).pending) == 0) {
6019 <                    if ((s = t.sibling) != null && (u = s.result) != null)
6020 <                        r = (r == null) ? u : reducer.apply(r, u);
6021 <                    (t = p).result = r;
6010 >            result = r;
6011 >            CountedCompleter<?> c;
6012 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6013 >                MapReduceEntriesTask<K,V,U>
6014 >                    t = (MapReduceEntriesTask<K,V,U>)c,
6015 >                    s = t.rights;
6016 >                while (s != null) {
6017 >                    U tr, sr;
6018 >                    if ((sr = s.result) != null)
6019 >                        t.result = (((tr = t.result) == null) ? sr :
6020 >                                    reducer.apply(tr, sr));
6021 >                    s = t.rights = s.nextRight;
6022                  }
5793                else if (p.casPending(c, 0))
5794                    break;
6023              }
6024          }
5797        public final U getRawResult() { return result; }
6025      }
6026  
6027 <    static final class MapReduceMappingsTask<K,V,U>
6028 <        extends BulkTask<K,V,U> {
6027 >    @SuppressWarnings("serial") static final class MapReduceMappingsTask<K,V,U>
6028 >        extends Traverser<K,V,U> {
6029          final BiFun<? super K, ? super V, ? extends U> transformer;
6030          final BiFun<? super U, ? super U, ? extends U> reducer;
6031          U result;
6032 <        MapReduceMappingsTask<K,V,U> sibling;
5806 <        MapReduceMappingsTask
5807 <            (ConcurrentHashMapV8<K,V> m,
5808 <             BiFun<? super K, ? super V, ? extends U> transformer,
5809 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5810 <            super(m);
5811 <            this.transformer = transformer;
5812 <            this.reducer = reducer;
5813 <        }
6032 >        MapReduceMappingsTask<K,V,U> rights, nextRight;
6033          MapReduceMappingsTask
6034 <            (BulkTask<K,V,?> p, int b, boolean split,
6034 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6035 >             MapReduceMappingsTask<K,V,U> nextRight,
6036               BiFun<? super K, ? super V, ? extends U> transformer,
6037               BiFun<? super U, ? super U, ? extends U> reducer) {
6038 <            super(p, b, split);
6038 >            super(m, p, b); this.nextRight = nextRight;
6039              this.transformer = transformer;
6040              this.reducer = reducer;
6041          }
6042 <        public final void compute() {
6043 <            MapReduceMappingsTask<K,V,U> t = this;
6042 >        public final U getRawResult() { return result; }
6043 >        @SuppressWarnings("unchecked") public final void compute() {
6044              final BiFun<? super K, ? super V, ? extends U> transformer =
6045                  this.transformer;
6046              final BiFun<? super U, ? super U, ? extends U> reducer =
6047                  this.reducer;
6048              if (transformer == null || reducer == null)
6049 <                throw new Error(NullFunctionMessage);
6050 <            int b = batch();
6051 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6052 <                b >>>= 1;
5833 <                t.pending = 1;
5834 <                MapReduceMappingsTask<K,V,U> rt =
5835 <                    new MapReduceMappingsTask<K,V,U>
5836 <                    (t, b, true, transformer, reducer);
5837 <                t = new MapReduceMappingsTask<K,V,U>
5838 <                    (t, b, false, transformer, reducer);
5839 <                t.sibling = rt;
5840 <                rt.sibling = t;
5841 <                rt.fork();
5842 <            }
6049 >                throw new NullPointerException();
6050 >            for (int b; (b = preSplit()) > 0;)
6051 >                (rights = new MapReduceMappingsTask<K,V,U>
6052 >                 (map, this, b, rights, transformer, reducer)).fork();
6053              U r = null, u;
6054              Object v;
6055 <            while ((v = t.advance()) != null) {
6056 <                if ((u = transformer.apply((K)t.nextKey, (V)v)) != null)
6055 >            while ((v = advance()) != null) {
6056 >                if ((u = transformer.apply((K)nextKey, (V)v)) != null)
6057                      r = (r == null) ? u : reducer.apply(r, u);
6058              }
6059 <            for (;;) {
6060 <                int c; BulkTask<K,V,?> par; MapReduceMappingsTask<K,V,U> s, p;
6061 <                if ((par = t.parent) == null ||
6062 <                    !(par instanceof MapReduceMappingsTask)) {
6063 <                    t.quietlyComplete();
6064 <                    break;
6059 >            result = r;
6060 >            CountedCompleter<?> c;
6061 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6062 >                MapReduceMappingsTask<K,V,U>
6063 >                    t = (MapReduceMappingsTask<K,V,U>)c,
6064 >                    s = t.rights;
6065 >                while (s != null) {
6066 >                    U tr, sr;
6067 >                    if ((sr = s.result) != null)
6068 >                        t.result = (((tr = t.result) == null) ? sr :
6069 >                                    reducer.apply(tr, sr));
6070 >                    s = t.rights = s.nextRight;
6071                  }
5856                else if ((c = (p = (MapReduceMappingsTask<K,V,U>)par).pending) == 0) {
5857                    if ((s = t.sibling) != null && (u = s.result) != null)
5858                        r = (r == null) ? u : reducer.apply(r, u);
5859                    (t = p).result = r;
5860                }
5861                else if (p.casPending(c, 0))
5862                    break;
6072              }
6073          }
5865        public final U getRawResult() { return result; }
6074      }
6075  
6076 <    static final class MapReduceKeysToDoubleTask<K,V>
6077 <        extends BulkTask<K,V,Double> {
6076 >    @SuppressWarnings("serial") static final class MapReduceKeysToDoubleTask<K,V>
6077 >        extends Traverser<K,V,Double> {
6078          final ObjectToDouble<? super K> transformer;
6079          final DoubleByDoubleToDouble reducer;
6080          final double basis;
6081          double result;
6082 <        MapReduceKeysToDoubleTask<K,V> sibling;
5875 <        MapReduceKeysToDoubleTask
5876 <            (ConcurrentHashMapV8<K,V> m,
5877 <             ObjectToDouble<? super K> transformer,
5878 <             double basis,
5879 <             DoubleByDoubleToDouble reducer) {
5880 <            super(m);
5881 <            this.transformer = transformer;
5882 <            this.basis = basis; this.reducer = reducer;
5883 <        }
6082 >        MapReduceKeysToDoubleTask<K,V> rights, nextRight;
6083          MapReduceKeysToDoubleTask
6084 <            (BulkTask<K,V,?> p, int b, boolean split,
6084 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6085 >             MapReduceKeysToDoubleTask<K,V> nextRight,
6086               ObjectToDouble<? super K> transformer,
6087               double basis,
6088               DoubleByDoubleToDouble reducer) {
6089 <            super(p, b, split);
6089 >            super(m, p, b); this.nextRight = nextRight;
6090              this.transformer = transformer;
6091              this.basis = basis; this.reducer = reducer;
6092          }
6093 <        public final void compute() {
6094 <            MapReduceKeysToDoubleTask<K,V> t = this;
6093 >        public final Double getRawResult() { return result; }
6094 >        @SuppressWarnings("unchecked") public final void compute() {
6095              final ObjectToDouble<? super K> transformer =
6096                  this.transformer;
6097              final DoubleByDoubleToDouble reducer = this.reducer;
6098              if (transformer == null || reducer == null)
6099 <                throw new Error(NullFunctionMessage);
6100 <            final double id = this.basis;
6101 <            int b = batch();
6102 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6103 <                b >>>= 1;
6104 <                t.pending = 1;
6105 <                MapReduceKeysToDoubleTask<K,V> rt =
6106 <                    new MapReduceKeysToDoubleTask<K,V>
6107 <                    (t, b, true, transformer, id, reducer);
6108 <                t = new MapReduceKeysToDoubleTask<K,V>
6109 <                    (t, b, false, transformer, id, reducer);
6110 <                t.sibling = rt;
6111 <                rt.sibling = t;
6112 <                rt.fork();
6113 <            }
6114 <            double r = id;
5915 <            while (t.advance() != null)
5916 <                r = reducer.apply(r, transformer.apply((K)t.nextKey));
5917 <            t.result = r;
5918 <            for (;;) {
5919 <                int c; BulkTask<K,V,?> par; MapReduceKeysToDoubleTask<K,V> s, p;
5920 <                if ((par = t.parent) == null ||
5921 <                    !(par instanceof MapReduceKeysToDoubleTask)) {
5922 <                    t.quietlyComplete();
5923 <                    break;
5924 <                }
5925 <                else if ((c = (p = (MapReduceKeysToDoubleTask<K,V>)par).pending) == 0) {
5926 <                    if ((s = t.sibling) != null)
5927 <                        r = reducer.apply(r, s.result);
5928 <                    (t = p).result = r;
6099 >                throw new NullPointerException();
6100 >            double r = this.basis;
6101 >            for (int b; (b = preSplit()) > 0;)
6102 >                (rights = new MapReduceKeysToDoubleTask<K,V>
6103 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6104 >            while (advance() != null)
6105 >                r = reducer.apply(r, transformer.apply((K)nextKey));
6106 >            result = r;
6107 >            CountedCompleter<?> c;
6108 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6109 >                MapReduceKeysToDoubleTask<K,V>
6110 >                    t = (MapReduceKeysToDoubleTask<K,V>)c,
6111 >                    s = t.rights;
6112 >                while (s != null) {
6113 >                    t.result = reducer.apply(t.result, s.result);
6114 >                    s = t.rights = s.nextRight;
6115                  }
5930                else if (p.casPending(c, 0))
5931                    break;
6116              }
6117          }
5934        public final Double getRawResult() { return result; }
6118      }
6119  
6120 <    static final class MapReduceValuesToDoubleTask<K,V>
6121 <        extends BulkTask<K,V,Double> {
6120 >    @SuppressWarnings("serial") static final class MapReduceValuesToDoubleTask<K,V>
6121 >        extends Traverser<K,V,Double> {
6122          final ObjectToDouble<? super V> transformer;
6123          final DoubleByDoubleToDouble reducer;
6124          final double basis;
6125          double result;
6126 <        MapReduceValuesToDoubleTask<K,V> sibling;
5944 <        MapReduceValuesToDoubleTask
5945 <            (ConcurrentHashMapV8<K,V> m,
5946 <             ObjectToDouble<? super V> transformer,
5947 <             double basis,
5948 <             DoubleByDoubleToDouble reducer) {
5949 <            super(m);
5950 <            this.transformer = transformer;
5951 <            this.basis = basis; this.reducer = reducer;
5952 <        }
6126 >        MapReduceValuesToDoubleTask<K,V> rights, nextRight;
6127          MapReduceValuesToDoubleTask
6128 <            (BulkTask<K,V,?> p, int b, boolean split,
6128 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6129 >             MapReduceValuesToDoubleTask<K,V> nextRight,
6130               ObjectToDouble<? super V> transformer,
6131               double basis,
6132               DoubleByDoubleToDouble reducer) {
6133 <            super(p, b, split);
6133 >            super(m, p, b); this.nextRight = nextRight;
6134              this.transformer = transformer;
6135              this.basis = basis; this.reducer = reducer;
6136          }
6137 <        public final void compute() {
6138 <            MapReduceValuesToDoubleTask<K,V> t = this;
6137 >        public final Double getRawResult() { return result; }
6138 >        @SuppressWarnings("unchecked") public final void compute() {
6139              final ObjectToDouble<? super V> transformer =
6140                  this.transformer;
6141              final DoubleByDoubleToDouble reducer = this.reducer;
6142              if (transformer == null || reducer == null)
6143 <                throw new Error(NullFunctionMessage);
6144 <            final double id = this.basis;
6145 <            int b = batch();
6146 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6147 <                b >>>= 1;
5973 <                t.pending = 1;
5974 <                MapReduceValuesToDoubleTask<K,V> rt =
5975 <                    new MapReduceValuesToDoubleTask<K,V>
5976 <                    (t, b, true, transformer, id, reducer);
5977 <                t = new MapReduceValuesToDoubleTask<K,V>
5978 <                    (t, b, false, transformer, id, reducer);
5979 <                t.sibling = rt;
5980 <                rt.sibling = t;
5981 <                rt.fork();
5982 <            }
5983 <            double r = id;
6143 >                throw new NullPointerException();
6144 >            double r = this.basis;
6145 >            for (int b; (b = preSplit()) > 0;)
6146 >                (rights = new MapReduceValuesToDoubleTask<K,V>
6147 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6148              Object v;
6149 <            while ((v = t.advance()) != null)
6149 >            while ((v = advance()) != null)
6150                  r = reducer.apply(r, transformer.apply((V)v));
6151 <            t.result = r;
6152 <            for (;;) {
6153 <                int c; BulkTask<K,V,?> par; MapReduceValuesToDoubleTask<K,V> s, p;
6154 <                if ((par = t.parent) == null ||
6155 <                    !(par instanceof MapReduceValuesToDoubleTask)) {
6156 <                    t.quietlyComplete();
6157 <                    break;
6158 <                }
6159 <                else if ((c = (p = (MapReduceValuesToDoubleTask<K,V>)par).pending) == 0) {
5996 <                    if ((s = t.sibling) != null)
5997 <                        r = reducer.apply(r, s.result);
5998 <                    (t = p).result = r;
6151 >            result = r;
6152 >            CountedCompleter<?> c;
6153 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6154 >                MapReduceValuesToDoubleTask<K,V>
6155 >                    t = (MapReduceValuesToDoubleTask<K,V>)c,
6156 >                    s = t.rights;
6157 >                while (s != null) {
6158 >                    t.result = reducer.apply(t.result, s.result);
6159 >                    s = t.rights = s.nextRight;
6160                  }
6000                else if (p.casPending(c, 0))
6001                    break;
6161              }
6162          }
6004        public final Double getRawResult() { return result; }
6163      }
6164  
6165 <    static final class MapReduceEntriesToDoubleTask<K,V>
6166 <        extends BulkTask<K,V,Double> {
6165 >    @SuppressWarnings("serial") static final class MapReduceEntriesToDoubleTask<K,V>
6166 >        extends Traverser<K,V,Double> {
6167          final ObjectToDouble<Map.Entry<K,V>> transformer;
6168          final DoubleByDoubleToDouble reducer;
6169          final double basis;
6170          double result;
6171 <        MapReduceEntriesToDoubleTask<K,V> sibling;
6171 >        MapReduceEntriesToDoubleTask<K,V> rights, nextRight;
6172          MapReduceEntriesToDoubleTask
6173 <            (ConcurrentHashMapV8<K,V> m,
6173 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6174 >             MapReduceEntriesToDoubleTask<K,V> nextRight,
6175               ObjectToDouble<Map.Entry<K,V>> transformer,
6176               double basis,
6177               DoubleByDoubleToDouble reducer) {
6178 <            super(m);
6178 >            super(m, p, b); this.nextRight = nextRight;
6179              this.transformer = transformer;
6180              this.basis = basis; this.reducer = reducer;
6181          }
6182 <        MapReduceEntriesToDoubleTask
6183 <            (BulkTask<K,V,?> p, int b, boolean split,
6025 <             ObjectToDouble<Map.Entry<K,V>> transformer,
6026 <             double basis,
6027 <             DoubleByDoubleToDouble reducer) {
6028 <            super(p, b, split);
6029 <            this.transformer = transformer;
6030 <            this.basis = basis; this.reducer = reducer;
6031 <        }
6032 <        public final void compute() {
6033 <            MapReduceEntriesToDoubleTask<K,V> t = this;
6182 >        public final Double getRawResult() { return result; }
6183 >        @SuppressWarnings("unchecked") public final void compute() {
6184              final ObjectToDouble<Map.Entry<K,V>> transformer =
6185                  this.transformer;
6186              final DoubleByDoubleToDouble reducer = this.reducer;
6187              if (transformer == null || reducer == null)
6188 <                throw new Error(NullFunctionMessage);
6189 <            final double id = this.basis;
6190 <            int b = batch();
6191 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6192 <                b >>>= 1;
6043 <                t.pending = 1;
6044 <                MapReduceEntriesToDoubleTask<K,V> rt =
6045 <                    new MapReduceEntriesToDoubleTask<K,V>
6046 <                    (t, b, true, transformer, id, reducer);
6047 <                t = new MapReduceEntriesToDoubleTask<K,V>
6048 <                    (t, b, false, transformer, id, reducer);
6049 <                t.sibling = rt;
6050 <                rt.sibling = t;
6051 <                rt.fork();
6052 <            }
6053 <            double r = id;
6188 >                throw new NullPointerException();
6189 >            double r = this.basis;
6190 >            for (int b; (b = preSplit()) > 0;)
6191 >                (rights = new MapReduceEntriesToDoubleTask<K,V>
6192 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6193              Object v;
6194 <            while ((v = t.advance()) != null)
6195 <                r = reducer.apply(r, transformer.apply(entryFor((K)t.nextKey, (V)v)));
6196 <            t.result = r;
6197 <            for (;;) {
6198 <                int c; BulkTask<K,V,?> par; MapReduceEntriesToDoubleTask<K,V> s, p;
6199 <                if ((par = t.parent) == null ||
6200 <                    !(par instanceof MapReduceEntriesToDoubleTask)) {
6201 <                    t.quietlyComplete();
6202 <                    break;
6203 <                }
6204 <                else if ((c = (p = (MapReduceEntriesToDoubleTask<K,V>)par).pending) == 0) {
6066 <                    if ((s = t.sibling) != null)
6067 <                        r = reducer.apply(r, s.result);
6068 <                    (t = p).result = r;
6194 >            while ((v = advance()) != null)
6195 >                r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6196 >            result = r;
6197 >            CountedCompleter<?> c;
6198 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6199 >                MapReduceEntriesToDoubleTask<K,V>
6200 >                    t = (MapReduceEntriesToDoubleTask<K,V>)c,
6201 >                    s = t.rights;
6202 >                while (s != null) {
6203 >                    t.result = reducer.apply(t.result, s.result);
6204 >                    s = t.rights = s.nextRight;
6205                  }
6070                else if (p.casPending(c, 0))
6071                    break;
6206              }
6207          }
6074        public final Double getRawResult() { return result; }
6208      }
6209  
6210 <    static final class MapReduceMappingsToDoubleTask<K,V>
6211 <        extends BulkTask<K,V,Double> {
6210 >    @SuppressWarnings("serial") static final class MapReduceMappingsToDoubleTask<K,V>
6211 >        extends Traverser<K,V,Double> {
6212          final ObjectByObjectToDouble<? super K, ? super V> transformer;
6213          final DoubleByDoubleToDouble reducer;
6214          final double basis;
6215          double result;
6216 <        MapReduceMappingsToDoubleTask<K,V> sibling;
6216 >        MapReduceMappingsToDoubleTask<K,V> rights, nextRight;
6217          MapReduceMappingsToDoubleTask
6218 <            (ConcurrentHashMapV8<K,V> m,
6218 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6219 >             MapReduceMappingsToDoubleTask<K,V> nextRight,
6220               ObjectByObjectToDouble<? super K, ? super V> transformer,
6221               double basis,
6222               DoubleByDoubleToDouble reducer) {
6223 <            super(m);
6223 >            super(m, p, b); this.nextRight = nextRight;
6224              this.transformer = transformer;
6225              this.basis = basis; this.reducer = reducer;
6226          }
6227 <        MapReduceMappingsToDoubleTask
6228 <            (BulkTask<K,V,?> p, int b, boolean split,
6095 <             ObjectByObjectToDouble<? super K, ? super V> transformer,
6096 <             double basis,
6097 <             DoubleByDoubleToDouble reducer) {
6098 <            super(p, b, split);
6099 <            this.transformer = transformer;
6100 <            this.basis = basis; this.reducer = reducer;
6101 <        }
6102 <        public final void compute() {
6103 <            MapReduceMappingsToDoubleTask<K,V> t = this;
6227 >        public final Double getRawResult() { return result; }
6228 >        @SuppressWarnings("unchecked") public final void compute() {
6229              final ObjectByObjectToDouble<? super K, ? super V> transformer =
6230                  this.transformer;
6231              final DoubleByDoubleToDouble reducer = this.reducer;
6232              if (transformer == null || reducer == null)
6233 <                throw new Error(NullFunctionMessage);
6234 <            final double id = this.basis;
6235 <            int b = batch();
6236 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6237 <                b >>>= 1;
6113 <                t.pending = 1;
6114 <                MapReduceMappingsToDoubleTask<K,V> rt =
6115 <                    new MapReduceMappingsToDoubleTask<K,V>
6116 <                    (t, b, true, transformer, id, reducer);
6117 <                t = new MapReduceMappingsToDoubleTask<K,V>
6118 <                    (t, b, false, transformer, id, reducer);
6119 <                t.sibling = rt;
6120 <                rt.sibling = t;
6121 <                rt.fork();
6122 <            }
6123 <            double r = id;
6233 >                throw new NullPointerException();
6234 >            double r = this.basis;
6235 >            for (int b; (b = preSplit()) > 0;)
6236 >                (rights = new MapReduceMappingsToDoubleTask<K,V>
6237 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6238              Object v;
6239 <            while ((v = t.advance()) != null)
6240 <                r = reducer.apply(r, transformer.apply((K)t.nextKey, (V)v));
6241 <            t.result = r;
6242 <            for (;;) {
6243 <                int c; BulkTask<K,V,?> par; MapReduceMappingsToDoubleTask<K,V> s, p;
6244 <                if ((par = t.parent) == null ||
6245 <                    !(par instanceof MapReduceMappingsToDoubleTask)) {
6246 <                    t.quietlyComplete();
6247 <                    break;
6248 <                }
6249 <                else if ((c = (p = (MapReduceMappingsToDoubleTask<K,V>)par).pending) == 0) {
6136 <                    if ((s = t.sibling) != null)
6137 <                        r = reducer.apply(r, s.result);
6138 <                    (t = p).result = r;
6239 >            while ((v = advance()) != null)
6240 >                r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6241 >            result = r;
6242 >            CountedCompleter<?> c;
6243 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6244 >                MapReduceMappingsToDoubleTask<K,V>
6245 >                    t = (MapReduceMappingsToDoubleTask<K,V>)c,
6246 >                    s = t.rights;
6247 >                while (s != null) {
6248 >                    t.result = reducer.apply(t.result, s.result);
6249 >                    s = t.rights = s.nextRight;
6250                  }
6140                else if (p.casPending(c, 0))
6141                    break;
6251              }
6252          }
6144        public final Double getRawResult() { return result; }
6253      }
6254  
6255 <    static final class MapReduceKeysToLongTask<K,V>
6256 <        extends BulkTask<K,V,Long> {
6255 >    @SuppressWarnings("serial") static final class MapReduceKeysToLongTask<K,V>
6256 >        extends Traverser<K,V,Long> {
6257          final ObjectToLong<? super K> transformer;
6258          final LongByLongToLong reducer;
6259          final long basis;
6260          long result;
6261 <        MapReduceKeysToLongTask<K,V> sibling;
6154 <        MapReduceKeysToLongTask
6155 <            (ConcurrentHashMapV8<K,V> m,
6156 <             ObjectToLong<? super K> transformer,
6157 <             long basis,
6158 <             LongByLongToLong reducer) {
6159 <            super(m);
6160 <            this.transformer = transformer;
6161 <            this.basis = basis; this.reducer = reducer;
6162 <        }
6261 >        MapReduceKeysToLongTask<K,V> rights, nextRight;
6262          MapReduceKeysToLongTask
6263 <            (BulkTask<K,V,?> p, int b, boolean split,
6263 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6264 >             MapReduceKeysToLongTask<K,V> nextRight,
6265               ObjectToLong<? super K> transformer,
6266               long basis,
6267               LongByLongToLong reducer) {
6268 <            super(p, b, split);
6268 >            super(m, p, b); this.nextRight = nextRight;
6269              this.transformer = transformer;
6270              this.basis = basis; this.reducer = reducer;
6271          }
6272 <        public final void compute() {
6273 <            MapReduceKeysToLongTask<K,V> t = this;
6272 >        public final Long getRawResult() { return result; }
6273 >        @SuppressWarnings("unchecked") public final void compute() {
6274              final ObjectToLong<? super K> transformer =
6275                  this.transformer;
6276              final LongByLongToLong reducer = this.reducer;
6277              if (transformer == null || reducer == null)
6278 <                throw new Error(NullFunctionMessage);
6279 <            final long id = this.basis;
6280 <            int b = batch();
6281 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6282 <                b >>>= 1;
6283 <                t.pending = 1;
6284 <                MapReduceKeysToLongTask<K,V> rt =
6285 <                    new MapReduceKeysToLongTask<K,V>
6286 <                    (t, b, true, transformer, id, reducer);
6287 <                t = new MapReduceKeysToLongTask<K,V>
6288 <                    (t, b, false, transformer, id, reducer);
6289 <                t.sibling = rt;
6290 <                rt.sibling = t;
6291 <                rt.fork();
6292 <            }
6293 <            long r = id;
6194 <            while (t.advance() != null)
6195 <                r = reducer.apply(r, transformer.apply((K)t.nextKey));
6196 <            t.result = r;
6197 <            for (;;) {
6198 <                int c; BulkTask<K,V,?> par; MapReduceKeysToLongTask<K,V> s, p;
6199 <                if ((par = t.parent) == null ||
6200 <                    !(par instanceof MapReduceKeysToLongTask)) {
6201 <                    t.quietlyComplete();
6202 <                    break;
6203 <                }
6204 <                else if ((c = (p = (MapReduceKeysToLongTask<K,V>)par).pending) == 0) {
6205 <                    if ((s = t.sibling) != null)
6206 <                        r = reducer.apply(r, s.result);
6207 <                    (t = p).result = r;
6278 >                throw new NullPointerException();
6279 >            long r = this.basis;
6280 >            for (int b; (b = preSplit()) > 0;)
6281 >                (rights = new MapReduceKeysToLongTask<K,V>
6282 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6283 >            while (advance() != null)
6284 >                r = reducer.apply(r, transformer.apply((K)nextKey));
6285 >            result = r;
6286 >            CountedCompleter<?> c;
6287 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6288 >                MapReduceKeysToLongTask<K,V>
6289 >                    t = (MapReduceKeysToLongTask<K,V>)c,
6290 >                    s = t.rights;
6291 >                while (s != null) {
6292 >                    t.result = reducer.apply(t.result, s.result);
6293 >                    s = t.rights = s.nextRight;
6294                  }
6209                else if (p.casPending(c, 0))
6210                    break;
6295              }
6296          }
6213        public final Long getRawResult() { return result; }
6297      }
6298  
6299 <    static final class MapReduceValuesToLongTask<K,V>
6300 <        extends BulkTask<K,V,Long> {
6299 >    @SuppressWarnings("serial") static final class MapReduceValuesToLongTask<K,V>
6300 >        extends Traverser<K,V,Long> {
6301          final ObjectToLong<? super V> transformer;
6302          final LongByLongToLong reducer;
6303          final long basis;
6304          long result;
6305 <        MapReduceValuesToLongTask<K,V> sibling;
6223 <        MapReduceValuesToLongTask
6224 <            (ConcurrentHashMapV8<K,V> m,
6225 <             ObjectToLong<? super V> transformer,
6226 <             long basis,
6227 <             LongByLongToLong reducer) {
6228 <            super(m);
6229 <            this.transformer = transformer;
6230 <            this.basis = basis; this.reducer = reducer;
6231 <        }
6305 >        MapReduceValuesToLongTask<K,V> rights, nextRight;
6306          MapReduceValuesToLongTask
6307 <            (BulkTask<K,V,?> p, int b, boolean split,
6307 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6308 >             MapReduceValuesToLongTask<K,V> nextRight,
6309               ObjectToLong<? super V> transformer,
6310               long basis,
6311               LongByLongToLong reducer) {
6312 <            super(p, b, split);
6312 >            super(m, p, b); this.nextRight = nextRight;
6313              this.transformer = transformer;
6314              this.basis = basis; this.reducer = reducer;
6315          }
6316 <        public final void compute() {
6317 <            MapReduceValuesToLongTask<K,V> t = this;
6316 >        public final Long getRawResult() { return result; }
6317 >        @SuppressWarnings("unchecked") public final void compute() {
6318              final ObjectToLong<? super V> transformer =
6319                  this.transformer;
6320              final LongByLongToLong reducer = this.reducer;
6321              if (transformer == null || reducer == null)
6322 <                throw new Error(NullFunctionMessage);
6323 <            final long id = this.basis;
6324 <            int b = batch();
6325 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6326 <                b >>>= 1;
6252 <                t.pending = 1;
6253 <                MapReduceValuesToLongTask<K,V> rt =
6254 <                    new MapReduceValuesToLongTask<K,V>
6255 <                    (t, b, true, transformer, id, reducer);
6256 <                t = new MapReduceValuesToLongTask<K,V>
6257 <                    (t, b, false, transformer, id, reducer);
6258 <                t.sibling = rt;
6259 <                rt.sibling = t;
6260 <                rt.fork();
6261 <            }
6262 <            long r = id;
6322 >                throw new NullPointerException();
6323 >            long r = this.basis;
6324 >            for (int b; (b = preSplit()) > 0;)
6325 >                (rights = new MapReduceValuesToLongTask<K,V>
6326 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6327              Object v;
6328 <            while ((v = t.advance()) != null)
6328 >            while ((v = advance()) != null)
6329                  r = reducer.apply(r, transformer.apply((V)v));
6330 <            t.result = r;
6331 <            for (;;) {
6332 <                int c; BulkTask<K,V,?> par; MapReduceValuesToLongTask<K,V> s, p;
6333 <                if ((par = t.parent) == null ||
6334 <                    !(par instanceof MapReduceValuesToLongTask)) {
6335 <                    t.quietlyComplete();
6336 <                    break;
6337 <                }
6338 <                else if ((c = (p = (MapReduceValuesToLongTask<K,V>)par).pending) == 0) {
6275 <                    if ((s = t.sibling) != null)
6276 <                        r = reducer.apply(r, s.result);
6277 <                    (t = p).result = r;
6330 >            result = r;
6331 >            CountedCompleter<?> c;
6332 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6333 >                MapReduceValuesToLongTask<K,V>
6334 >                    t = (MapReduceValuesToLongTask<K,V>)c,
6335 >                    s = t.rights;
6336 >                while (s != null) {
6337 >                    t.result = reducer.apply(t.result, s.result);
6338 >                    s = t.rights = s.nextRight;
6339                  }
6279                else if (p.casPending(c, 0))
6280                    break;
6340              }
6341          }
6283        public final Long getRawResult() { return result; }
6342      }
6343  
6344 <    static final class MapReduceEntriesToLongTask<K,V>
6345 <        extends BulkTask<K,V,Long> {
6344 >    @SuppressWarnings("serial") static final class MapReduceEntriesToLongTask<K,V>
6345 >        extends Traverser<K,V,Long> {
6346          final ObjectToLong<Map.Entry<K,V>> transformer;
6347          final LongByLongToLong reducer;
6348          final long basis;
6349          long result;
6350 <        MapReduceEntriesToLongTask<K,V> sibling;
6293 <        MapReduceEntriesToLongTask
6294 <            (ConcurrentHashMapV8<K,V> m,
6295 <             ObjectToLong<Map.Entry<K,V>> transformer,
6296 <             long basis,
6297 <             LongByLongToLong reducer) {
6298 <            super(m);
6299 <            this.transformer = transformer;
6300 <            this.basis = basis; this.reducer = reducer;
6301 <        }
6350 >        MapReduceEntriesToLongTask<K,V> rights, nextRight;
6351          MapReduceEntriesToLongTask
6352 <            (BulkTask<K,V,?> p, int b, boolean split,
6352 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6353 >             MapReduceEntriesToLongTask<K,V> nextRight,
6354               ObjectToLong<Map.Entry<K,V>> transformer,
6355               long basis,
6356               LongByLongToLong reducer) {
6357 <            super(p, b, split);
6357 >            super(m, p, b); this.nextRight = nextRight;
6358              this.transformer = transformer;
6359              this.basis = basis; this.reducer = reducer;
6360          }
6361 <        public final void compute() {
6362 <            MapReduceEntriesToLongTask<K,V> t = this;
6361 >        public final Long getRawResult() { return result; }
6362 >        @SuppressWarnings("unchecked") public final void compute() {
6363              final ObjectToLong<Map.Entry<K,V>> transformer =
6364                  this.transformer;
6365              final LongByLongToLong reducer = this.reducer;
6366              if (transformer == null || reducer == null)
6367 <                throw new Error(NullFunctionMessage);
6368 <            final long id = this.basis;
6369 <            int b = batch();
6370 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6371 <                b >>>= 1;
6322 <                t.pending = 1;
6323 <                MapReduceEntriesToLongTask<K,V> rt =
6324 <                    new MapReduceEntriesToLongTask<K,V>
6325 <                    (t, b, true, transformer, id, reducer);
6326 <                t = new MapReduceEntriesToLongTask<K,V>
6327 <                    (t, b, false, transformer, id, reducer);
6328 <                t.sibling = rt;
6329 <                rt.sibling = t;
6330 <                rt.fork();
6331 <            }
6332 <            long r = id;
6367 >                throw new NullPointerException();
6368 >            long r = this.basis;
6369 >            for (int b; (b = preSplit()) > 0;)
6370 >                (rights = new MapReduceEntriesToLongTask<K,V>
6371 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6372              Object v;
6373 <            while ((v = t.advance()) != null)
6374 <                r = reducer.apply(r, transformer.apply(entryFor((K)t.nextKey, (V)v)));
6375 <            t.result = r;
6376 <            for (;;) {
6377 <                int c; BulkTask<K,V,?> par; MapReduceEntriesToLongTask<K,V> s, p;
6378 <                if ((par = t.parent) == null ||
6379 <                    !(par instanceof MapReduceEntriesToLongTask)) {
6380 <                    t.quietlyComplete();
6381 <                    break;
6382 <                }
6383 <                else if ((c = (p = (MapReduceEntriesToLongTask<K,V>)par).pending) == 0) {
6345 <                    if ((s = t.sibling) != null)
6346 <                        r = reducer.apply(r, s.result);
6347 <                    (t = p).result = r;
6373 >            while ((v = advance()) != null)
6374 >                r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6375 >            result = r;
6376 >            CountedCompleter<?> c;
6377 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6378 >                MapReduceEntriesToLongTask<K,V>
6379 >                    t = (MapReduceEntriesToLongTask<K,V>)c,
6380 >                    s = t.rights;
6381 >                while (s != null) {
6382 >                    t.result = reducer.apply(t.result, s.result);
6383 >                    s = t.rights = s.nextRight;
6384                  }
6349                else if (p.casPending(c, 0))
6350                    break;
6385              }
6386          }
6353        public final Long getRawResult() { return result; }
6387      }
6388  
6389 <    static final class MapReduceMappingsToLongTask<K,V>
6390 <        extends BulkTask<K,V,Long> {
6389 >    @SuppressWarnings("serial") static final class MapReduceMappingsToLongTask<K,V>
6390 >        extends Traverser<K,V,Long> {
6391          final ObjectByObjectToLong<? super K, ? super V> transformer;
6392          final LongByLongToLong reducer;
6393          final long basis;
6394          long result;
6395 <        MapReduceMappingsToLongTask<K,V> sibling;
6395 >        MapReduceMappingsToLongTask<K,V> rights, nextRight;
6396          MapReduceMappingsToLongTask
6397 <            (ConcurrentHashMapV8<K,V> m,
6397 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6398 >             MapReduceMappingsToLongTask<K,V> nextRight,
6399               ObjectByObjectToLong<? super K, ? super V> transformer,
6400               long basis,
6401               LongByLongToLong reducer) {
6402 <            super(m);
6402 >            super(m, p, b); this.nextRight = nextRight;
6403              this.transformer = transformer;
6404              this.basis = basis; this.reducer = reducer;
6405          }
6406 <        MapReduceMappingsToLongTask
6407 <            (BulkTask<K,V,?> p, int b, boolean split,
6374 <             ObjectByObjectToLong<? super K, ? super V> transformer,
6375 <             long basis,
6376 <             LongByLongToLong reducer) {
6377 <            super(p, b, split);
6378 <            this.transformer = transformer;
6379 <            this.basis = basis; this.reducer = reducer;
6380 <        }
6381 <        public final void compute() {
6382 <            MapReduceMappingsToLongTask<K,V> t = this;
6406 >        public final Long getRawResult() { return result; }
6407 >        @SuppressWarnings("unchecked") public final void compute() {
6408              final ObjectByObjectToLong<? super K, ? super V> transformer =
6409                  this.transformer;
6410              final LongByLongToLong reducer = this.reducer;
6411              if (transformer == null || reducer == null)
6412 <                throw new Error(NullFunctionMessage);
6413 <            final long id = this.basis;
6414 <            int b = batch();
6415 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6416 <                b >>>= 1;
6392 <                t.pending = 1;
6393 <                MapReduceMappingsToLongTask<K,V> rt =
6394 <                    new MapReduceMappingsToLongTask<K,V>
6395 <                    (t, b, true, transformer, id, reducer);
6396 <                t = new MapReduceMappingsToLongTask<K,V>
6397 <                    (t, b, false, transformer, id, reducer);
6398 <                t.sibling = rt;
6399 <                rt.sibling = t;
6400 <                rt.fork();
6401 <            }
6402 <            long r = id;
6412 >                throw new NullPointerException();
6413 >            long r = this.basis;
6414 >            for (int b; (b = preSplit()) > 0;)
6415 >                (rights = new MapReduceMappingsToLongTask<K,V>
6416 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6417              Object v;
6418 <            while ((v = t.advance()) != null)
6419 <                r = reducer.apply(r, transformer.apply((K)t.nextKey, (V)v));
6420 <            t.result = r;
6421 <            for (;;) {
6422 <                int c; BulkTask<K,V,?> par; MapReduceMappingsToLongTask<K,V> s, p;
6423 <                if ((par = t.parent) == null ||
6424 <                    !(par instanceof MapReduceMappingsToLongTask)) {
6425 <                    t.quietlyComplete();
6426 <                    break;
6427 <                }
6428 <                else if ((c = (p = (MapReduceMappingsToLongTask<K,V>)par).pending) == 0) {
6415 <                    if ((s = t.sibling) != null)
6416 <                        r = reducer.apply(r, s.result);
6417 <                    (t = p).result = r;
6418 >            while ((v = advance()) != null)
6419 >                r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6420 >            result = r;
6421 >            CountedCompleter<?> c;
6422 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6423 >                MapReduceMappingsToLongTask<K,V>
6424 >                    t = (MapReduceMappingsToLongTask<K,V>)c,
6425 >                    s = t.rights;
6426 >                while (s != null) {
6427 >                    t.result = reducer.apply(t.result, s.result);
6428 >                    s = t.rights = s.nextRight;
6429                  }
6419                else if (p.casPending(c, 0))
6420                    break;
6430              }
6431          }
6423        public final Long getRawResult() { return result; }
6432      }
6433  
6434 <    static final class MapReduceKeysToIntTask<K,V>
6435 <        extends BulkTask<K,V,Integer> {
6434 >    @SuppressWarnings("serial") static final class MapReduceKeysToIntTask<K,V>
6435 >        extends Traverser<K,V,Integer> {
6436          final ObjectToInt<? super K> transformer;
6437          final IntByIntToInt reducer;
6438          final int basis;
6439          int result;
6440 <        MapReduceKeysToIntTask<K,V> sibling;
6433 <        MapReduceKeysToIntTask
6434 <            (ConcurrentHashMapV8<K,V> m,
6435 <             ObjectToInt<? super K> transformer,
6436 <             int basis,
6437 <             IntByIntToInt reducer) {
6438 <            super(m);
6439 <            this.transformer = transformer;
6440 <            this.basis = basis; this.reducer = reducer;
6441 <        }
6440 >        MapReduceKeysToIntTask<K,V> rights, nextRight;
6441          MapReduceKeysToIntTask
6442 <            (BulkTask<K,V,?> p, int b, boolean split,
6442 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6443 >             MapReduceKeysToIntTask<K,V> nextRight,
6444               ObjectToInt<? super K> transformer,
6445               int basis,
6446               IntByIntToInt reducer) {
6447 <            super(p, b, split);
6447 >            super(m, p, b); this.nextRight = nextRight;
6448              this.transformer = transformer;
6449              this.basis = basis; this.reducer = reducer;
6450          }
6451 <        public final void compute() {
6452 <            MapReduceKeysToIntTask<K,V> t = this;
6451 >        public final Integer getRawResult() { return result; }
6452 >        @SuppressWarnings("unchecked") public final void compute() {
6453              final ObjectToInt<? super K> transformer =
6454                  this.transformer;
6455              final IntByIntToInt reducer = this.reducer;
6456              if (transformer == null || reducer == null)
6457 <                throw new Error(NullFunctionMessage);
6458 <            final int id = this.basis;
6459 <            int b = batch();
6460 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6461 <                b >>>= 1;
6462 <                t.pending = 1;
6463 <                MapReduceKeysToIntTask<K,V> rt =
6464 <                    new MapReduceKeysToIntTask<K,V>
6465 <                    (t, b, true, transformer, id, reducer);
6466 <                t = new MapReduceKeysToIntTask<K,V>
6467 <                    (t, b, false, transformer, id, reducer);
6468 <                t.sibling = rt;
6469 <                rt.sibling = t;
6470 <                rt.fork();
6471 <            }
6472 <            int r = id;
6473 <            while (t.advance() != null)
6474 <                r = reducer.apply(r, transformer.apply((K)t.nextKey));
6475 <            t.result = r;
6476 <            for (;;) {
6477 <                int c; BulkTask<K,V,?> par; MapReduceKeysToIntTask<K,V> s, p;
6478 <                if ((par = t.parent) == null ||
6479 <                    !(par instanceof MapReduceKeysToIntTask)) {
6480 <                    t.quietlyComplete();
6481 <                    break;
6482 <                }
6483 <                else if ((c = (p = (MapReduceKeysToIntTask<K,V>)par).pending) == 0) {
6484 <                    if ((s = t.sibling) != null)
6485 <                        r = reducer.apply(r, s.result);
6486 <                    (t = p).result = r;
6457 >                throw new NullPointerException();
6458 >            int r = this.basis;
6459 >            for (int b; (b = preSplit()) > 0;)
6460 >                (rights = new MapReduceKeysToIntTask<K,V>
6461 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6462 >            while (advance() != null)
6463 >                r = reducer.apply(r, transformer.apply((K)nextKey));
6464 >            result = r;
6465 >            CountedCompleter<?> c;
6466 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6467 >                MapReduceKeysToIntTask<K,V>
6468 >                    t = (MapReduceKeysToIntTask<K,V>)c,
6469 >                    s = t.rights;
6470 >                while (s != null) {
6471 >                    t.result = reducer.apply(t.result, s.result);
6472 >                    s = t.rights = s.nextRight;
6473                  }
6488                else if (p.casPending(c, 0))
6489                    break;
6474              }
6475          }
6492        public final Integer getRawResult() { return result; }
6476      }
6477  
6478 <    static final class MapReduceValuesToIntTask<K,V>
6479 <        extends BulkTask<K,V,Integer> {
6478 >    @SuppressWarnings("serial") static final class MapReduceValuesToIntTask<K,V>
6479 >        extends Traverser<K,V,Integer> {
6480          final ObjectToInt<? super V> transformer;
6481          final IntByIntToInt reducer;
6482          final int basis;
6483          int result;
6484 <        MapReduceValuesToIntTask<K,V> sibling;
6502 <        MapReduceValuesToIntTask
6503 <            (ConcurrentHashMapV8<K,V> m,
6504 <             ObjectToInt<? super V> transformer,
6505 <             int basis,
6506 <             IntByIntToInt reducer) {
6507 <            super(m);
6508 <            this.transformer = transformer;
6509 <            this.basis = basis; this.reducer = reducer;
6510 <        }
6484 >        MapReduceValuesToIntTask<K,V> rights, nextRight;
6485          MapReduceValuesToIntTask
6486 <            (BulkTask<K,V,?> p, int b, boolean split,
6486 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6487 >             MapReduceValuesToIntTask<K,V> nextRight,
6488               ObjectToInt<? super V> transformer,
6489               int basis,
6490               IntByIntToInt reducer) {
6491 <            super(p, b, split);
6491 >            super(m, p, b); this.nextRight = nextRight;
6492              this.transformer = transformer;
6493              this.basis = basis; this.reducer = reducer;
6494          }
6495 <        public final void compute() {
6496 <            MapReduceValuesToIntTask<K,V> t = this;
6495 >        public final Integer getRawResult() { return result; }
6496 >        @SuppressWarnings("unchecked") public final void compute() {
6497              final ObjectToInt<? super V> transformer =
6498                  this.transformer;
6499              final IntByIntToInt reducer = this.reducer;
6500              if (transformer == null || reducer == null)
6501 <                throw new Error(NullFunctionMessage);
6502 <            final int id = this.basis;
6503 <            int b = batch();
6504 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6505 <                b >>>= 1;
6531 <                t.pending = 1;
6532 <                MapReduceValuesToIntTask<K,V> rt =
6533 <                    new MapReduceValuesToIntTask<K,V>
6534 <                    (t, b, true, transformer, id, reducer);
6535 <                t = new MapReduceValuesToIntTask<K,V>
6536 <                    (t, b, false, transformer, id, reducer);
6537 <                t.sibling = rt;
6538 <                rt.sibling = t;
6539 <                rt.fork();
6540 <            }
6541 <            int r = id;
6501 >                throw new NullPointerException();
6502 >            int r = this.basis;
6503 >            for (int b; (b = preSplit()) > 0;)
6504 >                (rights = new MapReduceValuesToIntTask<K,V>
6505 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6506              Object v;
6507 <            while ((v = t.advance()) != null)
6507 >            while ((v = advance()) != null)
6508                  r = reducer.apply(r, transformer.apply((V)v));
6509 <            t.result = r;
6510 <            for (;;) {
6511 <                int c; BulkTask<K,V,?> par; MapReduceValuesToIntTask<K,V> s, p;
6512 <                if ((par = t.parent) == null ||
6513 <                    !(par instanceof MapReduceValuesToIntTask)) {
6514 <                    t.quietlyComplete();
6515 <                    break;
6516 <                }
6517 <                else if ((c = (p = (MapReduceValuesToIntTask<K,V>)par).pending) == 0) {
6554 <                    if ((s = t.sibling) != null)
6555 <                        r = reducer.apply(r, s.result);
6556 <                    (t = p).result = r;
6509 >            result = r;
6510 >            CountedCompleter<?> c;
6511 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6512 >                MapReduceValuesToIntTask<K,V>
6513 >                    t = (MapReduceValuesToIntTask<K,V>)c,
6514 >                    s = t.rights;
6515 >                while (s != null) {
6516 >                    t.result = reducer.apply(t.result, s.result);
6517 >                    s = t.rights = s.nextRight;
6518                  }
6558                else if (p.casPending(c, 0))
6559                    break;
6519              }
6520          }
6562        public final Integer getRawResult() { return result; }
6521      }
6522  
6523 <    static final class MapReduceEntriesToIntTask<K,V>
6524 <        extends BulkTask<K,V,Integer> {
6523 >    @SuppressWarnings("serial") static final class MapReduceEntriesToIntTask<K,V>
6524 >        extends Traverser<K,V,Integer> {
6525          final ObjectToInt<Map.Entry<K,V>> transformer;
6526          final IntByIntToInt reducer;
6527          final int basis;
6528          int result;
6529 <        MapReduceEntriesToIntTask<K,V> sibling;
6572 <        MapReduceEntriesToIntTask
6573 <            (ConcurrentHashMapV8<K,V> m,
6574 <             ObjectToInt<Map.Entry<K,V>> transformer,
6575 <             int basis,
6576 <             IntByIntToInt reducer) {
6577 <            super(m);
6578 <            this.transformer = transformer;
6579 <            this.basis = basis; this.reducer = reducer;
6580 <        }
6529 >        MapReduceEntriesToIntTask<K,V> rights, nextRight;
6530          MapReduceEntriesToIntTask
6531 <            (BulkTask<K,V,?> p, int b, boolean split,
6531 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6532 >             MapReduceEntriesToIntTask<K,V> nextRight,
6533               ObjectToInt<Map.Entry<K,V>> transformer,
6534               int basis,
6535               IntByIntToInt reducer) {
6536 <            super(p, b, split);
6536 >            super(m, p, b); this.nextRight = nextRight;
6537              this.transformer = transformer;
6538              this.basis = basis; this.reducer = reducer;
6539          }
6540 <        public final void compute() {
6541 <            MapReduceEntriesToIntTask<K,V> t = this;
6540 >        public final Integer getRawResult() { return result; }
6541 >        @SuppressWarnings("unchecked") public final void compute() {
6542              final ObjectToInt<Map.Entry<K,V>> transformer =
6543                  this.transformer;
6544              final IntByIntToInt reducer = this.reducer;
6545              if (transformer == null || reducer == null)
6546 <                throw new Error(NullFunctionMessage);
6547 <            final int id = this.basis;
6548 <            int b = batch();
6549 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6550 <                b >>>= 1;
6601 <                t.pending = 1;
6602 <                MapReduceEntriesToIntTask<K,V> rt =
6603 <                    new MapReduceEntriesToIntTask<K,V>
6604 <                    (t, b, true, transformer, id, reducer);
6605 <                t = new MapReduceEntriesToIntTask<K,V>
6606 <                    (t, b, false, transformer, id, reducer);
6607 <                t.sibling = rt;
6608 <                rt.sibling = t;
6609 <                rt.fork();
6610 <            }
6611 <            int r = id;
6546 >                throw new NullPointerException();
6547 >            int r = this.basis;
6548 >            for (int b; (b = preSplit()) > 0;)
6549 >                (rights = new MapReduceEntriesToIntTask<K,V>
6550 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6551              Object v;
6552 <            while ((v = t.advance()) != null)
6553 <                r = reducer.apply(r, transformer.apply(entryFor((K)t.nextKey, (V)v)));
6554 <            t.result = r;
6555 <            for (;;) {
6556 <                int c; BulkTask<K,V,?> par; MapReduceEntriesToIntTask<K,V> s, p;
6557 <                if ((par = t.parent) == null ||
6558 <                    !(par instanceof MapReduceEntriesToIntTask)) {
6559 <                    t.quietlyComplete();
6560 <                    break;
6561 <                }
6562 <                else if ((c = (p = (MapReduceEntriesToIntTask<K,V>)par).pending) == 0) {
6624 <                    if ((s = t.sibling) != null)
6625 <                        r = reducer.apply(r, s.result);
6626 <                    (t = p).result = r;
6552 >            while ((v = advance()) != null)
6553 >                r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6554 >            result = r;
6555 >            CountedCompleter<?> c;
6556 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6557 >                MapReduceEntriesToIntTask<K,V>
6558 >                    t = (MapReduceEntriesToIntTask<K,V>)c,
6559 >                    s = t.rights;
6560 >                while (s != null) {
6561 >                    t.result = reducer.apply(t.result, s.result);
6562 >                    s = t.rights = s.nextRight;
6563                  }
6628                else if (p.casPending(c, 0))
6629                    break;
6564              }
6565          }
6632        public final Integer getRawResult() { return result; }
6566      }
6567  
6568 <    static final class MapReduceMappingsToIntTask<K,V>
6569 <        extends BulkTask<K,V,Integer> {
6568 >    @SuppressWarnings("serial") static final class MapReduceMappingsToIntTask<K,V>
6569 >        extends Traverser<K,V,Integer> {
6570          final ObjectByObjectToInt<? super K, ? super V> transformer;
6571          final IntByIntToInt reducer;
6572          final int basis;
6573          int result;
6574 <        MapReduceMappingsToIntTask<K,V> sibling;
6642 <        MapReduceMappingsToIntTask
6643 <            (ConcurrentHashMapV8<K,V> m,
6644 <             ObjectByObjectToInt<? super K, ? super V> transformer,
6645 <             int basis,
6646 <             IntByIntToInt reducer) {
6647 <            super(m);
6648 <            this.transformer = transformer;
6649 <            this.basis = basis; this.reducer = reducer;
6650 <        }
6574 >        MapReduceMappingsToIntTask<K,V> rights, nextRight;
6575          MapReduceMappingsToIntTask
6576 <            (BulkTask<K,V,?> p, int b, boolean split,
6576 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6577 >             MapReduceMappingsToIntTask<K,V> nextRight,
6578               ObjectByObjectToInt<? super K, ? super V> transformer,
6579               int basis,
6580               IntByIntToInt reducer) {
6581 <            super(p, b, split);
6581 >            super(m, p, b); this.nextRight = nextRight;
6582              this.transformer = transformer;
6583              this.basis = basis; this.reducer = reducer;
6584          }
6585 <        public final void compute() {
6586 <            MapReduceMappingsToIntTask<K,V> t = this;
6585 >        public final Integer getRawResult() { return result; }
6586 >        @SuppressWarnings("unchecked") public final void compute() {
6587              final ObjectByObjectToInt<? super K, ? super V> transformer =
6588                  this.transformer;
6589              final IntByIntToInt reducer = this.reducer;
6590              if (transformer == null || reducer == null)
6591 <                throw new Error(NullFunctionMessage);
6592 <            final int id = this.basis;
6593 <            int b = batch();
6594 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6595 <                b >>>= 1;
6671 <                t.pending = 1;
6672 <                MapReduceMappingsToIntTask<K,V> rt =
6673 <                    new MapReduceMappingsToIntTask<K,V>
6674 <                    (t, b, true, transformer, id, reducer);
6675 <                t = new MapReduceMappingsToIntTask<K,V>
6676 <                    (t, b, false, transformer, id, reducer);
6677 <                t.sibling = rt;
6678 <                rt.sibling = t;
6679 <                rt.fork();
6680 <            }
6681 <            int r = id;
6591 >                throw new NullPointerException();
6592 >            int r = this.basis;
6593 >            for (int b; (b = preSplit()) > 0;)
6594 >                (rights = new MapReduceMappingsToIntTask<K,V>
6595 >                 (map, this, b, rights, transformer, r, reducer)).fork();
6596              Object v;
6597 <            while ((v = t.advance()) != null)
6598 <                r = reducer.apply(r, transformer.apply((K)t.nextKey, (V)v));
6599 <            t.result = r;
6600 <            for (;;) {
6601 <                int c; BulkTask<K,V,?> par; MapReduceMappingsToIntTask<K,V> s, p;
6602 <                if ((par = t.parent) == null ||
6603 <                    !(par instanceof MapReduceMappingsToIntTask)) {
6604 <                    t.quietlyComplete();
6605 <                    break;
6606 <                }
6607 <                else if ((c = (p = (MapReduceMappingsToIntTask<K,V>)par).pending) == 0) {
6694 <                    if ((s = t.sibling) != null)
6695 <                        r = reducer.apply(r, s.result);
6696 <                    (t = p).result = r;
6597 >            while ((v = advance()) != null)
6598 >                r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6599 >            result = r;
6600 >            CountedCompleter<?> c;
6601 >            for (c = firstComplete(); c != null; c = c.nextComplete()) {
6602 >                MapReduceMappingsToIntTask<K,V>
6603 >                    t = (MapReduceMappingsToIntTask<K,V>)c,
6604 >                    s = t.rights;
6605 >                while (s != null) {
6606 >                    t.result = reducer.apply(t.result, s.result);
6607 >                    s = t.rights = s.nextRight;
6608                  }
6698                else if (p.casPending(c, 0))
6699                    break;
6609              }
6610          }
6702        public final Integer getRawResult() { return result; }
6611      }
6612  
6705
6613      // Unsafe mechanics
6614      private static final sun.misc.Unsafe UNSAFE;
6615      private static final long counterOffset;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines