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.70 by dl, Sun Oct 28 22:35:45 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;
33   import java.util.Map;
# Line 42 | Line 62 | import java.io.Serializable;
62   * interoperable with {@code Hashtable} in programs that rely on its
63   * thread safety but not on its synchronization details.
64   *
65 < * <p> Retrieval operations (including {@code get}) generally do not
65 > * <p>Retrieval operations (including {@code get}) generally do not
66   * block, so may overlap with update operations (including {@code put}
67   * and {@code remove}). Retrievals reflect the results of the most
68   * recently <em>completed</em> update operations holding upon their
# Line 63 | Line 83 | import java.io.Serializable;
83   * that may be adequate for monitoring or estimation purposes, but not
84   * for program control.
85   *
86 < * <p> The table is dynamically expanded when there are too many
86 > * <p>The table is dynamically expanded when there are too many
87   * collisions (i.e., keys that have distinct hash codes but fall into
88   * the same slot modulo the table size), with the expected average
89   * effect of maintaining roughly two bins per mapping (corresponding
# Line 84 | 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 ConcurrentHashMap may be created
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
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
# Line 101 | Line 121 | import java.io.Serializable;
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}. (Task that may be used in other contexts
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. Because the elements of a
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
# Line 184 | Line 206 | import java.io.Serializable;
206   * arguments can be supplied using {@code new
207   * AbstractMap.SimpleEntry(k,v)}.
208   *
209 < * <p> Bulk operations may complete abruptly, throwing an
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
# Line 195 | Line 217 | import java.io.Serializable;
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
221 < * itself. Similarly, parallelization may not lead to much actual
222 < * parallelism if all processors are busy performing unrelated tasks.
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.
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>
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">
# Line 225 | 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 287 | Line 309 | public class ConcurrentHashMapV8<K, V>
309          Spliterator<T> split();
310      }
311  
290    /**
291     * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in
292     * which additions may optionally be enabled by mapping to a
293     * common value.  This class cannot be directly instantiated. See
294     * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
295     * {@link #newKeySet(int)}.
296     *
297     * <p>The view's {@code iterator} is a "weakly consistent" iterator
298     * that will never throw {@link ConcurrentModificationException},
299     * and guarantees to traverse elements as they existed upon
300     * construction of the iterator, and may (but is not guaranteed to)
301     * reflect any modifications subsequent to construction.
302     */
303    public static class KeySetView<K,V> extends CHMView<K,V> implements Set<K>, java.io.Serializable {
304        private static final long serialVersionUID = 7249069246763182397L;
305        private final V value;
306        KeySetView(ConcurrentHashMapV8<K, V> map, V value) {  // non-public
307            super(map);
308            this.value = value;
309        }
310
311        /**
312         * Returns the map backing this view.
313         *
314         * @return the map backing this view
315         */
316        public ConcurrentHashMapV8<K,V> getMap() { return map; }
317
318        /**
319         * Returns the default mapped value for additions,
320         * or {@code null} if additions are not supported.
321         *
322         * @return the default mapped value for additions, or {@code null}
323         * if not supported.
324         */
325        public V getMappedValue() { return value; }
326
327        // implement Set API
328
329        public boolean contains(Object o) { return map.containsKey(o); }
330        public boolean remove(Object o)   { return map.remove(o) != null; }
331        public Iterator<K> iterator()     { return new KeyIterator<K,V>(map); }
332        public boolean add(K e) {
333            V v;
334            if ((v = value) == null)
335                throw new UnsupportedOperationException();
336            if (e == null)
337                throw new NullPointerException();
338            return map.internalPutIfAbsent(e, v) == null;
339        }
340        public boolean addAll(Collection<? extends K> c) {
341            boolean added = false;
342            V v;
343            if ((v = value) == null)
344                throw new UnsupportedOperationException();
345            for (K e : c) {
346                if (e == null)
347                    throw new NullPointerException();
348                if (map.internalPutIfAbsent(e, v) == null)
349                    added = true;
350            }
351            return added;
352        }
353        public boolean equals(Object o) {
354            Set<?> c;
355            return ((o instanceof Set) &&
356                    ((c = (Set<?>)o) == this ||
357                     (containsAll(c) && c.containsAll(this))));
358        }
359    }
312  
313      /*
314       * Overview:
# Line 641 | Line 593 | public class ConcurrentHashMapV8<K, V>
593  
594      // views
595      private transient KeySetView<K,V> keySet;
596 <    private transient Values<K,V> values;
597 <    private transient EntrySet<K,V> entrySet;
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 741 | 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 912 | 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                          }
921                        else if ((pr = p.right) != null && h >= pr.hash)
922                            s = pr;
923                        if (s != null && (r = getTreeNode(h, k, s)) != null)
924                            return r;
881                      }
882                  }
883                  else
# Line 976 | 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 2450 | 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.  Because
2416 <     * ForkJoinTask is Serializable, but iterators need not be, we
2417 <     * need to add warning suppressions.
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 <    @SuppressWarnings("serial") 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
2422          Object nextKey;      // cached key field of next
# Line 2467 | Line 2426 | public class ConcurrentHashMapV8<K, V>
2426          int baseIndex;       // current index of initial table
2427          int baseLimit;       // index bound for initial table
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.map = map;
2434          }
2435  
2436 <        /** Creates iterator for split() methods */
2437 <        Traverser(Traverser<K,V,?> it) {
2438 <            ConcurrentHashMapV8<K, V> m; Node[] t;
2439 <            if ((m = this.map = it.map) == null)
2440 <                t = null;
2441 <            else if ((t = it.tab) == null && // force parent tab initialization
2442 <                     (t = it.tab = m.table) != null)
2443 <                it.baseLimit = it.baseSize = t.length;
2444 <            this.tab = t;
2445 <            this.baseSize = it.baseSize;
2446 <            it.baseLimit = this.index = this.baseIndex =
2447 <                ((this.baseLimit = it.baseLimit) + it.baseIndex + 1) >>> 1;
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 2537 | 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 2679 | Line 2672 | public class ConcurrentHashMapV8<K, V>
2672       * Returns the number of mappings. This method should be used
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 or 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       */
# Line 2783 | 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 3080 | Line 3073 | public class ConcurrentHashMapV8<K, V>
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
3084 <     * supports element removal, which removes the corresponding
3085 <     * mapping from this map, via the {@code Iterator.remove},
3086 <     * {@code Collection.remove}, {@code removeAll},
3087 <     * {@code retainAll}, and {@code clear} operations.  It does not
3088 <     * support the {@code add} or {@code addAll} operations.
3089 <     *
3090 <     * <p>The view's {@code iterator} is a "weakly consistent" iterator
3091 <     * that will never throw {@link ConcurrentModificationException},
3092 <     * and guarantees to traverse elements as they existed upon
3093 <     * construction of the iterator, and may (but is not guaranteed to)
3094 <     * 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 3115 | 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 3252 | Line 3234 | public class ConcurrentHashMapV8<K, V>
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) {
3238 <            super(it);
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 (nextKey != null)
3242                  throw new IllegalStateException();
3243 <            return new KeyIterator<K,V>(this);
3243 >            return new KeyIterator<K,V>(map, this);
3244          }
3245          @SuppressWarnings("unchecked") public final K next() {
3246              if (nextVal == null && advance() == null)
# Line 3274 | Line 3256 | public class ConcurrentHashMapV8<K, V>
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) {
3260 <            super(it);
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 (nextKey != null)
3264                  throw new IllegalStateException();
3265 <            return new ValueIterator<K,V>(this);
3265 >            return new ValueIterator<K,V>(map, this);
3266          }
3267  
3268          @SuppressWarnings("unchecked") public final V next() {
# Line 3297 | Line 3279 | public class ConcurrentHashMapV8<K, V>
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) {
3283 <            super(it);
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 (nextKey != null)
3287                  throw new IllegalStateException();
3288 <            return new EntryIterator<K,V>(this);
3288 >            return new EntryIterator<K,V>(map, this);
3289          }
3290  
3291          @SuppressWarnings("unchecked") public final Map.Entry<K,V> next() {
# Line 3359 | Line 3341 | public class ConcurrentHashMapV8<K, V>
3341          }
3342      }
3343  
3362    /* ----------------Views -------------- */
3363
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;
3369 <        CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
3370 <        public final int size()                 { return map.size(); }
3371 <        public final boolean isEmpty()          { return map.isEmpty(); }
3372 <        public final void clear()               { map.clear(); }
3373 <
3374 <        // implementations below rely on concrete classes supplying these
3375 <        abstract public Iterator<?> iterator();
3376 <        abstract public boolean contains(Object o);
3377 <        abstract public boolean remove(Object o);
3378 <
3379 <        private static final String oomeMsg = "Required array size too large";
3380 <
3381 <        public final Object[] toArray() {
3382 <            long sz = map.mappingCount();
3383 <            if (sz > (long)(MAX_ARRAY_SIZE))
3384 <                throw new OutOfMemoryError(oomeMsg);
3385 <            int n = (int)sz;
3386 <            Object[] r = new Object[n];
3387 <            int i = 0;
3388 <            Iterator<?> it = iterator();
3389 <            while (it.hasNext()) {
3390 <                if (i == n) {
3391 <                    if (n >= MAX_ARRAY_SIZE)
3392 <                        throw new OutOfMemoryError(oomeMsg);
3393 <                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3394 <                        n = MAX_ARRAY_SIZE;
3395 <                    else
3396 <                        n += (n >>> 1) + 1;
3397 <                    r = Arrays.copyOf(r, n);
3398 <                }
3399 <                r[i++] = it.next();
3400 <            }
3401 <            return (i == n) ? r : Arrays.copyOf(r, i);
3402 <        }
3403 <
3404 <        @SuppressWarnings("unchecked") public final <T> T[] toArray(T[] a) {
3405 <            long sz = map.mappingCount();
3406 <            if (sz > (long)(MAX_ARRAY_SIZE))
3407 <                throw new OutOfMemoryError(oomeMsg);
3408 <            int m = (int)sz;
3409 <            T[] r = (a.length >= m) ? a :
3410 <                (T[])java.lang.reflect.Array
3411 <                .newInstance(a.getClass().getComponentType(), m);
3412 <            int n = r.length;
3413 <            int i = 0;
3414 <            Iterator<?> it = iterator();
3415 <            while (it.hasNext()) {
3416 <                if (i == n) {
3417 <                    if (n >= MAX_ARRAY_SIZE)
3418 <                        throw new OutOfMemoryError(oomeMsg);
3419 <                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3420 <                        n = MAX_ARRAY_SIZE;
3421 <                    else
3422 <                        n += (n >>> 1) + 1;
3423 <                    r = Arrays.copyOf(r, n);
3424 <                }
3425 <                r[i++] = (T)it.next();
3426 <            }
3427 <            if (a == r && i < n) {
3428 <                r[i] = null; // null-terminate
3429 <                return r;
3430 <            }
3431 <            return (i == n) ? r : Arrays.copyOf(r, i);
3432 <        }
3433 <
3434 <        public final int hashCode() {
3435 <            int h = 0;
3436 <            for (Iterator<?> it = iterator(); it.hasNext();)
3437 <                h += it.next().hashCode();
3438 <            return h;
3439 <        }
3440 <
3441 <        public final String toString() {
3442 <            StringBuilder sb = new StringBuilder();
3443 <            sb.append('[');
3444 <            Iterator<?> it = iterator();
3445 <            if (it.hasNext()) {
3446 <                for (;;) {
3447 <                    Object e = it.next();
3448 <                    sb.append(e == this ? "(this Collection)" : e);
3449 <                    if (!it.hasNext())
3450 <                        break;
3451 <                    sb.append(',').append(' ');
3452 <                }
3453 <            }
3454 <            return sb.append(']').toString();
3455 <        }
3456 <
3457 <        public final boolean containsAll(Collection<?> c) {
3458 <            if (c != this) {
3459 <                for (Iterator<?> it = c.iterator(); it.hasNext();) {
3460 <                    Object e = it.next();
3461 <                    if (e == null || !contains(e))
3462 <                        return false;
3463 <                }
3464 <            }
3465 <            return true;
3466 <        }
3467 <
3468 <        public final boolean removeAll(Collection<?> c) {
3469 <            boolean modified = false;
3470 <            for (Iterator<?> it = iterator(); it.hasNext();) {
3471 <                if (c.contains(it.next())) {
3472 <                    it.remove();
3473 <                    modified = true;
3474 <                }
3475 <            }
3476 <            return modified;
3477 <        }
3478 <
3479 <        public final boolean retainAll(Collection<?> c) {
3480 <            boolean modified = false;
3481 <            for (Iterator<?> it = iterator(); it.hasNext();) {
3482 <                if (!c.contains(it.next())) {
3483 <                    it.remove();
3484 <                    modified = true;
3485 <                }
3486 <            }
3487 <            return modified;
3488 <        }
3489 <
3490 <    }
3491 <
3492 <    static final class Values<K,V> extends CHMView<K,V>
3493 <        implements Collection<V> {
3494 <        Values(ConcurrentHashMapV8<K, V> map)   { super(map); }
3495 <        public final boolean contains(Object o) { return map.containsValue(o); }
3496 <        public final boolean remove(Object o) {
3497 <            if (o != null) {
3498 <                Iterator<V> it = new ValueIterator<K,V>(map);
3499 <                while (it.hasNext()) {
3500 <                    if (o.equals(it.next())) {
3501 <                        it.remove();
3502 <                        return true;
3503 <                    }
3504 <                }
3505 <            }
3506 <            return false;
3507 <        }
3508 <        public final Iterator<V> iterator() {
3509 <            return new ValueIterator<K,V>(map);
3510 <        }
3511 <        public final boolean add(V e) {
3512 <            throw new UnsupportedOperationException();
3513 <        }
3514 <        public final boolean addAll(Collection<? extends V> c) {
3515 <            throw new UnsupportedOperationException();
3516 <        }
3517 <
3518 <    }
3519 <
3520 <    static final class EntrySet<K,V> extends CHMView<K,V>
3521 <        implements Set<Map.Entry<K,V>> {
3522 <        EntrySet(ConcurrentHashMapV8<K, V> map) { super(map); }
3523 <        public final boolean contains(Object o) {
3524 <            Object k, v, r; Map.Entry<?,?> e;
3525 <            return ((o instanceof Map.Entry) &&
3526 <                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
3527 <                    (r = map.get(k)) != null &&
3528 <                    (v = e.getValue()) != null &&
3529 <                    (v == r || v.equals(r)));
3530 <        }
3531 <        public final boolean remove(Object o) {
3532 <            Object k, v; Map.Entry<?,?> e;
3533 <            return ((o instanceof Map.Entry) &&
3534 <                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
3535 <                    (v = e.getValue()) != null &&
3536 <                    map.remove(k, v));
3537 <        }
3538 <        public final Iterator<Map.Entry<K,V>> iterator() {
3539 <            return new EntryIterator<K,V>(map);
3540 <        }
3541 <        public final boolean add(Entry<K,V> e) {
3542 <            throw new UnsupportedOperationException();
3543 <        }
3544 <        public final boolean addAll(Collection<? extends Entry<K,V>> c) {
3545 <            throw new UnsupportedOperationException();
3546 <        }
3547 <        public boolean equals(Object o) {
3548 <            Set<?> c;
3549 <            return ((o instanceof Set) &&
3550 <                    ((c = (Set<?>)o) == this ||
3551 <                     (containsAll(c) && c.containsAll(this))));
3552 <        }
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 3860 | Line 3657 | public class ConcurrentHashMapV8<K, V>
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       *
# Line 4205 | Line 4019 | public class ConcurrentHashMapV8<K, V>
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 +         * Returns the map backing this view.
4033 +         *
4034 +         * @return the map backing this view
4035 +         */
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 +        @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 +        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 +        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 +        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 default mapped value for additions,
4177 +         * or {@code null} if additions are not supported.
4178 +         *
4179 +         * @return the default mapped value for additions, or {@code null}
4180 +         * if not supported.
4181 +         */
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 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 +         * @return an iterator over the keys of this map
4198 +         */
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 +        /**
4229 +         * Performs the given action for each key.
4230 +         *
4231 +         * @param action the action
4232 +         */
4233 +        public void forEach(Action<K> action) {
4234 +            ForkJoinTasks.forEachKey
4235 +                (map, action).invoke();
4236 +        }
4237 +
4238 +        /**
4239 +         * Performs the given action for each non-null transformation
4240 +         * of each key.
4241 +         *
4242 +         * @param transformer a function returning the transformation
4243 +         * for an element, or null of there is no transformation (in
4244 +         * which case the action is not applied).
4245 +         * @param action the action
4246 +         */
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. 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 search(Fun<? super K, ? extends U> searchFunction) {
4266 +            return ForkJoinTasks.searchKeys
4267 +                (map, searchFunction).invoke();
4268 +        }
4269 +
4270 +        /**
4271 +         * Returns the result of accumulating all keys using the given
4272 +         * reducer to combine values, or null if none.
4273 +         *
4274 +         * @param reducer a commutative associative combining function
4275 +         * @return the result of accumulating all keys using the given
4276 +         * reducer to combine values, or null if none
4277 +         */
4278 +        public K reduce(BiFun<? super K, ? super K, ? extends K> reducer) {
4279 +            return ForkJoinTasks.reduceKeys
4280 +                (map, reducer).invoke();
4281 +        }
4282 +
4283 +        /**
4284 +         * Returns the result of accumulating the given transformation
4285 +         * of all keys using the given reducer to combine values, and
4286 +         * the given basis as an identity value.
4287 +         *
4288 +         * @param transformer a function returning the transformation
4289 +         * for an element
4290 +         * @param basis the identity (initial default value) for the reduction
4291 +         * @param reducer a commutative associative combining function
4292 +         * @return  the result of accumulating the given transformation
4293 +         * of all keys
4294 +         */
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
4306 +         * the given basis as an identity value.
4307 +         *
4308 +         * @param transformer a function returning the transformation
4309 +         * for an element
4310 +         * @param basis the identity (initial default value) for the reduction
4311 +         * @param reducer a commutative associative combining function
4312 +         * @return the result of accumulating the given transformation
4313 +         * of all keys
4314 +         */
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 +        /**
4323 +         * Returns the result of accumulating the given transformation
4324 +         * of all keys using the given reducer to combine values, and
4325 +         * the given basis as an identity value.
4326 +         *
4327 +         * @param transformer a function returning the transformation
4328 +         * for an element
4329 +         * @param basis the identity (initial default value) for the reduction
4330 +         * @param reducer a commutative associative combining function
4331 +         * @return the result of accumulating the given transformation
4332 +         * of all keys
4333 +         */
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 +        /**
4392 +         * Performs the given action for each value.
4393 +         *
4394 +         * @param action the action
4395 +         */
4396 +        public void forEach(Action<V> action) {
4397 +            ForkJoinTasks.forEachValue
4398 +                (map, action).invoke();
4399 +        }
4400 +
4401 +        /**
4402 +         * Performs the given action for each non-null transformation
4403 +         * of each value.
4404 +         *
4405 +         * @param transformer a function returning the transformation
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 forEach(Fun<? super V, ? extends U> transformer,
4410 +                                     Action<U> 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.  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
4424 +         * @return a non-null result from applying the given search
4425 +         * function on each value, or null if none
4426 +         *
4427 +         */
4428 +        public <U> U search(Fun<? super V, ? extends U> searchFunction) {
4429 +            return ForkJoinTasks.searchValues
4430 +                (map, searchFunction).invoke();
4431 +        }
4432 +
4433 +        /**
4434 +         * Returns the result of accumulating all values using the
4435 +         * given reducer to combine values, or null if none.
4436 +         *
4437 +         * @param reducer a commutative associative combining function
4438 +         * @return  the result of accumulating all values
4439 +         */
4440 +        public V reduce(BiFun<? super V, ? super V, ? extends V> reducer) {
4441 +            return ForkJoinTasks.reduceValues
4442 +                (map, reducer).invoke();
4443 +        }
4444 +
4445 +        /**
4446 +         * Returns the result of accumulating the given transformation
4447 +         * of all values using the given reducer to combine values, or
4448 +         * null if none.
4449 +         *
4450 +         * @param transformer a function returning the transformation
4451 +         * for an element, or null of there is no transformation (in
4452 +         * which case it is not combined).
4453 +         * @param reducer a commutative associative combining function
4454 +         * @return the result of accumulating the given transformation
4455 +         * of all values
4456 +         */
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 +        /**
4464 +         * Returns the result of accumulating the given transformation
4465 +         * of all values using the given reducer to combine values,
4466 +         * and the given basis as an identity value.
4467 +         *
4468 +         * @param transformer a function returning the transformation
4469 +         * for an element
4470 +         * @param basis the identity (initial default value) for the reduction
4471 +         * @param reducer a commutative associative combining function
4472 +         * @return the result of accumulating the given transformation
4473 +         * of all values
4474 +         */
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 +        /**
4483 +         * Returns the result of accumulating the given transformation
4484 +         * of all values using the given reducer to combine values,
4485 +         * and the given basis as an identity value.
4486 +         *
4487 +         * @param transformer a function returning the transformation
4488 +         * for an element
4489 +         * @param basis the identity (initial default value) for the reduction
4490 +         * @param reducer a commutative associative combining function
4491 +         * @return the result of accumulating the given transformation
4492 +         * of all values
4493 +         */
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 +        /**
4502 +         * Returns the result of accumulating the given transformation
4503 +         * of all values using the given reducer to combine values,
4504 +         * and the given basis as an identity value.
4505 +         *
4506 +         * @param transformer a function returning the transformation
4507 +         * for an element
4508 +         * @param basis the identity (initial default value) for the reduction
4509 +         * @param reducer a commutative associative combining function
4510 +         * @return the result of accumulating the given transformation
4511 +         * of all values
4512 +         */
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 +        /**
4583 +         * Performs the given action for each entry.
4584 +         *
4585 +         * @param action the action
4586 +         */
4587 +        public void forEach(Action<Map.Entry<K,V>> action) {
4588 +            ForkJoinTasks.forEachEntry
4589 +                (map, action).invoke();
4590 +        }
4591 +
4592 +        /**
4593 +         * Performs the given action for each non-null transformation
4594 +         * of each entry.
4595 +         *
4596 +         * @param transformer a function returning the transformation
4597 +         * for an element, or null of there is no transformation (in
4598 +         * which case the action is not applied).
4599 +         * @param action the action
4600 +         */
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.  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 search(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4620 +            return ForkJoinTasks.searchEntries
4621 +                (map, searchFunction).invoke();
4622 +        }
4623 +
4624 +        /**
4625 +         * Returns the result of accumulating all entries using the
4626 +         * given reducer to combine values, or null if none.
4627 +         *
4628 +         * @param reducer a commutative associative combining function
4629 +         * @return the result of accumulating all entries
4630 +         */
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 +        /**
4637 +         * Returns the result of accumulating the given transformation
4638 +         * of all entries using the given reducer to combine values,
4639 +         * or null if none.
4640 +         *
4641 +         * @param transformer a function returning the transformation
4642 +         * for an element, or null of there is no transformation (in
4643 +         * which case it is not combined).
4644 +         * @param reducer a commutative associative combining function
4645 +         * @return the result of accumulating the given transformation
4646 +         * of all entries
4647 +         */
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 +        /**
4655 +         * Returns the result of accumulating the given transformation
4656 +         * of all entries using the given reducer to combine values,
4657 +         * and the given basis as an identity value.
4658 +         *
4659 +         * @param transformer a function returning the transformation
4660 +         * for an element
4661 +         * @param basis the identity (initial default value) for the reduction
4662 +         * @param reducer a commutative associative combining function
4663 +         * @return the result of accumulating the given transformation
4664 +         * of all entries
4665 +         */
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 +        /**
4674 +         * Returns the result of accumulating the given transformation
4675 +         * of all entries using the given reducer to combine values,
4676 +         * and the given basis as an identity value.
4677 +         *
4678 +         * @param transformer a function returning the transformation
4679 +         * for an element
4680 +         * @param basis the identity (initial default value) for the reduction
4681 +         * @param reducer a commutative associative combining function
4682 +         * @return  the result of accumulating the given transformation
4683 +         * of all entries
4684 +         */
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 +        /**
4693 +         * Returns the result of accumulating the given transformation
4694 +         * of all entries using the given reducer to combine values,
4695 +         * and the given basis as an identity value.
4696 +         *
4697 +         * @param transformer a function returning the transformation
4698 +         * for an element
4699 +         * @param basis the identity (initial default value) for the reduction
4700 +         * @param reducer a commutative associative combining function
4701 +         * @return the result of accumulating the given transformation
4702 +         * of all entries
4703 +         */
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      /**
# Line 4231 | 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, null, -1, null, action);
4739 >            return new ForEachMappingTask<K,V>(map, null, -1, action);
4740          }
4741  
4742          /**
# Line 4252 | 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, null, -1, null, transformer, action);
4760 >                (map, null, -1, transformer, action);
4761          }
4762  
4763          /**
# Line 4272 | 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, null, -1, null, searchFunction,
4780 >                (map, null, -1, searchFunction,
4781                   new AtomicReference<U>());
4782          }
4783  
# Line 4381 | 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, null, -1, null, action);
4889 >            return new ForEachKeyTask<K,V>(map, null, -1, action);
4890          }
4891  
4892          /**
# Line 4402 | 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, null, -1, null, transformer, action);
4910 >                (map, null, -1, transformer, action);
4911          }
4912  
4913          /**
# Line 4422 | 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, null, -1, null, searchFunction,
4930 >                (map, null, -1, searchFunction,
4931                   new AtomicReference<U>());
4932          }
4933  
# Line 4548 | 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, null, -1, null, action);
5056 >            return new ForEachValueTask<K,V>(map, null, -1, action);
5057          }
5058  
5059          /**
# Line 4568 | 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, null, -1, null, transformer, action);
5076 >                (map, null, -1, transformer, action);
5077          }
5078  
5079          /**
# Line 4588 | Line 5093 | public class ConcurrentHashMapV8<K, V>
5093               Fun<? super V, ? extends U> searchFunction) {
5094              if (searchFunction == null) throw new NullPointerException();
5095              return new SearchValuesTask<K,V,U>
5096 <                (map, null, -1, null, searchFunction,
5096 >                (map, null, -1, searchFunction,
5097                   new AtomicReference<U>());
5098          }
5099  
# Line 4714 | 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, null, -1, null, action);
5222 >            return new ForEachEntryTask<K,V>(map, null, -1, action);
5223          }
5224  
5225          /**
# Line 4734 | 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, null, -1, null, transformer, action);
5242 >                (map, null, -1, transformer, action);
5243          }
5244  
5245          /**
# Line 4754 | Line 5259 | public class ConcurrentHashMapV8<K, V>
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, null, -1, null, searchFunction,
5262 >                (map, null, -1, searchFunction,
5263                   new AtomicReference<U>());
5264          }
5265  
# Line 4872 | Line 5377 | public class ConcurrentHashMapV8<K, V>
5377  
5378      // -------------------------------------------------------
5379  
4875    /**
4876     * Base for FJ tasks for bulk operations. This adds a variant of
4877     * CountedCompleters and some split and merge bookkeeping to
4878     * iterator functionality. The forEach and reduce methods are
4879     * similar to those illustrated in CountedCompleter documentation,
4880     * except that bottom-up reduction completions perform them within
4881     * their compute methods. The search methods are like forEach
4882     * except they continually poll for success and exit early.  Also,
4883     * exceptions are handled in a simpler manner, by just trying to
4884     * complete root task exceptionally.
4885     */
4886    @SuppressWarnings("serial") static abstract class BulkTask<K,V,R> extends Traverser<K,V,R> {
4887        final BulkTask<K,V,?> parent;  // completion target
4888        int batch;                     // split control; -1 for unknown
4889        int pending;                   // completion control
4890
4891        BulkTask(ConcurrentHashMapV8<K,V> map, BulkTask<K,V,?> parent,
4892                 int batch) {
4893            super(map);
4894            this.parent = parent;
4895            this.batch = batch;
4896            if (parent != null && map != null) { // split parent
4897                Node[] t;
4898                if ((t = parent.tab) == null &&
4899                    (t = parent.tab = map.table) != null)
4900                    parent.baseLimit = parent.baseSize = t.length;
4901                this.tab = t;
4902                this.baseSize = parent.baseSize;
4903                int hi = this.baseLimit = parent.baseLimit;
4904                parent.baseLimit = this.index = this.baseIndex =
4905                    (hi + parent.baseIndex + 1) >>> 1;
4906            }
4907        }
4908
4909        // FJ methods
4910
4911        /**
4912         * Propagates completion. Note that all reduce actions
4913         * bypass this method to combine while completing.
4914         */
4915        final void tryComplete() {
4916            BulkTask<K,V,?> a = this, s = a;
4917            for (int c;;) {
4918                if ((c = a.pending) == 0) {
4919                    if ((a = (s = a).parent) == null) {
4920                        s.quietlyComplete();
4921                        break;
4922                    }
4923                }
4924                else if (U.compareAndSwapInt(a, PENDING, c, c - 1))
4925                    break;
4926            }
4927        }
4928
4929        /**
4930         * Forces root task to complete.
4931         * @param ex if null, complete normally, else exceptionally
4932         * @return false to simplify use
4933         */
4934        final boolean tryCompleteComputation(Throwable ex) {
4935            for (BulkTask<K,V,?> a = this;;) {
4936                BulkTask<K,V,?> p = a.parent;
4937                if (p == null) {
4938                    if (ex != null)
4939                        a.completeExceptionally(ex);
4940                    else
4941                        a.quietlyComplete();
4942                    return false;
4943                }
4944                a = p;
4945            }
4946        }
4947
4948        /**
4949         * Version of tryCompleteComputation for function screening checks
4950         */
4951        final boolean abortOnNullFunction() {
4952            return tryCompleteComputation(new Error("Unexpected null function"));
4953        }
4954
4955        // utilities
4956
4957        /** CompareAndSet pending count */
4958        final boolean casPending(int cmp, int val) {
4959            return U.compareAndSwapInt(this, PENDING, cmp, val);
4960        }
4961
4962        /**
4963         * Returns approx exp2 of the number of times (minus one) to
4964         * split task by two before executing leaf action. This value
4965         * is faster to compute and more convenient to use as a guide
4966         * to splitting than is the depth, since it is used while
4967         * dividing by two anyway.
4968         */
4969        final int batch() {
4970            ConcurrentHashMapV8<K, V> m; int b; Node[] t;  ForkJoinPool pool;
4971            if ((b = batch) < 0 && (m = map) != null) { // force initialization
4972                if ((t = tab) == null && (t = tab = m.table) != null)
4973                    baseLimit = baseSize = t.length;
4974                if (t != null) {
4975                    long n = m.counter.sum();
4976                    int par = (pool = getPool()) == null?
4977                        ForkJoinPool.getCommonPoolParallelism() :
4978                        pool.getParallelism();
4979                    int sp = par << 3; // slack of 8
4980                    b = batch = (n <= 0L) ? 0 : (n < (long)sp) ? (int)n : sp;
4981                }
4982            }
4983            return b;
4984        }
4985
4986        /**
4987         * Returns exportable snapshot entry.
4988         */
4989        static <K,V> AbstractMap.SimpleEntry<K,V> entryFor(K k, V v) {
4990            return new AbstractMap.SimpleEntry<K,V>(k, v);
4991        }
4992
4993        // Unsafe mechanics
4994        private static final sun.misc.Unsafe U;
4995        private static final long PENDING;
4996        static {
4997            try {
4998                U = getUnsafe();
4999                PENDING = U.objectFieldOffset
5000                    (BulkTask.class.getDeclaredField("pending"));
5001            } catch (Exception e) {
5002                throw new Error(e);
5003            }
5004        }
5005    }
5006
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
# Line 5011 | Line 5384 | public class ConcurrentHashMapV8<K, V>
5384       */
5385  
5386      @SuppressWarnings("serial") static final class ForEachKeyTask<K,V>
5387 <        extends BulkTask<K,V,Void> {
5387 >        extends Traverser<K,V,Void> {
5388          final Action<K> action;
5016        ForEachKeyTask<K,V> nextRight;
5389          ForEachKeyTask
5390 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5019 <             ForEachKeyTask<K,V> nextRight,
5390 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5391               Action<K> action) {
5392              super(m, p, b);
5022            this.nextRight = nextRight;
5393              this.action = action;
5394          }
5395 <        @SuppressWarnings("unchecked") public final boolean exec() {
5396 <            final Action<K> action = this.action;
5397 <            if (action == null)
5398 <                return abortOnNullFunction();
5399 <            ForEachKeyTask<K,V> rights = null;
5400 <            try {
5401 <                int b = batch(), c;
5402 <                while (b > 1 && baseIndex != baseLimit) {
5403 <                    do {} while (!casPending(c = pending, c+1));
5034 <                    (rights = new ForEachKeyTask<K,V>
5035 <                     (map, this, b >>>= 1, rights, action)).fork();
5036 <                }
5037 <                while (advance() != null)
5038 <                    action.apply((K)nextKey);
5039 <                tryComplete();
5040 <            } catch (Throwable ex) {
5041 <                return tryCompleteComputation(ex);
5042 <            }
5043 <            while (rights != null && rights.tryUnfork()) {
5044 <                rights.exec();
5045 <                rights = rights.nextRight;
5046 <            }
5047 <            return false;
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 >            propagateCompletion();
5404          }
5405      }
5406  
5407      @SuppressWarnings("serial") static final class ForEachValueTask<K,V>
5408 <        extends BulkTask<K,V,Void> {
5053 <        ForEachValueTask<K,V> nextRight;
5408 >        extends Traverser<K,V,Void> {
5409          final Action<V> action;
5410          ForEachValueTask
5411 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5057 <             ForEachValueTask<K,V> nextRight,
5411 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5412               Action<V> action) {
5413              super(m, p, b);
5060            this.nextRight = nextRight;
5414              this.action = action;
5415          }
5416 <        @SuppressWarnings("unchecked") public final boolean exec() {
5417 <            final Action<V> action = this.action;
5418 <            if (action == null)
5419 <                return abortOnNullFunction();
5420 <            ForEachValueTask<K,V> rights = null;
5421 <            try {
5422 <                int b = batch(), c;
5423 <                while (b > 1 && baseIndex != baseLimit) {
5424 <                    do {} while (!casPending(c = pending, c+1));
5425 <                    (rights = new ForEachValueTask<K,V>
5073 <                     (map, this, b >>>= 1, rights, action)).fork();
5074 <                }
5075 <                Object v;
5076 <                while ((v = advance()) != null)
5077 <                    action.apply((V)v);
5078 <                tryComplete();
5079 <            } catch (Throwable ex) {
5080 <                return tryCompleteComputation(ex);
5081 <            }
5082 <            while (rights != null && rights.tryUnfork()) {
5083 <                rights.exec();
5084 <                rights = rights.nextRight;
5085 <            }
5086 <            return false;
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 >            propagateCompletion();
5426          }
5427      }
5428  
5429      @SuppressWarnings("serial") static final class ForEachEntryTask<K,V>
5430 <        extends BulkTask<K,V,Void> {
5092 <        ForEachEntryTask<K,V> nextRight;
5430 >        extends Traverser<K,V,Void> {
5431          final Action<Entry<K,V>> action;
5432          ForEachEntryTask
5433 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5096 <             ForEachEntryTask<K,V> nextRight,
5433 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5434               Action<Entry<K,V>> action) {
5435              super(m, p, b);
5099            this.nextRight = nextRight;
5436              this.action = action;
5437          }
5438 <        @SuppressWarnings("unchecked") public final boolean exec() {
5439 <            final Action<Entry<K,V>> action = this.action;
5440 <            if (action == null)
5441 <                return abortOnNullFunction();
5442 <            ForEachEntryTask<K,V> rights = null;
5443 <            try {
5444 <                int b = batch(), c;
5445 <                while (b > 1 && baseIndex != baseLimit) {
5446 <                    do {} while (!casPending(c = pending, c+1));
5447 <                    (rights = new ForEachEntryTask<K,V>
5112 <                     (map, this, b >>>= 1, rights, action)).fork();
5113 <                }
5114 <                Object v;
5115 <                while ((v = advance()) != null)
5116 <                    action.apply(entryFor((K)nextKey, (V)v));
5117 <                tryComplete();
5118 <            } catch (Throwable ex) {
5119 <                return tryCompleteComputation(ex);
5120 <            }
5121 <            while (rights != null && rights.tryUnfork()) {
5122 <                rights.exec();
5123 <                rights = rights.nextRight;
5124 <            }
5125 <            return false;
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 >            propagateCompletion();
5448          }
5449      }
5450  
5451      @SuppressWarnings("serial") static final class ForEachMappingTask<K,V>
5452 <        extends BulkTask<K,V,Void> {
5131 <        ForEachMappingTask<K,V> nextRight;
5452 >        extends Traverser<K,V,Void> {
5453          final BiAction<K,V> action;
5454          ForEachMappingTask
5455 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5135 <             ForEachMappingTask<K,V> nextRight,
5455 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5456               BiAction<K,V> action) {
5457              super(m, p, b);
5138            this.nextRight = nextRight;
5458              this.action = action;
5459          }
5460 <        @SuppressWarnings("unchecked") public final boolean exec() {
5461 <            final BiAction<K,V> action = this.action;
5462 <            if (action == null)
5463 <                return abortOnNullFunction();
5464 <            ForEachMappingTask<K,V> rights = null;
5465 <            try {
5466 <                int b = batch(), c;
5467 <                while (b > 1 && baseIndex != baseLimit) {
5468 <                    do {} while (!casPending(c = pending, c+1));
5469 <                    (rights = new ForEachMappingTask<K,V>
5151 <                     (map, this, b >>>= 1, rights, action)).fork();
5152 <                }
5153 <                Object v;
5154 <                while ((v = advance()) != null)
5155 <                    action.apply((K)nextKey, (V)v);
5156 <                tryComplete();
5157 <            } catch (Throwable ex) {
5158 <                return tryCompleteComputation(ex);
5159 <            }
5160 <            while (rights != null && rights.tryUnfork()) {
5161 <                rights.exec();
5162 <                rights = rights.nextRight;
5163 <            }
5164 <            return false;
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 >            propagateCompletion();
5470          }
5471      }
5472  
5473      @SuppressWarnings("serial") static final class ForEachTransformedKeyTask<K,V,U>
5474 <        extends BulkTask<K,V,Void> {
5170 <        ForEachTransformedKeyTask<K,V,U> nextRight;
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, BulkTask<K,V,?> p, int b,
5479 <             ForEachTransformedKeyTask<K,V,U> nextRight,
5176 <             Fun<? super K, ? extends U> transformer,
5177 <             Action<U> action) {
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.nextRight = nextRight;
5180 <            this.transformer = transformer;
5181 <            this.action = action;
5182 <
5481 >            this.transformer = transformer; this.action = action;
5482          }
5483 <        @SuppressWarnings("unchecked") public final boolean exec() {
5484 <            final Fun<? super K, ? extends U> transformer =
5485 <                this.transformer;
5486 <            final Action<U> action = this.action;
5487 <            if (transformer == null || action == null)
5488 <                return abortOnNullFunction();
5489 <            ForEachTransformedKeyTask<K,V,U> rights = null;
5490 <            try {
5491 <                int b = batch(), c;
5492 <                while (b > 1 && baseIndex != baseLimit) {
5493 <                    do {} while (!casPending(c = pending, c+1));
5494 <                    (rights = new ForEachTransformedKeyTask<K,V,U>
5495 <                     (map, this, b >>>= 1, rights, transformer, action)).fork();
5197 <                }
5198 <                U u;
5199 <                while (advance() != null) {
5200 <                    if ((u = transformer.apply((K)nextKey)) != null)
5201 <                        action.apply(u);
5202 <                }
5203 <                tryComplete();
5204 <            } catch (Throwable ex) {
5205 <                return tryCompleteComputation(ex);
5206 <            }
5207 <            while (rights != null && rights.tryUnfork()) {
5208 <                rights.exec();
5209 <                rights = rights.nextRight;
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 >                     (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 <            return false;
5497 >            propagateCompletion();
5498          }
5499      }
5500  
5501      @SuppressWarnings("serial") static final class ForEachTransformedValueTask<K,V,U>
5502 <        extends BulkTask<K,V,Void> {
5217 <        ForEachTransformedValueTask<K,V,U> nextRight;
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, BulkTask<K,V,?> p, int b,
5507 <             ForEachTransformedValueTask<K,V,U> nextRight,
5223 <             Fun<? super V, ? extends U> transformer,
5224 <             Action<U> action) {
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.nextRight = nextRight;
5227 <            this.transformer = transformer;
5228 <            this.action = action;
5229 <
5509 >            this.transformer = transformer; this.action = action;
5510          }
5511 <        @SuppressWarnings("unchecked") public final boolean exec() {
5512 <            final Fun<? super V, ? extends U> transformer =
5513 <                this.transformer;
5514 <            final Action<U> action = this.action;
5515 <            if (transformer == null || action == null)
5516 <                return abortOnNullFunction();
5517 <            ForEachTransformedValueTask<K,V,U> rights = null;
5518 <            try {
5519 <                int b = batch(), c;
5520 <                while (b > 1 && baseIndex != baseLimit) {
5521 <                    do {} while (!casPending(c = pending, c+1));
5522 <                    (rights = new ForEachTransformedValueTask<K,V,U>
5523 <                     (map, this, b >>>= 1, rights, transformer, action)).fork();
5244 <                }
5245 <                Object v; U u;
5246 <                while ((v = advance()) != null) {
5247 <                    if ((u = transformer.apply((V)v)) != null)
5248 <                        action.apply(u);
5249 <                }
5250 <                tryComplete();
5251 <            } catch (Throwable ex) {
5252 <                return tryCompleteComputation(ex);
5253 <            }
5254 <            while (rights != null && rights.tryUnfork()) {
5255 <                rights.exec();
5256 <                rights = rights.nextRight;
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 >                    (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 <            return false;
5525 >            propagateCompletion();
5526          }
5527      }
5528  
5529      @SuppressWarnings("serial") static final class ForEachTransformedEntryTask<K,V,U>
5530 <        extends BulkTask<K,V,Void> {
5264 <        ForEachTransformedEntryTask<K,V,U> nextRight;
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, BulkTask<K,V,?> p, int b,
5535 <             ForEachTransformedEntryTask<K,V,U> nextRight,
5270 <             Fun<Map.Entry<K,V>, ? extends U> transformer,
5271 <             Action<U> action) {
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.nextRight = nextRight;
5274 <            this.transformer = transformer;
5275 <            this.action = action;
5276 <
5537 >            this.transformer = transformer; this.action = action;
5538          }
5539 <        @SuppressWarnings("unchecked") public final boolean exec() {
5540 <            final Fun<Map.Entry<K,V>, ? extends U> transformer =
5541 <                this.transformer;
5542 <            final Action<U> action = this.action;
5543 <            if (transformer == null || action == null)
5544 <                return abortOnNullFunction();
5545 <            ForEachTransformedEntryTask<K,V,U> rights = null;
5546 <            try {
5547 <                int b = batch(), c;
5548 <                while (b > 1 && baseIndex != baseLimit) {
5549 <                    do {} while (!casPending(c = pending, c+1));
5550 <                    (rights = new ForEachTransformedEntryTask<K,V,U>
5551 <                     (map, this, b >>>= 1, rights, transformer, action)).fork();
5291 <                }
5292 <                Object v; U u;
5293 <                while ((v = advance()) != null) {
5294 <                    if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
5295 <                        action.apply(u);
5296 <                }
5297 <                tryComplete();
5298 <            } catch (Throwable ex) {
5299 <                return tryCompleteComputation(ex);
5300 <            }
5301 <            while (rights != null && rights.tryUnfork()) {
5302 <                rights.exec();
5303 <                rights = rights.nextRight;
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 >                    (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 <            return false;
5553 >            propagateCompletion();
5554          }
5555      }
5556  
5557      @SuppressWarnings("serial") static final class ForEachTransformedMappingTask<K,V,U>
5558 <        extends BulkTask<K,V,Void> {
5311 <        ForEachTransformedMappingTask<K,V,U> nextRight;
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, BulkTask<K,V,?> p, int b,
5316 <             ForEachTransformedMappingTask<K,V,U> nextRight,
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(m, p, b);
5566 <            this.nextRight = nextRight;
5321 <            this.transformer = transformer;
5322 <            this.action = action;
5323 <
5566 >            this.transformer = transformer; this.action = action;
5567          }
5568 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
5574 <            ForEachTransformedMappingTask<K,V,U> rights = null;
5575 <            try {
5576 <                int b = batch(), c;
5577 <                while (b > 1 && baseIndex != baseLimit) {
5578 <                    do {} while (!casPending(c = pending, c+1));
5579 <                    (rights = new ForEachTransformedMappingTask<K,V,U>
5580 <                     (map, this, b >>>= 1, rights, transformer, action)).fork();
5338 <                }
5339 <                Object v; U u;
5340 <                while ((v = advance()) != null) {
5341 <                    if ((u = transformer.apply((K)nextKey, (V)v)) != null)
5342 <                        action.apply(u);
5343 <                }
5344 <                tryComplete();
5345 <            } catch (Throwable ex) {
5346 <                return tryCompleteComputation(ex);
5347 <            }
5348 <            while (rights != null && rights.tryUnfork()) {
5349 <                rights.exec();
5350 <                rights = rights.nextRight;
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 >                    (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 <            return false;
5582 >            propagateCompletion();
5583          }
5584      }
5585  
5586      @SuppressWarnings("serial") static final class SearchKeysTask<K,V,U>
5587 <        extends BulkTask<K,V,U> {
5358 <        SearchKeysTask<K,V,U> nextRight;
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, BulkTask<K,V,?> p, int b,
5363 <             SearchKeysTask<K,V,U> nextRight,
5591 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5592               Fun<? super K, ? extends U> searchFunction,
5593               AtomicReference<U> result) {
5594              super(m, p, b);
5367            this.nextRight = nextRight;
5595              this.searchFunction = searchFunction; this.result = result;
5596          }
5597 <        @SuppressWarnings("unchecked") public final boolean exec() {
5598 <            AtomicReference<U> result = this.result;
5599 <            final Fun<? super K, ? extends U> searchFunction =
5600 <                this.searchFunction;
5601 <            if (searchFunction == null || result == null)
5602 <                return abortOnNullFunction();
5603 <            SearchKeysTask<K,V,U> rights = null;
5604 <            try {
5605 <                int b = batch(), c;
5606 <                while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5607 <                    do {} while (!casPending(c = pending, c+1));
5608 <                    (rights = new SearchKeysTask<K,V,U>
5609 <                     (map, this, b >>>= 1, rights, searchFunction, result)).fork();
5610 <                }
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 >            while (result.get() == null) {
5613                  U u;
5614 <                while (result.get() == null && advance() != null) {
5615 <                    if ((u = searchFunction.apply((K)nextKey)) != null) {
5616 <                        if (result.compareAndSet(null, u))
5617 <                            tryCompleteComputation(null);
5618 <                        break;
5619 <                    }
5614 >                if (advance() == null) {
5615 >                    propagateCompletion();
5616 >                    break;
5617 >                }
5618 >                if ((u = searchFunction.apply((K)nextKey)) != null) {
5619 >                    if (result.compareAndSet(null, u))
5620 >                        quietlyCompleteRoot();
5621 >                    break;
5622                  }
5392                tryComplete();
5393            } catch (Throwable ex) {
5394                return tryCompleteComputation(ex);
5395            }
5396            while (rights != null && result.get() == null && rights.tryUnfork()) {
5397                rights.exec();
5398                rights = rights.nextRight;
5623              }
5400            return false;
5624          }
5402        public final U getRawResult() { return result.get(); }
5625      }
5626  
5627      @SuppressWarnings("serial") static final class SearchValuesTask<K,V,U>
5628 <        extends BulkTask<K,V,U> {
5407 <        SearchValuesTask<K,V,U> nextRight;
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, BulkTask<K,V,?> p, int b,
5412 <             SearchValuesTask<K,V,U> nextRight,
5632 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5633               Fun<? super V, ? extends U> searchFunction,
5634               AtomicReference<U> result) {
5635              super(m, p, b);
5416            this.nextRight = nextRight;
5636              this.searchFunction = searchFunction; this.result = result;
5637          }
5638 <        @SuppressWarnings("unchecked") public final boolean exec() {
5639 <            AtomicReference<U> result = this.result;
5640 <            final Fun<? super V, ? extends U> searchFunction =
5641 <                this.searchFunction;
5642 <            if (searchFunction == null || result == null)
5643 <                return abortOnNullFunction();
5644 <            SearchValuesTask<K,V,U> rights = null;
5645 <            try {
5646 <                int b = batch(), c;
5647 <                while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5648 <                    do {} while (!casPending(c = pending, c+1));
5649 <                    (rights = new SearchValuesTask<K,V,U>
5650 <                     (map, this, b >>>= 1, rights, searchFunction, result)).fork();
5651 <                }
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 >            while (result.get() == null) {
5654                  Object v; U u;
5655 <                while (result.get() == null && (v = advance()) != null) {
5656 <                    if ((u = searchFunction.apply((V)v)) != null) {
5657 <                        if (result.compareAndSet(null, u))
5658 <                            tryCompleteComputation(null);
5659 <                        break;
5660 <                    }
5655 >                if ((v = advance()) == null) {
5656 >                    propagateCompletion();
5657 >                    break;
5658 >                }
5659 >                if ((u = searchFunction.apply((V)v)) != null) {
5660 >                    if (result.compareAndSet(null, u))
5661 >                        quietlyCompleteRoot();
5662 >                    break;
5663                  }
5441                tryComplete();
5442            } catch (Throwable ex) {
5443                return tryCompleteComputation(ex);
5444            }
5445            while (rights != null && result.get() == null && rights.tryUnfork()) {
5446                rights.exec();
5447                rights = rights.nextRight;
5664              }
5449            return false;
5665          }
5451        public final U getRawResult() { return result.get(); }
5666      }
5667  
5668      @SuppressWarnings("serial") static final class SearchEntriesTask<K,V,U>
5669 <        extends BulkTask<K,V,U> {
5456 <        SearchEntriesTask<K,V,U> nextRight;
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, BulkTask<K,V,?> p, int b,
5461 <             SearchEntriesTask<K,V,U> nextRight,
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, p, b);
5465            this.nextRight = nextRight;
5677              this.searchFunction = searchFunction; this.result = result;
5678          }
5679 <        @SuppressWarnings("unchecked") public final boolean exec() {
5680 <            AtomicReference<U> result = this.result;
5681 <            final Fun<Entry<K,V>, ? extends U> searchFunction =
5682 <                this.searchFunction;
5683 <            if (searchFunction == null || result == null)
5684 <                return abortOnNullFunction();
5685 <            SearchEntriesTask<K,V,U> rights = null;
5686 <            try {
5687 <                int b = batch(), c;
5688 <                while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5689 <                    do {} while (!casPending(c = pending, c+1));
5690 <                    (rights = new SearchEntriesTask<K,V,U>
5691 <                     (map, this, b >>>= 1, rights, searchFunction, result)).fork();
5692 <                }
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 >            while (result.get() == null) {
5695                  Object v; U u;
5696 <                while (result.get() == null && (v = advance()) != null) {
5697 <                    if ((u = searchFunction.apply(entryFor((K)nextKey, (V)v))) != null) {
5698 <                        if (result.compareAndSet(null, u))
5699 <                            tryCompleteComputation(null);
5700 <                        break;
5701 <                    }
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                  }
5490                tryComplete();
5491            } catch (Throwable ex) {
5492                return tryCompleteComputation(ex);
5493            }
5494            while (rights != null && result.get() == null && rights.tryUnfork()) {
5495                rights.exec();
5496                rights = rights.nextRight;
5705              }
5498            return false;
5706          }
5500        public final U getRawResult() { return result.get(); }
5707      }
5708  
5709      @SuppressWarnings("serial") static final class SearchMappingsTask<K,V,U>
5710 <        extends BulkTask<K,V,U> {
5505 <        SearchMappingsTask<K,V,U> nextRight;
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, BulkTask<K,V,?> p, int b,
5510 <             SearchMappingsTask<K,V,U> nextRight,
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(m, p, b);
5514            this.nextRight = nextRight;
5718              this.searchFunction = searchFunction; this.result = result;
5719          }
5720 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
5726 <            SearchMappingsTask<K,V,U> rights = null;
5727 <            try {
5728 <                int b = batch(), c;
5729 <                while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5730 <                    do {} while (!casPending(c = pending, c+1));
5731 <                    (rights = new SearchMappingsTask<K,V,U>
5732 <                     (map, this, b >>>= 1, rights, searchFunction, result)).fork();
5733 <                }
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 >            while (result.get() == null) {
5736                  Object v; U u;
5737 <                while (result.get() == null && (v = advance()) != null) {
5738 <                    if ((u = searchFunction.apply((K)nextKey, (V)v)) != null) {
5739 <                        if (result.compareAndSet(null, u))
5740 <                            tryCompleteComputation(null);
5741 <                        break;
5742 <                    }
5737 >                if ((v = advance()) == null) {
5738 >                    propagateCompletion();
5739 >                    break;
5740 >                }
5741 >                if ((u = searchFunction.apply((K)nextKey, (V)v)) != null) {
5742 >                    if (result.compareAndSet(null, u))
5743 >                        quietlyCompleteRoot();
5744 >                    break;
5745                  }
5539                tryComplete();
5540            } catch (Throwable ex) {
5541                return tryCompleteComputation(ex);
5542            }
5543            while (rights != null && result.get() == null && rights.tryUnfork()) {
5544                rights.exec();
5545                rights = rights.nextRight;
5746              }
5547            return false;
5747          }
5549        public final U getRawResult() { return result.get(); }
5748      }
5749  
5750      @SuppressWarnings("serial") static final class ReduceKeysTask<K,V>
5751 <        extends BulkTask<K,V,K> {
5751 >        extends Traverser<K,V,K> {
5752          final BiFun<? super K, ? super K, ? extends K> reducer;
5753          K result;
5754          ReduceKeysTask<K,V> rights, nextRight;
5755          ReduceKeysTask
5756 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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(m, p, b); this.nextRight = nextRight;
5760              this.reducer = reducer;
5761          }
5762 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
5768 <            try {
5769 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
5770 <                    do {} while (!casPending(c = pending, c+1));
5771 <                    (rights = new ReduceKeysTask<K,V>
5772 <                     (map, this, b >>>= 1, rights, reducer)).fork();
5773 <                }
5774 <                K r = null;
5775 <                while (advance() != null) {
5776 <                    K u = (K)nextKey;
5777 <                    r = (r == null) ? u : reducer.apply(r, u);
5778 <                }
5779 <                result = r;
5780 <                for (ReduceKeysTask<K,V> t = this, s;;) {
5781 <                    int c; BulkTask<K,V,?> par; K tr, sr;
5782 <                    if ((c = t.pending) == 0) {
5783 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
5784 <                            if ((sr = s.result) != null)
5785 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
5786 <                        }
5787 <                        if ((par = t.parent) == null ||
5589 <                            !(par instanceof ReduceKeysTask)) {
5590 <                            t.quietlyComplete();
5591 <                            break;
5592 <                        }
5593 <                        t = (ReduceKeysTask<K,V>)par;
5594 <                    }
5595 <                    else if (t.casPending(c, c - 1))
5596 <                        break;
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 (advance() != null) {
5773 >                K u = (K)nextKey;
5774 >                r = (r == null) ? u : reducer.apply(r, u);
5775 >            }
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                  }
5598            } catch (Throwable ex) {
5599                return tryCompleteComputation(ex);
5789              }
5601            for (ReduceKeysTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
5602                s.exec();
5603            return false;
5790          }
5605        public final K getRawResult() { return result; }
5791      }
5792  
5793      @SuppressWarnings("serial") static final class ReduceValuesTask<K,V>
5794 <        extends BulkTask<K,V,V> {
5794 >        extends Traverser<K,V,V> {
5795          final BiFun<? super V, ? super V, ? extends V> reducer;
5796          V result;
5797          ReduceValuesTask<K,V> rights, nextRight;
5798          ReduceValuesTask
5799 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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, p, b); this.nextRight = nextRight;
5803              this.reducer = reducer;
5804          }
5805 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
5811 <            try {
5812 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
5813 <                    do {} while (!casPending(c = pending, c+1));
5814 <                    (rights = new ReduceValuesTask<K,V>
5815 <                     (map, this, b >>>= 1, rights, reducer)).fork();
5816 <                }
5817 <                V r = null;
5818 <                Object v;
5819 <                while ((v = advance()) != null) {
5820 <                    V u = (V)v;
5821 <                    r = (r == null) ? u : reducer.apply(r, u);
5822 <                }
5823 <                result = r;
5824 <                for (ReduceValuesTask<K,V> t = this, s;;) {
5825 <                    int c; BulkTask<K,V,?> par; V tr, sr;
5826 <                    if ((c = t.pending) == 0) {
5827 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
5828 <                            if ((sr = s.result) != null)
5829 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
5830 <                        }
5831 <                        if ((par = t.parent) == null ||
5646 <                            !(par instanceof ReduceValuesTask)) {
5647 <                            t.quietlyComplete();
5648 <                            break;
5649 <                        }
5650 <                        t = (ReduceValuesTask<K,V>)par;
5651 <                    }
5652 <                    else if (t.casPending(c, c - 1))
5653 <                        break;
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 = advance()) != null) {
5817 >                V u = (V)v;
5818 >                r = (r == null) ? u : reducer.apply(r, u);
5819 >            }
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                  }
5655            } catch (Throwable ex) {
5656                return tryCompleteComputation(ex);
5833              }
5658            for (ReduceValuesTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
5659                s.exec();
5660            return false;
5834          }
5662        public final V getRawResult() { return result; }
5835      }
5836  
5837      @SuppressWarnings("serial") static final class ReduceEntriesTask<K,V>
5838 <        extends BulkTask<K,V,Map.Entry<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> rights, nextRight;
5842          ReduceEntriesTask
5843 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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, p, b); this.nextRight = nextRight;
5847              this.reducer = reducer;
5848          }
5849 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
5855 <            try {
5856 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
5857 <                    do {} while (!casPending(c = pending, c+1));
5858 <                    (rights = new ReduceEntriesTask<K,V>
5859 <                     (map, this, b >>>= 1, rights, reducer)).fork();
5860 <                }
5861 <                Map.Entry<K,V> r = null;
5862 <                Object v;
5863 <                while ((v = advance()) != null) {
5864 <                    Map.Entry<K,V> u = entryFor((K)nextKey, (V)v);
5865 <                    r = (r == null) ? u : reducer.apply(r, u);
5866 <                }
5867 <                result = r;
5868 <                for (ReduceEntriesTask<K,V> t = this, s;;) {
5869 <                    int c; BulkTask<K,V,?> par; Map.Entry<K,V> tr, sr;
5870 <                    if ((c = t.pending) == 0) {
5871 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
5872 <                            if ((sr = s.result) != null)
5873 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
5874 <                        }
5875 <                        if ((par = t.parent) == null ||
5703 <                            !(par instanceof ReduceEntriesTask)) {
5704 <                            t.quietlyComplete();
5705 <                            break;
5706 <                        }
5707 <                        t = (ReduceEntriesTask<K,V>)par;
5708 <                    }
5709 <                    else if (t.casPending(c, c - 1))
5710 <                        break;
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 = advance()) != null) {
5861 >                Map.Entry<K,V> u = entryFor((K)nextKey, (V)v);
5862 >                r = (r == null) ? u : reducer.apply(r, u);
5863 >            }
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                  }
5712            } catch (Throwable ex) {
5713                return tryCompleteComputation(ex);
5877              }
5715            for (ReduceEntriesTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
5716                s.exec();
5717            return false;
5878          }
5719        public final Map.Entry<K,V> getRawResult() { return result; }
5879      }
5880  
5881      @SuppressWarnings("serial") static final class MapReduceKeysTask<K,V,U>
5882 <        extends BulkTask<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> rights, nextRight;
5887          MapReduceKeysTask
5888 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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) {
# Line 5734 | Line 5893 | public class ConcurrentHashMapV8<K, V>
5893              this.transformer = transformer;
5894              this.reducer = reducer;
5895          }
5896 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
5904 <            try {
5905 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
5906 <                    do {} while (!casPending(c = pending, c+1));
5907 <                    (rights = new MapReduceKeysTask<K,V,U>
5908 <                     (map, this, b >>>= 1, rights, transformer, reducer)).fork();
5909 <                }
5910 <                U r = null, u;
5911 <                while (advance() != null) {
5912 <                    if ((u = transformer.apply((K)nextKey)) != null)
5913 <                        r = (r == null) ? u : reducer.apply(r, u);
5914 <                }
5915 <                result = r;
5916 <                for (MapReduceKeysTask<K,V,U> t = this, s;;) {
5917 <                    int c; BulkTask<K,V,?> par; U tr, sr;
5918 <                    if ((c = t.pending) == 0) {
5919 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
5920 <                            if ((sr = s.result) != null)
5921 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
5922 <                        }
5923 <                        if ((par = t.parent) == null ||
5764 <                            !(par instanceof MapReduceKeysTask)) {
5765 <                            t.quietlyComplete();
5766 <                            break;
5767 <                        }
5768 <                        t = (MapReduceKeysTask<K,V,U>)par;
5769 <                    }
5770 <                    else if (t.casPending(c, c - 1))
5771 <                        break;
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 (advance() != null) {
5909 >                if ((u = transformer.apply((K)nextKey)) != null)
5910 >                    r = (r == null) ? u : reducer.apply(r, u);
5911 >            }
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                  }
5773            } catch (Throwable ex) {
5774                return tryCompleteComputation(ex);
5925              }
5776            for (MapReduceKeysTask<K,V,U> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
5777                s.exec();
5778            return false;
5926          }
5780        public final U getRawResult() { return result; }
5927      }
5928  
5929      @SuppressWarnings("serial") static final class MapReduceValuesTask<K,V,U>
5930 <        extends BulkTask<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> rights, nextRight;
5935          MapReduceValuesTask
5936 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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) {
# Line 5795 | Line 5941 | public class ConcurrentHashMapV8<K, V>
5941              this.transformer = transformer;
5942              this.reducer = reducer;
5943          }
5944 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
5952 <            try {
5953 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
5954 <                    do {} while (!casPending(c = pending, c+1));
5955 <                    (rights = new MapReduceValuesTask<K,V,U>
5956 <                     (map, this, b >>>= 1, rights, transformer, reducer)).fork();
5957 <                }
5958 <                U r = null, u;
5959 <                Object v;
5960 <                while ((v = advance()) != null) {
5961 <                    if ((u = transformer.apply((V)v)) != null)
5962 <                        r = (r == null) ? u : reducer.apply(r, u);
5963 <                }
5964 <                result = r;
5965 <                for (MapReduceValuesTask<K,V,U> t = this, s;;) {
5966 <                    int c; BulkTask<K,V,?> par; U tr, sr;
5967 <                    if ((c = t.pending) == 0) {
5968 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
5969 <                            if ((sr = s.result) != null)
5970 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
5971 <                        }
5972 <                        if ((par = t.parent) == null ||
5826 <                            !(par instanceof MapReduceValuesTask)) {
5827 <                            t.quietlyComplete();
5828 <                            break;
5829 <                        }
5830 <                        t = (MapReduceValuesTask<K,V,U>)par;
5831 <                    }
5832 <                    else if (t.casPending(c, c - 1))
5833 <                        break;
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 = advance()) != null) {
5958 >                if ((u = transformer.apply((V)v)) != null)
5959 >                    r = (r == null) ? u : reducer.apply(r, u);
5960 >            }
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                  }
5835            } catch (Throwable ex) {
5836                return tryCompleteComputation(ex);
5974              }
5838            for (MapReduceValuesTask<K,V,U> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
5839                s.exec();
5840            return false;
5975          }
5842        public final U getRawResult() { return result; }
5976      }
5977  
5978      @SuppressWarnings("serial") static final class MapReduceEntriesTask<K,V,U>
5979 <        extends BulkTask<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> rights, nextRight;
5984          MapReduceEntriesTask
5985 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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) {
# Line 5857 | Line 5990 | public class ConcurrentHashMapV8<K, V>
5990              this.transformer = transformer;
5991              this.reducer = reducer;
5992          }
5993 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6001 <            try {
6002 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6003 <                    do {} while (!casPending(c = pending, c+1));
6004 <                    (rights = new MapReduceEntriesTask<K,V,U>
6005 <                     (map, this, b >>>= 1, rights, transformer, reducer)).fork();
6006 <                }
6007 <                U r = null, u;
6008 <                Object v;
6009 <                while ((v = advance()) != null) {
6010 <                    if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
6011 <                        r = (r == null) ? u : reducer.apply(r, u);
6012 <                }
6013 <                result = r;
6014 <                for (MapReduceEntriesTask<K,V,U> t = this, s;;) {
6015 <                    int c; BulkTask<K,V,?> par; U tr, sr;
6016 <                    if ((c = t.pending) == 0) {
6017 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6018 <                            if ((sr = s.result) != null)
6019 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
6020 <                        }
6021 <                        if ((par = t.parent) == null ||
5888 <                            !(par instanceof MapReduceEntriesTask)) {
5889 <                            t.quietlyComplete();
5890 <                            break;
5891 <                        }
5892 <                        t = (MapReduceEntriesTask<K,V,U>)par;
5893 <                    }
5894 <                    else if (t.casPending(c, c - 1))
5895 <                        break;
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 = advance()) != null) {
6007 >                if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
6008 >                    r = (r == null) ? u : reducer.apply(r, u);
6009 >            }
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                  }
5897            } catch (Throwable ex) {
5898                return tryCompleteComputation(ex);
6023              }
5900            for (MapReduceEntriesTask<K,V,U> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
5901                s.exec();
5902            return false;
6024          }
5904        public final U getRawResult() { return result; }
6025      }
6026  
6027      @SuppressWarnings("serial") static final class MapReduceMappingsTask<K,V,U>
6028 <        extends BulkTask<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> rights, nextRight;
6033          MapReduceMappingsTask
6034 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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) {
# Line 5919 | Line 6039 | public class ConcurrentHashMapV8<K, V>
6039              this.transformer = transformer;
6040              this.reducer = reducer;
6041          }
6042 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6050 <            try {
6051 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6052 <                    do {} while (!casPending(c = pending, c+1));
6053 <                    (rights = new MapReduceMappingsTask<K,V,U>
6054 <                     (map, this, b >>>= 1, rights, transformer, reducer)).fork();
6055 <                }
6056 <                U r = null, u;
6057 <                Object v;
6058 <                while ((v = advance()) != null) {
6059 <                    if ((u = transformer.apply((K)nextKey, (V)v)) != null)
6060 <                        r = (r == null) ? u : reducer.apply(r, u);
6061 <                }
6062 <                result = r;
6063 <                for (MapReduceMappingsTask<K,V,U> t = this, s;;) {
6064 <                    int c; BulkTask<K,V,?> par; U tr, sr;
6065 <                    if ((c = t.pending) == 0) {
6066 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6067 <                            if ((sr = s.result) != null)
6068 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
6069 <                        }
6070 <                        if ((par = t.parent) == null ||
5950 <                            !(par instanceof MapReduceMappingsTask)) {
5951 <                            t.quietlyComplete();
5952 <                            break;
5953 <                        }
5954 <                        t = (MapReduceMappingsTask<K,V,U>)par;
5955 <                    }
5956 <                    else if (t.casPending(c, c - 1))
5957 <                        break;
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 = advance()) != null) {
6056 >                if ((u = transformer.apply((K)nextKey, (V)v)) != null)
6057 >                    r = (r == null) ? u : reducer.apply(r, u);
6058 >            }
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                  }
5959            } catch (Throwable ex) {
5960                return tryCompleteComputation(ex);
6072              }
5962            for (MapReduceMappingsTask<K,V,U> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
5963                s.exec();
5964            return false;
6073          }
5966        public final U getRawResult() { return result; }
6074      }
6075  
6076      @SuppressWarnings("serial") static final class MapReduceKeysToDoubleTask<K,V>
6077 <        extends BulkTask<K,V,Double> {
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> rights, nextRight;
6083          MapReduceKeysToDoubleTask
6084 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6084 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6085               MapReduceKeysToDoubleTask<K,V> nextRight,
6086               ObjectToDouble<? super K> transformer,
6087               double basis,
# Line 5983 | Line 6090 | public class ConcurrentHashMapV8<K, V>
6090              this.transformer = transformer;
6091              this.basis = basis; this.reducer = reducer;
6092          }
6093 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6100 <            try {
6101 <                final double id = this.basis;
6102 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6103 <                    do {} while (!casPending(c = pending, c+1));
6104 <                    (rights = new MapReduceKeysToDoubleTask<K,V>
6105 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6106 <                }
6107 <                double r = id;
6108 <                while (advance() != null)
6109 <                    r = reducer.apply(r, transformer.apply((K)nextKey));
6110 <                result = r;
6111 <                for (MapReduceKeysToDoubleTask<K,V> t = this, s;;) {
6112 <                    int c; BulkTask<K,V,?> par;
6113 <                    if ((c = t.pending) == 0) {
6114 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6007 <                            t.result = reducer.apply(t.result, s.result);
6008 <                        }
6009 <                        if ((par = t.parent) == null ||
6010 <                            !(par instanceof MapReduceKeysToDoubleTask)) {
6011 <                            t.quietlyComplete();
6012 <                            break;
6013 <                        }
6014 <                        t = (MapReduceKeysToDoubleTask<K,V>)par;
6015 <                    }
6016 <                    else if (t.casPending(c, c - 1))
6017 <                        break;
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                  }
6019            } catch (Throwable ex) {
6020                return tryCompleteComputation(ex);
6116              }
6022            for (MapReduceKeysToDoubleTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6023                s.exec();
6024            return false;
6117          }
6026        public final Double getRawResult() { return result; }
6118      }
6119  
6120      @SuppressWarnings("serial") static final class MapReduceValuesToDoubleTask<K,V>
6121 <        extends BulkTask<K,V,Double> {
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> rights, nextRight;
6127          MapReduceValuesToDoubleTask
6128 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6128 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6129               MapReduceValuesToDoubleTask<K,V> nextRight,
6130               ObjectToDouble<? super V> transformer,
6131               double basis,
# Line 6043 | Line 6134 | public class ConcurrentHashMapV8<K, V>
6134              this.transformer = transformer;
6135              this.basis = basis; this.reducer = reducer;
6136          }
6137 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6144 <            try {
6145 <                final double id = this.basis;
6146 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6147 <                    do {} while (!casPending(c = pending, c+1));
6148 <                    (rights = new MapReduceValuesToDoubleTask<K,V>
6149 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6150 <                }
6151 <                double r = id;
6152 <                Object v;
6153 <                while ((v = advance()) != null)
6154 <                    r = reducer.apply(r, transformer.apply((V)v));
6155 <                result = r;
6156 <                for (MapReduceValuesToDoubleTask<K,V> t = this, s;;) {
6157 <                    int c; BulkTask<K,V,?> par;
6158 <                    if ((c = t.pending) == 0) {
6159 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6068 <                            t.result = reducer.apply(t.result, s.result);
6069 <                        }
6070 <                        if ((par = t.parent) == null ||
6071 <                            !(par instanceof MapReduceValuesToDoubleTask)) {
6072 <                            t.quietlyComplete();
6073 <                            break;
6074 <                        }
6075 <                        t = (MapReduceValuesToDoubleTask<K,V>)par;
6076 <                    }
6077 <                    else if (t.casPending(c, c - 1))
6078 <                        break;
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 = advance()) != null)
6150 >                r = reducer.apply(r, transformer.apply((V)v));
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                  }
6080            } catch (Throwable ex) {
6081                return tryCompleteComputation(ex);
6161              }
6083            for (MapReduceValuesToDoubleTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6084                s.exec();
6085            return false;
6162          }
6087        public final Double getRawResult() { return result; }
6163      }
6164  
6165      @SuppressWarnings("serial") static final class MapReduceEntriesToDoubleTask<K,V>
6166 <        extends BulkTask<K,V,Double> {
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> rights, nextRight;
6172          MapReduceEntriesToDoubleTask
6173 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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,
# Line 6104 | Line 6179 | public class ConcurrentHashMapV8<K, V>
6179              this.transformer = transformer;
6180              this.basis = basis; this.reducer = reducer;
6181          }
6182 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6189 <            try {
6190 <                final double id = this.basis;
6191 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6192 <                    do {} while (!casPending(c = pending, c+1));
6193 <                    (rights = new MapReduceEntriesToDoubleTask<K,V>
6194 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6195 <                }
6196 <                double r = id;
6197 <                Object v;
6198 <                while ((v = advance()) != null)
6199 <                    r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6200 <                result = r;
6201 <                for (MapReduceEntriesToDoubleTask<K,V> t = this, s;;) {
6202 <                    int c; BulkTask<K,V,?> par;
6203 <                    if ((c = t.pending) == 0) {
6204 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6129 <                            t.result = reducer.apply(t.result, s.result);
6130 <                        }
6131 <                        if ((par = t.parent) == null ||
6132 <                            !(par instanceof MapReduceEntriesToDoubleTask)) {
6133 <                            t.quietlyComplete();
6134 <                            break;
6135 <                        }
6136 <                        t = (MapReduceEntriesToDoubleTask<K,V>)par;
6137 <                    }
6138 <                    else if (t.casPending(c, c - 1))
6139 <                        break;
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 = 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                  }
6141            } catch (Throwable ex) {
6142                return tryCompleteComputation(ex);
6206              }
6144            for (MapReduceEntriesToDoubleTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6145                s.exec();
6146            return false;
6207          }
6148        public final Double getRawResult() { return result; }
6208      }
6209  
6210      @SuppressWarnings("serial") static final class MapReduceMappingsToDoubleTask<K,V>
6211 <        extends BulkTask<K,V,Double> {
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> rights, nextRight;
6217          MapReduceMappingsToDoubleTask
6218 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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,
# Line 6165 | Line 6224 | public class ConcurrentHashMapV8<K, V>
6224              this.transformer = transformer;
6225              this.basis = basis; this.reducer = reducer;
6226          }
6227 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6234 <            try {
6235 <                final double id = this.basis;
6236 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6237 <                    do {} while (!casPending(c = pending, c+1));
6238 <                    (rights = new MapReduceMappingsToDoubleTask<K,V>
6239 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6240 <                }
6241 <                double r = id;
6242 <                Object v;
6243 <                while ((v = advance()) != null)
6244 <                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6245 <                result = r;
6246 <                for (MapReduceMappingsToDoubleTask<K,V> t = this, s;;) {
6247 <                    int c; BulkTask<K,V,?> par;
6248 <                    if ((c = t.pending) == 0) {
6249 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6190 <                            t.result = reducer.apply(t.result, s.result);
6191 <                        }
6192 <                        if ((par = t.parent) == null ||
6193 <                            !(par instanceof MapReduceMappingsToDoubleTask)) {
6194 <                            t.quietlyComplete();
6195 <                            break;
6196 <                        }
6197 <                        t = (MapReduceMappingsToDoubleTask<K,V>)par;
6198 <                    }
6199 <                    else if (t.casPending(c, c - 1))
6200 <                        break;
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 = 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                  }
6202            } catch (Throwable ex) {
6203                return tryCompleteComputation(ex);
6251              }
6205            for (MapReduceMappingsToDoubleTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6206                s.exec();
6207            return false;
6252          }
6209        public final Double getRawResult() { return result; }
6253      }
6254  
6255      @SuppressWarnings("serial") static final class MapReduceKeysToLongTask<K,V>
6256 <        extends BulkTask<K,V,Long> {
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> rights, nextRight;
6262          MapReduceKeysToLongTask
6263 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6263 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6264               MapReduceKeysToLongTask<K,V> nextRight,
6265               ObjectToLong<? super K> transformer,
6266               long basis,
# Line 6226 | Line 6269 | public class ConcurrentHashMapV8<K, V>
6269              this.transformer = transformer;
6270              this.basis = basis; this.reducer = reducer;
6271          }
6272 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6279 <            try {
6280 <                final long id = this.basis;
6281 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6282 <                    do {} while (!casPending(c = pending, c+1));
6283 <                    (rights = new MapReduceKeysToLongTask<K,V>
6284 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6285 <                }
6286 <                long r = id;
6287 <                while (advance() != null)
6288 <                    r = reducer.apply(r, transformer.apply((K)nextKey));
6289 <                result = r;
6290 <                for (MapReduceKeysToLongTask<K,V> t = this, s;;) {
6291 <                    int c; BulkTask<K,V,?> par;
6292 <                    if ((c = t.pending) == 0) {
6293 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6250 <                            t.result = reducer.apply(t.result, s.result);
6251 <                        }
6252 <                        if ((par = t.parent) == null ||
6253 <                            !(par instanceof MapReduceKeysToLongTask)) {
6254 <                            t.quietlyComplete();
6255 <                            break;
6256 <                        }
6257 <                        t = (MapReduceKeysToLongTask<K,V>)par;
6258 <                    }
6259 <                    else if (t.casPending(c, c - 1))
6260 <                        break;
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                  }
6262            } catch (Throwable ex) {
6263                return tryCompleteComputation(ex);
6295              }
6265            for (MapReduceKeysToLongTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6266                s.exec();
6267            return false;
6296          }
6269        public final Long getRawResult() { return result; }
6297      }
6298  
6299      @SuppressWarnings("serial") static final class MapReduceValuesToLongTask<K,V>
6300 <        extends BulkTask<K,V,Long> {
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> rights, nextRight;
6306          MapReduceValuesToLongTask
6307 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6307 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6308               MapReduceValuesToLongTask<K,V> nextRight,
6309               ObjectToLong<? super V> transformer,
6310               long basis,
# Line 6286 | Line 6313 | public class ConcurrentHashMapV8<K, V>
6313              this.transformer = transformer;
6314              this.basis = basis; this.reducer = reducer;
6315          }
6316 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6323 <            try {
6324 <                final long id = this.basis;
6325 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6326 <                    do {} while (!casPending(c = pending, c+1));
6327 <                    (rights = new MapReduceValuesToLongTask<K,V>
6328 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6329 <                }
6330 <                long r = id;
6331 <                Object v;
6332 <                while ((v = advance()) != null)
6333 <                    r = reducer.apply(r, transformer.apply((V)v));
6334 <                result = r;
6335 <                for (MapReduceValuesToLongTask<K,V> t = this, s;;) {
6336 <                    int c; BulkTask<K,V,?> par;
6337 <                    if ((c = t.pending) == 0) {
6338 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6311 <                            t.result = reducer.apply(t.result, s.result);
6312 <                        }
6313 <                        if ((par = t.parent) == null ||
6314 <                            !(par instanceof MapReduceValuesToLongTask)) {
6315 <                            t.quietlyComplete();
6316 <                            break;
6317 <                        }
6318 <                        t = (MapReduceValuesToLongTask<K,V>)par;
6319 <                    }
6320 <                    else if (t.casPending(c, c - 1))
6321 <                        break;
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 = advance()) != null)
6329 >                r = reducer.apply(r, transformer.apply((V)v));
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                  }
6323            } catch (Throwable ex) {
6324                return tryCompleteComputation(ex);
6340              }
6326            for (MapReduceValuesToLongTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6327                s.exec();
6328            return false;
6341          }
6330        public final Long getRawResult() { return result; }
6342      }
6343  
6344      @SuppressWarnings("serial") static final class MapReduceEntriesToLongTask<K,V>
6345 <        extends BulkTask<K,V,Long> {
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> rights, nextRight;
6351          MapReduceEntriesToLongTask
6352 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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,
# Line 6347 | Line 6358 | public class ConcurrentHashMapV8<K, V>
6358              this.transformer = transformer;
6359              this.basis = basis; this.reducer = reducer;
6360          }
6361 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6368 <            try {
6369 <                final long id = this.basis;
6370 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6371 <                    do {} while (!casPending(c = pending, c+1));
6372 <                    (rights = new MapReduceEntriesToLongTask<K,V>
6373 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6374 <                }
6375 <                long r = id;
6376 <                Object v;
6377 <                while ((v = advance()) != null)
6378 <                    r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6379 <                result = r;
6380 <                for (MapReduceEntriesToLongTask<K,V> t = this, s;;) {
6381 <                    int c; BulkTask<K,V,?> par;
6382 <                    if ((c = t.pending) == 0) {
6383 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6372 <                            t.result = reducer.apply(t.result, s.result);
6373 <                        }
6374 <                        if ((par = t.parent) == null ||
6375 <                            !(par instanceof MapReduceEntriesToLongTask)) {
6376 <                            t.quietlyComplete();
6377 <                            break;
6378 <                        }
6379 <                        t = (MapReduceEntriesToLongTask<K,V>)par;
6380 <                    }
6381 <                    else if (t.casPending(c, c - 1))
6382 <                        break;
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 = 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                  }
6384            } catch (Throwable ex) {
6385                return tryCompleteComputation(ex);
6385              }
6387            for (MapReduceEntriesToLongTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6388                s.exec();
6389            return false;
6386          }
6391        public final Long getRawResult() { return result; }
6387      }
6388  
6389      @SuppressWarnings("serial") static final class MapReduceMappingsToLongTask<K,V>
6390 <        extends BulkTask<K,V,Long> {
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> rights, nextRight;
6396          MapReduceMappingsToLongTask
6397 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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,
# Line 6408 | Line 6403 | public class ConcurrentHashMapV8<K, V>
6403              this.transformer = transformer;
6404              this.basis = basis; this.reducer = reducer;
6405          }
6406 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6413 <            try {
6414 <                final long id = this.basis;
6415 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6416 <                    do {} while (!casPending(c = pending, c+1));
6417 <                    (rights = new MapReduceMappingsToLongTask<K,V>
6418 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6419 <                }
6420 <                long r = id;
6421 <                Object v;
6422 <                while ((v = advance()) != null)
6423 <                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6424 <                result = r;
6425 <                for (MapReduceMappingsToLongTask<K,V> t = this, s;;) {
6426 <                    int c; BulkTask<K,V,?> par;
6427 <                    if ((c = t.pending) == 0) {
6428 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6433 <                            t.result = reducer.apply(t.result, s.result);
6434 <                        }
6435 <                        if ((par = t.parent) == null ||
6436 <                            !(par instanceof MapReduceMappingsToLongTask)) {
6437 <                            t.quietlyComplete();
6438 <                            break;
6439 <                        }
6440 <                        t = (MapReduceMappingsToLongTask<K,V>)par;
6441 <                    }
6442 <                    else if (t.casPending(c, c - 1))
6443 <                        break;
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 = 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                  }
6445            } catch (Throwable ex) {
6446                return tryCompleteComputation(ex);
6430              }
6448            for (MapReduceMappingsToLongTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6449                s.exec();
6450            return false;
6431          }
6452        public final Long getRawResult() { return result; }
6432      }
6433  
6434      @SuppressWarnings("serial") static final class MapReduceKeysToIntTask<K,V>
6435 <        extends BulkTask<K,V,Integer> {
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> rights, nextRight;
6441          MapReduceKeysToIntTask
6442 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6442 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6443               MapReduceKeysToIntTask<K,V> nextRight,
6444               ObjectToInt<? super K> transformer,
6445               int basis,
# Line 6469 | Line 6448 | public class ConcurrentHashMapV8<K, V>
6448              this.transformer = transformer;
6449              this.basis = basis; this.reducer = reducer;
6450          }
6451 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6458 <            try {
6459 <                final int id = this.basis;
6460 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6461 <                    do {} while (!casPending(c = pending, c+1));
6462 <                    (rights = new MapReduceKeysToIntTask<K,V>
6463 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6464 <                }
6465 <                int r = id;
6466 <                while (advance() != null)
6467 <                    r = reducer.apply(r, transformer.apply((K)nextKey));
6468 <                result = r;
6469 <                for (MapReduceKeysToIntTask<K,V> t = this, s;;) {
6470 <                    int c; BulkTask<K,V,?> par;
6471 <                    if ((c = t.pending) == 0) {
6472 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6493 <                            t.result = reducer.apply(t.result, s.result);
6494 <                        }
6495 <                        if ((par = t.parent) == null ||
6496 <                            !(par instanceof MapReduceKeysToIntTask)) {
6497 <                            t.quietlyComplete();
6498 <                            break;
6499 <                        }
6500 <                        t = (MapReduceKeysToIntTask<K,V>)par;
6501 <                    }
6502 <                    else if (t.casPending(c, c - 1))
6503 <                        break;
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                  }
6505            } catch (Throwable ex) {
6506                return tryCompleteComputation(ex);
6474              }
6508            for (MapReduceKeysToIntTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6509                s.exec();
6510            return false;
6475          }
6512        public final Integer getRawResult() { return result; }
6476      }
6477  
6478      @SuppressWarnings("serial") static final class MapReduceValuesToIntTask<K,V>
6479 <        extends BulkTask<K,V,Integer> {
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> rights, nextRight;
6485          MapReduceValuesToIntTask
6486 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6486 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
6487               MapReduceValuesToIntTask<K,V> nextRight,
6488               ObjectToInt<? super V> transformer,
6489               int basis,
# Line 6529 | Line 6492 | public class ConcurrentHashMapV8<K, V>
6492              this.transformer = transformer;
6493              this.basis = basis; this.reducer = reducer;
6494          }
6495 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6502 <            try {
6503 <                final int id = this.basis;
6504 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6505 <                    do {} while (!casPending(c = pending, c+1));
6506 <                    (rights = new MapReduceValuesToIntTask<K,V>
6507 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6508 <                }
6509 <                int r = id;
6510 <                Object v;
6511 <                while ((v = advance()) != null)
6512 <                    r = reducer.apply(r, transformer.apply((V)v));
6513 <                result = r;
6514 <                for (MapReduceValuesToIntTask<K,V> t = this, s;;) {
6515 <                    int c; BulkTask<K,V,?> par;
6516 <                    if ((c = t.pending) == 0) {
6517 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6554 <                            t.result = reducer.apply(t.result, s.result);
6555 <                        }
6556 <                        if ((par = t.parent) == null ||
6557 <                            !(par instanceof MapReduceValuesToIntTask)) {
6558 <                            t.quietlyComplete();
6559 <                            break;
6560 <                        }
6561 <                        t = (MapReduceValuesToIntTask<K,V>)par;
6562 <                    }
6563 <                    else if (t.casPending(c, c - 1))
6564 <                        break;
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 = advance()) != null)
6508 >                r = reducer.apply(r, transformer.apply((V)v));
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                  }
6566            } catch (Throwable ex) {
6567                return tryCompleteComputation(ex);
6519              }
6569            for (MapReduceValuesToIntTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6570                s.exec();
6571            return false;
6520          }
6573        public final Integer getRawResult() { return result; }
6521      }
6522  
6523      @SuppressWarnings("serial") static final class MapReduceEntriesToIntTask<K,V>
6524 <        extends BulkTask<K,V,Integer> {
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> rights, nextRight;
6530          MapReduceEntriesToIntTask
6531 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
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,
# Line 6590 | Line 6537 | public class ConcurrentHashMapV8<K, V>
6537              this.transformer = transformer;
6538              this.basis = basis; this.reducer = reducer;
6539          }
6540 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6547 <            try {
6548 <                final int id = this.basis;
6549 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6550 <                    do {} while (!casPending(c = pending, c+1));
6551 <                    (rights = new MapReduceEntriesToIntTask<K,V>
6552 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6553 <                }
6554 <                int r = id;
6555 <                Object v;
6556 <                while ((v = advance()) != null)
6557 <                    r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6558 <                result = r;
6559 <                for (MapReduceEntriesToIntTask<K,V> t = this, s;;) {
6560 <                    int c; BulkTask<K,V,?> par;
6561 <                    if ((c = t.pending) == 0) {
6562 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6615 <                            t.result = reducer.apply(t.result, s.result);
6616 <                        }
6617 <                        if ((par = t.parent) == null ||
6618 <                            !(par instanceof MapReduceEntriesToIntTask)) {
6619 <                            t.quietlyComplete();
6620 <                            break;
6621 <                        }
6622 <                        t = (MapReduceEntriesToIntTask<K,V>)par;
6623 <                    }
6624 <                    else if (t.casPending(c, c - 1))
6625 <                        break;
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 = 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                  }
6627            } catch (Throwable ex) {
6628                return tryCompleteComputation(ex);
6564              }
6630            for (MapReduceEntriesToIntTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6631                s.exec();
6632            return false;
6565          }
6634        public final Integer getRawResult() { return result; }
6566      }
6567  
6568      @SuppressWarnings("serial") static final class MapReduceMappingsToIntTask<K,V>
6569 <        extends BulkTask<K,V,Integer> {
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> rights, nextRight;
6575          MapReduceMappingsToIntTask
6576 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6577 <             MapReduceMappingsToIntTask<K,V> rights,
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) {
# Line 6651 | Line 6582 | public class ConcurrentHashMapV8<K, V>
6582              this.transformer = transformer;
6583              this.basis = basis; this.reducer = reducer;
6584          }
6585 <        @SuppressWarnings("unchecked") public final boolean exec() {
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 <                return abortOnNullFunction();
6592 <            try {
6593 <                final int id = this.basis;
6594 <                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6595 <                    do {} while (!casPending(c = pending, c+1));
6596 <                    (rights = new MapReduceMappingsToIntTask<K,V>
6597 <                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6598 <                }
6599 <                int r = id;
6600 <                Object v;
6601 <                while ((v = advance()) != null)
6602 <                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6603 <                result = r;
6604 <                for (MapReduceMappingsToIntTask<K,V> t = this, s;;) {
6605 <                    int c; BulkTask<K,V,?> par;
6606 <                    if ((c = t.pending) == 0) {
6607 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6676 <                            t.result = reducer.apply(t.result, s.result);
6677 <                        }
6678 <                        if ((par = t.parent) == null ||
6679 <                            !(par instanceof MapReduceMappingsToIntTask)) {
6680 <                            t.quietlyComplete();
6681 <                            break;
6682 <                        }
6683 <                        t = (MapReduceMappingsToIntTask<K,V>)par;
6684 <                    }
6685 <                    else if (t.casPending(c, c - 1))
6686 <                        break;
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 = 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                  }
6688            } catch (Throwable ex) {
6689                return tryCompleteComputation(ex);
6609              }
6691            for (MapReduceMappingsToIntTask<K,V> s = rights; s != null && s.tryUnfork(); s = s.nextRight)
6692                s.exec();
6693            return false;
6610          }
6695        public final Integer getRawResult() { return result; }
6611      }
6612  
6613      // Unsafe mechanics

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines