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.77 by jsr166, Sun Nov 18 03:07:22 2012 UTC vs.
Revision 1.81 by dl, Sat Dec 8 14:10:38 2012 UTC

# Line 28 | Line 28 | import java.util.concurrent.atomic.Atomi
28  
29   import java.io.Serializable;
30  
31 + import java.util.Comparator;
32 + import java.util.Arrays;
33 + import java.util.Map;
34 + import java.util.Set;
35 + import java.util.Collection;
36 + import java.util.AbstractMap;
37 + import java.util.AbstractSet;
38 + import java.util.AbstractCollection;
39 + import java.util.Hashtable;
40 + import java.util.HashMap;
41 + import java.util.Iterator;
42 + import java.util.Enumeration;
43 + import java.util.ConcurrentModificationException;
44 + import java.util.NoSuchElementException;
45 + import java.util.concurrent.ConcurrentMap;
46 + import java.util.concurrent.ThreadLocalRandom;
47 + import java.util.concurrent.locks.LockSupport;
48 + import java.util.concurrent.locks.AbstractQueuedSynchronizer;
49 + import java.util.concurrent.atomic.AtomicReference;
50 +
51 + import java.io.Serializable;
52 +
53   /**
54   * A hash table supporting full concurrency of retrievals and
55   * high expected concurrency for updates. This class obeys the
# Line 40 | 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 61 | 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 82 | Line 104 | import java.io.Serializable;
104   * {@code hashCode()} is a sure way to slow down performance of any
105   * hash table.
106   *
107 < * <p> A {@link Set} projection of a ConcurrentHashMapV8 may be created
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 99 | 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
# 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 199 | Line 221 | import java.io.Serializable;
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
# 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 671 | 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 842 | 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                          }
851                        else if ((pr = p.right) != null && h >= pr.hash)
852                            s = pr;
853                        if (s != null && (r = getTreeNode(h, k, s)) != null)
854                            return r;
881                      }
882                  }
883                  else
# Line 906 | 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 2380 | 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 2397 | 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 2467 | 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 2609 | 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 2713 | 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 3171 | 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 3193 | 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 3216 | 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 3278 | Line 3341 | public class ConcurrentHashMapV8<K, V>
3341          }
3342      }
3343  
3344 +    /**
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 <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 -------------- */
3353  
3354      /**
# Line 4665 | 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 4686 | 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 4706 | 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 4815 | 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 4836 | 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 4856 | 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 4982 | 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 5002 | 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 5022 | 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 5148 | 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 5168 | 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 5188 | 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 5306 | Line 5377 | public class ConcurrentHashMapV8<K, V>
5377  
5378      // -------------------------------------------------------
5379  
5309    /**
5310     * Base for FJ tasks for bulk operations. This adds a variant of
5311     * CountedCompleters and some split and merge bookkeeping to
5312     * iterator functionality. The forEach and reduce methods are
5313     * similar to those illustrated in CountedCompleter documentation,
5314     * except that bottom-up reduction completions perform them within
5315     * their compute methods. The search methods are like forEach
5316     * except they continually poll for success and exit early.  Also,
5317     * exceptions are handled in a simpler manner, by just trying to
5318     * complete root task exceptionally.
5319     */
5320    @SuppressWarnings("serial") static abstract class BulkTask<K,V,R> extends Traverser<K,V,R> {
5321        final BulkTask<K,V,?> parent;  // completion target
5322        int batch;                     // split control; -1 for unknown
5323        int pending;                   // completion control
5324
5325        BulkTask(ConcurrentHashMapV8<K,V> map, BulkTask<K,V,?> parent,
5326                 int batch) {
5327            super(map);
5328            this.parent = parent;
5329            this.batch = batch;
5330            if (parent != null && map != null) { // split parent
5331                Node[] t;
5332                if ((t = parent.tab) == null &&
5333                    (t = parent.tab = map.table) != null)
5334                    parent.baseLimit = parent.baseSize = t.length;
5335                this.tab = t;
5336                this.baseSize = parent.baseSize;
5337                int hi = this.baseLimit = parent.baseLimit;
5338                parent.baseLimit = this.index = this.baseIndex =
5339                    (hi + parent.baseIndex + 1) >>> 1;
5340            }
5341        }
5342
5343        /**
5344         * Forces root task to complete.
5345         * @param ex if null, complete normally, else exceptionally
5346         * @return false to simplify use
5347         */
5348        final boolean tryCompleteComputation(Throwable ex) {
5349            for (BulkTask<K,V,?> a = this;;) {
5350                BulkTask<K,V,?> p = a.parent;
5351                if (p == null) {
5352                    if (ex != null)
5353                        a.completeExceptionally(ex);
5354                    else
5355                        a.quietlyComplete();
5356                    return false;
5357                }
5358                a = p;
5359            }
5360        }
5361
5362        /**
5363         * Version of tryCompleteComputation for function screening checks
5364         */
5365        final boolean abortOnNullFunction() {
5366            return tryCompleteComputation(new Error("Unexpected null function"));
5367        }
5368
5369        // utilities
5370
5371        /** CompareAndSet pending count */
5372        final boolean casPending(int cmp, int val) {
5373            return U.compareAndSwapInt(this, PENDING, cmp, val);
5374        }
5375
5376        /**
5377         * Returns approx exp2 of the number of times (minus one) to
5378         * split task by two before executing leaf action. This value
5379         * is faster to compute and more convenient to use as a guide
5380         * to splitting than is the depth, since it is used while
5381         * dividing by two anyway.
5382         */
5383        final int batch() {
5384            ConcurrentHashMapV8<K, V> m; int b; Node[] t;  ForkJoinPool pool;
5385            if ((b = batch) < 0 && (m = map) != null) { // force initialization
5386                if ((t = tab) == null && (t = tab = m.table) != null)
5387                    baseLimit = baseSize = t.length;
5388                if (t != null) {
5389                    long n = m.counter.sum();
5390                    int par = ((pool = getPool()) == null) ?
5391                        ForkJoinPool.getCommonPoolParallelism() :
5392                        pool.getParallelism();
5393                    int sp = par << 3; // slack of 8
5394                    b = batch = (n <= 0L) ? 0 : (n < (long)sp) ? (int)n : sp;
5395                }
5396            }
5397            return b;
5398        }
5399
5400        /**
5401         * Returns exportable snapshot entry.
5402         */
5403        static <K,V> AbstractMap.SimpleEntry<K,V> entryFor(K k, V v) {
5404            return new AbstractMap.SimpleEntry<K,V>(k, v);
5405        }
5406
5407        // Unsafe mechanics
5408        private static final sun.misc.Unsafe U;
5409        private static final long PENDING;
5410        static {
5411            try {
5412                U = getUnsafe();
5413                PENDING = U.objectFieldOffset
5414                    (BulkTask.class.getDeclaredField("pending"));
5415            } catch (Exception e) {
5416                throw new Error(e);
5417            }
5418        }
5419    }
5420
5421    /**
5422     * Base class for non-reductive actions
5423     */
5424    @SuppressWarnings("serial") static abstract class BulkAction<K,V,R> extends BulkTask<K,V,R> {
5425        BulkAction<K,V,?> nextTask;
5426        BulkAction(ConcurrentHashMapV8<K,V> map, BulkTask<K,V,?> parent,
5427                   int batch, BulkAction<K,V,?> nextTask) {
5428            super(map, parent, batch);
5429            this.nextTask = nextTask;
5430        }
5431
5432        /**
5433         * Try to complete task and upward parents. Upon hitting
5434         * non-completed parent, if a non-FJ task, try to help out the
5435         * computation.
5436         */
5437        final void tryComplete(BulkAction<K,V,?> subtasks) {
5438            BulkTask<K,V,?> a = this, s = a;
5439            for (int c;;) {
5440                if ((c = a.pending) == 0) {
5441                    if ((a = (s = a).parent) == null) {
5442                        s.quietlyComplete();
5443                        break;
5444                    }
5445                }
5446                else if (a.casPending(c, c - 1)) {
5447                    if (subtasks != null && !inForkJoinPool()) {
5448                        while ((s = a.parent) != null)
5449                            a = s;
5450                        while (!a.isDone()) {
5451                            BulkAction<K,V,?> next = subtasks.nextTask;
5452                            if (subtasks.tryUnfork())
5453                                subtasks.exec();
5454                            if ((subtasks = next) == null)
5455                                break;
5456                        }
5457                    }
5458                    break;
5459                }
5460            }
5461        }
5462
5463    }
5464
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 5469 | Line 5384 | public class ConcurrentHashMapV8<K, V>
5384       */
5385  
5386      @SuppressWarnings("serial") static final class ForEachKeyTask<K,V>
5387 <        extends BulkAction<K,V,Void> {
5387 >        extends Traverser<K,V,Void> {
5388          final Action<K> action;
5389          ForEachKeyTask
5390 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5476 <             ForEachKeyTask<K,V> nextTask,
5390 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5391               Action<K> action) {
5392 <            super(m, p, b, nextTask);
5392 >            super(m, p, b);
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> subtasks = null;
5400 <            try {
5401 <                int b = batch(), c;
5402 <                while (b > 1 && baseIndex != baseLimit) {
5403 <                    do {} while (!casPending(c = pending, c+1));
5490 <                    (subtasks = new ForEachKeyTask<K,V>
5491 <                     (map, this, b >>>= 1, subtasks, action)).fork();
5492 <                }
5493 <                while (advance() != null)
5494 <                    action.apply((K)nextKey);
5495 <            } catch (Throwable ex) {
5496 <                return tryCompleteComputation(ex);
5497 <            }
5498 <            tryComplete(subtasks);
5499 <            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 BulkAction<K,V,Void> {
5408 >        extends Traverser<K,V,Void> {
5409          final Action<V> action;
5410          ForEachValueTask
5411 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5508 <             ForEachValueTask<K,V> nextTask,
5411 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5412               Action<V> action) {
5413 <            super(m, p, b, nextTask);
5413 >            super(m, p, b);
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> subtasks = null;
5421 <            try {
5422 <                int b = batch(), c;
5423 <                while (b > 1 && baseIndex != baseLimit) {
5424 <                    do {} while (!casPending(c = pending, c+1));
5425 <                    (subtasks = new ForEachValueTask<K,V>
5523 <                     (map, this, b >>>= 1, subtasks, action)).fork();
5524 <                }
5525 <                Object v;
5526 <                while ((v = advance()) != null)
5527 <                    action.apply((V)v);
5528 <            } catch (Throwable ex) {
5529 <                return tryCompleteComputation(ex);
5530 <            }
5531 <            tryComplete(subtasks);
5532 <            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 BulkAction<K,V,Void> {
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,
5541 <             ForEachEntryTask<K,V> nextTask,
5433 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5434               Action<Entry<K,V>> action) {
5435 <            super(m, p, b, nextTask);
5435 >            super(m, p, b);
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> subtasks = null;
5443 <            try {
5444 <                int b = batch(), c;
5445 <                while (b > 1 && baseIndex != baseLimit) {
5446 <                    do {} while (!casPending(c = pending, c+1));
5447 <                    (subtasks = new ForEachEntryTask<K,V>
5556 <                     (map, this, b >>>= 1, subtasks, action)).fork();
5557 <                }
5558 <                Object v;
5559 <                while ((v = advance()) != null)
5560 <                    action.apply(entryFor((K)nextKey, (V)v));
5561 <            } catch (Throwable ex) {
5562 <                return tryCompleteComputation(ex);
5563 <            }
5564 <            tryComplete(subtasks);
5565 <            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 BulkAction<K,V,Void> {
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,
5574 <             ForEachMappingTask<K,V> nextTask,
5455 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5456               BiAction<K,V> action) {
5457 <            super(m, p, b, nextTask);
5457 >            super(m, p, b);
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> subtasks = null;
5465 <            try {
5466 <                int b = batch(), c;
5467 <                while (b > 1 && baseIndex != baseLimit) {
5468 <                    do {} while (!casPending(c = pending, c+1));
5469 <                    (subtasks = new ForEachMappingTask<K,V>
5589 <                     (map, this, b >>>= 1, subtasks, action)).fork();
5590 <                }
5591 <                Object v;
5592 <                while ((v = advance()) != null)
5593 <                    action.apply((K)nextKey, (V)v);
5594 <            } catch (Throwable ex) {
5595 <                return tryCompleteComputation(ex);
5596 <            }
5597 <            tryComplete(subtasks);
5598 <            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 BulkAction<K,V,Void> {
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> nextTask,
5480 <             Fun<? super K, ? extends U> transformer,
5481 <             Action<U> action) {
5482 <            super(m, p, b, nextTask);
5483 <            this.transformer = transformer;
5484 <            this.action = action;
5485 <
5486 <        }
5487 <        @SuppressWarnings("unchecked") public final boolean exec() {
5488 <            final Fun<? super K, ? extends U> transformer =
5489 <                this.transformer;
5490 <            final Action<U> action = this.action;
5491 <            if (transformer == null || action == null)
5492 <                return abortOnNullFunction();
5493 <            ForEachTransformedKeyTask<K,V,U> subtasks = null;
5494 <            try {
5495 <                int b = batch(), c;
5625 <                while (b > 1 && baseIndex != baseLimit) {
5626 <                    do {} while (!casPending(c = pending, c+1));
5627 <                    (subtasks = new ForEachTransformedKeyTask<K,V,U>
5628 <                     (map, this, b >>>= 1, subtasks, transformer, action)).fork();
5629 <                }
5630 <                U u;
5631 <                while (advance() != null) {
5632 <                    if ((u = transformer.apply((K)nextKey)) != null)
5633 <                        action.apply(u);
5634 <                }
5635 <            } catch (Throwable ex) {
5636 <                return tryCompleteComputation(ex);
5478 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5479 >             Fun<? super K, ? extends U> transformer, Action<U> action) {
5480 >            super(m, p, b);
5481 >            this.transformer = transformer; this.action = action;
5482 >        }
5483 >        @SuppressWarnings("unchecked") public final void compute() {
5484 >            final Fun<? super K, ? extends U> transformer;
5485 >            final Action<U> action;
5486 >            if ((transformer = this.transformer) == null ||
5487 >                (action = this.action) == null)
5488 >                throw new NullPointerException();
5489 >            for (int b; (b = preSplit()) > 0;)
5490 >                new ForEachTransformedKeyTask<K,V,U>
5491 >                     (map, this, b, transformer, action).fork();
5492 >            U u;
5493 >            while (advance() != null) {
5494 >                if ((u = transformer.apply((K)nextKey)) != null)
5495 >                    action.apply(u);
5496              }
5497 <            tryComplete(subtasks);
5639 <            return false;
5497 >            propagateCompletion();
5498          }
5499      }
5500  
5501      @SuppressWarnings("serial") static final class ForEachTransformedValueTask<K,V,U>
5502 <        extends BulkAction<K,V,Void> {
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> nextTask,
5508 <             Fun<? super V, ? extends U> transformer,
5509 <             Action<U> action) {
5510 <            super(m, p, b, nextTask);
5511 <            this.transformer = transformer;
5512 <            this.action = action;
5513 <
5514 <        }
5515 <        @SuppressWarnings("unchecked") public final boolean exec() {
5516 <            final Fun<? super V, ? extends U> transformer =
5517 <                this.transformer;
5518 <            final Action<U> action = this.action;
5519 <            if (transformer == null || action == null)
5520 <                return abortOnNullFunction();
5521 <            ForEachTransformedValueTask<K,V,U> subtasks = null;
5522 <            try {
5523 <                int b = batch(), c;
5666 <                while (b > 1 && baseIndex != baseLimit) {
5667 <                    do {} while (!casPending(c = pending, c+1));
5668 <                    (subtasks = new ForEachTransformedValueTask<K,V,U>
5669 <                     (map, this, b >>>= 1, subtasks, transformer, action)).fork();
5670 <                }
5671 <                Object v; U u;
5672 <                while ((v = advance()) != null) {
5673 <                    if ((u = transformer.apply((V)v)) != null)
5674 <                        action.apply(u);
5675 <                }
5676 <            } catch (Throwable ex) {
5677 <                return tryCompleteComputation(ex);
5506 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5507 >             Fun<? super V, ? extends U> transformer, Action<U> action) {
5508 >            super(m, p, b);
5509 >            this.transformer = transformer; this.action = action;
5510 >        }
5511 >        @SuppressWarnings("unchecked") public final void compute() {
5512 >            final Fun<? super V, ? extends U> transformer;
5513 >            final Action<U> action;
5514 >            if ((transformer = this.transformer) == null ||
5515 >                (action = this.action) == null)
5516 >                throw new NullPointerException();
5517 >            for (int b; (b = preSplit()) > 0;)
5518 >                new ForEachTransformedValueTask<K,V,U>
5519 >                    (map, this, b, transformer, action).fork();
5520 >            Object v; U u;
5521 >            while ((v = advance()) != null) {
5522 >                if ((u = transformer.apply((V)v)) != null)
5523 >                    action.apply(u);
5524              }
5525 <            tryComplete(subtasks);
5680 <            return false;
5525 >            propagateCompletion();
5526          }
5527      }
5528  
5529      @SuppressWarnings("serial") static final class ForEachTransformedEntryTask<K,V,U>
5530 <        extends BulkAction<K,V,Void> {
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> nextTask,
5536 <             Fun<Map.Entry<K,V>, ? extends U> transformer,
5537 <             Action<U> action) {
5538 <            super(m, p, b, nextTask);
5539 <            this.transformer = transformer;
5540 <            this.action = action;
5541 <
5542 <        }
5543 <        @SuppressWarnings("unchecked") public final boolean exec() {
5544 <            final Fun<Map.Entry<K,V>, ? extends U> transformer =
5545 <                this.transformer;
5546 <            final Action<U> action = this.action;
5547 <            if (transformer == null || action == null)
5548 <                return abortOnNullFunction();
5549 <            ForEachTransformedEntryTask<K,V,U> subtasks = null;
5550 <            try {
5551 <                int b = batch(), c;
5707 <                while (b > 1 && baseIndex != baseLimit) {
5708 <                    do {} while (!casPending(c = pending, c+1));
5709 <                    (subtasks = new ForEachTransformedEntryTask<K,V,U>
5710 <                     (map, this, b >>>= 1, subtasks, transformer, action)).fork();
5711 <                }
5712 <                Object v; U u;
5713 <                while ((v = advance()) != null) {
5714 <                    if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
5715 <                        action.apply(u);
5716 <                }
5717 <            } catch (Throwable ex) {
5718 <                return tryCompleteComputation(ex);
5534 >            (ConcurrentHashMapV8<K,V> m, Traverser<K,V,?> p, int b,
5535 >             Fun<Map.Entry<K,V>, ? extends U> transformer, Action<U> action) {
5536 >            super(m, p, b);
5537 >            this.transformer = transformer; this.action = action;
5538 >        }
5539 >        @SuppressWarnings("unchecked") public final void compute() {
5540 >            final Fun<Map.Entry<K,V>, ? extends U> transformer;
5541 >            final Action<U> action;
5542 >            if ((transformer = this.transformer) == null ||
5543 >                (action = this.action) == null)
5544 >                throw new NullPointerException();
5545 >            for (int b; (b = preSplit()) > 0;)
5546 >                new ForEachTransformedEntryTask<K,V,U>
5547 >                    (map, this, b, transformer, action).fork();
5548 >            Object v; U u;
5549 >            while ((v = advance()) != null) {
5550 >                if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
5551 >                    action.apply(u);
5552              }
5553 <            tryComplete(subtasks);
5721 <            return false;
5553 >            propagateCompletion();
5554          }
5555      }
5556  
5557      @SuppressWarnings("serial") static final class ForEachTransformedMappingTask<K,V,U>
5558 <        extends BulkAction<K,V,Void> {
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,
5731 <             ForEachTransformedMappingTask<K,V,U> nextTask,
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, nextTask);
5566 <            this.transformer = transformer;
5736 <            this.action = action;
5737 <
5565 >            super(m, p, b);
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> subtasks = null;
5575 <            try {
5576 <                int b = batch(), c;
5577 <                while (b > 1 && baseIndex != baseLimit) {
5578 <                    do {} while (!casPending(c = pending, c+1));
5579 <                    (subtasks = new ForEachTransformedMappingTask<K,V,U>
5580 <                     (map, this, b >>>= 1, subtasks, transformer, action)).fork();
5752 <                }
5753 <                Object v; U u;
5754 <                while ((v = advance()) != null) {
5755 <                    if ((u = transformer.apply((K)nextKey, (V)v)) != null)
5756 <                        action.apply(u);
5757 <                }
5758 <            } catch (Throwable ex) {
5759 <                return tryCompleteComputation(ex);
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 <            tryComplete(subtasks);
5762 <            return false;
5582 >            propagateCompletion();
5583          }
5584      }
5585  
5586      @SuppressWarnings("serial") static final class SearchKeysTask<K,V,U>
5587 <        extends BulkAction<K,V,U> {
5587 >        extends Traverser<K,V,U> {
5588          final Fun<? super K, ? extends U> searchFunction;
5589          final AtomicReference<U> result;
5590          SearchKeysTask
5591 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5772 <             SearchKeysTask<K,V,U> nextTask,
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, nextTask);
5594 >            super(m, p, b);
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> subtasks = 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 <                    (subtasks = new SearchKeysTask<K,V,U>
5609 <                     (map, this, b >>>= 1, subtasks, 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                  }
5800            } catch (Throwable ex) {
5801                return tryCompleteComputation(ex);
5623              }
5803            tryComplete(subtasks);
5804            return false;
5624          }
5806        public final U getRawResult() { return result.get(); }
5625      }
5626  
5627      @SuppressWarnings("serial") static final class SearchValuesTask<K,V,U>
5628 <        extends BulkAction<K,V,U> {
5628 >        extends Traverser<K,V,U> {
5629          final Fun<? super V, ? extends U> searchFunction;
5630          final AtomicReference<U> result;
5631          SearchValuesTask
5632 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5815 <             SearchValuesTask<K,V,U> nextTask,
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, nextTask);
5635 >            super(m, p, b);
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> subtasks = 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 <                    (subtasks = new SearchValuesTask<K,V,U>
5650 <                     (map, this, b >>>= 1, subtasks, 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                  }
5843            } catch (Throwable ex) {
5844                return tryCompleteComputation(ex);
5664              }
5846            tryComplete(subtasks);
5847            return false;
5665          }
5849        public final U getRawResult() { return result.get(); }
5666      }
5667  
5668      @SuppressWarnings("serial") static final class SearchEntriesTask<K,V,U>
5669 <        extends BulkAction<K,V,U> {
5669 >        extends Traverser<K,V,U> {
5670          final Fun<Entry<K,V>, ? extends U> searchFunction;
5671          final AtomicReference<U> result;
5672          SearchEntriesTask
5673 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5858 <             SearchEntriesTask<K,V,U> nextTask,
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, nextTask);
5676 >            super(m, p, b);
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> subtasks = 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 <                    (subtasks = new SearchEntriesTask<K,V,U>
5691 <                     (map, this, b >>>= 1, subtasks, 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                  }
5886            } catch (Throwable ex) {
5887                return tryCompleteComputation(ex);
5705              }
5889            tryComplete(subtasks);
5890            return false;
5706          }
5892        public final U getRawResult() { return result.get(); }
5707      }
5708  
5709      @SuppressWarnings("serial") static final class SearchMappingsTask<K,V,U>
5710 <        extends BulkAction<K,V,U> {
5710 >        extends Traverser<K,V,U> {
5711          final BiFun<? super K, ? super V, ? extends U> searchFunction;
5712          final AtomicReference<U> result;
5713          SearchMappingsTask
5714 <            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5901 <             SearchMappingsTask<K,V,U> nextTask,
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, nextTask);
5717 >            super(m, p, b);
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> subtasks = 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 <                    (subtasks = new SearchMappingsTask<K,V,U>
5732 <                     (map, this, b >>>= 1, subtasks, 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                  }
5929            } catch (Throwable ex) {
5930                return tryCompleteComputation(ex);
5746              }
5932            tryComplete(subtasks);
5933            return false;
5747          }
5935        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 ||
5975 <                            !(par instanceof ReduceKeysTask)) {
5976 <                            t.quietlyComplete();
5977 <                            break;
5978 <                        }
5979 <                        t = (ReduceKeysTask<K,V>)par;
5980 <                    }
5981 <                    else if (t.casPending(c, c - 1))
5982 <                        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                  }
5984            } catch (Throwable ex) {
5985                return tryCompleteComputation(ex);
5789              }
5987            ReduceKeysTask<K,V> s = rights;
5988            if (s != null && !inForkJoinPool()) {
5989                do  {
5990                    if (s.tryUnfork())
5991                        s.exec();
5992                } while ((s = s.nextRight) != null);
5993            }
5994            return false;
5790          }
5996        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 ||
6037 <                            !(par instanceof ReduceValuesTask)) {
6038 <                            t.quietlyComplete();
6039 <                            break;
6040 <                        }
6041 <                        t = (ReduceValuesTask<K,V>)par;
6042 <                    }
6043 <                    else if (t.casPending(c, c - 1))
6044 <                        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                  }
6046            } catch (Throwable ex) {
6047                return tryCompleteComputation(ex);
5833              }
6049            ReduceValuesTask<K,V> s = rights;
6050            if (s != null && !inForkJoinPool()) {
6051                do  {
6052                    if (s.tryUnfork())
6053                        s.exec();
6054                } while ((s = s.nextRight) != null);
6055            }
6056            return false;
5834          }
6058        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 ||
6099 <                            !(par instanceof ReduceEntriesTask)) {
6100 <                            t.quietlyComplete();
6101 <                            break;
6102 <                        }
6103 <                        t = (ReduceEntriesTask<K,V>)par;
6104 <                    }
6105 <                    else if (t.casPending(c, c - 1))
6106 <                        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                  }
6108            } catch (Throwable ex) {
6109                return tryCompleteComputation(ex);
5877              }
6111            ReduceEntriesTask<K,V> s = rights;
6112            if (s != null && !inForkJoinPool()) {
6113                do  {
6114                    if (s.tryUnfork())
6115                        s.exec();
6116                } while ((s = s.nextRight) != null);
6117            }
6118            return false;
5878          }
6120        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 6135 | 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;
6152 <                while (advance() != null) {
6153 <                    if ((u = transformer.apply((K)nextKey)) != null)
6154 <                        r = (r == null) ? u : reducer.apply(r, u);
6155 <                }
6156 <                result = r;
6157 <                for (MapReduceKeysTask<K,V,U> t = this, s;;) {
6158 <                    int c; BulkTask<K,V,?> par; U tr, sr;
6159 <                    if ((c = t.pending) == 0) {
6160 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6161 <                            if ((sr = s.result) != null)
6162 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
6163 <                        }
6164 <                        if ((par = t.parent) == null ||
6165 <                            !(par instanceof MapReduceKeysTask)) {
6166 <                            t.quietlyComplete();
6167 <                            break;
6168 <                        }
6169 <                        t = (MapReduceKeysTask<K,V,U>)par;
6170 <                    }
6171 <                    else if (t.casPending(c, c - 1))
6172 <                        break;
6173 <                }
6174 <            } catch (Throwable ex) {
6175 <                return tryCompleteComputation(ex);
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 <            MapReduceKeysTask<K,V,U> s = rights;
5913 <            if (s != null && !inForkJoinPool()) {
5914 <                do  {
5915 <                    if (s.tryUnfork())
5916 <                        s.exec();
5917 <                } while ((s = s.nextRight) != null);
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 >                }
5925              }
6184            return false;
5926          }
6186        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 6201 | 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;
6219 <                while ((v = advance()) != null) {
6220 <                    if ((u = transformer.apply((V)v)) != null)
6221 <                        r = (r == null) ? u : reducer.apply(r, u);
6222 <                }
6223 <                result = r;
6224 <                for (MapReduceValuesTask<K,V,U> t = this, s;;) {
6225 <                    int c; BulkTask<K,V,?> par; U tr, sr;
6226 <                    if ((c = t.pending) == 0) {
6227 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6228 <                            if ((sr = s.result) != null)
6229 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
6230 <                        }
6231 <                        if ((par = t.parent) == null ||
6232 <                            !(par instanceof MapReduceValuesTask)) {
6233 <                            t.quietlyComplete();
6234 <                            break;
6235 <                        }
6236 <                        t = (MapReduceValuesTask<K,V,U>)par;
6237 <                    }
6238 <                    else if (t.casPending(c, c - 1))
6239 <                        break;
6240 <                }
6241 <            } catch (Throwable ex) {
6242 <                return tryCompleteComputation(ex);
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 <            MapReduceValuesTask<K,V,U> s = rights;
5962 <            if (s != null && !inForkJoinPool()) {
5963 <                do  {
5964 <                    if (s.tryUnfork())
5965 <                        s.exec();
5966 <                } while ((s = s.nextRight) != null);
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 >                }
5974              }
6251            return false;
5975          }
6253        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 6268 | 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;
6286 <                while ((v = advance()) != null) {
6287 <                    if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
6288 <                        r = (r == null) ? u : reducer.apply(r, u);
6289 <                }
6290 <                result = r;
6291 <                for (MapReduceEntriesTask<K,V,U> t = this, s;;) {
6292 <                    int c; BulkTask<K,V,?> par; U tr, sr;
6293 <                    if ((c = t.pending) == 0) {
6294 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6295 <                            if ((sr = s.result) != null)
6296 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
6297 <                        }
6298 <                        if ((par = t.parent) == null ||
6299 <                            !(par instanceof MapReduceEntriesTask)) {
6300 <                            t.quietlyComplete();
6301 <                            break;
6302 <                        }
6303 <                        t = (MapReduceEntriesTask<K,V,U>)par;
6304 <                    }
6305 <                    else if (t.casPending(c, c - 1))
6306 <                        break;
6307 <                }
6308 <            } catch (Throwable ex) {
6309 <                return tryCompleteComputation(ex);
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 <            MapReduceEntriesTask<K,V,U> s = rights;
6011 <            if (s != null && !inForkJoinPool()) {
6012 <                do  {
6013 <                    if (s.tryUnfork())
6014 <                        s.exec();
6015 <                } while ((s = s.nextRight) != null);
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 >                }
6023              }
6318            return false;
6024          }
6320        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 6335 | 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;
6353 <                while ((v = advance()) != null) {
6354 <                    if ((u = transformer.apply((K)nextKey, (V)v)) != null)
6355 <                        r = (r == null) ? u : reducer.apply(r, u);
6356 <                }
6357 <                result = r;
6358 <                for (MapReduceMappingsTask<K,V,U> t = this, s;;) {
6359 <                    int c; BulkTask<K,V,?> par; U tr, sr;
6360 <                    if ((c = t.pending) == 0) {
6361 <                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6362 <                            if ((sr = s.result) != null)
6363 <                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
6364 <                        }
6365 <                        if ((par = t.parent) == null ||
6366 <                            !(par instanceof MapReduceMappingsTask)) {
6367 <                            t.quietlyComplete();
6368 <                            break;
6369 <                        }
6370 <                        t = (MapReduceMappingsTask<K,V,U>)par;
6371 <                    }
6372 <                    else if (t.casPending(c, c - 1))
6373 <                        break;
6374 <                }
6375 <            } catch (Throwable ex) {
6376 <                return tryCompleteComputation(ex);
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 <            MapReduceMappingsTask<K,V,U> s = rights;
6060 <            if (s != null && !inForkJoinPool()) {
6061 <                do  {
6062 <                    if (s.tryUnfork())
6063 <                        s.exec();
6064 <                } while ((s = s.nextRight) != null);
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 >                }
6072              }
6385            return false;
6073          }
6387        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 6404 | 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) {
6428 <                            t.result = reducer.apply(t.result, s.result);
6429 <                        }
6430 <                        if ((par = t.parent) == null ||
6431 <                            !(par instanceof MapReduceKeysToDoubleTask)) {
6432 <                            t.quietlyComplete();
6433 <                            break;
6434 <                        }
6435 <                        t = (MapReduceKeysToDoubleTask<K,V>)par;
6436 <                    }
6437 <                    else if (t.casPending(c, c - 1))
6438 <                        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                  }
6440            } catch (Throwable ex) {
6441                return tryCompleteComputation(ex);
6116              }
6443            MapReduceKeysToDoubleTask<K,V> s = rights;
6444            if (s != null && !inForkJoinPool()) {
6445                do  {
6446                    if (s.tryUnfork())
6447                        s.exec();
6448                } while ((s = s.nextRight) != null);
6449            }
6450            return false;
6117          }
6452        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 6469 | 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) {
6494 <                            t.result = reducer.apply(t.result, s.result);
6495 <                        }
6496 <                        if ((par = t.parent) == null ||
6497 <                            !(par instanceof MapReduceValuesToDoubleTask)) {
6498 <                            t.quietlyComplete();
6499 <                            break;
6500 <                        }
6501 <                        t = (MapReduceValuesToDoubleTask<K,V>)par;
6502 <                    }
6503 <                    else if (t.casPending(c, c - 1))
6504 <                        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                  }
6506            } catch (Throwable ex) {
6507                return tryCompleteComputation(ex);
6161              }
6509            MapReduceValuesToDoubleTask<K,V> s = rights;
6510            if (s != null && !inForkJoinPool()) {
6511                do  {
6512                    if (s.tryUnfork())
6513                        s.exec();
6514                } while ((s = s.nextRight) != null);
6515            }
6516            return false;
6162          }
6518        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 6535 | 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) {
6560 <                            t.result = reducer.apply(t.result, s.result);
6561 <                        }
6562 <                        if ((par = t.parent) == null ||
6563 <                            !(par instanceof MapReduceEntriesToDoubleTask)) {
6564 <                            t.quietlyComplete();
6565 <                            break;
6566 <                        }
6567 <                        t = (MapReduceEntriesToDoubleTask<K,V>)par;
6568 <                    }
6569 <                    else if (t.casPending(c, c - 1))
6570 <                        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                  }
6572            } catch (Throwable ex) {
6573                return tryCompleteComputation(ex);
6206              }
6575            MapReduceEntriesToDoubleTask<K,V> s = rights;
6576            if (s != null && !inForkJoinPool()) {
6577                do  {
6578                    if (s.tryUnfork())
6579                        s.exec();
6580                } while ((s = s.nextRight) != null);
6581            }
6582            return false;
6207          }
6584        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 6601 | 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) {
6626 <                            t.result = reducer.apply(t.result, s.result);
6627 <                        }
6628 <                        if ((par = t.parent) == null ||
6629 <                            !(par instanceof MapReduceMappingsToDoubleTask)) {
6630 <                            t.quietlyComplete();
6631 <                            break;
6632 <                        }
6633 <                        t = (MapReduceMappingsToDoubleTask<K,V>)par;
6634 <                    }
6635 <                    else if (t.casPending(c, c - 1))
6636 <                        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                  }
6638            } catch (Throwable ex) {
6639                return tryCompleteComputation(ex);
6251              }
6641            MapReduceMappingsToDoubleTask<K,V> s = rights;
6642            if (s != null && !inForkJoinPool()) {
6643                do  {
6644                    if (s.tryUnfork())
6645                        s.exec();
6646                } while ((s = s.nextRight) != null);
6647            }
6648            return false;
6252          }
6650        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 6667 | 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) {
6691 <                            t.result = reducer.apply(t.result, s.result);
6692 <                        }
6693 <                        if ((par = t.parent) == null ||
6694 <                            !(par instanceof MapReduceKeysToLongTask)) {
6695 <                            t.quietlyComplete();
6696 <                            break;
6697 <                        }
6698 <                        t = (MapReduceKeysToLongTask<K,V>)par;
6699 <                    }
6700 <                    else if (t.casPending(c, c - 1))
6701 <                        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                  }
6703            } catch (Throwable ex) {
6704                return tryCompleteComputation(ex);
6705            }
6706            MapReduceKeysToLongTask<K,V> s = rights;
6707            if (s != null && !inForkJoinPool()) {
6708                do  {
6709                    if (s.tryUnfork())
6710                        s.exec();
6711                } while ((s = s.nextRight) != null);
6295              }
6713            return false;
6296          }
6715        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 6732 | 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) {
6757 <                            t.result = reducer.apply(t.result, s.result);
6758 <                        }
6759 <                        if ((par = t.parent) == null ||
6760 <                            !(par instanceof MapReduceValuesToLongTask)) {
6761 <                            t.quietlyComplete();
6762 <                            break;
6763 <                        }
6764 <                        t = (MapReduceValuesToLongTask<K,V>)par;
6765 <                    }
6766 <                    else if (t.casPending(c, c - 1))
6767 <                        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                  }
6769            } catch (Throwable ex) {
6770                return tryCompleteComputation(ex);
6771            }
6772            MapReduceValuesToLongTask<K,V> s = rights;
6773            if (s != null && !inForkJoinPool()) {
6774                do  {
6775                    if (s.tryUnfork())
6776                        s.exec();
6777                } while ((s = s.nextRight) != null);
6340              }
6779            return false;
6341          }
6781        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 6798 | 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) {
6823 <                            t.result = reducer.apply(t.result, s.result);
6824 <                        }
6825 <                        if ((par = t.parent) == null ||
6826 <                            !(par instanceof MapReduceEntriesToLongTask)) {
6827 <                            t.quietlyComplete();
6828 <                            break;
6829 <                        }
6830 <                        t = (MapReduceEntriesToLongTask<K,V>)par;
6831 <                    }
6832 <                    else if (t.casPending(c, c - 1))
6833 <                        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                  }
6835            } catch (Throwable ex) {
6836                return tryCompleteComputation(ex);
6385              }
6838            MapReduceEntriesToLongTask<K,V> s = rights;
6839            if (s != null && !inForkJoinPool()) {
6840                do  {
6841                    if (s.tryUnfork())
6842                        s.exec();
6843                } while ((s = s.nextRight) != null);
6844            }
6845            return false;
6386          }
6847        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 6864 | 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) {
6889 <                            t.result = reducer.apply(t.result, s.result);
6890 <                        }
6891 <                        if ((par = t.parent) == null ||
6892 <                            !(par instanceof MapReduceMappingsToLongTask)) {
6893 <                            t.quietlyComplete();
6894 <                            break;
6895 <                        }
6896 <                        t = (MapReduceMappingsToLongTask<K,V>)par;
6897 <                    }
6898 <                    else if (t.casPending(c, c - 1))
6899 <                        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                  }
6901            } catch (Throwable ex) {
6902                return tryCompleteComputation(ex);
6903            }
6904            MapReduceMappingsToLongTask<K,V> s = rights;
6905            if (s != null && !inForkJoinPool()) {
6906                do  {
6907                    if (s.tryUnfork())
6908                        s.exec();
6909                } while ((s = s.nextRight) != null);
6430              }
6911            return false;
6431          }
6913        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 6930 | 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) {
6954 <                            t.result = reducer.apply(t.result, s.result);
6955 <                        }
6956 <                        if ((par = t.parent) == null ||
6957 <                            !(par instanceof MapReduceKeysToIntTask)) {
6958 <                            t.quietlyComplete();
6959 <                            break;
6960 <                        }
6961 <                        t = (MapReduceKeysToIntTask<K,V>)par;
6962 <                    }
6963 <                    else if (t.casPending(c, c - 1))
6964 <                        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                  }
6966            } catch (Throwable ex) {
6967                return tryCompleteComputation(ex);
6968            }
6969            MapReduceKeysToIntTask<K,V> s = rights;
6970            if (s != null && !inForkJoinPool()) {
6971                do  {
6972                    if (s.tryUnfork())
6973                        s.exec();
6974                } while ((s = s.nextRight) != null);
6474              }
6976            return false;
6475          }
6978        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 6995 | 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) {
7020 <                            t.result = reducer.apply(t.result, s.result);
7021 <                        }
7022 <                        if ((par = t.parent) == null ||
7023 <                            !(par instanceof MapReduceValuesToIntTask)) {
7024 <                            t.quietlyComplete();
7025 <                            break;
7026 <                        }
7027 <                        t = (MapReduceValuesToIntTask<K,V>)par;
7028 <                    }
7029 <                    else if (t.casPending(c, c - 1))
7030 <                        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                  }
7032            } catch (Throwable ex) {
7033                return tryCompleteComputation(ex);
7034            }
7035            MapReduceValuesToIntTask<K,V> s = rights;
7036            if (s != null && !inForkJoinPool()) {
7037                do  {
7038                    if (s.tryUnfork())
7039                        s.exec();
7040                } while ((s = s.nextRight) != null);
6519              }
7042            return false;
6520          }
7044        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 7061 | 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) {
7086 <                            t.result = reducer.apply(t.result, s.result);
7087 <                        }
7088 <                        if ((par = t.parent) == null ||
7089 <                            !(par instanceof MapReduceEntriesToIntTask)) {
7090 <                            t.quietlyComplete();
7091 <                            break;
7092 <                        }
7093 <                        t = (MapReduceEntriesToIntTask<K,V>)par;
7094 <                    }
7095 <                    else if (t.casPending(c, c - 1))
7096 <                        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                  }
7098            } catch (Throwable ex) {
7099                return tryCompleteComputation(ex);
6564              }
7101            MapReduceEntriesToIntTask<K,V> s = rights;
7102            if (s != null && !inForkJoinPool()) {
7103                do  {
7104                    if (s.tryUnfork())
7105                        s.exec();
7106                } while ((s = s.nextRight) != null);
7107            }
7108            return false;
6565          }
7110        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 7127 | 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) {
7152 <                            t.result = reducer.apply(t.result, s.result);
7153 <                        }
7154 <                        if ((par = t.parent) == null ||
7155 <                            !(par instanceof MapReduceMappingsToIntTask)) {
7156 <                            t.quietlyComplete();
7157 <                            break;
7158 <                        }
7159 <                        t = (MapReduceMappingsToIntTask<K,V>)par;
7160 <                    }
7161 <                    else if (t.casPending(c, c - 1))
7162 <                        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                  }
7164            } catch (Throwable ex) {
7165                return tryCompleteComputation(ex);
6609              }
7167            MapReduceMappingsToIntTask<K,V> s = rights;
7168            if (s != null && !inForkJoinPool()) {
7169                do  {
7170                    if (s.tryUnfork())
7171                        s.exec();
7172                } while ((s = s.nextRight) != null);
7173            }
7174            return false;
6610          }
7176        public final Integer getRawResult() { return result; }
6611      }
6612  
6613      // Unsafe mechanics

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines