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.60 by dl, Thu Aug 16 12:24:58 2012 UTC vs.
Revision 1.76 by jsr166, Fri Nov 9 03:30:03 2012 UTC

# Line 5 | Line 5
5   */
6  
7   package jsr166e;
8 import jsr166e.LongAdder;
9 import jsr166e.ForkJoinPool;
10 import jsr166e.ForkJoinTask;
8  
9   import java.util.Comparator;
10   import java.util.Arrays;
# Line 85 | Line 82 | import java.io.Serializable;
82   * {@code hashCode()} is a sure way to slow down performance of any
83   * hash table.
84   *
85 + * <p> A {@link Set} projection of a ConcurrentHashMapV8 may be created
86 + * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed
87 + * (using {@link #keySet(Object)} when only keys are of interest, and the
88 + * mapped values are (perhaps transiently) not used or all take the
89 + * same mapping value.
90 + *
91 + * <p> A ConcurrentHashMapV8 can be used as scalable frequency map (a
92 + * form of histogram or multiset) by using {@link LongAdder} values
93 + * and initializing via {@link #computeIfAbsent}. For example, to add
94 + * a count to a {@code ConcurrentHashMapV8<String,LongAdder> freqs}, you
95 + * can use {@code freqs.computeIfAbsent(k -> new
96 + * LongAdder()).increment();}
97 + *
98   * <p>This class and its views and iterators implement all of the
99   * <em>optional</em> methods of the {@link Map} and {@link Iterator}
100   * interfaces.
# Line 92 | Line 102 | import java.io.Serializable;
102   * <p> Like {@link Hashtable} but unlike {@link HashMap}, this class
103   * does <em>not</em> allow {@code null} to be used as a key or value.
104   *
105 + * <p>ConcurrentHashMapV8s support parallel operations using the {@link
106 + * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts
107 + * are available in class {@link ForkJoinTasks}). These operations are
108 + * designed to be safely, and often sensibly, applied even with maps
109 + * that are being concurrently updated by other threads; for example,
110 + * when computing a snapshot summary of the values in a shared
111 + * registry.  There are three kinds of operation, each with four
112 + * forms, accepting functions with Keys, Values, Entries, and (Key,
113 + * Value) arguments and/or return values. (The first three forms are
114 + * also available via the {@link #keySet()}, {@link #values()} and
115 + * {@link #entrySet()} views). Because the elements of a
116 + * ConcurrentHashMapV8 are not ordered in any particular way, and may be
117 + * processed in different orders in different parallel executions, the
118 + * correctness of supplied functions should not depend on any
119 + * ordering, or on any other objects or values that may transiently
120 + * change while computation is in progress; and except for forEach
121 + * actions, should ideally be side-effect-free.
122 + *
123 + * <ul>
124 + * <li> forEach: Perform a given action on each element.
125 + * A variant form applies a given transformation on each element
126 + * before performing the action.</li>
127 + *
128 + * <li> search: Return the first available non-null result of
129 + * applying a given function on each element; skipping further
130 + * search when a result is found.</li>
131 + *
132 + * <li> reduce: Accumulate each element.  The supplied reduction
133 + * function cannot rely on ordering (more formally, it should be
134 + * both associative and commutative).  There are five variants:
135 + *
136 + * <ul>
137 + *
138 + * <li> Plain reductions. (There is not a form of this method for
139 + * (key, value) function arguments since there is no corresponding
140 + * return type.)</li>
141 + *
142 + * <li> Mapped reductions that accumulate the results of a given
143 + * function applied to each element.</li>
144 + *
145 + * <li> Reductions to scalar doubles, longs, and ints, using a
146 + * given basis value.</li>
147 + *
148 + * </li>
149 + * </ul>
150 + * </ul>
151 + *
152 + * <p>The concurrency properties of bulk operations follow
153 + * from those of ConcurrentHashMapV8: Any non-null result returned
154 + * from {@code get(key)} and related access methods bears a
155 + * happens-before relation with the associated insertion or
156 + * update.  The result of any bulk operation reflects the
157 + * composition of these per-element relations (but is not
158 + * necessarily atomic with respect to the map as a whole unless it
159 + * is somehow known to be quiescent).  Conversely, because keys
160 + * and values in the map are never null, null serves as a reliable
161 + * atomic indicator of the current lack of any result.  To
162 + * maintain this property, null serves as an implicit basis for
163 + * all non-scalar reduction operations. For the double, long, and
164 + * int versions, the basis should be one that, when combined with
165 + * any other value, returns that other value (more formally, it
166 + * should be the identity element for the reduction). Most common
167 + * reductions have these properties; for example, computing a sum
168 + * with basis 0 or a minimum with basis MAX_VALUE.
169 + *
170 + * <p>Search and transformation functions provided as arguments
171 + * should similarly return null to indicate the lack of any result
172 + * (in which case it is not used). In the case of mapped
173 + * reductions, this also enables transformations to serve as
174 + * filters, returning null (or, in the case of primitive
175 + * specializations, the identity basis) if the element should not
176 + * be combined. You can create compound transformations and
177 + * filterings by composing them yourself under this "null means
178 + * there is nothing there now" rule before using them in search or
179 + * reduce operations.
180 + *
181 + * <p>Methods accepting and/or returning Entry arguments maintain
182 + * key-value associations. They may be useful for example when
183 + * finding the key for the greatest value. Note that "plain" Entry
184 + * arguments can be supplied using {@code new
185 + * AbstractMap.SimpleEntry(k,v)}.
186 + *
187 + * <p> Bulk operations may complete abruptly, throwing an
188 + * exception encountered in the application of a supplied
189 + * function. Bear in mind when handling such exceptions that other
190 + * concurrently executing functions could also have thrown
191 + * exceptions, or would have done so if the first exception had
192 + * not occurred.
193 + *
194 + * <p>Parallel speedups for bulk operations compared to sequential
195 + * processing are common but not guaranteed.  Operations involving
196 + * brief functions on small maps may execute more slowly than
197 + * sequential loops if the underlying work to parallelize the
198 + * computation is more expensive than the computation itself.
199 + * Similarly, parallelization may not lead to much actual parallelism
200 + * if all processors are busy performing unrelated tasks.
201 + *
202 + * <p> All arguments to all task methods must be non-null.
203 + *
204 + * <p><em>jsr166e note: During transition, this class
205 + * uses nested functional interfaces with different names but the
206 + * same forms as those expected for JDK8.<em>
207 + *
208   * <p>This class is a member of the
209   * <a href="{@docRoot}/../technotes/guides/collections/index.html">
210   * Java Collections Framework</a>.
211   *
99 * <p><em>jsr166e note: This class is a candidate replacement for
100 * java.util.concurrent.ConcurrentHashMap.  During transition, this
101 * class declares and uses nested functional interfaces with different
102 * names but the same forms as those expected for JDK8.<em>
103 *
212   * @since 1.5
213   * @author Doug Lea
214   * @param <K> the type of keys maintained by this map
# Line 179 | Line 287 | public class ConcurrentHashMapV8<K, V>
287          Spliterator<T> split();
288      }
289  
290 +
291      /*
292       * Overview:
293       *
# Line 461 | Line 570 | public class ConcurrentHashMapV8<K, V>
570      private transient volatile int sizeCtl;
571  
572      // views
573 <    private transient KeySet<K,V> keySet;
574 <    private transient Values<K,V> values;
575 <    private transient EntrySet<K,V> entrySet;
573 >    private transient KeySetView<K,V> keySet;
574 >    private transient ValuesView<K,V> values;
575 >    private transient EntrySetView<K,V> entrySet;
576  
577      /** For serialization compatibility. Null unless serialized; see below */
578      private Segment<K,V>[] segments;
# Line 540 | Line 649 | public class ConcurrentHashMapV8<K, V>
649           * unlocking lock (via a failed CAS from non-waiting LOCKED
650           * state), unlockers acquire the sync lock and perform a
651           * notifyAll.
652 +         *
653 +         * The initial sanity check on tab and bounds is not currently
654 +         * necessary in the only usages of this method, but enables
655 +         * use in other future contexts.
656           */
657          final void tryAwaitLock(Node[] tab, int i) {
658 <            if (tab != null && i >= 0 && i < tab.length) { // bounds check
658 >            if (tab != null && i >= 0 && i < tab.length) { // sanity check
659                  int r = ThreadLocalRandom.current().nextInt(); // randomize spins
660                  int spins = MAX_SPINS, h;
661                  while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) {
# Line 718 | Line 831 | public class ConcurrentHashMapV8<K, V>
831           * Returns the TreeNode (or null if not found) for the given key
832           * starting at given root.
833           */
834 <        @SuppressWarnings("unchecked") // suppress Comparable cast warning
835 <        final TreeNode getTreeNode(int h, Object k, TreeNode p) {
834 >        @SuppressWarnings("unchecked") final TreeNode getTreeNode
835 >            (int h, Object k, TreeNode p) {
836              Class<?> c = k.getClass();
837              while (p != null) {
838                  int dir, ph;  Object pk; Class<?> pc;
# Line 779 | Line 892 | public class ConcurrentHashMapV8<K, V>
892           * Finds or adds a node.
893           * @return null if added
894           */
895 <        @SuppressWarnings("unchecked") // suppress Comparable cast warning
896 <        final TreeNode putTreeNode(int h, Object k, Object v) {
895 >        @SuppressWarnings("unchecked") final TreeNode putTreeNode
896 >            (int h, Object k, Object v) {
897              Class<?> c = k.getClass();
898              TreeNode pp = root, p = null;
899              int dir = 0;
# Line 1550 | Line 1663 | public class ConcurrentHashMapV8<K, V>
1663      }
1664  
1665      /** Implementation for compute */
1666 <    @SuppressWarnings("unchecked")
1667 <    private final Object internalCompute(K k, boolean onlyIfPresent,
1555 <                                             BiFun<? super K, ? super V, ? extends V> mf) {
1666 >    @SuppressWarnings("unchecked") private final Object internalCompute
1667 >        (K k, boolean onlyIfPresent, BiFun<? super K, ? super V, ? extends V> mf) {
1668          int h = spread(k.hashCode());
1669          Object val = null;
1670          int delta = 0;
# Line 1676 | Line 1788 | public class ConcurrentHashMapV8<K, V>
1788      }
1789  
1790      /** Implementation for merge */
1791 <    @SuppressWarnings("unchecked")
1792 <    private final Object internalMerge(K k, V v,
1681 <                                       BiFun<? super V, ? super V, ? extends V> mf) {
1791 >    @SuppressWarnings("unchecked") private final Object internalMerge
1792 >        (K k, V v, BiFun<? super V, ? super V, ? extends V> mf) {
1793          int h = spread(k.hashCode());
1794          Object val = null;
1795          int delta = 0;
# Line 2008 | Line 2119 | public class ConcurrentHashMapV8<K, V>
2119          for (int i = bin;;) {      // start upwards sweep
2120              int fh; Node f;
2121              if ((f = tabAt(tab, i)) == null) {
2122 <                if (bin >= 0) {    // no lock needed (or available)
2122 >                if (bin >= 0) {    // Unbuffered; no lock needed (or available)
2123                      if (!casTabAt(tab, i, f, fwd))
2124                          continue;
2125                  }
# Line 2184 | Line 2295 | public class ConcurrentHashMapV8<K, V>
2295                      try {
2296                          if (tabAt(tab, i) == f) {
2297                              for (Node p = t.first; p != null; p = p.next) {
2298 <                                p.val = null;
2299 <                                --delta;
2298 >                                if (p.val != null) { // (currently always true)
2299 >                                    p.val = null;
2300 >                                    --delta;
2301 >                                }
2302                              }
2303                              t.first = null;
2304                              t.root = null;
# Line 2207 | Line 2320 | public class ConcurrentHashMapV8<K, V>
2320                  try {
2321                      if (tabAt(tab, i) == f) {
2322                          for (Node e = f; e != null; e = e.next) {
2323 <                            e.val = null;
2324 <                            --delta;
2323 >                            if (e.val != null) {  // (currently always true)
2324 >                                e.val = null;
2325 >                                --delta;
2326 >                            }
2327                          }
2328                          setTabAt(tab, i, null);
2329                          ++i;
# Line 2237 | Line 2352 | public class ConcurrentHashMapV8<K, V>
2352       * change (including to null, indicating deletion), field nextVal
2353       * might not be accurate at point of use, but still maintains the
2354       * weak consistency property of holding a value that was once
2355 <     * valid.
2355 >     * valid. To support iterator.remove, the nextKey field is not
2356 >     * updated (nulled out) when the iterator cannot advance.
2357       *
2358       * Internal traversals directly access these fields, as in:
2359       * {@code while (it.advance() != null) { process(it.nextKey); }}
# Line 2271 | Line 2387 | public class ConcurrentHashMapV8<K, V>
2387       * ForkJoinTask is Serializable, but iterators need not be, we
2388       * need to add warning suppressions.
2389       */
2390 <    @SuppressWarnings("serial")
2275 <    static class Traverser<K,V,R> extends ForkJoinTask<R> {
2390 >    @SuppressWarnings("serial") static class Traverser<K,V,R> extends ForkJoinTask<R> {
2391          final ConcurrentHashMapV8<K, V> map;
2392          Node next;           // the next entry to use
2278        Node last;           // the last entry used
2393          Object nextKey;      // cached key field of next
2394          Object nextVal;      // cached val field of next
2395          Node[] tab;          // current table; updated if resized
2396          int index;           // index of bin to use next
2397          int baseIndex;       // current index of initial table
2398          int baseLimit;       // index bound for initial table
2399 <        final int baseSize;  // initial table size
2399 >        int baseSize;        // initial table size
2400  
2401          /** Creates iterator for all entries in the table. */
2402          Traverser(ConcurrentHashMapV8<K, V> map) {
2403 <            this.tab = (this.map = map).table;
2290 <            baseLimit = baseSize = (tab == null) ? 0 : tab.length;
2403 >            this.map = map;
2404          }
2405  
2406          /** Creates iterator for split() methods */
2407 <        Traverser(Traverser<K,V,?> it, boolean split) {
2408 <            this.map = it.map;
2409 <            this.tab = it.tab;
2407 >        Traverser(Traverser<K,V,?> it) {
2408 >            ConcurrentHashMapV8<K, V> m; Node[] t;
2409 >            if ((m = this.map = it.map) == null)
2410 >                t = null;
2411 >            else if ((t = it.tab) == null && // force parent tab initialization
2412 >                     (t = it.tab = m.table) != null)
2413 >                it.baseLimit = it.baseSize = t.length;
2414 >            this.tab = t;
2415              this.baseSize = it.baseSize;
2416 <            int lo = it.baseIndex;
2417 <            int hi = this.baseLimit = it.baseLimit;
2300 <            int i;
2301 <            if (split) // adjust parent
2302 <                i = it.baseLimit = (lo + hi + 1) >>> 1;
2303 <            else       // clone parent
2304 <                i = lo;
2305 <            this.index = this.baseIndex = i;
2416 >            it.baseLimit = this.index = this.baseIndex =
2417 >                ((this.baseLimit = it.baseLimit) + it.baseIndex + 1) >>> 1;
2418          }
2419  
2420          /**
# Line 2310 | Line 2422 | public class ConcurrentHashMapV8<K, V>
2422           * See above for explanation.
2423           */
2424          final Object advance() {
2425 <            Node e = last = next;
2425 >            Node e = next;
2426              Object ev = null;
2427              outer: do {
2428                  if (e != null)                  // advance past used/skipped node
2429                      e = e.next;
2430                  while (e == null) {             // get to next non-null bin
2431 +                    ConcurrentHashMapV8<K, V> m;
2432                      Node[] t; int b, i, n; Object ek; // checks must use locals
2433 <                    if ((b = baseIndex) >= baseLimit || (i = index) < 0 ||
2434 <                        (t = tab) == null || i >= (n = t.length))
2433 >                    if ((t = tab) != null)
2434 >                        n = t.length;
2435 >                    else if ((m = map) != null && (t = tab = m.table) != null)
2436 >                        n = baseLimit = baseSize = t.length;
2437 >                    else
2438                          break outer;
2439 <                    else if ((e = tabAt(t, i)) != null && e.hash == MOVED) {
2439 >                    if ((b = baseIndex) >= baseLimit ||
2440 >                        (i = index) < 0 || i >= n)
2441 >                        break outer;
2442 >                    if ((e = tabAt(t, i)) != null && e.hash == MOVED) {
2443                          if ((ek = e.key) instanceof TreeBin)
2444                              e = ((TreeBin)ek).first;
2445                          else {
# Line 2337 | Line 2456 | public class ConcurrentHashMapV8<K, V>
2456          }
2457  
2458          public final void remove() {
2459 <            if (nextVal == null && last == null)
2460 <                advance();
2342 <            Node e = last;
2343 <            if (e == null)
2459 >            Object k = nextKey;
2460 >            if (k == null && (advance() == null || (k = nextKey) == null))
2461                  throw new IllegalStateException();
2462 <            last = null;
2346 <            map.remove(e.key);
2462 >            map.internalReplace(k, null, null);
2463          }
2464  
2465          public final boolean hasNext() {
# Line 2447 | Line 2563 | public class ConcurrentHashMapV8<K, V>
2563      }
2564  
2565      /**
2566 +     * Creates a new {@link Set} backed by a ConcurrentHashMapV8
2567 +     * from the given type to {@code Boolean.TRUE}.
2568 +     *
2569 +     * @return the new set
2570 +     */
2571 +    public static <K> KeySetView<K,Boolean> newKeySet() {
2572 +        return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(),
2573 +                                      Boolean.TRUE);
2574 +    }
2575 +
2576 +    /**
2577 +     * Creates a new {@link Set} backed by a ConcurrentHashMapV8
2578 +     * from the given type to {@code Boolean.TRUE}.
2579 +     *
2580 +     * @param initialCapacity The implementation performs internal
2581 +     * sizing to accommodate this many elements.
2582 +     * @throws IllegalArgumentException if the initial capacity of
2583 +     * elements is negative
2584 +     * @return the new set
2585 +     */
2586 +    public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) {
2587 +        return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(initialCapacity),
2588 +                                      Boolean.TRUE);
2589 +    }
2590 +
2591 +    /**
2592       * {@inheritDoc}
2593       */
2594      public boolean isEmpty() {
# Line 2465 | Line 2607 | public class ConcurrentHashMapV8<K, V>
2607  
2608      /**
2609       * Returns the number of mappings. This method should be used
2610 <     * instead of {@link #size} because a ConcurrentHashMap may
2610 >     * instead of {@link #size} because a ConcurrentHashMapV8 may
2611       * contain more mappings than can be represented as an int. The
2612       * value returned is a snapshot; the actual count may differ if
2613       * there are ongoing concurrent insertions or removals.
# Line 2488 | Line 2630 | public class ConcurrentHashMapV8<K, V>
2630       *
2631       * @throws NullPointerException if the specified key is null
2632       */
2633 <    @SuppressWarnings("unchecked")
2492 <    public V get(Object key) {
2633 >    @SuppressWarnings("unchecked") public V get(Object key) {
2634          if (key == null)
2635              throw new NullPointerException();
2636          return (V)internalGet(key);
2637      }
2638  
2639      /**
2640 +     * Returns the value to which the specified key is mapped,
2641 +     * or the given defaultValue if this map contains no mapping for the key.
2642 +     *
2643 +     * @param key the key
2644 +     * @param defaultValue the value to return if this map contains
2645 +     * no mapping for the given key
2646 +     * @return the mapping for the key, if present; else the defaultValue
2647 +     * @throws NullPointerException if the specified key is null
2648 +     */
2649 +    @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) {
2650 +        if (key == null)
2651 +            throw new NullPointerException();
2652 +        V v = (V) internalGet(key);
2653 +        return v == null ? defaultValue : v;
2654 +    }
2655 +
2656 +    /**
2657       * Tests if the specified object is a key in this table.
2658       *
2659       * @param  key   possible key
# Line 2564 | Line 2722 | public class ConcurrentHashMapV8<K, V>
2722       *         {@code null} if there was no mapping for {@code key}
2723       * @throws NullPointerException if the specified key or value is null
2724       */
2725 <    @SuppressWarnings("unchecked")
2568 <    public V put(K key, V value) {
2725 >    @SuppressWarnings("unchecked") public V put(K key, V value) {
2726          if (key == null || value == null)
2727              throw new NullPointerException();
2728          return (V)internalPut(key, value);
# Line 2578 | Line 2735 | public class ConcurrentHashMapV8<K, V>
2735       *         or {@code null} if there was no mapping for the key
2736       * @throws NullPointerException if the specified key or value is null
2737       */
2738 <    @SuppressWarnings("unchecked")
2582 <    public V putIfAbsent(K key, V value) {
2738 >    @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) {
2739          if (key == null || value == null)
2740              throw new NullPointerException();
2741          return (V)internalPutIfAbsent(key, value);
# Line 2626 | Line 2782 | public class ConcurrentHashMapV8<K, V>
2782       * @param key key with which the specified value is to be associated
2783       * @param mappingFunction the function to compute a value
2784       * @return the current (existing or computed) value associated with
2785 <     *         the specified key, or null if the computed value is null.
2785 >     *         the specified key, or null if the computed value is null
2786       * @throws NullPointerException if the specified key or mappingFunction
2787       *         is null
2788       * @throws IllegalStateException if the computation detectably
# Line 2635 | Line 2791 | public class ConcurrentHashMapV8<K, V>
2791       * @throws RuntimeException or Error if the mappingFunction does so,
2792       *         in which case the mapping is left unestablished
2793       */
2794 <    @SuppressWarnings("unchecked")
2795 <    public V computeIfAbsent(K key, Fun<? super K, ? extends V> mappingFunction) {
2794 >    @SuppressWarnings("unchecked") public V computeIfAbsent
2795 >        (K key, Fun<? super K, ? extends V> mappingFunction) {
2796          if (key == null || mappingFunction == null)
2797              throw new NullPointerException();
2798          return (V)internalComputeIfAbsent(key, mappingFunction);
# Line 2676 | Line 2832 | public class ConcurrentHashMapV8<K, V>
2832       * @throws RuntimeException or Error if the remappingFunction does so,
2833       *         in which case the mapping is unchanged
2834       */
2835 <    @SuppressWarnings("unchecked")
2836 <    public V computeIfPresent(K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2835 >    @SuppressWarnings("unchecked") public V computeIfPresent
2836 >        (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2837          if (key == null || remappingFunction == null)
2838              throw new NullPointerException();
2839          return (V)internalCompute(key, true, remappingFunction);
# Line 2723 | Line 2879 | public class ConcurrentHashMapV8<K, V>
2879       * @throws RuntimeException or Error if the remappingFunction does so,
2880       *         in which case the mapping is unchanged
2881       */
2882 <    @SuppressWarnings("unchecked")
2883 <    public V compute(K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2882 >    @SuppressWarnings("unchecked") public V compute
2883 >        (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
2884          if (key == null || remappingFunction == null)
2885              throw new NullPointerException();
2886          return (V)internalCompute(key, false, remappingFunction);
# Line 2755 | Line 2911 | public class ConcurrentHashMapV8<K, V>
2911       * so the computation should be short and simple, and must not
2912       * attempt to update any other mappings of this Map.
2913       */
2914 <    @SuppressWarnings("unchecked")
2915 <    public V merge(K key, V value, BiFun<? super V, ? super V, ? extends V> remappingFunction) {
2914 >    @SuppressWarnings("unchecked") public V merge
2915 >        (K key, V value, BiFun<? super V, ? super V, ? extends V> remappingFunction) {
2916          if (key == null || value == null || remappingFunction == null)
2917              throw new NullPointerException();
2918          return (V)internalMerge(key, value, remappingFunction);
# Line 2771 | Line 2927 | public class ConcurrentHashMapV8<K, V>
2927       *         {@code null} if there was no mapping for {@code key}
2928       * @throws NullPointerException if the specified key is null
2929       */
2930 <    @SuppressWarnings("unchecked")
2775 <        public V remove(Object key) {
2930 >    @SuppressWarnings("unchecked") public V remove(Object key) {
2931          if (key == null)
2932              throw new NullPointerException();
2933          return (V)internalReplace(key, null, null);
# Line 2809 | Line 2964 | public class ConcurrentHashMapV8<K, V>
2964       *         or {@code null} if there was no mapping for the key
2965       * @throws NullPointerException if the specified key or value is null
2966       */
2967 <    @SuppressWarnings("unchecked")
2813 <        public V replace(K key, V value) {
2967 >    @SuppressWarnings("unchecked") public V replace(K key, V value) {
2968          if (key == null || value == null)
2969              throw new NullPointerException();
2970          return (V)internalReplace(key, value, null);
# Line 2826 | Line 2980 | public class ConcurrentHashMapV8<K, V>
2980      /**
2981       * Returns a {@link Set} view of the keys contained in this map.
2982       * The set is backed by the map, so changes to the map are
2983 <     * reflected in the set, and vice-versa.  The set supports element
2830 <     * removal, which removes the corresponding mapping from this map,
2831 <     * via the {@code Iterator.remove}, {@code Set.remove},
2832 <     * {@code removeAll}, {@code retainAll}, and {@code clear}
2833 <     * operations.  It does not support the {@code add} or
2834 <     * {@code addAll} operations.
2983 >     * reflected in the set, and vice-versa.
2984       *
2985 <     * <p>The view's {@code iterator} is a "weakly consistent" iterator
2837 <     * that will never throw {@link ConcurrentModificationException},
2838 <     * and guarantees to traverse elements as they existed upon
2839 <     * construction of the iterator, and may (but is not guaranteed to)
2840 <     * reflect any modifications subsequent to construction.
2985 >     * @return the set view
2986       */
2987 <    public Set<K> keySet() {
2988 <        KeySet<K,V> ks = keySet;
2989 <        return (ks != null) ? ks : (keySet = new KeySet<K,V>(this));
2987 >    public KeySetView<K,V> keySet() {
2988 >        KeySetView<K,V> ks = keySet;
2989 >        return (ks != null) ? ks : (keySet = new KeySetView<K,V>(this, null));
2990 >    }
2991 >
2992 >    /**
2993 >     * Returns a {@link Set} view of the keys in this map, using the
2994 >     * given common mapped value for any additions (i.e., {@link
2995 >     * Collection#add} and {@link Collection#addAll}). This is of
2996 >     * course only appropriate if it is acceptable to use the same
2997 >     * value for all additions from this view.
2998 >     *
2999 >     * @param mappedValue the mapped value to use for any
3000 >     * additions.
3001 >     * @return the set view
3002 >     * @throws NullPointerException if the mappedValue is null
3003 >     */
3004 >    public KeySetView<K,V> keySet(V mappedValue) {
3005 >        if (mappedValue == null)
3006 >            throw new NullPointerException();
3007 >        return new KeySetView<K,V>(this, mappedValue);
3008      }
3009  
3010      /**
3011       * Returns a {@link Collection} view of the values contained in this map.
3012       * The collection is backed by the map, so changes to the map are
3013 <     * reflected in the collection, and vice-versa.  The collection
2851 <     * supports element removal, which removes the corresponding
2852 <     * mapping from this map, via the {@code Iterator.remove},
2853 <     * {@code Collection.remove}, {@code removeAll},
2854 <     * {@code retainAll}, and {@code clear} operations.  It does not
2855 <     * support the {@code add} or {@code addAll} operations.
2856 <     *
2857 <     * <p>The view's {@code iterator} is a "weakly consistent" iterator
2858 <     * that will never throw {@link ConcurrentModificationException},
2859 <     * and guarantees to traverse elements as they existed upon
2860 <     * construction of the iterator, and may (but is not guaranteed to)
2861 <     * reflect any modifications subsequent to construction.
3013 >     * reflected in the collection, and vice-versa.
3014       */
3015 <    public Collection<V> values() {
3016 <        Values<K,V> vs = values;
3017 <        return (vs != null) ? vs : (values = new Values<K,V>(this));
3015 >    public ValuesView<K,V> values() {
3016 >        ValuesView<K,V> vs = values;
3017 >        return (vs != null) ? vs : (values = new ValuesView<K,V>(this));
3018      }
3019  
3020      /**
# Line 2882 | Line 3034 | public class ConcurrentHashMapV8<K, V>
3034       * reflect any modifications subsequent to construction.
3035       */
3036      public Set<Map.Entry<K,V>> entrySet() {
3037 <        EntrySet<K,V> es = entrySet;
3038 <        return (es != null) ? es : (entrySet = new EntrySet<K,V>(this));
3037 >        EntrySetView<K,V> es = entrySet;
3038 >        return (es != null) ? es : (entrySet = new EntrySetView<K,V>(this));
3039      }
3040  
3041      /**
# Line 3016 | Line 3168 | public class ConcurrentHashMapV8<K, V>
3168  
3169      /* ----------------Iterators -------------- */
3170  
3171 <    @SuppressWarnings("serial")
3020 <    static final class KeyIterator<K,V> extends Traverser<K,V,Object>
3171 >    @SuppressWarnings("serial") static final class KeyIterator<K,V> extends Traverser<K,V,Object>
3172          implements Spliterator<K>, Enumeration<K> {
3173          KeyIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3174 <        KeyIterator(Traverser<K,V,Object> it, boolean split) {
3175 <            super(it, split);
3174 >        KeyIterator(Traverser<K,V,Object> it) {
3175 >            super(it);
3176          }
3177          public KeyIterator<K,V> split() {
3178 <            if (last != null || (next != null && nextVal == null))
3178 >            if (nextKey != null)
3179                  throw new IllegalStateException();
3180 <            return new KeyIterator<K,V>(this, true);
3180 >            return new KeyIterator<K,V>(this);
3181          }
3182 <        @SuppressWarnings("unchecked")
3032 <            public final K next() {
3182 >        @SuppressWarnings("unchecked") public final K next() {
3183              if (nextVal == null && advance() == null)
3184                  throw new NoSuchElementException();
3185              Object k = nextKey;
# Line 3040 | Line 3190 | public class ConcurrentHashMapV8<K, V>
3190          public final K nextElement() { return next(); }
3191      }
3192  
3193 <    @SuppressWarnings("serial")
3044 <    static final class ValueIterator<K,V> extends Traverser<K,V,Object>
3193 >    @SuppressWarnings("serial") static final class ValueIterator<K,V> extends Traverser<K,V,Object>
3194          implements Spliterator<V>, Enumeration<V> {
3195          ValueIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3196 <        ValueIterator(Traverser<K,V,Object> it, boolean split) {
3197 <            super(it, split);
3196 >        ValueIterator(Traverser<K,V,Object> it) {
3197 >            super(it);
3198          }
3199          public ValueIterator<K,V> split() {
3200 <            if (last != null || (next != null && nextVal == null))
3200 >            if (nextKey != null)
3201                  throw new IllegalStateException();
3202 <            return new ValueIterator<K,V>(this, true);
3202 >            return new ValueIterator<K,V>(this);
3203          }
3204  
3205 <        @SuppressWarnings("unchecked")
3057 <            public final V next() {
3205 >        @SuppressWarnings("unchecked") public final V next() {
3206              Object v;
3207              if ((v = nextVal) == null && (v = advance()) == null)
3208                  throw new NoSuchElementException();
# Line 3065 | Line 3213 | public class ConcurrentHashMapV8<K, V>
3213          public final V nextElement() { return next(); }
3214      }
3215  
3216 <    @SuppressWarnings("serial")
3069 <    static final class EntryIterator<K,V> extends Traverser<K,V,Object>
3216 >    @SuppressWarnings("serial") static final class EntryIterator<K,V> extends Traverser<K,V,Object>
3217          implements Spliterator<Map.Entry<K,V>> {
3218          EntryIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3219 <        EntryIterator(Traverser<K,V,Object> it, boolean split) {
3220 <            super(it, split);
3219 >        EntryIterator(Traverser<K,V,Object> it) {
3220 >            super(it);
3221          }
3222          public EntryIterator<K,V> split() {
3223 <            if (last != null || (next != null && nextVal == null))
3223 >            if (nextKey != null)
3224                  throw new IllegalStateException();
3225 <            return new EntryIterator<K,V>(this, true);
3225 >            return new EntryIterator<K,V>(this);
3226          }
3227  
3228 <        @SuppressWarnings("unchecked")
3082 <            public final Map.Entry<K,V> next() {
3228 >        @SuppressWarnings("unchecked") public final Map.Entry<K,V> next() {
3229              Object v;
3230              if ((v = nextVal) == null && (v = advance()) == null)
3231                  throw new NoSuchElementException();
# Line 3132 | Line 3278 | public class ConcurrentHashMapV8<K, V>
3278          }
3279      }
3280  
3135    /* ----------------Views -------------- */
3136
3137    /**
3138     * Base class for views.
3139     */
3140    static abstract class CHMView<K, V> {
3141        final ConcurrentHashMapV8<K, V> map;
3142        CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
3143        public final int size()                 { return map.size(); }
3144        public final boolean isEmpty()          { return map.isEmpty(); }
3145        public final void clear()               { map.clear(); }
3146
3147        // implementations below rely on concrete classes supplying these
3148        abstract public Iterator<?> iterator();
3149        abstract public boolean contains(Object o);
3150        abstract public boolean remove(Object o);
3151
3152        private static final String oomeMsg = "Required array size too large";
3153
3154        public final Object[] toArray() {
3155            long sz = map.mappingCount();
3156            if (sz > (long)(MAX_ARRAY_SIZE))
3157                throw new OutOfMemoryError(oomeMsg);
3158            int n = (int)sz;
3159            Object[] r = new Object[n];
3160            int i = 0;
3161            Iterator<?> it = iterator();
3162            while (it.hasNext()) {
3163                if (i == n) {
3164                    if (n >= MAX_ARRAY_SIZE)
3165                        throw new OutOfMemoryError(oomeMsg);
3166                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3167                        n = MAX_ARRAY_SIZE;
3168                    else
3169                        n += (n >>> 1) + 1;
3170                    r = Arrays.copyOf(r, n);
3171                }
3172                r[i++] = it.next();
3173            }
3174            return (i == n) ? r : Arrays.copyOf(r, i);
3175        }
3176
3177        @SuppressWarnings("unchecked")
3178            public final <T> T[] toArray(T[] a) {
3179            long sz = map.mappingCount();
3180            if (sz > (long)(MAX_ARRAY_SIZE))
3181                throw new OutOfMemoryError(oomeMsg);
3182            int m = (int)sz;
3183            T[] r = (a.length >= m) ? a :
3184                (T[])java.lang.reflect.Array
3185                .newInstance(a.getClass().getComponentType(), m);
3186            int n = r.length;
3187            int i = 0;
3188            Iterator<?> it = iterator();
3189            while (it.hasNext()) {
3190                if (i == n) {
3191                    if (n >= MAX_ARRAY_SIZE)
3192                        throw new OutOfMemoryError(oomeMsg);
3193                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3194                        n = MAX_ARRAY_SIZE;
3195                    else
3196                        n += (n >>> 1) + 1;
3197                    r = Arrays.copyOf(r, n);
3198                }
3199                r[i++] = (T)it.next();
3200            }
3201            if (a == r && i < n) {
3202                r[i] = null; // null-terminate
3203                return r;
3204            }
3205            return (i == n) ? r : Arrays.copyOf(r, i);
3206        }
3207
3208        public final int hashCode() {
3209            int h = 0;
3210            for (Iterator<?> it = iterator(); it.hasNext();)
3211                h += it.next().hashCode();
3212            return h;
3213        }
3214
3215        public final String toString() {
3216            StringBuilder sb = new StringBuilder();
3217            sb.append('[');
3218            Iterator<?> it = iterator();
3219            if (it.hasNext()) {
3220                for (;;) {
3221                    Object e = it.next();
3222                    sb.append(e == this ? "(this Collection)" : e);
3223                    if (!it.hasNext())
3224                        break;
3225                    sb.append(',').append(' ');
3226                }
3227            }
3228            return sb.append(']').toString();
3229        }
3230
3231        public final boolean containsAll(Collection<?> c) {
3232            if (c != this) {
3233                for (Iterator<?> it = c.iterator(); it.hasNext();) {
3234                    Object e = it.next();
3235                    if (e == null || !contains(e))
3236                        return false;
3237                }
3238            }
3239            return true;
3240        }
3241
3242        public final boolean removeAll(Collection<?> c) {
3243            boolean modified = false;
3244            for (Iterator<?> it = iterator(); it.hasNext();) {
3245                if (c.contains(it.next())) {
3246                    it.remove();
3247                    modified = true;
3248                }
3249            }
3250            return modified;
3251        }
3252
3253        public final boolean retainAll(Collection<?> c) {
3254            boolean modified = false;
3255            for (Iterator<?> it = iterator(); it.hasNext();) {
3256                if (!c.contains(it.next())) {
3257                    it.remove();
3258                    modified = true;
3259                }
3260            }
3261            return modified;
3262        }
3263
3264    }
3265
3266    static final class KeySet<K,V> extends CHMView<K,V> implements Set<K> {
3267        KeySet(ConcurrentHashMapV8<K, V> map)  {
3268            super(map);
3269        }
3270        public final boolean contains(Object o) { return map.containsKey(o); }
3271        public final boolean remove(Object o)   { return map.remove(o) != null; }
3272        public final Iterator<K> iterator() {
3273            return new KeyIterator<K,V>(map);
3274        }
3275        public final boolean add(K e) {
3276            throw new UnsupportedOperationException();
3277        }
3278        public final boolean addAll(Collection<? extends K> c) {
3279            throw new UnsupportedOperationException();
3280        }
3281        public boolean equals(Object o) {
3282            Set<?> c;
3283            return ((o instanceof Set) &&
3284                    ((c = (Set<?>)o) == this ||
3285                     (containsAll(c) && c.containsAll(this))));
3286        }
3287    }
3288
3289
3290    static final class Values<K,V> extends CHMView<K,V>
3291        implements Collection<V> {
3292        Values(ConcurrentHashMapV8<K, V> map)   { super(map); }
3293        public final boolean contains(Object o) { return map.containsValue(o); }
3294        public final boolean remove(Object o) {
3295            if (o != null) {
3296                Iterator<V> it = new ValueIterator<K,V>(map);
3297                while (it.hasNext()) {
3298                    if (o.equals(it.next())) {
3299                        it.remove();
3300                        return true;
3301                    }
3302                }
3303            }
3304            return false;
3305        }
3306        public final Iterator<V> iterator() {
3307            return new ValueIterator<K,V>(map);
3308        }
3309        public final boolean add(V e) {
3310            throw new UnsupportedOperationException();
3311        }
3312        public final boolean addAll(Collection<? extends V> c) {
3313            throw new UnsupportedOperationException();
3314        }
3315
3316    }
3317
3318    static final class EntrySet<K,V> extends CHMView<K,V>
3319        implements Set<Map.Entry<K,V>> {
3320        EntrySet(ConcurrentHashMapV8<K, V> map) { super(map); }
3321        public final boolean contains(Object o) {
3322            Object k, v, r; Map.Entry<?,?> e;
3323            return ((o instanceof Map.Entry) &&
3324                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
3325                    (r = map.get(k)) != null &&
3326                    (v = e.getValue()) != null &&
3327                    (v == r || v.equals(r)));
3328        }
3329        public final boolean remove(Object o) {
3330            Object k, v; Map.Entry<?,?> e;
3331            return ((o instanceof Map.Entry) &&
3332                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
3333                    (v = e.getValue()) != null &&
3334                    map.remove(k, v));
3335        }
3336        public final Iterator<Map.Entry<K,V>> iterator() {
3337            return new EntryIterator<K,V>(map);
3338        }
3339        public final boolean add(Entry<K,V> e) {
3340            throw new UnsupportedOperationException();
3341        }
3342        public final boolean addAll(Collection<? extends Entry<K,V>> c) {
3343            throw new UnsupportedOperationException();
3344        }
3345        public boolean equals(Object o) {
3346            Set<?> c;
3347            return ((o instanceof Set) &&
3348                    ((c = (Set<?>)o) == this ||
3349                     (containsAll(c) && c.containsAll(this))));
3350        }
3351    }
3352
3281      /* ---------------- Serialization Support -------------- */
3282  
3283      /**
# Line 3371 | Line 3299 | public class ConcurrentHashMapV8<K, V>
3299       * for each key-value mapping, followed by a null pair.
3300       * The key-value mappings are emitted in no particular order.
3301       */
3302 <    @SuppressWarnings("unchecked")
3375 <        private void writeObject(java.io.ObjectOutputStream s)
3302 >    @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s)
3303          throws java.io.IOException {
3304          if (segments == null) { // for serialization compatibility
3305              segments = (Segment<K,V>[])
# Line 3396 | Line 3323 | public class ConcurrentHashMapV8<K, V>
3323       * Reconstitutes the instance from a stream (that is, deserializes it).
3324       * @param s the stream
3325       */
3326 <    @SuppressWarnings("unchecked")
3400 <        private void readObject(java.io.ObjectInputStream s)
3326 >    @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s)
3327          throws java.io.IOException, ClassNotFoundException {
3328          s.defaultReadObject();
3329          this.segments = null; // unneeded
# Line 3518 | Line 3444 | public class ConcurrentHashMapV8<K, V>
3444      // -------------------------------------------------------
3445  
3446      /**
3447 <     * Returns an extended {@link Parallel} view of this map using the
3522 <     * given executor for bulk parallel operations.
3447 >     * Performs the given action for each (key, value).
3448       *
3449 <     * @param executor the executor
3525 <     * @return a parallel view
3449 >     * @param action the action
3450       */
3451 <    public Parallel parallel(ForkJoinPool executor)  {
3452 <        return new Parallel(executor);
3451 >    public void forEach(BiAction<K,V> action) {
3452 >        ForkJoinTasks.forEach
3453 >            (this, action).invoke();
3454      }
3455  
3456      /**
3457 <     * An extended view of a ConcurrentHashMap supporting bulk
3458 <     * parallel operations. These operations are designed to be
3459 <     * safely, and often sensibly, applied even with maps that are
3460 <     * being concurrently updated by other threads; for example, when
3461 <     * computing a snapshot summary of the values in a shared
3462 <     * registry.  There are three kinds of operation, each with four
3463 <     * forms, accepting functions with Keys, Values, Entries, and
3464 <     * (Key, Value) arguments and/or return values. Because the
3465 <     * elements of a ConcurrentHashMap are not ordered in any
3466 <     * particular way, and may be processed in different orders in
3467 <     * different parallel executions, the correctness of supplied
3468 <     * functions should not depend on any ordering, or on any other
3469 <     * objects or values that may transiently change while computation
3470 <     * is in progress; and except for forEach actions, should ideally
3471 <     * be side-effect-free.
3472 <     *
3473 <     * <ul>
3474 <     * <li> forEach: Perform a given action on each element.
3475 <     * A variant form applies a given transformation on each element
3476 <     * before performing the action.</li>
3477 <     *
3478 <     * <li> search: Return the first available non-null result of
3479 <     * applying a given function on each element; skipping further
3480 <     * search when a result is found.</li>
3481 <     *
3482 <     * <li> reduce: Accumulate each element.  The supplied reduction
3483 <     * function cannot rely on ordering (more formally, it should be
3484 <     * both associative and commutative).  There are five variants:
3485 <     *
3486 <     * <ul>
3487 <     *
3488 <     * <li> Plain reductions. (There is not a form of this method for
3489 <     * (key, value) function arguments since there is no corresponding
3490 <     * return type.)</li>
3491 <     *
3492 <     * <li> Mapped reductions that accumulate the results of a given
3493 <     * function applied to each element.</li>
3494 <     *
3495 <     * <li> Reductions to scalar doubles, longs, and ints, using a
3496 <     * given basis value.</li>
3497 <     *
3498 <     * </li>
3499 <     * </ul>
3500 <     * </ul>
3501 <     *
3502 <     * <p>The concurrency properties of the bulk operations follow
3503 <     * from those of ConcurrentHashMap: Any non-null result returned
3504 <     * from {@code get(key)} and related access methods bears a
3505 <     * happens-before relation with the associated insertion or
3506 <     * update.  The result of any bulk operation reflects the
3507 <     * composition of these per-element relations (but is not
3508 <     * necessarily atomic with respect to the map as a whole unless it
3509 <     * is somehow known to be quiescent).  Conversely, because keys
3510 <     * and values in the map are never null, null serves as a reliable
3511 <     * atomic indicator of the current lack of any result.  To
3512 <     * maintain this property, null serves as an implicit basis for
3513 <     * all non-scalar reduction operations. For the double, long, and
3514 <     * int versions, the basis should be one that, when combined with
3515 <     * any other value, returns that other value (more formally, it
3516 <     * should be the identity element for the reduction). Most common
3517 <     * reductions have these properties; for example, computing a sum
3518 <     * with basis 0 or a minimum with basis MAX_VALUE.
3519 <     *
3520 <     * <p>Search and transformation functions provided as arguments
3521 <     * should similarly return null to indicate the lack of any result
3522 <     * (in which case it is not used). In the case of mapped
3523 <     * reductions, this also enables transformations to serve as
3524 <     * filters, returning null (or, in the case of primitive
3525 <     * specializations, the identity basis) if the element should not
3526 <     * be combined. You can create compound transformations and
3527 <     * filterings by composing them yourself under this "null means
3528 <     * there is nothing there now" rule before using them in search or
3529 <     * reduce operations.
3530 <     *
3531 <     * <p>Methods accepting and/or returning Entry arguments maintain
3532 <     * key-value associations. They may be useful for example when
3533 <     * finding the key for the greatest value. Note that "plain" Entry
3534 <     * arguments can be supplied using {@code new
3535 <     * AbstractMap.SimpleEntry(k,v)}.
3536 <     *
3537 <     * <p> Bulk operations may complete abruptly, throwing an
3538 <     * exception encountered in the application of a supplied
3539 <     * function. Bear in mind when handling such exceptions that other
3540 <     * concurrently executing functions could also have thrown
3541 <     * exceptions, or would have done so if the first exception had
3542 <     * not occurred.
3543 <     *
3544 <     * <p>Parallel speedups compared to sequential processing are
3545 <     * common but not guaranteed.  Operations involving brief
3546 <     * functions on small maps may execute more slowly than sequential
3547 <     * loops if the underlying work to parallelize the computation is
3548 <     * more expensive than the computation itself. Similarly,
3549 <     * parallelization may not lead to much actual parallelism if all
3550 <     * processors are busy performing unrelated tasks.
3551 <     *
3552 <     * <p> All arguments to all task methods must be non-null.
3553 <     *
3554 <     * <p><em>jsr166e note: During transition, this class
3555 <     * uses nested functional interfaces with different names but the
3556 <     * same forms as those expected for JDK8.<em>
3557 <     */
3558 <    public class Parallel {
3559 <        final ForkJoinPool fjp;
3560 <
3561 <        /**
3562 <         * Returns an extended view of this map using the given
3563 <         * executor for bulk parallel operations.
3564 <         *
3565 <         * @param executor the executor
3566 <         */
3567 <        public Parallel(ForkJoinPool executor)  {
3568 <            this.fjp = executor;
3569 <        }
3457 >     * Performs the given action for each non-null transformation
3458 >     * of each (key, value).
3459 >     *
3460 >     * @param transformer a function returning the transformation
3461 >     * for an element, or null of there is no transformation (in
3462 >     * which case the action is not applied).
3463 >     * @param action the action
3464 >     */
3465 >    public <U> void forEach(BiFun<? super K, ? super V, ? extends U> transformer,
3466 >                            Action<U> action) {
3467 >        ForkJoinTasks.forEach
3468 >            (this, transformer, action).invoke();
3469 >    }
3470 >
3471 >    /**
3472 >     * Returns a non-null result from applying the given search
3473 >     * function on each (key, value), or null if none.  Upon
3474 >     * success, further element processing is suppressed and the
3475 >     * results of any other parallel invocations of the search
3476 >     * function are ignored.
3477 >     *
3478 >     * @param searchFunction a function returning a non-null
3479 >     * result on success, else null
3480 >     * @return a non-null result from applying the given search
3481 >     * function on each (key, value), or null if none
3482 >     */
3483 >    public <U> U search(BiFun<? super K, ? super V, ? extends U> searchFunction) {
3484 >        return ForkJoinTasks.search
3485 >            (this, searchFunction).invoke();
3486 >    }
3487 >
3488 >    /**
3489 >     * Returns the result of accumulating the given transformation
3490 >     * of all (key, value) pairs using the given reducer to
3491 >     * combine values, or null if none.
3492 >     *
3493 >     * @param transformer a function returning the transformation
3494 >     * for an element, or null of there is no transformation (in
3495 >     * which case it is not combined).
3496 >     * @param reducer a commutative associative combining function
3497 >     * @return the result of accumulating the given transformation
3498 >     * of all (key, value) pairs
3499 >     */
3500 >    public <U> U reduce(BiFun<? super K, ? super V, ? extends U> transformer,
3501 >                        BiFun<? super U, ? super U, ? extends U> reducer) {
3502 >        return ForkJoinTasks.reduce
3503 >            (this, transformer, reducer).invoke();
3504 >    }
3505 >
3506 >    /**
3507 >     * Returns the result of accumulating the given transformation
3508 >     * of all (key, value) pairs using the given reducer to
3509 >     * combine values, and the given basis as an identity value.
3510 >     *
3511 >     * @param transformer a function returning the transformation
3512 >     * for an element
3513 >     * @param basis the identity (initial default value) for the reduction
3514 >     * @param reducer a commutative associative combining function
3515 >     * @return the result of accumulating the given transformation
3516 >     * of all (key, value) pairs
3517 >     */
3518 >    public double reduceToDouble(ObjectByObjectToDouble<? super K, ? super V> transformer,
3519 >                                 double basis,
3520 >                                 DoubleByDoubleToDouble reducer) {
3521 >        return ForkJoinTasks.reduceToDouble
3522 >            (this, transformer, basis, reducer).invoke();
3523 >    }
3524 >
3525 >    /**
3526 >     * Returns the result of accumulating the given transformation
3527 >     * of all (key, value) pairs using the given reducer to
3528 >     * combine values, and the given basis as an identity value.
3529 >     *
3530 >     * @param transformer a function returning the transformation
3531 >     * for an element
3532 >     * @param basis the identity (initial default value) for the reduction
3533 >     * @param reducer a commutative associative combining function
3534 >     * @return the result of accumulating the given transformation
3535 >     * of all (key, value) pairs
3536 >     */
3537 >    public long reduceToLong(ObjectByObjectToLong<? super K, ? super V> transformer,
3538 >                             long basis,
3539 >                             LongByLongToLong reducer) {
3540 >        return ForkJoinTasks.reduceToLong
3541 >            (this, transformer, basis, reducer).invoke();
3542 >    }
3543 >
3544 >    /**
3545 >     * Returns the result of accumulating the given transformation
3546 >     * of all (key, value) pairs using the given reducer to
3547 >     * combine values, and the given basis as an identity value.
3548 >     *
3549 >     * @param transformer a function returning the transformation
3550 >     * for an element
3551 >     * @param basis the identity (initial default value) for the reduction
3552 >     * @param reducer a commutative associative combining function
3553 >     * @return the result of accumulating the given transformation
3554 >     * of all (key, value) pairs
3555 >     */
3556 >    public int reduceToInt(ObjectByObjectToInt<? super K, ? super V> transformer,
3557 >                           int basis,
3558 >                           IntByIntToInt reducer) {
3559 >        return ForkJoinTasks.reduceToInt
3560 >            (this, transformer, basis, reducer).invoke();
3561 >    }
3562 >
3563 >    /**
3564 >     * Performs the given action for each key.
3565 >     *
3566 >     * @param action the action
3567 >     */
3568 >    public void forEachKey(Action<K> action) {
3569 >        ForkJoinTasks.forEachKey
3570 >            (this, action).invoke();
3571 >    }
3572 >
3573 >    /**
3574 >     * Performs the given action for each non-null transformation
3575 >     * of each key.
3576 >     *
3577 >     * @param transformer a function returning the transformation
3578 >     * for an element, or null of there is no transformation (in
3579 >     * which case the action is not applied).
3580 >     * @param action the action
3581 >     */
3582 >    public <U> void forEachKey(Fun<? super K, ? extends U> transformer,
3583 >                               Action<U> action) {
3584 >        ForkJoinTasks.forEachKey
3585 >            (this, transformer, action).invoke();
3586 >    }
3587 >
3588 >    /**
3589 >     * Returns a non-null result from applying the given search
3590 >     * function on each key, or null if none. Upon success,
3591 >     * further element processing is suppressed and the results of
3592 >     * any other parallel invocations of the search function are
3593 >     * ignored.
3594 >     *
3595 >     * @param searchFunction a function returning a non-null
3596 >     * result on success, else null
3597 >     * @return a non-null result from applying the given search
3598 >     * function on each key, or null if none
3599 >     */
3600 >    public <U> U searchKeys(Fun<? super K, ? extends U> searchFunction) {
3601 >        return ForkJoinTasks.searchKeys
3602 >            (this, searchFunction).invoke();
3603 >    }
3604 >
3605 >    /**
3606 >     * Returns the result of accumulating all keys using the given
3607 >     * reducer to combine values, or null if none.
3608 >     *
3609 >     * @param reducer a commutative associative combining function
3610 >     * @return the result of accumulating all keys using the given
3611 >     * reducer to combine values, or null if none
3612 >     */
3613 >    public K reduceKeys(BiFun<? super K, ? super K, ? extends K> reducer) {
3614 >        return ForkJoinTasks.reduceKeys
3615 >            (this, reducer).invoke();
3616 >    }
3617 >
3618 >    /**
3619 >     * Returns the result of accumulating the given transformation
3620 >     * of all keys using the given reducer to combine values, or
3621 >     * null if none.
3622 >     *
3623 >     * @param transformer a function returning the transformation
3624 >     * for an element, or null of there is no transformation (in
3625 >     * which case it is not combined).
3626 >     * @param reducer a commutative associative combining function
3627 >     * @return the result of accumulating the given transformation
3628 >     * of all keys
3629 >     */
3630 >    public <U> U reduceKeys(Fun<? super K, ? extends U> transformer,
3631 >                            BiFun<? super U, ? super U, ? extends U> reducer) {
3632 >        return ForkJoinTasks.reduceKeys
3633 >            (this, transformer, reducer).invoke();
3634 >    }
3635 >
3636 >    /**
3637 >     * Returns the result of accumulating the given transformation
3638 >     * of all keys using the given reducer to combine values, and
3639 >     * the given basis as an identity value.
3640 >     *
3641 >     * @param transformer a function returning the transformation
3642 >     * for an element
3643 >     * @param basis the identity (initial default value) for the reduction
3644 >     * @param reducer a commutative associative combining function
3645 >     * @return  the result of accumulating the given transformation
3646 >     * of all keys
3647 >     */
3648 >    public double reduceKeysToDouble(ObjectToDouble<? super K> transformer,
3649 >                                     double basis,
3650 >                                     DoubleByDoubleToDouble reducer) {
3651 >        return ForkJoinTasks.reduceKeysToDouble
3652 >            (this, transformer, basis, reducer).invoke();
3653 >    }
3654 >
3655 >    /**
3656 >     * Returns the result of accumulating the given transformation
3657 >     * of all keys using the given reducer to combine values, and
3658 >     * the given basis as an identity value.
3659 >     *
3660 >     * @param transformer a function returning the transformation
3661 >     * for an element
3662 >     * @param basis the identity (initial default value) for the reduction
3663 >     * @param reducer a commutative associative combining function
3664 >     * @return the result of accumulating the given transformation
3665 >     * of all keys
3666 >     */
3667 >    public long reduceKeysToLong(ObjectToLong<? super K> transformer,
3668 >                                 long basis,
3669 >                                 LongByLongToLong reducer) {
3670 >        return ForkJoinTasks.reduceKeysToLong
3671 >            (this, transformer, basis, reducer).invoke();
3672 >    }
3673 >
3674 >    /**
3675 >     * Returns the result of accumulating the given transformation
3676 >     * of all keys using the given reducer to combine values, and
3677 >     * the given basis as an identity value.
3678 >     *
3679 >     * @param transformer a function returning the transformation
3680 >     * for an element
3681 >     * @param basis the identity (initial default value) for the reduction
3682 >     * @param reducer a commutative associative combining function
3683 >     * @return the result of accumulating the given transformation
3684 >     * of all keys
3685 >     */
3686 >    public int reduceKeysToInt(ObjectToInt<? super K> transformer,
3687 >                               int basis,
3688 >                               IntByIntToInt reducer) {
3689 >        return ForkJoinTasks.reduceKeysToInt
3690 >            (this, transformer, basis, reducer).invoke();
3691 >    }
3692 >
3693 >    /**
3694 >     * Performs the given action for each value.
3695 >     *
3696 >     * @param action the action
3697 >     */
3698 >    public void forEachValue(Action<V> action) {
3699 >        ForkJoinTasks.forEachValue
3700 >            (this, action).invoke();
3701 >    }
3702 >
3703 >    /**
3704 >     * Performs the given action for each non-null transformation
3705 >     * of each value.
3706 >     *
3707 >     * @param transformer a function returning the transformation
3708 >     * for an element, or null of there is no transformation (in
3709 >     * which case the action is not applied).
3710 >     */
3711 >    public <U> void forEachValue(Fun<? super V, ? extends U> transformer,
3712 >                                 Action<U> action) {
3713 >        ForkJoinTasks.forEachValue
3714 >            (this, transformer, action).invoke();
3715 >    }
3716 >
3717 >    /**
3718 >     * Returns a non-null result from applying the given search
3719 >     * function on each value, or null if none.  Upon success,
3720 >     * further element processing is suppressed and the results of
3721 >     * any other parallel invocations of the search function are
3722 >     * ignored.
3723 >     *
3724 >     * @param searchFunction a function returning a non-null
3725 >     * result on success, else null
3726 >     * @return a non-null result from applying the given search
3727 >     * function on each value, or null if none
3728 >     *
3729 >     */
3730 >    public <U> U searchValues(Fun<? super V, ? extends U> searchFunction) {
3731 >        return ForkJoinTasks.searchValues
3732 >            (this, searchFunction).invoke();
3733 >    }
3734 >
3735 >    /**
3736 >     * Returns the result of accumulating all values using the
3737 >     * given reducer to combine values, or null if none.
3738 >     *
3739 >     * @param reducer a commutative associative combining function
3740 >     * @return  the result of accumulating all values
3741 >     */
3742 >    public V reduceValues(BiFun<? super V, ? super V, ? extends V> reducer) {
3743 >        return ForkJoinTasks.reduceValues
3744 >            (this, reducer).invoke();
3745 >    }
3746 >
3747 >    /**
3748 >     * Returns the result of accumulating the given transformation
3749 >     * of all values using the given reducer to combine values, or
3750 >     * null if none.
3751 >     *
3752 >     * @param transformer a function returning the transformation
3753 >     * for an element, or null of there is no transformation (in
3754 >     * which case it is not combined).
3755 >     * @param reducer a commutative associative combining function
3756 >     * @return the result of accumulating the given transformation
3757 >     * of all values
3758 >     */
3759 >    public <U> U reduceValues(Fun<? super V, ? extends U> transformer,
3760 >                              BiFun<? super U, ? super U, ? extends U> reducer) {
3761 >        return ForkJoinTasks.reduceValues
3762 >            (this, transformer, reducer).invoke();
3763 >    }
3764 >
3765 >    /**
3766 >     * Returns the result of accumulating the given transformation
3767 >     * of all values using the given reducer to combine values,
3768 >     * and the given basis as an identity value.
3769 >     *
3770 >     * @param transformer a function returning the transformation
3771 >     * for an element
3772 >     * @param basis the identity (initial default value) for the reduction
3773 >     * @param reducer a commutative associative combining function
3774 >     * @return the result of accumulating the given transformation
3775 >     * of all values
3776 >     */
3777 >    public double reduceValuesToDouble(ObjectToDouble<? super V> transformer,
3778 >                                       double basis,
3779 >                                       DoubleByDoubleToDouble reducer) {
3780 >        return ForkJoinTasks.reduceValuesToDouble
3781 >            (this, transformer, basis, reducer).invoke();
3782 >    }
3783 >
3784 >    /**
3785 >     * Returns the result of accumulating the given transformation
3786 >     * of all values using the given reducer to combine values,
3787 >     * and the given basis as an identity value.
3788 >     *
3789 >     * @param transformer a function returning the transformation
3790 >     * for an element
3791 >     * @param basis the identity (initial default value) for the reduction
3792 >     * @param reducer a commutative associative combining function
3793 >     * @return the result of accumulating the given transformation
3794 >     * of all values
3795 >     */
3796 >    public long reduceValuesToLong(ObjectToLong<? super V> transformer,
3797 >                                   long basis,
3798 >                                   LongByLongToLong reducer) {
3799 >        return ForkJoinTasks.reduceValuesToLong
3800 >            (this, transformer, basis, reducer).invoke();
3801 >    }
3802 >
3803 >    /**
3804 >     * Returns the result of accumulating the given transformation
3805 >     * of all values using the given reducer to combine values,
3806 >     * and the given basis as an identity value.
3807 >     *
3808 >     * @param transformer a function returning the transformation
3809 >     * for an element
3810 >     * @param basis the identity (initial default value) for the reduction
3811 >     * @param reducer a commutative associative combining function
3812 >     * @return the result of accumulating the given transformation
3813 >     * of all values
3814 >     */
3815 >    public int reduceValuesToInt(ObjectToInt<? super V> transformer,
3816 >                                 int basis,
3817 >                                 IntByIntToInt reducer) {
3818 >        return ForkJoinTasks.reduceValuesToInt
3819 >            (this, transformer, basis, reducer).invoke();
3820 >    }
3821 >
3822 >    /**
3823 >     * Performs the given action for each entry.
3824 >     *
3825 >     * @param action the action
3826 >     */
3827 >    public void forEachEntry(Action<Map.Entry<K,V>> action) {
3828 >        ForkJoinTasks.forEachEntry
3829 >            (this, action).invoke();
3830 >    }
3831 >
3832 >    /**
3833 >     * Performs the given action for each non-null transformation
3834 >     * of each entry.
3835 >     *
3836 >     * @param transformer a function returning the transformation
3837 >     * for an element, or null of there is no transformation (in
3838 >     * which case the action is not applied).
3839 >     * @param action the action
3840 >     */
3841 >    public <U> void forEachEntry(Fun<Map.Entry<K,V>, ? extends U> transformer,
3842 >                                 Action<U> action) {
3843 >        ForkJoinTasks.forEachEntry
3844 >            (this, transformer, action).invoke();
3845 >    }
3846 >
3847 >    /**
3848 >     * Returns a non-null result from applying the given search
3849 >     * function on each entry, or null if none.  Upon success,
3850 >     * further element processing is suppressed and the results of
3851 >     * any other parallel invocations of the search function are
3852 >     * ignored.
3853 >     *
3854 >     * @param searchFunction a function returning a non-null
3855 >     * result on success, else null
3856 >     * @return a non-null result from applying the given search
3857 >     * function on each entry, or null if none
3858 >     */
3859 >    public <U> U searchEntries(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
3860 >        return ForkJoinTasks.searchEntries
3861 >            (this, searchFunction).invoke();
3862 >    }
3863 >
3864 >    /**
3865 >     * Returns the result of accumulating all entries using the
3866 >     * given reducer to combine values, or null if none.
3867 >     *
3868 >     * @param reducer a commutative associative combining function
3869 >     * @return the result of accumulating all entries
3870 >     */
3871 >    public Map.Entry<K,V> reduceEntries(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
3872 >        return ForkJoinTasks.reduceEntries
3873 >            (this, reducer).invoke();
3874 >    }
3875 >
3876 >    /**
3877 >     * Returns the result of accumulating the given transformation
3878 >     * of all entries using the given reducer to combine values,
3879 >     * or null if none.
3880 >     *
3881 >     * @param transformer a function returning the transformation
3882 >     * for an element, or null of there is no transformation (in
3883 >     * which case it is not combined).
3884 >     * @param reducer a commutative associative combining function
3885 >     * @return the result of accumulating the given transformation
3886 >     * of all entries
3887 >     */
3888 >    public <U> U reduceEntries(Fun<Map.Entry<K,V>, ? extends U> transformer,
3889 >                               BiFun<? super U, ? super U, ? extends U> reducer) {
3890 >        return ForkJoinTasks.reduceEntries
3891 >            (this, transformer, reducer).invoke();
3892 >    }
3893 >
3894 >    /**
3895 >     * Returns the result of accumulating the given transformation
3896 >     * of all entries using the given reducer to combine values,
3897 >     * and the given basis as an identity value.
3898 >     *
3899 >     * @param transformer a function returning the transformation
3900 >     * for an element
3901 >     * @param basis the identity (initial default value) for the reduction
3902 >     * @param reducer a commutative associative combining function
3903 >     * @return the result of accumulating the given transformation
3904 >     * of all entries
3905 >     */
3906 >    public double reduceEntriesToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
3907 >                                        double basis,
3908 >                                        DoubleByDoubleToDouble reducer) {
3909 >        return ForkJoinTasks.reduceEntriesToDouble
3910 >            (this, transformer, basis, reducer).invoke();
3911 >    }
3912 >
3913 >    /**
3914 >     * Returns the result of accumulating the given transformation
3915 >     * of all entries using the given reducer to combine values,
3916 >     * and the given basis as an identity value.
3917 >     *
3918 >     * @param transformer a function returning the transformation
3919 >     * for an element
3920 >     * @param basis the identity (initial default value) for the reduction
3921 >     * @param reducer a commutative associative combining function
3922 >     * @return  the result of accumulating the given transformation
3923 >     * of all entries
3924 >     */
3925 >    public long reduceEntriesToLong(ObjectToLong<Map.Entry<K,V>> transformer,
3926 >                                    long basis,
3927 >                                    LongByLongToLong reducer) {
3928 >        return ForkJoinTasks.reduceEntriesToLong
3929 >            (this, transformer, basis, reducer).invoke();
3930 >    }
3931 >
3932 >    /**
3933 >     * Returns the result of accumulating the given transformation
3934 >     * of all entries using the given reducer to combine values,
3935 >     * and the given basis as an identity value.
3936 >     *
3937 >     * @param transformer a function returning the transformation
3938 >     * for an element
3939 >     * @param basis the identity (initial default value) for the reduction
3940 >     * @param reducer a commutative associative combining function
3941 >     * @return the result of accumulating the given transformation
3942 >     * of all entries
3943 >     */
3944 >    public int reduceEntriesToInt(ObjectToInt<Map.Entry<K,V>> transformer,
3945 >                                  int basis,
3946 >                                  IntByIntToInt reducer) {
3947 >        return ForkJoinTasks.reduceEntriesToInt
3948 >            (this, transformer, basis, reducer).invoke();
3949 >    }
3950 >
3951 >    /* ----------------Views -------------- */
3952 >
3953 >    /**
3954 >     * Base class for views.
3955 >     */
3956 >    static abstract class CHMView<K, V> {
3957 >        final ConcurrentHashMapV8<K, V> map;
3958 >        CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
3959  
3960          /**
3961 <         * Performs the given action for each (key, value).
3961 >         * Returns the map backing this view.
3962           *
3963 <         * @param action the action
3963 >         * @return the map backing this view
3964           */
3965 <        public void forEach(BiAction<K,V> action) {
3966 <            fjp.invoke(ForkJoinTasks.forEach
3967 <                       (ConcurrentHashMapV8.this, action));
3965 >        public ConcurrentHashMapV8<K,V> getMap() { return map; }
3966 >
3967 >        public final int size()                 { return map.size(); }
3968 >        public final boolean isEmpty()          { return map.isEmpty(); }
3969 >        public final void clear()               { map.clear(); }
3970 >
3971 >        // implementations below rely on concrete classes supplying these
3972 >        abstract public Iterator<?> iterator();
3973 >        abstract public boolean contains(Object o);
3974 >        abstract public boolean remove(Object o);
3975 >
3976 >        private static final String oomeMsg = "Required array size too large";
3977 >
3978 >        public final Object[] toArray() {
3979 >            long sz = map.mappingCount();
3980 >            if (sz > (long)(MAX_ARRAY_SIZE))
3981 >                throw new OutOfMemoryError(oomeMsg);
3982 >            int n = (int)sz;
3983 >            Object[] r = new Object[n];
3984 >            int i = 0;
3985 >            Iterator<?> it = iterator();
3986 >            while (it.hasNext()) {
3987 >                if (i == n) {
3988 >                    if (n >= MAX_ARRAY_SIZE)
3989 >                        throw new OutOfMemoryError(oomeMsg);
3990 >                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
3991 >                        n = MAX_ARRAY_SIZE;
3992 >                    else
3993 >                        n += (n >>> 1) + 1;
3994 >                    r = Arrays.copyOf(r, n);
3995 >                }
3996 >                r[i++] = it.next();
3997 >            }
3998 >            return (i == n) ? r : Arrays.copyOf(r, i);
3999          }
4000  
4001 <        /**
4002 <         * Performs the given action for each non-null transformation
4003 <         * of each (key, value).
4004 <         *
4005 <         * @param transformer a function returning the transformation
4006 <         * for an element, or null of there is no transformation (in
4007 <         * which case the action is not applied).
4008 <         * @param action the action
4009 <         */
4010 <        public <U> void forEach(BiFun<? super K, ? super V, ? extends U> transformer,
4011 <                                Action<U> action) {
4012 <            fjp.invoke(ForkJoinTasks.forEach
4013 <                       (ConcurrentHashMapV8.this, transformer, action));
4001 >        @SuppressWarnings("unchecked") public final <T> T[] toArray(T[] a) {
4002 >            long sz = map.mappingCount();
4003 >            if (sz > (long)(MAX_ARRAY_SIZE))
4004 >                throw new OutOfMemoryError(oomeMsg);
4005 >            int m = (int)sz;
4006 >            T[] r = (a.length >= m) ? a :
4007 >                (T[])java.lang.reflect.Array
4008 >                .newInstance(a.getClass().getComponentType(), m);
4009 >            int n = r.length;
4010 >            int i = 0;
4011 >            Iterator<?> it = iterator();
4012 >            while (it.hasNext()) {
4013 >                if (i == n) {
4014 >                    if (n >= MAX_ARRAY_SIZE)
4015 >                        throw new OutOfMemoryError(oomeMsg);
4016 >                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4017 >                        n = MAX_ARRAY_SIZE;
4018 >                    else
4019 >                        n += (n >>> 1) + 1;
4020 >                    r = Arrays.copyOf(r, n);
4021 >                }
4022 >                r[i++] = (T)it.next();
4023 >            }
4024 >            if (a == r && i < n) {
4025 >                r[i] = null; // null-terminate
4026 >                return r;
4027 >            }
4028 >            return (i == n) ? r : Arrays.copyOf(r, i);
4029          }
4030  
4031 <        /**
4032 <         * Returns a non-null result from applying the given search
4033 <         * function on each (key, value), or null if none.  Upon
4034 <         * success, further element processing is suppressed and the
4035 <         * results of any other parallel invocations of the search
3676 <         * function are ignored.
3677 <         *
3678 <         * @param searchFunction a function returning a non-null
3679 <         * result on success, else null
3680 <         * @return a non-null result from applying the given search
3681 <         * function on each (key, value), or null if none
3682 <         */
3683 <        public <U> U search(BiFun<? super K, ? super V, ? extends U> searchFunction) {
3684 <            return fjp.invoke(ForkJoinTasks.search
3685 <                              (ConcurrentHashMapV8.this, searchFunction));
4031 >        public final int hashCode() {
4032 >            int h = 0;
4033 >            for (Iterator<?> it = iterator(); it.hasNext();)
4034 >                h += it.next().hashCode();
4035 >            return h;
4036          }
4037  
4038 <        /**
4039 <         * Returns the result of accumulating the given transformation
4040 <         * of all (key, value) pairs using the given reducer to
4041 <         * combine values, or null if none.
4042 <         *
4043 <         * @param transformer a function returning the transformation
4044 <         * for an element, or null of there is no transformation (in
4045 <         * which case it is not combined).
4046 <         * @param reducer a commutative associative combining function
4047 <         * @return the result of accumulating the given transformation
4048 <         * of all (key, value) pairs
4049 <         */
4050 <        public <U> U reduce(BiFun<? super K, ? super V, ? extends U> transformer,
4051 <                            BiFun<? super U, ? super U, ? extends U> reducer) {
3702 <            return fjp.invoke(ForkJoinTasks.reduce
3703 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4038 >        public final String toString() {
4039 >            StringBuilder sb = new StringBuilder();
4040 >            sb.append('[');
4041 >            Iterator<?> it = iterator();
4042 >            if (it.hasNext()) {
4043 >                for (;;) {
4044 >                    Object e = it.next();
4045 >                    sb.append(e == this ? "(this Collection)" : e);
4046 >                    if (!it.hasNext())
4047 >                        break;
4048 >                    sb.append(',').append(' ');
4049 >                }
4050 >            }
4051 >            return sb.append(']').toString();
4052          }
4053  
4054 <        /**
4055 <         * Returns the result of accumulating the given transformation
4056 <         * of all (key, value) pairs using the given reducer to
4057 <         * combine values, and the given basis as an identity value.
4058 <         *
4059 <         * @param transformer a function returning the transformation
4060 <         * for an element
4061 <         * @param basis the identity (initial default value) for the reduction
4062 <         * @param reducer a commutative associative combining function
4063 <         * @return the result of accumulating the given transformation
4064 <         * of all (key, value) pairs
4065 <         */
4066 <        public double reduceToDouble(ObjectByObjectToDouble<? super K, ? super V> transformer,
4067 <                                     double basis,
4068 <                                     DoubleByDoubleToDouble reducer) {
4069 <            return fjp.invoke(ForkJoinTasks.reduceToDouble
4070 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4054 >        public final boolean containsAll(Collection<?> c) {
4055 >            if (c != this) {
4056 >                for (Iterator<?> it = c.iterator(); it.hasNext();) {
4057 >                    Object e = it.next();
4058 >                    if (e == null || !contains(e))
4059 >                        return false;
4060 >                }
4061 >            }
4062 >            return true;
4063 >        }
4064 >
4065 >        public final boolean removeAll(Collection<?> c) {
4066 >            boolean modified = false;
4067 >            for (Iterator<?> it = iterator(); it.hasNext();) {
4068 >                if (c.contains(it.next())) {
4069 >                    it.remove();
4070 >                    modified = true;
4071 >                }
4072 >            }
4073 >            return modified;
4074 >        }
4075 >
4076 >        public final boolean retainAll(Collection<?> c) {
4077 >            boolean modified = false;
4078 >            for (Iterator<?> it = iterator(); it.hasNext();) {
4079 >                if (!c.contains(it.next())) {
4080 >                    it.remove();
4081 >                    modified = true;
4082 >                }
4083 >            }
4084 >            return modified;
4085 >        }
4086 >
4087 >    }
4088 >
4089 >    /**
4090 >     * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in
4091 >     * which additions may optionally be enabled by mapping to a
4092 >     * common value.  This class cannot be directly instantiated. See
4093 >     * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
4094 >     * {@link #newKeySet(int)}.
4095 >     */
4096 >    public static class KeySetView<K,V> extends CHMView<K,V> implements Set<K>, java.io.Serializable {
4097 >        private static final long serialVersionUID = 7249069246763182397L;
4098 >        private final V value;
4099 >        KeySetView(ConcurrentHashMapV8<K, V> map, V value) {  // non-public
4100 >            super(map);
4101 >            this.value = value;
4102          }
4103  
4104          /**
4105 <         * Returns the result of accumulating the given transformation
4106 <         * of all (key, value) pairs using the given reducer to
3728 <         * combine values, and the given basis as an identity value.
4105 >         * Returns the default mapped value for additions,
4106 >         * or {@code null} if additions are not supported.
4107           *
4108 <         * @param transformer a function returning the transformation
4109 <         * for an element
3732 <         * @param basis the identity (initial default value) for the reduction
3733 <         * @param reducer a commutative associative combining function
3734 <         * @return the result of accumulating the given transformation
3735 <         * of all (key, value) pairs
4108 >         * @return the default mapped value for additions, or {@code null}
4109 >         * if not supported.
4110           */
4111 <        public long reduceToLong(ObjectByObjectToLong<? super K, ? super V> transformer,
4112 <                                 long basis,
4113 <                                 LongByLongToLong reducer) {
4114 <            return fjp.invoke(ForkJoinTasks.reduceToLong
4115 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4116 <        }
4111 >        public V getMappedValue() { return value; }
4112 >
4113 >        // implement Set API
4114 >
4115 >        public boolean contains(Object o) { return map.containsKey(o); }
4116 >        public boolean remove(Object o)   { return map.remove(o) != null; }
4117  
4118          /**
4119 <         * Returns the result of accumulating the given transformation
4120 <         * of all (key, value) pairs using the given reducer to
4121 <         * combine values, and the given basis as an identity value.
4119 >         * Returns a "weakly consistent" iterator that will never
4120 >         * throw {@link ConcurrentModificationException}, and
4121 >         * guarantees to traverse elements as they existed upon
4122 >         * construction of the iterator, and may (but is not
4123 >         * guaranteed to) reflect any modifications subsequent to
4124 >         * construction.
4125           *
4126 <         * @param transformer a function returning the transformation
3750 <         * for an element
3751 <         * @param basis the identity (initial default value) for the reduction
3752 <         * @param reducer a commutative associative combining function
3753 <         * @return the result of accumulating the given transformation
3754 <         * of all (key, value) pairs
4126 >         * @return an iterator over the keys of this map
4127           */
4128 <        public int reduceToInt(ObjectByObjectToInt<? super K, ? super V> transformer,
4129 <                               int basis,
4130 <                               IntByIntToInt reducer) {
4131 <            return fjp.invoke(ForkJoinTasks.reduceToInt
4132 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4128 >        public Iterator<K> iterator()     { return new KeyIterator<K,V>(map); }
4129 >        public boolean add(K e) {
4130 >            V v;
4131 >            if ((v = value) == null)
4132 >                throw new UnsupportedOperationException();
4133 >            if (e == null)
4134 >                throw new NullPointerException();
4135 >            return map.internalPutIfAbsent(e, v) == null;
4136 >        }
4137 >        public boolean addAll(Collection<? extends K> c) {
4138 >            boolean added = false;
4139 >            V v;
4140 >            if ((v = value) == null)
4141 >                throw new UnsupportedOperationException();
4142 >            for (K e : c) {
4143 >                if (e == null)
4144 >                    throw new NullPointerException();
4145 >                if (map.internalPutIfAbsent(e, v) == null)
4146 >                    added = true;
4147 >            }
4148 >            return added;
4149 >        }
4150 >        public boolean equals(Object o) {
4151 >            Set<?> c;
4152 >            return ((o instanceof Set) &&
4153 >                    ((c = (Set<?>)o) == this ||
4154 >                     (containsAll(c) && c.containsAll(this))));
4155          }
4156  
4157          /**
# Line 3765 | Line 4159 | public class ConcurrentHashMapV8<K, V>
4159           *
4160           * @param action the action
4161           */
4162 <        public void forEachKey(Action<K> action) {
4163 <            fjp.invoke(ForkJoinTasks.forEachKey
4164 <                       (ConcurrentHashMapV8.this, action));
4162 >        public void forEach(Action<K> action) {
4163 >            ForkJoinTasks.forEachKey
4164 >                (map, action).invoke();
4165          }
4166  
4167          /**
# Line 3779 | Line 4173 | public class ConcurrentHashMapV8<K, V>
4173           * which case the action is not applied).
4174           * @param action the action
4175           */
4176 <        public <U> void forEachKey(Fun<? super K, ? extends U> transformer,
4177 <                                   Action<U> action) {
4178 <            fjp.invoke(ForkJoinTasks.forEachKey
4179 <                       (ConcurrentHashMapV8.this, transformer, action));
4176 >        public <U> void forEach(Fun<? super K, ? extends U> transformer,
4177 >                                Action<U> action) {
4178 >            ForkJoinTasks.forEachKey
4179 >                (map, transformer, action).invoke();
4180          }
4181  
4182          /**
# Line 3797 | Line 4191 | public class ConcurrentHashMapV8<K, V>
4191           * @return a non-null result from applying the given search
4192           * function on each key, or null if none
4193           */
4194 <        public <U> U searchKeys(Fun<? super K, ? extends U> searchFunction) {
4195 <            return fjp.invoke(ForkJoinTasks.searchKeys
4196 <                              (ConcurrentHashMapV8.this, searchFunction));
4194 >        public <U> U search(Fun<? super K, ? extends U> searchFunction) {
4195 >            return ForkJoinTasks.searchKeys
4196 >                (map, searchFunction).invoke();
4197          }
4198  
4199          /**
# Line 3810 | Line 4204 | public class ConcurrentHashMapV8<K, V>
4204           * @return the result of accumulating all keys using the given
4205           * reducer to combine values, or null if none
4206           */
4207 <        public K reduceKeys(BiFun<? super K, ? super K, ? extends K> reducer) {
4208 <            return fjp.invoke(ForkJoinTasks.reduceKeys
4209 <                              (ConcurrentHashMapV8.this, reducer));
3816 <        }
3817 <
3818 <        /**
3819 <         * Returns the result of accumulating the given transformation
3820 <         * of all keys using the given reducer to combine values, or
3821 <         * null if none.
3822 <         *
3823 <         * @param transformer a function returning the transformation
3824 <         * for an element, or null of there is no transformation (in
3825 <         * which case it is not combined).
3826 <         * @param reducer a commutative associative combining function
3827 <         * @return the result of accumulating the given transformation
3828 <         * of all keys
3829 <         */
3830 <        public <U> U reduceKeys(Fun<? super K, ? extends U> transformer,
3831 <                                BiFun<? super U, ? super U, ? extends U> reducer) {
3832 <            return fjp.invoke(ForkJoinTasks.reduceKeys
3833 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4207 >        public K reduce(BiFun<? super K, ? super K, ? extends K> reducer) {
4208 >            return ForkJoinTasks.reduceKeys
4209 >                (map, reducer).invoke();
4210          }
4211  
4212          /**
# Line 3845 | Line 4221 | public class ConcurrentHashMapV8<K, V>
4221           * @return  the result of accumulating the given transformation
4222           * of all keys
4223           */
4224 <        public double reduceKeysToDouble(ObjectToDouble<? super K> transformer,
4225 <                                         double basis,
4226 <                                         DoubleByDoubleToDouble reducer) {
4227 <            return fjp.invoke(ForkJoinTasks.reduceKeysToDouble
4228 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4224 >        public double reduceToDouble(ObjectToDouble<? super K> transformer,
4225 >                                     double basis,
4226 >                                     DoubleByDoubleToDouble reducer) {
4227 >            return ForkJoinTasks.reduceKeysToDouble
4228 >                (map, transformer, basis, reducer).invoke();
4229          }
4230  
4231 +
4232          /**
4233           * Returns the result of accumulating the given transformation
4234           * of all keys using the given reducer to combine values, and
# Line 3864 | Line 4241 | public class ConcurrentHashMapV8<K, V>
4241           * @return the result of accumulating the given transformation
4242           * of all keys
4243           */
4244 <        public long reduceKeysToLong(ObjectToLong<? super K> transformer,
4245 <                                     long basis,
4246 <                                     LongByLongToLong reducer) {
4247 <            return fjp.invoke(ForkJoinTasks.reduceKeysToLong
4248 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4244 >        public long reduceToLong(ObjectToLong<? super K> transformer,
4245 >                                 long basis,
4246 >                                 LongByLongToLong reducer) {
4247 >            return ForkJoinTasks.reduceKeysToLong
4248 >                (map, transformer, basis, reducer).invoke();
4249          }
4250  
4251          /**
# Line 3883 | Line 4260 | public class ConcurrentHashMapV8<K, V>
4260           * @return the result of accumulating the given transformation
4261           * of all keys
4262           */
4263 <        public int reduceKeysToInt(ObjectToInt<? super K> transformer,
4264 <                                   int basis,
4265 <                                   IntByIntToInt reducer) {
4266 <            return fjp.invoke(ForkJoinTasks.reduceKeysToInt
4267 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4263 >        public int reduceToInt(ObjectToInt<? super K> transformer,
4264 >                               int basis,
4265 >                               IntByIntToInt reducer) {
4266 >            return ForkJoinTasks.reduceKeysToInt
4267 >                (map, transformer, basis, reducer).invoke();
4268 >        }
4269 >
4270 >    }
4271 >
4272 >    /**
4273 >     * A view of a ConcurrentHashMapV8 as a {@link Collection} of
4274 >     * values, in which additions are disabled. This class cannot be
4275 >     * directly instantiated. See {@link #values},
4276 >     *
4277 >     * <p>The view's {@code iterator} is a "weakly consistent" iterator
4278 >     * that will never throw {@link ConcurrentModificationException},
4279 >     * and guarantees to traverse elements as they existed upon
4280 >     * construction of the iterator, and may (but is not guaranteed to)
4281 >     * reflect any modifications subsequent to construction.
4282 >     */
4283 >    public static final class ValuesView<K,V> extends CHMView<K,V>
4284 >        implements Collection<V> {
4285 >        ValuesView(ConcurrentHashMapV8<K, V> map)   { super(map); }
4286 >        public final boolean contains(Object o) { return map.containsValue(o); }
4287 >        public final boolean remove(Object o) {
4288 >            if (o != null) {
4289 >                Iterator<V> it = new ValueIterator<K,V>(map);
4290 >                while (it.hasNext()) {
4291 >                    if (o.equals(it.next())) {
4292 >                        it.remove();
4293 >                        return true;
4294 >                    }
4295 >                }
4296 >            }
4297 >            return false;
4298 >        }
4299 >
4300 >        /**
4301 >         * Returns a "weakly consistent" iterator that will never
4302 >         * throw {@link ConcurrentModificationException}, and
4303 >         * guarantees to traverse elements as they existed upon
4304 >         * construction of the iterator, and may (but is not
4305 >         * guaranteed to) reflect any modifications subsequent to
4306 >         * construction.
4307 >         *
4308 >         * @return an iterator over the values of this map
4309 >         */
4310 >        public final Iterator<V> iterator() {
4311 >            return new ValueIterator<K,V>(map);
4312 >        }
4313 >        public final boolean add(V e) {
4314 >            throw new UnsupportedOperationException();
4315 >        }
4316 >        public final boolean addAll(Collection<? extends V> c) {
4317 >            throw new UnsupportedOperationException();
4318          }
4319  
4320          /**
# Line 3895 | Line 4322 | public class ConcurrentHashMapV8<K, V>
4322           *
4323           * @param action the action
4324           */
4325 <        public void forEachValue(Action<V> action) {
4326 <            fjp.invoke(ForkJoinTasks.forEachValue
4327 <                       (ConcurrentHashMapV8.this, action));
4325 >        public void forEach(Action<V> action) {
4326 >            ForkJoinTasks.forEachValue
4327 >                (map, action).invoke();
4328          }
4329  
4330          /**
# Line 3908 | Line 4335 | public class ConcurrentHashMapV8<K, V>
4335           * for an element, or null of there is no transformation (in
4336           * which case the action is not applied).
4337           */
4338 <        public <U> void forEachValue(Fun<? super V, ? extends U> transformer,
4338 >        public <U> void forEach(Fun<? super V, ? extends U> transformer,
4339                                       Action<U> action) {
4340 <            fjp.invoke(ForkJoinTasks.forEachValue
4341 <                       (ConcurrentHashMapV8.this, transformer, action));
4340 >            ForkJoinTasks.forEachValue
4341 >                (map, transformer, action).invoke();
4342          }
4343  
4344          /**
# Line 3927 | Line 4354 | public class ConcurrentHashMapV8<K, V>
4354           * function on each value, or null if none
4355           *
4356           */
4357 <        public <U> U searchValues(Fun<? super V, ? extends U> searchFunction) {
4358 <            return fjp.invoke(ForkJoinTasks.searchValues
4359 <                              (ConcurrentHashMapV8.this, searchFunction));
4357 >        public <U> U search(Fun<? super V, ? extends U> searchFunction) {
4358 >            return ForkJoinTasks.searchValues
4359 >                (map, searchFunction).invoke();
4360          }
4361  
4362          /**
# Line 3939 | Line 4366 | public class ConcurrentHashMapV8<K, V>
4366           * @param reducer a commutative associative combining function
4367           * @return  the result of accumulating all values
4368           */
4369 <        public V reduceValues(BiFun<? super V, ? super V, ? extends V> reducer) {
4370 <            return fjp.invoke(ForkJoinTasks.reduceValues
4371 <                              (ConcurrentHashMapV8.this, reducer));
4369 >        public V reduce(BiFun<? super V, ? super V, ? extends V> reducer) {
4370 >            return ForkJoinTasks.reduceValues
4371 >                (map, reducer).invoke();
4372          }
4373  
4374          /**
# Line 3956 | Line 4383 | public class ConcurrentHashMapV8<K, V>
4383           * @return the result of accumulating the given transformation
4384           * of all values
4385           */
4386 <        public <U> U reduceValues(Fun<? super V, ? extends U> transformer,
4387 <                                  BiFun<? super U, ? super U, ? extends U> reducer) {
4388 <            return fjp.invoke(ForkJoinTasks.reduceValues
4389 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4386 >        public <U> U reduce(Fun<? super V, ? extends U> transformer,
4387 >                            BiFun<? super U, ? super U, ? extends U> reducer) {
4388 >            return ForkJoinTasks.reduceValues
4389 >                (map, transformer, reducer).invoke();
4390          }
4391  
4392          /**
# Line 3974 | Line 4401 | public class ConcurrentHashMapV8<K, V>
4401           * @return the result of accumulating the given transformation
4402           * of all values
4403           */
4404 <        public double reduceValuesToDouble(ObjectToDouble<? super V> transformer,
4405 <                                           double basis,
4406 <                                           DoubleByDoubleToDouble reducer) {
4407 <            return fjp.invoke(ForkJoinTasks.reduceValuesToDouble
4408 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4404 >        public double reduceToDouble(ObjectToDouble<? super V> transformer,
4405 >                                     double basis,
4406 >                                     DoubleByDoubleToDouble reducer) {
4407 >            return ForkJoinTasks.reduceValuesToDouble
4408 >                (map, transformer, basis, reducer).invoke();
4409          }
4410  
4411          /**
# Line 3993 | Line 4420 | public class ConcurrentHashMapV8<K, V>
4420           * @return the result of accumulating the given transformation
4421           * of all values
4422           */
4423 <        public long reduceValuesToLong(ObjectToLong<? super V> transformer,
4424 <                                       long basis,
4425 <                                       LongByLongToLong reducer) {
4426 <            return fjp.invoke(ForkJoinTasks.reduceValuesToLong
4427 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4423 >        public long reduceToLong(ObjectToLong<? super V> transformer,
4424 >                                 long basis,
4425 >                                 LongByLongToLong reducer) {
4426 >            return ForkJoinTasks.reduceValuesToLong
4427 >                (map, transformer, basis, reducer).invoke();
4428          }
4429  
4430          /**
# Line 4012 | Line 4439 | public class ConcurrentHashMapV8<K, V>
4439           * @return the result of accumulating the given transformation
4440           * of all values
4441           */
4442 <        public int reduceValuesToInt(ObjectToInt<? super V> transformer,
4443 <                                     int basis,
4444 <                                     IntByIntToInt reducer) {
4445 <            return fjp.invoke(ForkJoinTasks.reduceValuesToInt
4446 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4442 >        public int reduceToInt(ObjectToInt<? super V> transformer,
4443 >                               int basis,
4444 >                               IntByIntToInt reducer) {
4445 >            return ForkJoinTasks.reduceValuesToInt
4446 >                (map, transformer, basis, reducer).invoke();
4447 >        }
4448 >
4449 >    }
4450 >
4451 >    /**
4452 >     * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value)
4453 >     * entries.  This class cannot be directly instantiated. See
4454 >     * {@link #entrySet}.
4455 >     */
4456 >    public static final class EntrySetView<K,V> extends CHMView<K,V>
4457 >        implements Set<Map.Entry<K,V>> {
4458 >        EntrySetView(ConcurrentHashMapV8<K, V> map) { super(map); }
4459 >        public final boolean contains(Object o) {
4460 >            Object k, v, r; Map.Entry<?,?> e;
4461 >            return ((o instanceof Map.Entry) &&
4462 >                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
4463 >                    (r = map.get(k)) != null &&
4464 >                    (v = e.getValue()) != null &&
4465 >                    (v == r || v.equals(r)));
4466 >        }
4467 >        public final boolean remove(Object o) {
4468 >            Object k, v; Map.Entry<?,?> e;
4469 >            return ((o instanceof Map.Entry) &&
4470 >                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
4471 >                    (v = e.getValue()) != null &&
4472 >                    map.remove(k, v));
4473 >        }
4474 >
4475 >        /**
4476 >         * Returns a "weakly consistent" iterator that will never
4477 >         * throw {@link ConcurrentModificationException}, and
4478 >         * guarantees to traverse elements as they existed upon
4479 >         * construction of the iterator, and may (but is not
4480 >         * guaranteed to) reflect any modifications subsequent to
4481 >         * construction.
4482 >         *
4483 >         * @return an iterator over the entries of this map
4484 >         */
4485 >        public final Iterator<Map.Entry<K,V>> iterator() {
4486 >            return new EntryIterator<K,V>(map);
4487 >        }
4488 >
4489 >        public final boolean add(Entry<K,V> e) {
4490 >            K key = e.getKey();
4491 >            V value = e.getValue();
4492 >            if (key == null || value == null)
4493 >                throw new NullPointerException();
4494 >            return map.internalPut(key, value) == null;
4495 >        }
4496 >        public final boolean addAll(Collection<? extends Entry<K,V>> c) {
4497 >            boolean added = false;
4498 >            for (Entry<K,V> e : c) {
4499 >                if (add(e))
4500 >                    added = true;
4501 >            }
4502 >            return added;
4503 >        }
4504 >        public boolean equals(Object o) {
4505 >            Set<?> c;
4506 >            return ((o instanceof Set) &&
4507 >                    ((c = (Set<?>)o) == this ||
4508 >                     (containsAll(c) && c.containsAll(this))));
4509          }
4510  
4511          /**
# Line 4024 | Line 4513 | public class ConcurrentHashMapV8<K, V>
4513           *
4514           * @param action the action
4515           */
4516 <        public void forEachEntry(Action<Map.Entry<K,V>> action) {
4517 <            fjp.invoke(ForkJoinTasks.forEachEntry
4518 <                       (ConcurrentHashMapV8.this, action));
4516 >        public void forEach(Action<Map.Entry<K,V>> action) {
4517 >            ForkJoinTasks.forEachEntry
4518 >                (map, action).invoke();
4519          }
4520  
4521          /**
# Line 4038 | Line 4527 | public class ConcurrentHashMapV8<K, V>
4527           * which case the action is not applied).
4528           * @param action the action
4529           */
4530 <        public <U> void forEachEntry(Fun<Map.Entry<K,V>, ? extends U> transformer,
4531 <                                     Action<U> action) {
4532 <            fjp.invoke(ForkJoinTasks.forEachEntry
4533 <                       (ConcurrentHashMapV8.this, transformer, action));
4530 >        public <U> void forEach(Fun<Map.Entry<K,V>, ? extends U> transformer,
4531 >                                Action<U> action) {
4532 >            ForkJoinTasks.forEachEntry
4533 >                (map, transformer, action).invoke();
4534          }
4535  
4536          /**
# Line 4056 | Line 4545 | public class ConcurrentHashMapV8<K, V>
4545           * @return a non-null result from applying the given search
4546           * function on each entry, or null if none
4547           */
4548 <        public <U> U searchEntries(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4549 <            return fjp.invoke(ForkJoinTasks.searchEntries
4550 <                              (ConcurrentHashMapV8.this, searchFunction));
4548 >        public <U> U search(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4549 >            return ForkJoinTasks.searchEntries
4550 >                (map, searchFunction).invoke();
4551          }
4552  
4553          /**
# Line 4068 | Line 4557 | public class ConcurrentHashMapV8<K, V>
4557           * @param reducer a commutative associative combining function
4558           * @return the result of accumulating all entries
4559           */
4560 <        public Map.Entry<K,V> reduceEntries(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4561 <            return fjp.invoke(ForkJoinTasks.reduceEntries
4562 <                              (ConcurrentHashMapV8.this, reducer));
4560 >        public Map.Entry<K,V> reduce(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4561 >            return ForkJoinTasks.reduceEntries
4562 >                (map, reducer).invoke();
4563          }
4564  
4565          /**
# Line 4085 | Line 4574 | public class ConcurrentHashMapV8<K, V>
4574           * @return the result of accumulating the given transformation
4575           * of all entries
4576           */
4577 <        public <U> U reduceEntries(Fun<Map.Entry<K,V>, ? extends U> transformer,
4578 <                                   BiFun<? super U, ? super U, ? extends U> reducer) {
4579 <            return fjp.invoke(ForkJoinTasks.reduceEntries
4580 <                              (ConcurrentHashMapV8.this, transformer, reducer));
4577 >        public <U> U reduce(Fun<Map.Entry<K,V>, ? extends U> transformer,
4578 >                            BiFun<? super U, ? super U, ? extends U> reducer) {
4579 >            return ForkJoinTasks.reduceEntries
4580 >                (map, transformer, reducer).invoke();
4581          }
4582  
4583          /**
# Line 4103 | Line 4592 | public class ConcurrentHashMapV8<K, V>
4592           * @return the result of accumulating the given transformation
4593           * of all entries
4594           */
4595 <        public double reduceEntriesToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
4596 <                                            double basis,
4597 <                                            DoubleByDoubleToDouble reducer) {
4598 <            return fjp.invoke(ForkJoinTasks.reduceEntriesToDouble
4599 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4595 >        public double reduceToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
4596 >                                     double basis,
4597 >                                     DoubleByDoubleToDouble reducer) {
4598 >            return ForkJoinTasks.reduceEntriesToDouble
4599 >                (map, transformer, basis, reducer).invoke();
4600          }
4601  
4602          /**
# Line 4122 | Line 4611 | public class ConcurrentHashMapV8<K, V>
4611           * @return  the result of accumulating the given transformation
4612           * of all entries
4613           */
4614 <        public long reduceEntriesToLong(ObjectToLong<Map.Entry<K,V>> transformer,
4615 <                                        long basis,
4616 <                                        LongByLongToLong reducer) {
4617 <            return fjp.invoke(ForkJoinTasks.reduceEntriesToLong
4618 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4614 >        public long reduceToLong(ObjectToLong<Map.Entry<K,V>> transformer,
4615 >                                 long basis,
4616 >                                 LongByLongToLong reducer) {
4617 >            return ForkJoinTasks.reduceEntriesToLong
4618 >                (map, transformer, basis, reducer).invoke();
4619          }
4620  
4621          /**
# Line 4141 | Line 4630 | public class ConcurrentHashMapV8<K, V>
4630           * @return the result of accumulating the given transformation
4631           * of all entries
4632           */
4633 <        public int reduceEntriesToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4634 <                                      int basis,
4635 <                                      IntByIntToInt reducer) {
4636 <            return fjp.invoke(ForkJoinTasks.reduceEntriesToInt
4637 <                              (ConcurrentHashMapV8.this, transformer, basis, reducer));
4633 >        public int reduceToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4634 >                               int basis,
4635 >                               IntByIntToInt reducer) {
4636 >            return ForkJoinTasks.reduceEntriesToInt
4637 >                (map, transformer, basis, reducer).invoke();
4638          }
4639 +
4640      }
4641  
4642      // ---------------------------------------------------------------------
4643  
4644      /**
4645       * Predefined tasks for performing bulk parallel operations on
4646 <     * ConcurrentHashMaps. These tasks follow the forms and rules used
4647 <     * in class {@link Parallel}. Each method has the same name, but
4648 <     * returns a task rather than invoking it. These methods may be
4649 <     * useful in custom applications such as submitting a task without
4650 <     * waiting for completion, or combining with other tasks.
4646 >     * ConcurrentHashMapV8s. These tasks follow the forms and rules used
4647 >     * for bulk operations. Each method has the same name, but returns
4648 >     * a task rather than invoking it. These methods may be useful in
4649 >     * custom applications such as submitting a task without waiting
4650 >     * for completion, using a custom pool, or combining with other
4651 >     * tasks.
4652       */
4653      public static class ForkJoinTasks {
4654          private ForkJoinTasks() {}
# Line 4174 | Line 4665 | public class ConcurrentHashMapV8<K, V>
4665              (ConcurrentHashMapV8<K,V> map,
4666               BiAction<K,V> action) {
4667              if (action == null) throw new NullPointerException();
4668 <            return new ForEachMappingTask<K,V>(map, action);
4668 >            return new ForEachMappingTask<K,V>(map, null, -1, null, action);
4669          }
4670  
4671          /**
# Line 4183 | Line 4674 | public class ConcurrentHashMapV8<K, V>
4674           *
4675           * @param map the map
4676           * @param transformer a function returning the transformation
4677 <         * for an element, or null of there is no transformation (in
4678 <         * which case the action is not applied).
4677 >         * for an element, or null if there is no transformation (in
4678 >         * which case the action is not applied)
4679           * @param action the action
4680           * @return the task
4681           */
# Line 4195 | Line 4686 | public class ConcurrentHashMapV8<K, V>
4686              if (transformer == null || action == null)
4687                  throw new NullPointerException();
4688              return new ForEachTransformedMappingTask<K,V,U>
4689 <                (map, transformer, action);
4689 >                (map, null, -1, null, transformer, action);
4690          }
4691  
4692          /**
# Line 4215 | Line 4706 | public class ConcurrentHashMapV8<K, V>
4706               BiFun<? super K, ? super V, ? extends U> searchFunction) {
4707              if (searchFunction == null) throw new NullPointerException();
4708              return new SearchMappingsTask<K,V,U>
4709 <                (map, searchFunction,
4709 >                (map, null, -1, null, searchFunction,
4710                   new AtomicReference<U>());
4711          }
4712  
# Line 4226 | Line 4717 | public class ConcurrentHashMapV8<K, V>
4717           *
4718           * @param map the map
4719           * @param transformer a function returning the transformation
4720 <         * for an element, or null of there is no transformation (in
4720 >         * for an element, or null if there is no transformation (in
4721           * which case it is not combined).
4722           * @param reducer a commutative associative combining function
4723           * @return the task
# Line 4238 | Line 4729 | public class ConcurrentHashMapV8<K, V>
4729              if (transformer == null || reducer == null)
4730                  throw new NullPointerException();
4731              return new MapReduceMappingsTask<K,V,U>
4732 <                (map, transformer, reducer);
4732 >                (map, null, -1, null, transformer, reducer);
4733          }
4734  
4735          /**
# Line 4262 | Line 4753 | public class ConcurrentHashMapV8<K, V>
4753              if (transformer == null || reducer == null)
4754                  throw new NullPointerException();
4755              return new MapReduceMappingsToDoubleTask<K,V>
4756 <                (map, transformer, basis, reducer);
4756 >                (map, null, -1, null, transformer, basis, reducer);
4757          }
4758  
4759          /**
# Line 4286 | Line 4777 | public class ConcurrentHashMapV8<K, V>
4777              if (transformer == null || reducer == null)
4778                  throw new NullPointerException();
4779              return new MapReduceMappingsToLongTask<K,V>
4780 <                (map, transformer, basis, reducer);
4780 >                (map, null, -1, null, transformer, basis, reducer);
4781          }
4782  
4783          /**
# Line 4309 | Line 4800 | public class ConcurrentHashMapV8<K, V>
4800              if (transformer == null || reducer == null)
4801                  throw new NullPointerException();
4802              return new MapReduceMappingsToIntTask<K,V>
4803 <                (map, transformer, basis, reducer);
4803 >                (map, null, -1, null, transformer, basis, reducer);
4804          }
4805  
4806          /**
# Line 4324 | Line 4815 | public class ConcurrentHashMapV8<K, V>
4815              (ConcurrentHashMapV8<K,V> map,
4816               Action<K> action) {
4817              if (action == null) throw new NullPointerException();
4818 <            return new ForEachKeyTask<K,V>(map, action);
4818 >            return new ForEachKeyTask<K,V>(map, null, -1, null, action);
4819          }
4820  
4821          /**
# Line 4333 | Line 4824 | public class ConcurrentHashMapV8<K, V>
4824           *
4825           * @param map the map
4826           * @param transformer a function returning the transformation
4827 <         * for an element, or null of there is no transformation (in
4828 <         * which case the action is not applied).
4827 >         * for an element, or null if there is no transformation (in
4828 >         * which case the action is not applied)
4829           * @param action the action
4830           * @return the task
4831           */
# Line 4345 | Line 4836 | public class ConcurrentHashMapV8<K, V>
4836              if (transformer == null || action == null)
4837                  throw new NullPointerException();
4838              return new ForEachTransformedKeyTask<K,V,U>
4839 <                (map, transformer, action);
4839 >                (map, null, -1, null, transformer, action);
4840          }
4841  
4842          /**
# Line 4365 | Line 4856 | public class ConcurrentHashMapV8<K, V>
4856               Fun<? super K, ? extends U> searchFunction) {
4857              if (searchFunction == null) throw new NullPointerException();
4858              return new SearchKeysTask<K,V,U>
4859 <                (map, searchFunction,
4859 >                (map, null, -1, null, searchFunction,
4860                   new AtomicReference<U>());
4861          }
4862  
# Line 4383 | Line 4874 | public class ConcurrentHashMapV8<K, V>
4874               BiFun<? super K, ? super K, ? extends K> reducer) {
4875              if (reducer == null) throw new NullPointerException();
4876              return new ReduceKeysTask<K,V>
4877 <                (map, reducer);
4877 >                (map, null, -1, null, reducer);
4878          }
4879  
4880          /**
# Line 4393 | Line 4884 | public class ConcurrentHashMapV8<K, V>
4884           *
4885           * @param map the map
4886           * @param transformer a function returning the transformation
4887 <         * for an element, or null of there is no transformation (in
4887 >         * for an element, or null if there is no transformation (in
4888           * which case it is not combined).
4889           * @param reducer a commutative associative combining function
4890           * @return the task
# Line 4405 | Line 4896 | public class ConcurrentHashMapV8<K, V>
4896              if (transformer == null || reducer == null)
4897                  throw new NullPointerException();
4898              return new MapReduceKeysTask<K,V,U>
4899 <                (map, transformer, reducer);
4899 >                (map, null, -1, null, transformer, reducer);
4900          }
4901  
4902          /**
# Line 4429 | Line 4920 | public class ConcurrentHashMapV8<K, V>
4920              if (transformer == null || reducer == null)
4921                  throw new NullPointerException();
4922              return new MapReduceKeysToDoubleTask<K,V>
4923 <                (map, transformer, basis, reducer);
4923 >                (map, null, -1, null, transformer, basis, reducer);
4924          }
4925  
4926          /**
# Line 4453 | Line 4944 | public class ConcurrentHashMapV8<K, V>
4944              if (transformer == null || reducer == null)
4945                  throw new NullPointerException();
4946              return new MapReduceKeysToLongTask<K,V>
4947 <                (map, transformer, basis, reducer);
4947 >                (map, null, -1, null, transformer, basis, reducer);
4948          }
4949  
4950          /**
# Line 4477 | Line 4968 | public class ConcurrentHashMapV8<K, V>
4968              if (transformer == null || reducer == null)
4969                  throw new NullPointerException();
4970              return new MapReduceKeysToIntTask<K,V>
4971 <                (map, transformer, basis, reducer);
4971 >                (map, null, -1, null, transformer, basis, reducer);
4972          }
4973  
4974          /**
# Line 4491 | Line 4982 | public class ConcurrentHashMapV8<K, V>
4982              (ConcurrentHashMapV8<K,V> map,
4983               Action<V> action) {
4984              if (action == null) throw new NullPointerException();
4985 <            return new ForEachValueTask<K,V>(map, action);
4985 >            return new ForEachValueTask<K,V>(map, null, -1, null, action);
4986          }
4987  
4988          /**
# Line 4500 | Line 4991 | public class ConcurrentHashMapV8<K, V>
4991           *
4992           * @param map the map
4993           * @param transformer a function returning the transformation
4994 <         * for an element, or null of there is no transformation (in
4995 <         * which case the action is not applied).
4994 >         * for an element, or null if there is no transformation (in
4995 >         * which case the action is not applied)
4996           * @param action the action
4997           */
4998          public static <K,V,U> ForkJoinTask<Void> forEachValue
# Line 4511 | Line 5002 | public class ConcurrentHashMapV8<K, V>
5002              if (transformer == null || action == null)
5003                  throw new NullPointerException();
5004              return new ForEachTransformedValueTask<K,V,U>
5005 <                (map, transformer, action);
5005 >                (map, null, -1, null, transformer, action);
5006          }
5007  
5008          /**
# Line 4525 | Line 5016 | public class ConcurrentHashMapV8<K, V>
5016           * @param searchFunction a function returning a non-null
5017           * result on success, else null
5018           * @return the task
4528         *
5019           */
5020          public static <K,V,U> ForkJoinTask<U> searchValues
5021              (ConcurrentHashMapV8<K,V> map,
5022               Fun<? super V, ? extends U> searchFunction) {
5023              if (searchFunction == null) throw new NullPointerException();
5024              return new SearchValuesTask<K,V,U>
5025 <                (map, searchFunction,
5025 >                (map, null, -1, null, searchFunction,
5026                   new AtomicReference<U>());
5027          }
5028  
# Line 4550 | Line 5040 | public class ConcurrentHashMapV8<K, V>
5040               BiFun<? super V, ? super V, ? extends V> reducer) {
5041              if (reducer == null) throw new NullPointerException();
5042              return new ReduceValuesTask<K,V>
5043 <                (map, reducer);
5043 >                (map, null, -1, null, reducer);
5044          }
5045  
5046          /**
# Line 4560 | Line 5050 | public class ConcurrentHashMapV8<K, V>
5050           *
5051           * @param map the map
5052           * @param transformer a function returning the transformation
5053 <         * for an element, or null of there is no transformation (in
5053 >         * for an element, or null if there is no transformation (in
5054           * which case it is not combined).
5055           * @param reducer a commutative associative combining function
5056           * @return the task
# Line 4572 | Line 5062 | public class ConcurrentHashMapV8<K, V>
5062              if (transformer == null || reducer == null)
5063                  throw new NullPointerException();
5064              return new MapReduceValuesTask<K,V,U>
5065 <                (map, transformer, reducer);
5065 >                (map, null, -1, null, transformer, reducer);
5066          }
5067  
5068          /**
# Line 4596 | Line 5086 | public class ConcurrentHashMapV8<K, V>
5086              if (transformer == null || reducer == null)
5087                  throw new NullPointerException();
5088              return new MapReduceValuesToDoubleTask<K,V>
5089 <                (map, transformer, basis, reducer);
5089 >                (map, null, -1, null, transformer, basis, reducer);
5090          }
5091  
5092          /**
# Line 4620 | Line 5110 | public class ConcurrentHashMapV8<K, V>
5110              if (transformer == null || reducer == null)
5111                  throw new NullPointerException();
5112              return new MapReduceValuesToLongTask<K,V>
5113 <                (map, transformer, basis, reducer);
5113 >                (map, null, -1, null, transformer, basis, reducer);
5114          }
5115  
5116          /**
# Line 4644 | Line 5134 | public class ConcurrentHashMapV8<K, V>
5134              if (transformer == null || reducer == null)
5135                  throw new NullPointerException();
5136              return new MapReduceValuesToIntTask<K,V>
5137 <                (map, transformer, basis, reducer);
5137 >                (map, null, -1, null, transformer, basis, reducer);
5138          }
5139  
5140          /**
# Line 4658 | Line 5148 | public class ConcurrentHashMapV8<K, V>
5148              (ConcurrentHashMapV8<K,V> map,
5149               Action<Map.Entry<K,V>> action) {
5150              if (action == null) throw new NullPointerException();
5151 <            return new ForEachEntryTask<K,V>(map, action);
5151 >            return new ForEachEntryTask<K,V>(map, null, -1, null, action);
5152          }
5153  
5154          /**
# Line 4667 | Line 5157 | public class ConcurrentHashMapV8<K, V>
5157           *
5158           * @param map the map
5159           * @param transformer a function returning the transformation
5160 <         * for an element, or null of there is no transformation (in
5161 <         * which case the action is not applied).
5160 >         * for an element, or null if there is no transformation (in
5161 >         * which case the action is not applied)
5162           * @param action the action
5163           */
5164          public static <K,V,U> ForkJoinTask<Void> forEachEntry
# Line 4678 | Line 5168 | public class ConcurrentHashMapV8<K, V>
5168              if (transformer == null || action == null)
5169                  throw new NullPointerException();
5170              return new ForEachTransformedEntryTask<K,V,U>
5171 <                (map, transformer, action);
5171 >                (map, null, -1, null, transformer, action);
5172          }
5173  
5174          /**
# Line 4692 | Line 5182 | public class ConcurrentHashMapV8<K, V>
5182           * @param searchFunction a function returning a non-null
5183           * result on success, else null
5184           * @return the task
4695         *
5185           */
5186          public static <K,V,U> ForkJoinTask<U> searchEntries
5187              (ConcurrentHashMapV8<K,V> map,
5188               Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
5189              if (searchFunction == null) throw new NullPointerException();
5190              return new SearchEntriesTask<K,V,U>
5191 <                (map, searchFunction,
5191 >                (map, null, -1, null, searchFunction,
5192                   new AtomicReference<U>());
5193          }
5194  
# Line 4717 | Line 5206 | public class ConcurrentHashMapV8<K, V>
5206               BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5207              if (reducer == null) throw new NullPointerException();
5208              return new ReduceEntriesTask<K,V>
5209 <                (map, reducer);
5209 >                (map, null, -1, null, reducer);
5210          }
5211  
5212          /**
# Line 4727 | Line 5216 | public class ConcurrentHashMapV8<K, V>
5216           *
5217           * @param map the map
5218           * @param transformer a function returning the transformation
5219 <         * for an element, or null of there is no transformation (in
5219 >         * for an element, or null if there is no transformation (in
5220           * which case it is not combined).
5221           * @param reducer a commutative associative combining function
5222           * @return the task
# Line 4739 | Line 5228 | public class ConcurrentHashMapV8<K, V>
5228              if (transformer == null || reducer == null)
5229                  throw new NullPointerException();
5230              return new MapReduceEntriesTask<K,V,U>
5231 <                (map, transformer, reducer);
5231 >                (map, null, -1, null, transformer, reducer);
5232          }
5233  
5234          /**
# Line 4763 | Line 5252 | public class ConcurrentHashMapV8<K, V>
5252              if (transformer == null || reducer == null)
5253                  throw new NullPointerException();
5254              return new MapReduceEntriesToDoubleTask<K,V>
5255 <                (map, transformer, basis, reducer);
5255 >                (map, null, -1, null, transformer, basis, reducer);
5256          }
5257  
5258          /**
# Line 4787 | Line 5276 | public class ConcurrentHashMapV8<K, V>
5276              if (transformer == null || reducer == null)
5277                  throw new NullPointerException();
5278              return new MapReduceEntriesToLongTask<K,V>
5279 <                (map, transformer, basis, reducer);
5279 >                (map, null, -1, null, transformer, basis, reducer);
5280          }
5281  
5282          /**
# Line 4811 | Line 5300 | public class ConcurrentHashMapV8<K, V>
5300              if (transformer == null || reducer == null)
5301                  throw new NullPointerException();
5302              return new MapReduceEntriesToIntTask<K,V>
5303 <                (map, transformer, basis, reducer);
5303 >                (map, null, -1, null, transformer, basis, reducer);
5304          }
5305      }
5306  
# Line 4828 | Line 5317 | public class ConcurrentHashMapV8<K, V>
5317       * exceptions are handled in a simpler manner, by just trying to
5318       * complete root task exceptionally.
5319       */
5320 <    @SuppressWarnings("serial")
4832 <    static abstract class BulkTask<K,V,R> extends Traverser<K,V,R> {
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
5322 >        int batch;                     // split control; -1 for unknown
5323          int pending;                   // completion control
5324  
5325 <        /** Constructor for root tasks */
5326 <        BulkTask(ConcurrentHashMapV8<K,V> map) {
5325 >        BulkTask(ConcurrentHashMapV8<K,V> map, BulkTask<K,V,?> parent,
5326 >                 int batch) {
5327              super(map);
4840            this.parent = null;
4841            this.batch = -1; // force call to batch() on execution
4842        }
4843
4844        /** Constructor for subtasks */
4845        BulkTask(BulkTask<K,V,?> parent, int batch, boolean split) {
4846            super(parent, split);
5328              this.parent = parent;
5329              this.batch = batch;
5330 <        }
5331 <
5332 <        // FJ methods
5333 <
5334 <        /**
5335 <         * Propagates completion. Note that all reduce actions
5336 <         * bypass this method to combine while completing.
5337 <         */
5338 <        final void tryComplete() {
5339 <            BulkTask<K,V,?> a = this, s = a;
4859 <            for (int c;;) {
4860 <                if ((c = a.pending) == 0) {
4861 <                    if ((a = (s = a).parent) == null) {
4862 <                        s.quietlyComplete();
4863 <                        break;
4864 <                    }
4865 <                }
4866 <                else if (U.compareAndSwapInt(a, PENDING, c, c - 1))
4867 <                    break;
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 throw exception unless already complete.
5344 >         * Forces root task to complete.
5345 >         * @param ex if null, complete normally, else exceptionally
5346 >         * @return false to simplify use
5347           */
5348 <        final void tryAbortComputation(Throwable ex) {
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 <                    a.completeExceptionally(ex);
5353 <                    break;
5352 >                    if (ex != null)
5353 >                        a.completeExceptionally(ex);
5354 >                    else
5355 >                        a.quietlyComplete();
5356 >                    return false;
5357                  }
5358                  a = p;
5359              }
5360          }
5361  
5362 <        public final boolean exec() {
5363 <            try {
5364 <                compute();
5365 <            }
5366 <            catch (Throwable ex) {
4890 <                tryAbortComputation(ex);
4891 <            }
4892 <            return false;
5362 >        /**
5363 >         * Version of tryCompleteComputation for function screening checks
5364 >         */
5365 >        final boolean abortOnNullFunction() {
5366 >            return tryCompleteComputation(new Error("Unexpected null function"));
5367          }
5368  
4895        public abstract void compute();
4896
5369          // utilities
5370  
5371          /** CompareAndSet pending count */
# Line 4909 | Line 5381 | public class ConcurrentHashMapV8<K, V>
5381           * dividing by two anyway.
5382           */
5383          final int batch() {
5384 <            int b = batch;
5385 <            if (b < 0) {
5386 <                long n = map.counter.sum();
5387 <                int sp = getPool().getParallelism() << 3; // slack of 8
5388 <                b = batch = (n <= 0L) ? 0 : (n < (long)sp) ? (int)n : sp;
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          /**
4922         * Error message for hoisted null checks of functions
4923         */
4924        static final String NullFunctionMessage =
4925            "Unexpected null function";
4926
4927        /**
5401           * Returns exportable snapshot entry.
5402           */
5403          static <K,V> AbstractMap.SimpleEntry<K,V> entryFor(K k, V v) {
# Line 4945 | Line 5418 | public class ConcurrentHashMapV8<K, V>
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 +
5465      /*
5466       * Task classes. Coded in a regular but ugly format/style to
5467       * simplify checks that each variant differs in the right way from
5468       * others.
5469       */
5470  
5471 <    @SuppressWarnings("serial")
5472 <    static final class ForEachKeyTask<K,V>
4956 <        extends BulkTask<K,V,Void> {
5471 >    @SuppressWarnings("serial") static final class ForEachKeyTask<K,V>
5472 >        extends BulkAction<K,V,Void> {
5473          final Action<K> action;
5474          ForEachKeyTask
5475 <            (ConcurrentHashMapV8<K,V> m,
5476 <             Action<K> action) {
4961 <            super(m);
4962 <            this.action = action;
4963 <        }
4964 <        ForEachKeyTask
4965 <            (BulkTask<K,V,?> p, int b, boolean split,
5475 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5476 >             ForEachKeyTask<K,V> nextTask,
5477               Action<K> action) {
5478 <            super(p, b, split);
5478 >            super(m, p, b, nextTask);
5479              this.action = action;
5480          }
5481 <        @SuppressWarnings("unchecked") public final void compute() {
5481 >        @SuppressWarnings("unchecked") public final boolean exec() {
5482              final Action<K> action = this.action;
5483              if (action == null)
5484 <                throw new Error(NullFunctionMessage);
5485 <            int b = batch(), c;
5486 <            while (b > 1 && baseIndex != baseLimit) {
5487 <                do {} while (!casPending(c = pending, c+1));
5488 <                new ForEachKeyTask<K,V>(this, b >>>= 1, true, action).fork();
5484 >                return abortOnNullFunction();
5485 >            ForEachKeyTask<K,V> subtasks = null;
5486 >            try {
5487 >                int b = batch(), c;
5488 >                while (b > 1 && baseIndex != baseLimit) {
5489 >                    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 <            while (advance() != null)
5499 <                action.apply((K)nextKey);
4981 <            tryComplete();
5498 >            tryComplete(subtasks);
5499 >            return false;
5500          }
5501      }
5502  
5503 <    @SuppressWarnings("serial")
5504 <    static final class ForEachValueTask<K,V>
4987 <        extends BulkTask<K,V,Void> {
5503 >    @SuppressWarnings("serial") static final class ForEachValueTask<K,V>
5504 >        extends BulkAction<K,V,Void> {
5505          final Action<V> action;
5506          ForEachValueTask
5507 <            (ConcurrentHashMapV8<K,V> m,
5507 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5508 >             ForEachValueTask<K,V> nextTask,
5509               Action<V> action) {
5510 <            super(m);
5510 >            super(m, p, b, nextTask);
5511              this.action = action;
5512          }
5513 <        ForEachValueTask
4996 <            (BulkTask<K,V,?> p, int b, boolean split,
4997 <             Action<V> action) {
4998 <            super(p, b, split);
4999 <            this.action = action;
5000 <        }
5001 <        @SuppressWarnings("unchecked") public final void compute() {
5513 >        @SuppressWarnings("unchecked") public final boolean exec() {
5514              final Action<V> action = this.action;
5515              if (action == null)
5516 <                throw new Error(NullFunctionMessage);
5517 <            int b = batch(), c;
5518 <            while (b > 1 && baseIndex != baseLimit) {
5519 <                do {} while (!casPending(c = pending, c+1));
5520 <                new ForEachValueTask<K,V>(this, b >>>= 1, true, action).fork();
5516 >                return abortOnNullFunction();
5517 >            ForEachValueTask<K,V> subtasks = null;
5518 >            try {
5519 >                int b = batch(), c;
5520 >                while (b > 1 && baseIndex != baseLimit) {
5521 >                    do {} while (!casPending(c = pending, c+1));
5522 >                    (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 <            Object v;
5532 <            while ((v = advance()) != null)
5012 <                action.apply((V)v);
5013 <            tryComplete();
5531 >            tryComplete(subtasks);
5532 >            return false;
5533          }
5534      }
5535  
5536 <    @SuppressWarnings("serial")
5537 <    static final class ForEachEntryTask<K,V>
5019 <        extends BulkTask<K,V,Void> {
5536 >    @SuppressWarnings("serial") static final class ForEachEntryTask<K,V>
5537 >        extends BulkAction<K,V,Void> {
5538          final Action<Entry<K,V>> action;
5539          ForEachEntryTask
5540 <            (ConcurrentHashMapV8<K,V> m,
5540 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5541 >             ForEachEntryTask<K,V> nextTask,
5542               Action<Entry<K,V>> action) {
5543 <            super(m);
5543 >            super(m, p, b, nextTask);
5544              this.action = action;
5545          }
5546 <        ForEachEntryTask
5028 <            (BulkTask<K,V,?> p, int b, boolean split,
5029 <             Action<Entry<K,V>> action) {
5030 <            super(p, b, split);
5031 <            this.action = action;
5032 <        }
5033 <        @SuppressWarnings("unchecked") public final void compute() {
5546 >        @SuppressWarnings("unchecked") public final boolean exec() {
5547              final Action<Entry<K,V>> action = this.action;
5548              if (action == null)
5549 <                throw new Error(NullFunctionMessage);
5550 <            int b = batch(), c;
5551 <            while (b > 1 && baseIndex != baseLimit) {
5552 <                do {} while (!casPending(c = pending, c+1));
5553 <                new ForEachEntryTask<K,V>(this, b >>>= 1, true, action).fork();
5549 >                return abortOnNullFunction();
5550 >            ForEachEntryTask<K,V> subtasks = null;
5551 >            try {
5552 >                int b = batch(), c;
5553 >                while (b > 1 && baseIndex != baseLimit) {
5554 >                    do {} while (!casPending(c = pending, c+1));
5555 >                    (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 <            Object v;
5565 <            while ((v = advance()) != null)
5044 <                action.apply(entryFor((K)nextKey, (V)v));
5045 <            tryComplete();
5564 >            tryComplete(subtasks);
5565 >            return false;
5566          }
5567      }
5568  
5569 <    @SuppressWarnings("serial")
5570 <    static final class ForEachMappingTask<K,V>
5051 <        extends BulkTask<K,V,Void> {
5569 >    @SuppressWarnings("serial") static final class ForEachMappingTask<K,V>
5570 >        extends BulkAction<K,V,Void> {
5571          final BiAction<K,V> action;
5572          ForEachMappingTask
5573 <            (ConcurrentHashMapV8<K,V> m,
5574 <             BiAction<K,V> action) {
5056 <            super(m);
5057 <            this.action = action;
5058 <        }
5059 <        ForEachMappingTask
5060 <            (BulkTask<K,V,?> p, int b, boolean split,
5573 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5574 >             ForEachMappingTask<K,V> nextTask,
5575               BiAction<K,V> action) {
5576 <            super(p, b, split);
5576 >            super(m, p, b, nextTask);
5577              this.action = action;
5578          }
5579 <
5066 <        @SuppressWarnings("unchecked") public final void compute() {
5579 >        @SuppressWarnings("unchecked") public final boolean exec() {
5580              final BiAction<K,V> action = this.action;
5581              if (action == null)
5582 <                throw new Error(NullFunctionMessage);
5583 <            int b = batch(), c;
5584 <            while (b > 1 && baseIndex != baseLimit) {
5585 <                do {} while (!casPending(c = pending, c+1));
5586 <                new ForEachMappingTask<K,V>(this, b >>>= 1, true,
5587 <                                            action).fork();
5582 >                return abortOnNullFunction();
5583 >            ForEachMappingTask<K,V> subtasks = null;
5584 >            try {
5585 >                int b = batch(), c;
5586 >                while (b > 1 && baseIndex != baseLimit) {
5587 >                    do {} while (!casPending(c = pending, c+1));
5588 >                    (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 <            Object v;
5598 <            while ((v = advance()) != null)
5078 <                action.apply((K)nextKey, (V)v);
5079 <            tryComplete();
5597 >            tryComplete(subtasks);
5598 >            return false;
5599          }
5600      }
5601  
5602 <    @SuppressWarnings("serial")
5603 <    static final class ForEachTransformedKeyTask<K,V,U>
5085 <        extends BulkTask<K,V,Void> {
5602 >    @SuppressWarnings("serial") static final class ForEachTransformedKeyTask<K,V,U>
5603 >        extends BulkAction<K,V,Void> {
5604          final Fun<? super K, ? extends U> transformer;
5605          final Action<U> action;
5606          ForEachTransformedKeyTask
5607 <            (ConcurrentHashMapV8<K,V> m,
5607 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5608 >             ForEachTransformedKeyTask<K,V,U> nextTask,
5609               Fun<? super K, ? extends U> transformer,
5610               Action<U> action) {
5611 <            super(m);
5611 >            super(m, p, b, nextTask);
5612              this.transformer = transformer;
5613              this.action = action;
5614  
5615          }
5616 <        ForEachTransformedKeyTask
5098 <            (BulkTask<K,V,?> p, int b, boolean split,
5099 <             Fun<? super K, ? extends U> transformer,
5100 <             Action<U> action) {
5101 <            super(p, b, split);
5102 <            this.transformer = transformer;
5103 <            this.action = action;
5104 <        }
5105 <        @SuppressWarnings("unchecked") public final void compute() {
5616 >        @SuppressWarnings("unchecked") public final boolean exec() {
5617              final Fun<? super K, ? extends U> transformer =
5618                  this.transformer;
5619              final Action<U> action = this.action;
5620              if (transformer == null || action == null)
5621 <                throw new Error(NullFunctionMessage);
5622 <            int b = batch(), c;
5623 <            while (b > 1 && baseIndex != baseLimit) {
5624 <                do {} while (!casPending(c = pending, c+1));
5625 <                new ForEachTransformedKeyTask<K,V,U>
5626 <                    (this, b >>>= 1, true, transformer, action).fork();
5627 <            }
5628 <            U u;
5629 <            while (advance() != null) {
5630 <                if ((u = transformer.apply((K)nextKey)) != null)
5631 <                    action.apply(u);
5621 >                return abortOnNullFunction();
5622 >            ForEachTransformedKeyTask<K,V,U> subtasks = null;
5623 >            try {
5624 >                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);
5637              }
5638 <            tryComplete();
5638 >            tryComplete(subtasks);
5639 >            return false;
5640          }
5641      }
5642  
5643 <    @SuppressWarnings("serial")
5644 <    static final class ForEachTransformedValueTask<K,V,U>
5128 <        extends BulkTask<K,V,Void> {
5643 >    @SuppressWarnings("serial") static final class ForEachTransformedValueTask<K,V,U>
5644 >        extends BulkAction<K,V,Void> {
5645          final Fun<? super V, ? extends U> transformer;
5646          final Action<U> action;
5647          ForEachTransformedValueTask
5648 <            (ConcurrentHashMapV8<K,V> m,
5648 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5649 >             ForEachTransformedValueTask<K,V,U> nextTask,
5650               Fun<? super V, ? extends U> transformer,
5651               Action<U> action) {
5652 <            super(m);
5652 >            super(m, p, b, nextTask);
5653              this.transformer = transformer;
5654              this.action = action;
5655  
5656          }
5657 <        ForEachTransformedValueTask
5141 <            (BulkTask<K,V,?> p, int b, boolean split,
5142 <             Fun<? super V, ? extends U> transformer,
5143 <             Action<U> action) {
5144 <            super(p, b, split);
5145 <            this.transformer = transformer;
5146 <            this.action = action;
5147 <        }
5148 <        @SuppressWarnings("unchecked") public final void compute() {
5657 >        @SuppressWarnings("unchecked") public final boolean exec() {
5658              final Fun<? super V, ? extends U> transformer =
5659                  this.transformer;
5660              final Action<U> action = this.action;
5661              if (transformer == null || action == null)
5662 <                throw new Error(NullFunctionMessage);
5663 <            int b = batch(), c;
5664 <            while (b > 1 && baseIndex != baseLimit) {
5665 <                do {} while (!casPending(c = pending, c+1));
5666 <                new ForEachTransformedValueTask<K,V,U>
5667 <                    (this, b >>>= 1, true, transformer, action).fork();
5668 <            }
5669 <            Object v; U u;
5670 <            while ((v = advance()) != null) {
5671 <                if ((u = transformer.apply((V)v)) != null)
5672 <                    action.apply(u);
5662 >                return abortOnNullFunction();
5663 >            ForEachTransformedValueTask<K,V,U> subtasks = null;
5664 >            try {
5665 >                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);
5678              }
5679 <            tryComplete();
5679 >            tryComplete(subtasks);
5680 >            return false;
5681          }
5682      }
5683  
5684 <    @SuppressWarnings("serial")
5685 <    static final class ForEachTransformedEntryTask<K,V,U>
5171 <        extends BulkTask<K,V,Void> {
5684 >    @SuppressWarnings("serial") static final class ForEachTransformedEntryTask<K,V,U>
5685 >        extends BulkAction<K,V,Void> {
5686          final Fun<Map.Entry<K,V>, ? extends U> transformer;
5687          final Action<U> action;
5688          ForEachTransformedEntryTask
5689 <            (ConcurrentHashMapV8<K,V> m,
5689 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5690 >             ForEachTransformedEntryTask<K,V,U> nextTask,
5691               Fun<Map.Entry<K,V>, ? extends U> transformer,
5692               Action<U> action) {
5693 <            super(m);
5693 >            super(m, p, b, nextTask);
5694              this.transformer = transformer;
5695              this.action = action;
5696  
5697          }
5698 <        ForEachTransformedEntryTask
5184 <            (BulkTask<K,V,?> p, int b, boolean split,
5185 <             Fun<Map.Entry<K,V>, ? extends U> transformer,
5186 <             Action<U> action) {
5187 <            super(p, b, split);
5188 <            this.transformer = transformer;
5189 <            this.action = action;
5190 <        }
5191 <        @SuppressWarnings("unchecked") public final void compute() {
5698 >        @SuppressWarnings("unchecked") public final boolean exec() {
5699              final Fun<Map.Entry<K,V>, ? extends U> transformer =
5700                  this.transformer;
5701              final Action<U> action = this.action;
5702              if (transformer == null || action == null)
5703 <                throw new Error(NullFunctionMessage);
5704 <            int b = batch(), c;
5705 <            while (b > 1 && baseIndex != baseLimit) {
5706 <                do {} while (!casPending(c = pending, c+1));
5707 <                new ForEachTransformedEntryTask<K,V,U>
5708 <                    (this, b >>>= 1, true, transformer, action).fork();
5709 <            }
5710 <            Object v; U u;
5711 <            while ((v = advance()) != null) {
5712 <                if ((u = transformer.apply(entryFor((K)nextKey, (V)v))) != null)
5713 <                    action.apply(u);
5703 >                return abortOnNullFunction();
5704 >            ForEachTransformedEntryTask<K,V,U> subtasks = null;
5705 >            try {
5706 >                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);
5719              }
5720 <            tryComplete();
5720 >            tryComplete(subtasks);
5721 >            return false;
5722          }
5723      }
5724  
5725 <    @SuppressWarnings("serial")
5726 <    static final class ForEachTransformedMappingTask<K,V,U>
5214 <        extends BulkTask<K,V,Void> {
5725 >    @SuppressWarnings("serial") static final class ForEachTransformedMappingTask<K,V,U>
5726 >        extends BulkAction<K,V,Void> {
5727          final BiFun<? super K, ? super V, ? extends U> transformer;
5728          final Action<U> action;
5729          ForEachTransformedMappingTask
5730 <            (ConcurrentHashMapV8<K,V> m,
5730 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5731 >             ForEachTransformedMappingTask<K,V,U> nextTask,
5732               BiFun<? super K, ? super V, ? extends U> transformer,
5733               Action<U> action) {
5734 <            super(m);
5734 >            super(m, p, b, nextTask);
5735              this.transformer = transformer;
5736              this.action = action;
5737  
5738          }
5739 <        ForEachTransformedMappingTask
5227 <            (BulkTask<K,V,?> p, int b, boolean split,
5228 <             BiFun<? super K, ? super V, ? extends U> transformer,
5229 <             Action<U> action) {
5230 <            super(p, b, split);
5231 <            this.transformer = transformer;
5232 <            this.action = action;
5233 <        }
5234 <        @SuppressWarnings("unchecked") public final void compute() {
5739 >        @SuppressWarnings("unchecked") public final boolean exec() {
5740              final BiFun<? super K, ? super V, ? extends U> transformer =
5741                  this.transformer;
5742              final Action<U> action = this.action;
5743              if (transformer == null || action == null)
5744 <                throw new Error(NullFunctionMessage);
5745 <            int b = batch(), c;
5746 <            while (b > 1 && baseIndex != baseLimit) {
5747 <                do {} while (!casPending(c = pending, c+1));
5748 <                new ForEachTransformedMappingTask<K,V,U>
5749 <                    (this, b >>>= 1, true, transformer, action).fork();
5750 <            }
5751 <            Object v; U u;
5752 <            while ((v = advance()) != null) {
5753 <                if ((u = transformer.apply((K)nextKey, (V)v)) != null)
5754 <                    action.apply(u);
5744 >                return abortOnNullFunction();
5745 >            ForEachTransformedMappingTask<K,V,U> subtasks = null;
5746 >            try {
5747 >                int b = batch(), c;
5748 >                while (b > 1 && baseIndex != baseLimit) {
5749 >                    do {} while (!casPending(c = pending, c+1));
5750 >                    (subtasks = new ForEachTransformedMappingTask<K,V,U>
5751 >                     (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);
5760              }
5761 <            tryComplete();
5761 >            tryComplete(subtasks);
5762 >            return false;
5763          }
5764      }
5765  
5766 <    @SuppressWarnings("serial")
5767 <    static final class SearchKeysTask<K,V,U>
5257 <        extends BulkTask<K,V,U> {
5766 >    @SuppressWarnings("serial") static final class SearchKeysTask<K,V,U>
5767 >        extends BulkAction<K,V,U> {
5768          final Fun<? super K, ? extends U> searchFunction;
5769          final AtomicReference<U> result;
5770          SearchKeysTask
5771 <            (ConcurrentHashMapV8<K,V> m,
5771 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5772 >             SearchKeysTask<K,V,U> nextTask,
5773               Fun<? super K, ? extends U> searchFunction,
5774               AtomicReference<U> result) {
5775 <            super(m);
5775 >            super(m, p, b, nextTask);
5776              this.searchFunction = searchFunction; this.result = result;
5777          }
5778 <        SearchKeysTask
5268 <            (BulkTask<K,V,?> p, int b, boolean split,
5269 <             Fun<? super K, ? extends U> searchFunction,
5270 <             AtomicReference<U> result) {
5271 <            super(p, b, split);
5272 <            this.searchFunction = searchFunction; this.result = result;
5273 <        }
5274 <        @SuppressWarnings("unchecked") public final void compute() {
5778 >        @SuppressWarnings("unchecked") public final boolean exec() {
5779              AtomicReference<U> result = this.result;
5780              final Fun<? super K, ? extends U> searchFunction =
5781                  this.searchFunction;
5782              if (searchFunction == null || result == null)
5783 <                throw new Error(NullFunctionMessage);
5784 <            int b = batch(), c;
5785 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5786 <                do {} while (!casPending(c = pending, c+1));
5787 <                new SearchKeysTask<K,V,U>(this, b >>>= 1, true,
5788 <                                          searchFunction, result).fork();
5789 <            }
5790 <            U u;
5791 <            while (result.get() == null && advance() != null) {
5792 <                if ((u = searchFunction.apply((K)nextKey)) != null) {
5793 <                    if (result.compareAndSet(null, u)) {
5794 <                        for (BulkTask<K,V,?> a = this, p;;) {
5795 <                            if ((p = a.parent) == null) {
5796 <                                a.quietlyComplete();
5797 <                                break;
5294 <                            }
5295 <                            a = p;
5296 <                        }
5783 >                return abortOnNullFunction();
5784 >            SearchKeysTask<K,V,U> subtasks = null;
5785 >            try {
5786 >                int b = batch(), c;
5787 >                while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5788 >                    do {} while (!casPending(c = pending, c+1));
5789 >                    (subtasks = new SearchKeysTask<K,V,U>
5790 >                     (map, this, b >>>= 1, subtasks, searchFunction, result)).fork();
5791 >                }
5792 >                U u;
5793 >                while (result.get() == null && advance() != null) {
5794 >                    if ((u = searchFunction.apply((K)nextKey)) != null) {
5795 >                        if (result.compareAndSet(null, u))
5796 >                            tryCompleteComputation(null);
5797 >                        break;
5798                      }
5298                    break;
5799                  }
5800 +            } catch (Throwable ex) {
5801 +                return tryCompleteComputation(ex);
5802              }
5803 <            tryComplete();
5803 >            tryComplete(subtasks);
5804 >            return false;
5805          }
5806          public final U getRawResult() { return result.get(); }
5807      }
5808  
5809 <    @SuppressWarnings("serial")
5810 <    static final class SearchValuesTask<K,V,U>
5308 <        extends BulkTask<K,V,U> {
5809 >    @SuppressWarnings("serial") static final class SearchValuesTask<K,V,U>
5810 >        extends BulkAction<K,V,U> {
5811          final Fun<? super V, ? extends U> searchFunction;
5812          final AtomicReference<U> result;
5813          SearchValuesTask
5814 <            (ConcurrentHashMapV8<K,V> m,
5815 <             Fun<? super V, ? extends U> searchFunction,
5314 <             AtomicReference<U> result) {
5315 <            super(m);
5316 <            this.searchFunction = searchFunction; this.result = result;
5317 <        }
5318 <        SearchValuesTask
5319 <            (BulkTask<K,V,?> p, int b, boolean split,
5814 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5815 >             SearchValuesTask<K,V,U> nextTask,
5816               Fun<? super V, ? extends U> searchFunction,
5817               AtomicReference<U> result) {
5818 <            super(p, b, split);
5818 >            super(m, p, b, nextTask);
5819              this.searchFunction = searchFunction; this.result = result;
5820          }
5821 <        @SuppressWarnings("unchecked") public final void compute() {
5821 >        @SuppressWarnings("unchecked") public final boolean exec() {
5822              AtomicReference<U> result = this.result;
5823              final Fun<? super V, ? extends U> searchFunction =
5824                  this.searchFunction;
5825              if (searchFunction == null || result == null)
5826 <                throw new Error(NullFunctionMessage);
5827 <            int b = batch(), c;
5828 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5829 <                do {} while (!casPending(c = pending, c+1));
5830 <                new SearchValuesTask<K,V,U>(this, b >>>= 1, true,
5831 <                                            searchFunction, result).fork();
5832 <            }
5833 <            Object v; U u;
5834 <            while (result.get() == null && (v = advance()) != null) {
5835 <                if ((u = searchFunction.apply((V)v)) != null) {
5836 <                    if (result.compareAndSet(null, u)) {
5837 <                        for (BulkTask<K,V,?> a = this, p;;) {
5838 <                            if ((p = a.parent) == null) {
5839 <                                a.quietlyComplete();
5840 <                                break;
5345 <                            }
5346 <                            a = p;
5347 <                        }
5826 >                return abortOnNullFunction();
5827 >            SearchValuesTask<K,V,U> subtasks = null;
5828 >            try {
5829 >                int b = batch(), c;
5830 >                while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5831 >                    do {} while (!casPending(c = pending, c+1));
5832 >                    (subtasks = new SearchValuesTask<K,V,U>
5833 >                     (map, this, b >>>= 1, subtasks, searchFunction, result)).fork();
5834 >                }
5835 >                Object v; U u;
5836 >                while (result.get() == null && (v = advance()) != null) {
5837 >                    if ((u = searchFunction.apply((V)v)) != null) {
5838 >                        if (result.compareAndSet(null, u))
5839 >                            tryCompleteComputation(null);
5840 >                        break;
5841                      }
5349                    break;
5842                  }
5843 +            } catch (Throwable ex) {
5844 +                return tryCompleteComputation(ex);
5845              }
5846 <            tryComplete();
5846 >            tryComplete(subtasks);
5847 >            return false;
5848          }
5849          public final U getRawResult() { return result.get(); }
5850      }
5851  
5852 <    @SuppressWarnings("serial")
5853 <    static final class SearchEntriesTask<K,V,U>
5359 <        extends BulkTask<K,V,U> {
5852 >    @SuppressWarnings("serial") static final class SearchEntriesTask<K,V,U>
5853 >        extends BulkAction<K,V,U> {
5854          final Fun<Entry<K,V>, ? extends U> searchFunction;
5855          final AtomicReference<U> result;
5856          SearchEntriesTask
5857 <            (ConcurrentHashMapV8<K,V> m,
5858 <             Fun<Entry<K,V>, ? extends U> searchFunction,
5365 <             AtomicReference<U> result) {
5366 <            super(m);
5367 <            this.searchFunction = searchFunction; this.result = result;
5368 <        }
5369 <        SearchEntriesTask
5370 <            (BulkTask<K,V,?> p, int b, boolean split,
5857 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5858 >             SearchEntriesTask<K,V,U> nextTask,
5859               Fun<Entry<K,V>, ? extends U> searchFunction,
5860               AtomicReference<U> result) {
5861 <            super(p, b, split);
5861 >            super(m, p, b, nextTask);
5862              this.searchFunction = searchFunction; this.result = result;
5863          }
5864 <        @SuppressWarnings("unchecked") public final void compute() {
5864 >        @SuppressWarnings("unchecked") public final boolean exec() {
5865              AtomicReference<U> result = this.result;
5866              final Fun<Entry<K,V>, ? extends U> searchFunction =
5867                  this.searchFunction;
5868              if (searchFunction == null || result == null)
5869 <                throw new Error(NullFunctionMessage);
5870 <            int b = batch(), c;
5871 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5872 <                do {} while (!casPending(c = pending, c+1));
5873 <                new SearchEntriesTask<K,V,U>(this, b >>>= 1, true,
5874 <                                             searchFunction, result).fork();
5875 <            }
5876 <            Object v; U u;
5877 <            while (result.get() == null && (v = advance()) != null) {
5878 <                if ((u = searchFunction.apply(entryFor((K)nextKey, (V)v))) != null) {
5879 <                    if (result.compareAndSet(null, u)) {
5880 <                        for (BulkTask<K,V,?> a = this, p;;) {
5881 <                            if ((p = a.parent) == null) {
5882 <                                a.quietlyComplete();
5883 <                                break;
5396 <                            }
5397 <                            a = p;
5398 <                        }
5869 >                return abortOnNullFunction();
5870 >            SearchEntriesTask<K,V,U> subtasks = null;
5871 >            try {
5872 >                int b = batch(), c;
5873 >                while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5874 >                    do {} while (!casPending(c = pending, c+1));
5875 >                    (subtasks = new SearchEntriesTask<K,V,U>
5876 >                     (map, this, b >>>= 1, subtasks, searchFunction, result)).fork();
5877 >                }
5878 >                Object v; U u;
5879 >                while (result.get() == null && (v = advance()) != null) {
5880 >                    if ((u = searchFunction.apply(entryFor((K)nextKey, (V)v))) != null) {
5881 >                        if (result.compareAndSet(null, u))
5882 >                            tryCompleteComputation(null);
5883 >                        break;
5884                      }
5400                    break;
5885                  }
5886 +            } catch (Throwable ex) {
5887 +                return tryCompleteComputation(ex);
5888              }
5889 <            tryComplete();
5889 >            tryComplete(subtasks);
5890 >            return false;
5891          }
5892          public final U getRawResult() { return result.get(); }
5893      }
5894  
5895 <    @SuppressWarnings("serial")
5896 <    static final class SearchMappingsTask<K,V,U>
5410 <        extends BulkTask<K,V,U> {
5895 >    @SuppressWarnings("serial") static final class SearchMappingsTask<K,V,U>
5896 >        extends BulkAction<K,V,U> {
5897          final BiFun<? super K, ? super V, ? extends U> searchFunction;
5898          final AtomicReference<U> result;
5899          SearchMappingsTask
5900 <            (ConcurrentHashMapV8<K,V> m,
5900 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5901 >             SearchMappingsTask<K,V,U> nextTask,
5902               BiFun<? super K, ? super V, ? extends U> searchFunction,
5903               AtomicReference<U> result) {
5904 <            super(m);
5904 >            super(m, p, b, nextTask);
5905              this.searchFunction = searchFunction; this.result = result;
5906          }
5907 <        SearchMappingsTask
5421 <            (BulkTask<K,V,?> p, int b, boolean split,
5422 <             BiFun<? super K, ? super V, ? extends U> searchFunction,
5423 <             AtomicReference<U> result) {
5424 <            super(p, b, split);
5425 <            this.searchFunction = searchFunction; this.result = result;
5426 <        }
5427 <        @SuppressWarnings("unchecked") public final void compute() {
5907 >        @SuppressWarnings("unchecked") public final boolean exec() {
5908              AtomicReference<U> result = this.result;
5909              final BiFun<? super K, ? super V, ? extends U> searchFunction =
5910                  this.searchFunction;
5911              if (searchFunction == null || result == null)
5912 <                throw new Error(NullFunctionMessage);
5913 <            int b = batch(), c;
5914 <            while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5915 <                do {} while (!casPending(c = pending, c+1));
5916 <                new SearchMappingsTask<K,V,U>(this, b >>>= 1, true,
5917 <                                              searchFunction, result).fork();
5918 <            }
5919 <            Object v; U u;
5920 <            while (result.get() == null && (v = advance()) != null) {
5921 <                if ((u = searchFunction.apply((K)nextKey, (V)v)) != null) {
5922 <                    if (result.compareAndSet(null, u)) {
5923 <                        for (BulkTask<K,V,?> a = this, p;;) {
5924 <                            if ((p = a.parent) == null) {
5925 <                                a.quietlyComplete();
5926 <                                break;
5447 <                            }
5448 <                            a = p;
5449 <                        }
5912 >                return abortOnNullFunction();
5913 >            SearchMappingsTask<K,V,U> subtasks = null;
5914 >            try {
5915 >                int b = batch(), c;
5916 >                while (b > 1 && baseIndex != baseLimit && result.get() == null) {
5917 >                    do {} while (!casPending(c = pending, c+1));
5918 >                    (subtasks = new SearchMappingsTask<K,V,U>
5919 >                     (map, this, b >>>= 1, subtasks, searchFunction, result)).fork();
5920 >                }
5921 >                Object v; U u;
5922 >                while (result.get() == null && (v = advance()) != null) {
5923 >                    if ((u = searchFunction.apply((K)nextKey, (V)v)) != null) {
5924 >                        if (result.compareAndSet(null, u))
5925 >                            tryCompleteComputation(null);
5926 >                        break;
5927                      }
5451                    break;
5928                  }
5929 +            } catch (Throwable ex) {
5930 +                return tryCompleteComputation(ex);
5931              }
5932 <            tryComplete();
5932 >            tryComplete(subtasks);
5933 >            return false;
5934          }
5935          public final U getRawResult() { return result.get(); }
5936      }
5937  
5938 <    @SuppressWarnings("serial")
5460 <    static final class ReduceKeysTask<K,V>
5938 >    @SuppressWarnings("serial") static final class ReduceKeysTask<K,V>
5939          extends BulkTask<K,V,K> {
5940          final BiFun<? super K, ? super K, ? extends K> reducer;
5941          K result;
5942 <        ReduceKeysTask<K,V> sibling;
5942 >        ReduceKeysTask<K,V> rights, nextRight;
5943          ReduceKeysTask
5944 <            (ConcurrentHashMapV8<K,V> m,
5944 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
5945 >             ReduceKeysTask<K,V> nextRight,
5946               BiFun<? super K, ? super K, ? extends K> reducer) {
5947 <            super(m);
5947 >            super(m, p, b); this.nextRight = nextRight;
5948              this.reducer = reducer;
5949          }
5950 <        ReduceKeysTask
5472 <            (BulkTask<K,V,?> p, int b, boolean split,
5473 <             BiFun<? super K, ? super K, ? extends K> reducer) {
5474 <            super(p, b, split);
5475 <            this.reducer = reducer;
5476 <        }
5477 <
5478 <        @SuppressWarnings("unchecked") public final void compute() {
5479 <            ReduceKeysTask<K,V> t = this;
5950 >        @SuppressWarnings("unchecked") public final boolean exec() {
5951              final BiFun<? super K, ? super K, ? extends K> reducer =
5952                  this.reducer;
5953              if (reducer == null)
5954 <                throw new Error(NullFunctionMessage);
5955 <            int b = batch();
5956 <            while (b > 1 && t.baseIndex != t.baseLimit) {
5957 <                b >>>= 1;
5958 <                t.pending = 1;
5959 <                ReduceKeysTask<K,V> rt =
5960 <                    new ReduceKeysTask<K,V>
5961 <                    (t, b, true, reducer);
5962 <                t = new ReduceKeysTask<K,V>
5963 <                    (t, b, false, reducer);
5964 <                t.sibling = rt;
5494 <                rt.sibling = t;
5495 <                rt.fork();
5496 <            }
5497 <            K r = null;
5498 <            while (t.advance() != null) {
5499 <                K u = (K)t.nextKey;
5500 <                r = (r == null) ? u : reducer.apply(r, u);
5501 <            }
5502 <            t.result = r;
5503 <            for (;;) {
5504 <                int c; BulkTask<K,V,?> par; ReduceKeysTask<K,V> s, p; K u;
5505 <                if ((par = t.parent) == null ||
5506 <                    !(par instanceof ReduceKeysTask)) {
5507 <                    t.quietlyComplete();
5508 <                    break;
5954 >                return abortOnNullFunction();
5955 >            try {
5956 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
5957 >                    do {} while (!casPending(c = pending, c+1));
5958 >                    (rights = new ReduceKeysTask<K,V>
5959 >                     (map, this, b >>>= 1, rights, reducer)).fork();
5960 >                }
5961 >                K r = null;
5962 >                while (advance() != null) {
5963 >                    K u = (K)nextKey;
5964 >                    r = (r == null) ? u : reducer.apply(r, u);
5965                  }
5966 <                else if ((c = (p = (ReduceKeysTask<K,V>)par).pending) == 0) {
5967 <                    if ((s = t.sibling) != null && (u = s.result) != null)
5968 <                        r = (r == null) ? u : reducer.apply(r, u);
5969 <                    (t = p).result = r;
5966 >                result = r;
5967 >                for (ReduceKeysTask<K,V> t = this, s;;) {
5968 >                    int c; BulkTask<K,V,?> par; K tr, sr;
5969 >                    if ((c = t.pending) == 0) {
5970 >                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
5971 >                            if ((sr = s.result) != null)
5972 >                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
5973 >                        }
5974 >                        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;
5983                  }
5984 <                else if (p.casPending(c, 0))
5985 <                    break;
5984 >            } catch (Throwable ex) {
5985 >                return tryCompleteComputation(ex);
5986              }
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;
5995          }
5996          public final K getRawResult() { return result; }
5997      }
5998  
5999 <    @SuppressWarnings("serial")
5523 <    static final class ReduceValuesTask<K,V>
5999 >    @SuppressWarnings("serial") static final class ReduceValuesTask<K,V>
6000          extends BulkTask<K,V,V> {
6001          final BiFun<? super V, ? super V, ? extends V> reducer;
6002          V result;
6003 <        ReduceValuesTask<K,V> sibling;
6003 >        ReduceValuesTask<K,V> rights, nextRight;
6004          ReduceValuesTask
6005 <            (ConcurrentHashMapV8<K,V> m,
6005 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6006 >             ReduceValuesTask<K,V> nextRight,
6007               BiFun<? super V, ? super V, ? extends V> reducer) {
6008 <            super(m);
6008 >            super(m, p, b); this.nextRight = nextRight;
6009              this.reducer = reducer;
6010          }
6011 <        ReduceValuesTask
5535 <            (BulkTask<K,V,?> p, int b, boolean split,
5536 <             BiFun<? super V, ? super V, ? extends V> reducer) {
5537 <            super(p, b, split);
5538 <            this.reducer = reducer;
5539 <        }
5540 <
5541 <        @SuppressWarnings("unchecked") public final void compute() {
5542 <            ReduceValuesTask<K,V> t = this;
6011 >        @SuppressWarnings("unchecked") public final boolean exec() {
6012              final BiFun<? super V, ? super V, ? extends V> reducer =
6013                  this.reducer;
6014              if (reducer == null)
6015 <                throw new Error(NullFunctionMessage);
6016 <            int b = batch();
6017 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6018 <                b >>>= 1;
6019 <                t.pending = 1;
6020 <                ReduceValuesTask<K,V> rt =
6021 <                    new ReduceValuesTask<K,V>
6022 <                    (t, b, true, reducer);
6023 <                t = new ReduceValuesTask<K,V>
6024 <                    (t, b, false, reducer);
6025 <                t.sibling = rt;
6026 <                rt.sibling = t;
5558 <                rt.fork();
5559 <            }
5560 <            V r = null;
5561 <            Object v;
5562 <            while ((v = t.advance()) != null) {
5563 <                V u = (V)v;
5564 <                r = (r == null) ? u : reducer.apply(r, u);
5565 <            }
5566 <            t.result = r;
5567 <            for (;;) {
5568 <                int c; BulkTask<K,V,?> par; ReduceValuesTask<K,V> s, p; V u;
5569 <                if ((par = t.parent) == null ||
5570 <                    !(par instanceof ReduceValuesTask)) {
5571 <                    t.quietlyComplete();
5572 <                    break;
6015 >                return abortOnNullFunction();
6016 >            try {
6017 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6018 >                    do {} while (!casPending(c = pending, c+1));
6019 >                    (rights = new ReduceValuesTask<K,V>
6020 >                     (map, this, b >>>= 1, rights, reducer)).fork();
6021 >                }
6022 >                V r = null;
6023 >                Object v;
6024 >                while ((v = advance()) != null) {
6025 >                    V u = (V)v;
6026 >                    r = (r == null) ? u : reducer.apply(r, u);
6027                  }
6028 <                else if ((c = (p = (ReduceValuesTask<K,V>)par).pending) == 0) {
6029 <                    if ((s = t.sibling) != null && (u = s.result) != null)
6030 <                        r = (r == null) ? u : reducer.apply(r, u);
6031 <                    (t = p).result = r;
6028 >                result = r;
6029 >                for (ReduceValuesTask<K,V> t = this, s;;) {
6030 >                    int c; BulkTask<K,V,?> par; V tr, sr;
6031 >                    if ((c = t.pending) == 0) {
6032 >                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6033 >                            if ((sr = s.result) != null)
6034 >                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
6035 >                        }
6036 >                        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;
6045                  }
6046 <                else if (p.casPending(c, 0))
6047 <                    break;
6046 >            } catch (Throwable ex) {
6047 >                return tryCompleteComputation(ex);
6048              }
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;
6057          }
6058          public final V getRawResult() { return result; }
6059      }
6060  
6061 <    @SuppressWarnings("serial")
5587 <    static final class ReduceEntriesTask<K,V>
6061 >    @SuppressWarnings("serial") static final class ReduceEntriesTask<K,V>
6062          extends BulkTask<K,V,Map.Entry<K,V>> {
6063          final BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer;
6064          Map.Entry<K,V> result;
6065 <        ReduceEntriesTask<K,V> sibling;
6065 >        ReduceEntriesTask<K,V> rights, nextRight;
6066          ReduceEntriesTask
6067 <            (ConcurrentHashMapV8<K,V> m,
6067 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6068 >             ReduceEntriesTask<K,V> nextRight,
6069               BiFun<Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
6070 <            super(m);
5596 <            this.reducer = reducer;
5597 <        }
5598 <        ReduceEntriesTask
5599 <            (BulkTask<K,V,?> p, int b, boolean split,
5600 <             BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5601 <            super(p, b, split);
6070 >            super(m, p, b); this.nextRight = nextRight;
6071              this.reducer = reducer;
6072          }
6073 <
5605 <        @SuppressWarnings("unchecked") public final void compute() {
5606 <            ReduceEntriesTask<K,V> t = this;
6073 >        @SuppressWarnings("unchecked") public final boolean exec() {
6074              final BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer =
6075                  this.reducer;
6076              if (reducer == null)
6077 <                throw new Error(NullFunctionMessage);
6078 <            int b = batch();
6079 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6080 <                b >>>= 1;
6081 <                t.pending = 1;
6082 <                ReduceEntriesTask<K,V> rt =
6083 <                    new ReduceEntriesTask<K,V>
6084 <                    (t, b, true, reducer);
6085 <                t = new ReduceEntriesTask<K,V>
6086 <                    (t, b, false, reducer);
6087 <                t.sibling = rt;
6088 <                rt.sibling = t;
5622 <                rt.fork();
5623 <            }
5624 <            Map.Entry<K,V> r = null;
5625 <            Object v;
5626 <            while ((v = t.advance()) != null) {
5627 <                Map.Entry<K,V> u = entryFor((K)t.nextKey, (V)v);
5628 <                r = (r == null) ? u : reducer.apply(r, u);
5629 <            }
5630 <            t.result = r;
5631 <            for (;;) {
5632 <                int c; BulkTask<K,V,?> par; ReduceEntriesTask<K,V> s, p;
5633 <                Map.Entry<K,V> u;
5634 <                if ((par = t.parent) == null ||
5635 <                    !(par instanceof ReduceEntriesTask)) {
5636 <                    t.quietlyComplete();
5637 <                    break;
6077 >                return abortOnNullFunction();
6078 >            try {
6079 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6080 >                    do {} while (!casPending(c = pending, c+1));
6081 >                    (rights = new ReduceEntriesTask<K,V>
6082 >                     (map, this, b >>>= 1, rights, reducer)).fork();
6083 >                }
6084 >                Map.Entry<K,V> r = null;
6085 >                Object v;
6086 >                while ((v = advance()) != null) {
6087 >                    Map.Entry<K,V> u = entryFor((K)nextKey, (V)v);
6088 >                    r = (r == null) ? u : reducer.apply(r, u);
6089                  }
6090 <                else if ((c = (p = (ReduceEntriesTask<K,V>)par).pending) == 0) {
6091 <                    if ((s = t.sibling) != null && (u = s.result) != null)
6092 <                        r = (r == null) ? u : reducer.apply(r, u);
6093 <                    (t = p).result = r;
6090 >                result = r;
6091 >                for (ReduceEntriesTask<K,V> t = this, s;;) {
6092 >                    int c; BulkTask<K,V,?> par; Map.Entry<K,V> tr, sr;
6093 >                    if ((c = t.pending) == 0) {
6094 >                        for (s = t.rights; s != null; s = t.rights = s.nextRight) {
6095 >                            if ((sr = s.result) != null)
6096 >                                t.result = ((tr = t.result) == null) ? sr : reducer.apply(tr, sr);
6097 >                        }
6098 >                        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;
6107                  }
6108 <                else if (p.casPending(c, 0))
6109 <                    break;
6108 >            } catch (Throwable ex) {
6109 >                return tryCompleteComputation(ex);
6110 >            }
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;
6119          }
6120          public final Map.Entry<K,V> getRawResult() { return result; }
6121      }
6122  
6123 <    @SuppressWarnings("serial")
5652 <    static final class MapReduceKeysTask<K,V,U>
6123 >    @SuppressWarnings("serial") static final class MapReduceKeysTask<K,V,U>
6124          extends BulkTask<K,V,U> {
6125          final Fun<? super K, ? extends U> transformer;
6126          final BiFun<? super U, ? super U, ? extends U> reducer;
6127          U result;
6128 <        MapReduceKeysTask<K,V,U> sibling;
6128 >        MapReduceKeysTask<K,V,U> rights, nextRight;
6129          MapReduceKeysTask
6130 <            (ConcurrentHashMapV8<K,V> m,
6130 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6131 >             MapReduceKeysTask<K,V,U> nextRight,
6132               Fun<? super K, ? extends U> transformer,
6133               BiFun<? super U, ? super U, ? extends U> reducer) {
6134 <            super(m);
6134 >            super(m, p, b); this.nextRight = nextRight;
6135              this.transformer = transformer;
6136              this.reducer = reducer;
6137          }
6138 <        MapReduceKeysTask
5667 <            (BulkTask<K,V,?> p, int b, boolean split,
5668 <             Fun<? super K, ? extends U> transformer,
5669 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5670 <            super(p, b, split);
5671 <            this.transformer = transformer;
5672 <            this.reducer = reducer;
5673 <        }
5674 <        @SuppressWarnings("unchecked") public final void compute() {
5675 <            MapReduceKeysTask<K,V,U> t = this;
6138 >        @SuppressWarnings("unchecked") public final boolean exec() {
6139              final Fun<? super K, ? extends U> transformer =
6140                  this.transformer;
6141              final BiFun<? super U, ? super U, ? extends U> reducer =
6142                  this.reducer;
6143              if (transformer == null || reducer == null)
6144 <                throw new Error(NullFunctionMessage);
6145 <            int b = batch();
6146 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6147 <                b >>>= 1;
6148 <                t.pending = 1;
6149 <                MapReduceKeysTask<K,V,U> rt =
6150 <                    new MapReduceKeysTask<K,V,U>
6151 <                    (t, b, true, transformer, reducer);
6152 <                t = new MapReduceKeysTask<K,V,U>
6153 <                    (t, b, false, transformer, reducer);
5691 <                t.sibling = rt;
5692 <                rt.sibling = t;
5693 <                rt.fork();
5694 <            }
5695 <            U r = null, u;
5696 <            while (t.advance() != null) {
5697 <                if ((u = transformer.apply((K)t.nextKey)) != null)
5698 <                    r = (r == null) ? u : reducer.apply(r, u);
5699 <            }
5700 <            t.result = r;
5701 <            for (;;) {
5702 <                int c; BulkTask<K,V,?> par; MapReduceKeysTask<K,V,U> s, p;
5703 <                if ((par = t.parent) == null ||
5704 <                    !(par instanceof MapReduceKeysTask)) {
5705 <                    t.quietlyComplete();
5706 <                    break;
5707 <                }
5708 <                else if ((c = (p = (MapReduceKeysTask<K,V,U>)par).pending) == 0) {
5709 <                    if ((s = t.sibling) != null && (u = s.result) != null)
6144 >                return abortOnNullFunction();
6145 >            try {
6146 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6147 >                    do {} while (!casPending(c = pending, c+1));
6148 >                    (rights = new MapReduceKeysTask<K,V,U>
6149 >                     (map, this, b >>>= 1, rights, transformer, reducer)).fork();
6150 >                }
6151 >                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);
5711                    (t = p).result = r;
6155                  }
6156 <                else if (p.casPending(c, 0))
6157 <                    break;
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);
6176 >            }
6177 >            MapReduceKeysTask<K,V,U> s = rights;
6178 >            if (s != null && !inForkJoinPool()) {
6179 >                do  {
6180 >                    if (s.tryUnfork())
6181 >                        s.exec();
6182 >                } while ((s = s.nextRight) != null);
6183              }
6184 +            return false;
6185          }
6186          public final U getRawResult() { return result; }
6187      }
6188  
6189 <    @SuppressWarnings("serial")
5721 <    static final class MapReduceValuesTask<K,V,U>
6189 >    @SuppressWarnings("serial") static final class MapReduceValuesTask<K,V,U>
6190          extends BulkTask<K,V,U> {
6191          final Fun<? super V, ? extends U> transformer;
6192          final BiFun<? super U, ? super U, ? extends U> reducer;
6193          U result;
6194 <        MapReduceValuesTask<K,V,U> sibling;
5727 <        MapReduceValuesTask
5728 <            (ConcurrentHashMapV8<K,V> m,
5729 <             Fun<? super V, ? extends U> transformer,
5730 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5731 <            super(m);
5732 <            this.transformer = transformer;
5733 <            this.reducer = reducer;
5734 <        }
6194 >        MapReduceValuesTask<K,V,U> rights, nextRight;
6195          MapReduceValuesTask
6196 <            (BulkTask<K,V,?> p, int b, boolean split,
6196 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6197 >             MapReduceValuesTask<K,V,U> nextRight,
6198               Fun<? super V, ? extends U> transformer,
6199               BiFun<? super U, ? super U, ? extends U> reducer) {
6200 <            super(p, b, split);
6200 >            super(m, p, b); this.nextRight = nextRight;
6201              this.transformer = transformer;
6202              this.reducer = reducer;
6203          }
6204 <        @SuppressWarnings("unchecked") public final void compute() {
5744 <            MapReduceValuesTask<K,V,U> t = this;
6204 >        @SuppressWarnings("unchecked") public final boolean exec() {
6205              final Fun<? super V, ? extends U> transformer =
6206                  this.transformer;
6207              final BiFun<? super U, ? super U, ? extends U> reducer =
6208                  this.reducer;
6209              if (transformer == null || reducer == null)
6210 <                throw new Error(NullFunctionMessage);
6211 <            int b = batch();
6212 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6213 <                b >>>= 1;
6214 <                t.pending = 1;
6215 <                MapReduceValuesTask<K,V,U> rt =
6216 <                    new MapReduceValuesTask<K,V,U>
6217 <                    (t, b, true, transformer, reducer);
6218 <                t = new MapReduceValuesTask<K,V,U>
6219 <                    (t, b, false, transformer, reducer);
6220 <                t.sibling = rt;
5761 <                rt.sibling = t;
5762 <                rt.fork();
5763 <            }
5764 <            U r = null, u;
5765 <            Object v;
5766 <            while ((v = t.advance()) != null) {
5767 <                if ((u = transformer.apply((V)v)) != null)
5768 <                    r = (r == null) ? u : reducer.apply(r, u);
5769 <            }
5770 <            t.result = r;
5771 <            for (;;) {
5772 <                int c; BulkTask<K,V,?> par; MapReduceValuesTask<K,V,U> s, p;
5773 <                if ((par = t.parent) == null ||
5774 <                    !(par instanceof MapReduceValuesTask)) {
5775 <                    t.quietlyComplete();
5776 <                    break;
5777 <                }
5778 <                else if ((c = (p = (MapReduceValuesTask<K,V,U>)par).pending) == 0) {
5779 <                    if ((s = t.sibling) != null && (u = s.result) != null)
6210 >                return abortOnNullFunction();
6211 >            try {
6212 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6213 >                    do {} while (!casPending(c = pending, c+1));
6214 >                    (rights = new MapReduceValuesTask<K,V,U>
6215 >                     (map, this, b >>>= 1, rights, transformer, reducer)).fork();
6216 >                }
6217 >                U r = null, u;
6218 >                Object v;
6219 >                while ((v = advance()) != null) {
6220 >                    if ((u = transformer.apply((V)v)) != null)
6221                          r = (r == null) ? u : reducer.apply(r, u);
5781                    (t = p).result = r;
6222                  }
6223 <                else if (p.casPending(c, 0))
6224 <                    break;
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);
6243              }
6244 +            MapReduceValuesTask<K,V,U> s = rights;
6245 +            if (s != null && !inForkJoinPool()) {
6246 +                do  {
6247 +                    if (s.tryUnfork())
6248 +                        s.exec();
6249 +                } while ((s = s.nextRight) != null);
6250 +            }
6251 +            return false;
6252          }
6253          public final U getRawResult() { return result; }
6254      }
6255  
6256 <    @SuppressWarnings("serial")
5791 <    static final class MapReduceEntriesTask<K,V,U>
6256 >    @SuppressWarnings("serial") static final class MapReduceEntriesTask<K,V,U>
6257          extends BulkTask<K,V,U> {
6258          final Fun<Map.Entry<K,V>, ? extends U> transformer;
6259          final BiFun<? super U, ? super U, ? extends U> reducer;
6260          U result;
6261 <        MapReduceEntriesTask<K,V,U> sibling;
6261 >        MapReduceEntriesTask<K,V,U> rights, nextRight;
6262          MapReduceEntriesTask
6263 <            (ConcurrentHashMapV8<K,V> m,
6263 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6264 >             MapReduceEntriesTask<K,V,U> nextRight,
6265               Fun<Map.Entry<K,V>, ? extends U> transformer,
6266               BiFun<? super U, ? super U, ? extends U> reducer) {
6267 <            super(m);
6267 >            super(m, p, b); this.nextRight = nextRight;
6268              this.transformer = transformer;
6269              this.reducer = reducer;
6270          }
6271 <        MapReduceEntriesTask
5806 <            (BulkTask<K,V,?> p, int b, boolean split,
5807 <             Fun<Map.Entry<K,V>, ? extends U> transformer,
5808 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5809 <            super(p, b, split);
5810 <            this.transformer = transformer;
5811 <            this.reducer = reducer;
5812 <        }
5813 <        @SuppressWarnings("unchecked") public final void compute() {
5814 <            MapReduceEntriesTask<K,V,U> t = this;
6271 >        @SuppressWarnings("unchecked") public final boolean exec() {
6272              final Fun<Map.Entry<K,V>, ? extends U> transformer =
6273                  this.transformer;
6274              final BiFun<? super U, ? super U, ? extends U> reducer =
6275                  this.reducer;
6276              if (transformer == null || reducer == null)
6277 <                throw new Error(NullFunctionMessage);
6278 <            int b = batch();
6279 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6280 <                b >>>= 1;
6281 <                t.pending = 1;
6282 <                MapReduceEntriesTask<K,V,U> rt =
6283 <                    new MapReduceEntriesTask<K,V,U>
6284 <                    (t, b, true, transformer, reducer);
6285 <                t = new MapReduceEntriesTask<K,V,U>
6286 <                    (t, b, false, transformer, reducer);
6287 <                t.sibling = rt;
5831 <                rt.sibling = t;
5832 <                rt.fork();
5833 <            }
5834 <            U r = null, u;
5835 <            Object v;
5836 <            while ((v = t.advance()) != null) {
5837 <                if ((u = transformer.apply(entryFor((K)t.nextKey, (V)v))) != null)
5838 <                    r = (r == null) ? u : reducer.apply(r, u);
5839 <            }
5840 <            t.result = r;
5841 <            for (;;) {
5842 <                int c; BulkTask<K,V,?> par; MapReduceEntriesTask<K,V,U> s, p;
5843 <                if ((par = t.parent) == null ||
5844 <                    !(par instanceof MapReduceEntriesTask)) {
5845 <                    t.quietlyComplete();
5846 <                    break;
5847 <                }
5848 <                else if ((c = (p = (MapReduceEntriesTask<K,V,U>)par).pending) == 0) {
5849 <                    if ((s = t.sibling) != null && (u = s.result) != null)
6277 >                return abortOnNullFunction();
6278 >            try {
6279 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6280 >                    do {} while (!casPending(c = pending, c+1));
6281 >                    (rights = new MapReduceEntriesTask<K,V,U>
6282 >                     (map, this, b >>>= 1, rights, transformer, reducer)).fork();
6283 >                }
6284 >                U r = null, u;
6285 >                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);
5851                    (t = p).result = r;
6289                  }
6290 <                else if (p.casPending(c, 0))
6291 <                    break;
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);
6310 >            }
6311 >            MapReduceEntriesTask<K,V,U> s = rights;
6312 >            if (s != null && !inForkJoinPool()) {
6313 >                do  {
6314 >                    if (s.tryUnfork())
6315 >                        s.exec();
6316 >                } while ((s = s.nextRight) != null);
6317              }
6318 +            return false;
6319          }
6320          public final U getRawResult() { return result; }
6321      }
6322  
6323 <    @SuppressWarnings("serial")
5861 <    static final class MapReduceMappingsTask<K,V,U>
6323 >    @SuppressWarnings("serial") static final class MapReduceMappingsTask<K,V,U>
6324          extends BulkTask<K,V,U> {
6325          final BiFun<? super K, ? super V, ? extends U> transformer;
6326          final BiFun<? super U, ? super U, ? extends U> reducer;
6327          U result;
6328 <        MapReduceMappingsTask<K,V,U> sibling;
5867 <        MapReduceMappingsTask
5868 <            (ConcurrentHashMapV8<K,V> m,
5869 <             BiFun<? super K, ? super V, ? extends U> transformer,
5870 <             BiFun<? super U, ? super U, ? extends U> reducer) {
5871 <            super(m);
5872 <            this.transformer = transformer;
5873 <            this.reducer = reducer;
5874 <        }
6328 >        MapReduceMappingsTask<K,V,U> rights, nextRight;
6329          MapReduceMappingsTask
6330 <            (BulkTask<K,V,?> p, int b, boolean split,
6330 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6331 >             MapReduceMappingsTask<K,V,U> nextRight,
6332               BiFun<? super K, ? super V, ? extends U> transformer,
6333               BiFun<? super U, ? super U, ? extends U> reducer) {
6334 <            super(p, b, split);
6334 >            super(m, p, b); this.nextRight = nextRight;
6335              this.transformer = transformer;
6336              this.reducer = reducer;
6337          }
6338 <        @SuppressWarnings("unchecked") public final void compute() {
5884 <            MapReduceMappingsTask<K,V,U> t = this;
6338 >        @SuppressWarnings("unchecked") public final boolean exec() {
6339              final BiFun<? super K, ? super V, ? extends U> transformer =
6340                  this.transformer;
6341              final BiFun<? super U, ? super U, ? extends U> reducer =
6342                  this.reducer;
6343              if (transformer == null || reducer == null)
6344 <                throw new Error(NullFunctionMessage);
6345 <            int b = batch();
6346 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6347 <                b >>>= 1;
6348 <                t.pending = 1;
6349 <                MapReduceMappingsTask<K,V,U> rt =
6350 <                    new MapReduceMappingsTask<K,V,U>
6351 <                    (t, b, true, transformer, reducer);
6352 <                t = new MapReduceMappingsTask<K,V,U>
6353 <                    (t, b, false, transformer, reducer);
6354 <                t.sibling = rt;
5901 <                rt.sibling = t;
5902 <                rt.fork();
5903 <            }
5904 <            U r = null, u;
5905 <            Object v;
5906 <            while ((v = t.advance()) != null) {
5907 <                if ((u = transformer.apply((K)t.nextKey, (V)v)) != null)
5908 <                    r = (r == null) ? u : reducer.apply(r, u);
5909 <            }
5910 <            for (;;) {
5911 <                int c; BulkTask<K,V,?> par; MapReduceMappingsTask<K,V,U> s, p;
5912 <                if ((par = t.parent) == null ||
5913 <                    !(par instanceof MapReduceMappingsTask)) {
5914 <                    t.quietlyComplete();
5915 <                    break;
5916 <                }
5917 <                else if ((c = (p = (MapReduceMappingsTask<K,V,U>)par).pending) == 0) {
5918 <                    if ((s = t.sibling) != null && (u = s.result) != null)
6344 >                return abortOnNullFunction();
6345 >            try {
6346 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6347 >                    do {} while (!casPending(c = pending, c+1));
6348 >                    (rights = new MapReduceMappingsTask<K,V,U>
6349 >                     (map, this, b >>>= 1, rights, transformer, reducer)).fork();
6350 >                }
6351 >                U r = null, u;
6352 >                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);
5920                    (t = p).result = r;
6356                  }
6357 <                else if (p.casPending(c, 0))
6358 <                    break;
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);
6377              }
6378 +            MapReduceMappingsTask<K,V,U> s = rights;
6379 +            if (s != null && !inForkJoinPool()) {
6380 +                do  {
6381 +                    if (s.tryUnfork())
6382 +                        s.exec();
6383 +                } while ((s = s.nextRight) != null);
6384 +            }
6385 +            return false;
6386          }
6387          public final U getRawResult() { return result; }
6388      }
6389  
6390 <    @SuppressWarnings("serial")
5930 <    static final class MapReduceKeysToDoubleTask<K,V>
6390 >    @SuppressWarnings("serial") static final class MapReduceKeysToDoubleTask<K,V>
6391          extends BulkTask<K,V,Double> {
6392          final ObjectToDouble<? super K> transformer;
6393          final DoubleByDoubleToDouble reducer;
6394          final double basis;
6395          double result;
6396 <        MapReduceKeysToDoubleTask<K,V> sibling;
6396 >        MapReduceKeysToDoubleTask<K,V> rights, nextRight;
6397          MapReduceKeysToDoubleTask
6398 <            (ConcurrentHashMapV8<K,V> m,
6398 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6399 >             MapReduceKeysToDoubleTask<K,V> nextRight,
6400               ObjectToDouble<? super K> transformer,
6401               double basis,
6402               DoubleByDoubleToDouble reducer) {
6403 <            super(m);
6403 >            super(m, p, b); this.nextRight = nextRight;
6404              this.transformer = transformer;
6405              this.basis = basis; this.reducer = reducer;
6406          }
6407 <        MapReduceKeysToDoubleTask
5947 <            (BulkTask<K,V,?> p, int b, boolean split,
5948 <             ObjectToDouble<? super K> transformer,
5949 <             double basis,
5950 <             DoubleByDoubleToDouble reducer) {
5951 <            super(p, b, split);
5952 <            this.transformer = transformer;
5953 <            this.basis = basis; this.reducer = reducer;
5954 <        }
5955 <        @SuppressWarnings("unchecked") public final void compute() {
5956 <            MapReduceKeysToDoubleTask<K,V> t = this;
6407 >        @SuppressWarnings("unchecked") public final boolean exec() {
6408              final ObjectToDouble<? super K> transformer =
6409                  this.transformer;
6410              final DoubleByDoubleToDouble reducer = this.reducer;
6411              if (transformer == null || reducer == null)
6412 <                throw new Error(NullFunctionMessage);
6413 <            final double id = this.basis;
6414 <            int b = batch();
6415 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6416 <                b >>>= 1;
6417 <                t.pending = 1;
6418 <                MapReduceKeysToDoubleTask<K,V> rt =
6419 <                    new MapReduceKeysToDoubleTask<K,V>
6420 <                    (t, b, true, transformer, id, reducer);
6421 <                t = new MapReduceKeysToDoubleTask<K,V>
6422 <                    (t, b, false, transformer, id, reducer);
6423 <                t.sibling = rt;
6424 <                rt.sibling = t;
6425 <                rt.fork();
6426 <            }
6427 <            double r = id;
6428 <            while (t.advance() != null)
6429 <                r = reducer.apply(r, transformer.apply((K)t.nextKey));
6430 <            t.result = r;
6431 <            for (;;) {
6432 <                int c; BulkTask<K,V,?> par; MapReduceKeysToDoubleTask<K,V> s, p;
6433 <                if ((par = t.parent) == null ||
6434 <                    !(par instanceof MapReduceKeysToDoubleTask)) {
6435 <                    t.quietlyComplete();
6436 <                    break;
6437 <                }
6438 <                else if ((c = (p = (MapReduceKeysToDoubleTask<K,V>)par).pending) == 0) {
5988 <                    if ((s = t.sibling) != null)
5989 <                        r = reducer.apply(r, s.result);
5990 <                    (t = p).result = r;
6412 >                return abortOnNullFunction();
6413 >            try {
6414 >                final double id = this.basis;
6415 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6416 >                    do {} while (!casPending(c = pending, c+1));
6417 >                    (rights = new MapReduceKeysToDoubleTask<K,V>
6418 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6419 >                }
6420 >                double r = id;
6421 >                while (advance() != null)
6422 >                    r = reducer.apply(r, transformer.apply((K)nextKey));
6423 >                result = r;
6424 >                for (MapReduceKeysToDoubleTask<K,V> t = this, s;;) {
6425 >                    int c; BulkTask<K,V,?> par;
6426 >                    if ((c = t.pending) == 0) {
6427 >                        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;
6439                  }
6440 <                else if (p.casPending(c, 0))
6441 <                    break;
6440 >            } catch (Throwable ex) {
6441 >                return tryCompleteComputation(ex);
6442 >            }
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;
6451          }
6452          public final Double getRawResult() { return result; }
6453      }
6454  
6455 <    @SuppressWarnings("serial")
6000 <    static final class MapReduceValuesToDoubleTask<K,V>
6455 >    @SuppressWarnings("serial") static final class MapReduceValuesToDoubleTask<K,V>
6456          extends BulkTask<K,V,Double> {
6457          final ObjectToDouble<? super V> transformer;
6458          final DoubleByDoubleToDouble reducer;
6459          final double basis;
6460          double result;
6461 <        MapReduceValuesToDoubleTask<K,V> sibling;
6007 <        MapReduceValuesToDoubleTask
6008 <            (ConcurrentHashMapV8<K,V> m,
6009 <             ObjectToDouble<? super V> transformer,
6010 <             double basis,
6011 <             DoubleByDoubleToDouble reducer) {
6012 <            super(m);
6013 <            this.transformer = transformer;
6014 <            this.basis = basis; this.reducer = reducer;
6015 <        }
6461 >        MapReduceValuesToDoubleTask<K,V> rights, nextRight;
6462          MapReduceValuesToDoubleTask
6463 <            (BulkTask<K,V,?> p, int b, boolean split,
6463 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6464 >             MapReduceValuesToDoubleTask<K,V> nextRight,
6465               ObjectToDouble<? super V> transformer,
6466               double basis,
6467               DoubleByDoubleToDouble reducer) {
6468 <            super(p, b, split);
6468 >            super(m, p, b); this.nextRight = nextRight;
6469              this.transformer = transformer;
6470              this.basis = basis; this.reducer = reducer;
6471          }
6472 <        @SuppressWarnings("unchecked") public final void compute() {
6026 <            MapReduceValuesToDoubleTask<K,V> t = this;
6472 >        @SuppressWarnings("unchecked") public final boolean exec() {
6473              final ObjectToDouble<? super V> transformer =
6474                  this.transformer;
6475              final DoubleByDoubleToDouble reducer = this.reducer;
6476              if (transformer == null || reducer == null)
6477 <                throw new Error(NullFunctionMessage);
6478 <            final double id = this.basis;
6479 <            int b = batch();
6480 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6481 <                b >>>= 1;
6482 <                t.pending = 1;
6483 <                MapReduceValuesToDoubleTask<K,V> rt =
6484 <                    new MapReduceValuesToDoubleTask<K,V>
6485 <                    (t, b, true, transformer, id, reducer);
6486 <                t = new MapReduceValuesToDoubleTask<K,V>
6487 <                    (t, b, false, transformer, id, reducer);
6488 <                t.sibling = rt;
6489 <                rt.sibling = t;
6490 <                rt.fork();
6491 <            }
6492 <            double r = id;
6493 <            Object v;
6494 <            while ((v = t.advance()) != null)
6495 <                r = reducer.apply(r, transformer.apply((V)v));
6496 <            t.result = r;
6497 <            for (;;) {
6498 <                int c; BulkTask<K,V,?> par; MapReduceValuesToDoubleTask<K,V> s, p;
6499 <                if ((par = t.parent) == null ||
6500 <                    !(par instanceof MapReduceValuesToDoubleTask)) {
6501 <                    t.quietlyComplete();
6502 <                    break;
6503 <                }
6504 <                else if ((c = (p = (MapReduceValuesToDoubleTask<K,V>)par).pending) == 0) {
6059 <                    if ((s = t.sibling) != null)
6060 <                        r = reducer.apply(r, s.result);
6061 <                    (t = p).result = r;
6477 >                return abortOnNullFunction();
6478 >            try {
6479 >                final double id = this.basis;
6480 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6481 >                    do {} while (!casPending(c = pending, c+1));
6482 >                    (rights = new MapReduceValuesToDoubleTask<K,V>
6483 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6484 >                }
6485 >                double r = id;
6486 >                Object v;
6487 >                while ((v = advance()) != null)
6488 >                    r = reducer.apply(r, transformer.apply((V)v));
6489 >                result = r;
6490 >                for (MapReduceValuesToDoubleTask<K,V> t = this, s;;) {
6491 >                    int c; BulkTask<K,V,?> par;
6492 >                    if ((c = t.pending) == 0) {
6493 >                        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;
6505                  }
6506 <                else if (p.casPending(c, 0))
6507 <                    break;
6506 >            } catch (Throwable ex) {
6507 >                return tryCompleteComputation(ex);
6508              }
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;
6517          }
6518          public final Double getRawResult() { return result; }
6519      }
6520  
6521 <    @SuppressWarnings("serial")
6071 <    static final class MapReduceEntriesToDoubleTask<K,V>
6521 >    @SuppressWarnings("serial") static final class MapReduceEntriesToDoubleTask<K,V>
6522          extends BulkTask<K,V,Double> {
6523          final ObjectToDouble<Map.Entry<K,V>> transformer;
6524          final DoubleByDoubleToDouble reducer;
6525          final double basis;
6526          double result;
6527 <        MapReduceEntriesToDoubleTask<K,V> sibling;
6527 >        MapReduceEntriesToDoubleTask<K,V> rights, nextRight;
6528          MapReduceEntriesToDoubleTask
6529 <            (ConcurrentHashMapV8<K,V> m,
6529 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6530 >             MapReduceEntriesToDoubleTask<K,V> nextRight,
6531               ObjectToDouble<Map.Entry<K,V>> transformer,
6532               double basis,
6533               DoubleByDoubleToDouble reducer) {
6534 <            super(m);
6534 >            super(m, p, b); this.nextRight = nextRight;
6535              this.transformer = transformer;
6536              this.basis = basis; this.reducer = reducer;
6537          }
6538 <        MapReduceEntriesToDoubleTask
6088 <            (BulkTask<K,V,?> p, int b, boolean split,
6089 <             ObjectToDouble<Map.Entry<K,V>> transformer,
6090 <             double basis,
6091 <             DoubleByDoubleToDouble reducer) {
6092 <            super(p, b, split);
6093 <            this.transformer = transformer;
6094 <            this.basis = basis; this.reducer = reducer;
6095 <        }
6096 <        @SuppressWarnings("unchecked") public final void compute() {
6097 <            MapReduceEntriesToDoubleTask<K,V> t = this;
6538 >        @SuppressWarnings("unchecked") public final boolean exec() {
6539              final ObjectToDouble<Map.Entry<K,V>> transformer =
6540                  this.transformer;
6541              final DoubleByDoubleToDouble reducer = this.reducer;
6542              if (transformer == null || reducer == null)
6543 <                throw new Error(NullFunctionMessage);
6544 <            final double id = this.basis;
6545 <            int b = batch();
6546 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6547 <                b >>>= 1;
6548 <                t.pending = 1;
6549 <                MapReduceEntriesToDoubleTask<K,V> rt =
6550 <                    new MapReduceEntriesToDoubleTask<K,V>
6551 <                    (t, b, true, transformer, id, reducer);
6552 <                t = new MapReduceEntriesToDoubleTask<K,V>
6553 <                    (t, b, false, transformer, id, reducer);
6554 <                t.sibling = rt;
6555 <                rt.sibling = t;
6556 <                rt.fork();
6557 <            }
6558 <            double r = id;
6559 <            Object v;
6560 <            while ((v = t.advance()) != null)
6561 <                r = reducer.apply(r, transformer.apply(entryFor((K)t.nextKey, (V)v)));
6562 <            t.result = r;
6563 <            for (;;) {
6564 <                int c; BulkTask<K,V,?> par; MapReduceEntriesToDoubleTask<K,V> s, p;
6565 <                if ((par = t.parent) == null ||
6566 <                    !(par instanceof MapReduceEntriesToDoubleTask)) {
6567 <                    t.quietlyComplete();
6568 <                    break;
6569 <                }
6570 <                else if ((c = (p = (MapReduceEntriesToDoubleTask<K,V>)par).pending) == 0) {
6130 <                    if ((s = t.sibling) != null)
6131 <                        r = reducer.apply(r, s.result);
6132 <                    (t = p).result = r;
6543 >                return abortOnNullFunction();
6544 >            try {
6545 >                final double id = this.basis;
6546 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6547 >                    do {} while (!casPending(c = pending, c+1));
6548 >                    (rights = new MapReduceEntriesToDoubleTask<K,V>
6549 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6550 >                }
6551 >                double r = id;
6552 >                Object v;
6553 >                while ((v = advance()) != null)
6554 >                    r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6555 >                result = r;
6556 >                for (MapReduceEntriesToDoubleTask<K,V> t = this, s;;) {
6557 >                    int c; BulkTask<K,V,?> par;
6558 >                    if ((c = t.pending) == 0) {
6559 >                        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;
6571                  }
6572 <                else if (p.casPending(c, 0))
6573 <                    break;
6572 >            } catch (Throwable ex) {
6573 >                return tryCompleteComputation(ex);
6574              }
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;
6583          }
6584          public final Double getRawResult() { return result; }
6585      }
6586  
6587 <    @SuppressWarnings("serial")
6142 <    static final class MapReduceMappingsToDoubleTask<K,V>
6587 >    @SuppressWarnings("serial") static final class MapReduceMappingsToDoubleTask<K,V>
6588          extends BulkTask<K,V,Double> {
6589          final ObjectByObjectToDouble<? super K, ? super V> transformer;
6590          final DoubleByDoubleToDouble reducer;
6591          final double basis;
6592          double result;
6593 <        MapReduceMappingsToDoubleTask<K,V> sibling;
6149 <        MapReduceMappingsToDoubleTask
6150 <            (ConcurrentHashMapV8<K,V> m,
6151 <             ObjectByObjectToDouble<? super K, ? super V> transformer,
6152 <             double basis,
6153 <             DoubleByDoubleToDouble reducer) {
6154 <            super(m);
6155 <            this.transformer = transformer;
6156 <            this.basis = basis; this.reducer = reducer;
6157 <        }
6593 >        MapReduceMappingsToDoubleTask<K,V> rights, nextRight;
6594          MapReduceMappingsToDoubleTask
6595 <            (BulkTask<K,V,?> p, int b, boolean split,
6595 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6596 >             MapReduceMappingsToDoubleTask<K,V> nextRight,
6597               ObjectByObjectToDouble<? super K, ? super V> transformer,
6598               double basis,
6599               DoubleByDoubleToDouble reducer) {
6600 <            super(p, b, split);
6600 >            super(m, p, b); this.nextRight = nextRight;
6601              this.transformer = transformer;
6602              this.basis = basis; this.reducer = reducer;
6603          }
6604 <        @SuppressWarnings("unchecked") public final void compute() {
6168 <            MapReduceMappingsToDoubleTask<K,V> t = this;
6604 >        @SuppressWarnings("unchecked") public final boolean exec() {
6605              final ObjectByObjectToDouble<? super K, ? super V> transformer =
6606                  this.transformer;
6607              final DoubleByDoubleToDouble reducer = this.reducer;
6608              if (transformer == null || reducer == null)
6609 <                throw new Error(NullFunctionMessage);
6610 <            final double id = this.basis;
6611 <            int b = batch();
6612 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6613 <                b >>>= 1;
6614 <                t.pending = 1;
6615 <                MapReduceMappingsToDoubleTask<K,V> rt =
6616 <                    new MapReduceMappingsToDoubleTask<K,V>
6617 <                    (t, b, true, transformer, id, reducer);
6618 <                t = new MapReduceMappingsToDoubleTask<K,V>
6619 <                    (t, b, false, transformer, id, reducer);
6620 <                t.sibling = rt;
6621 <                rt.sibling = t;
6622 <                rt.fork();
6623 <            }
6624 <            double r = id;
6625 <            Object v;
6626 <            while ((v = t.advance()) != null)
6627 <                r = reducer.apply(r, transformer.apply((K)t.nextKey, (V)v));
6628 <            t.result = r;
6629 <            for (;;) {
6630 <                int c; BulkTask<K,V,?> par; MapReduceMappingsToDoubleTask<K,V> s, p;
6631 <                if ((par = t.parent) == null ||
6632 <                    !(par instanceof MapReduceMappingsToDoubleTask)) {
6633 <                    t.quietlyComplete();
6634 <                    break;
6635 <                }
6636 <                else if ((c = (p = (MapReduceMappingsToDoubleTask<K,V>)par).pending) == 0) {
6201 <                    if ((s = t.sibling) != null)
6202 <                        r = reducer.apply(r, s.result);
6203 <                    (t = p).result = r;
6609 >                return abortOnNullFunction();
6610 >            try {
6611 >                final double id = this.basis;
6612 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6613 >                    do {} while (!casPending(c = pending, c+1));
6614 >                    (rights = new MapReduceMappingsToDoubleTask<K,V>
6615 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6616 >                }
6617 >                double r = id;
6618 >                Object v;
6619 >                while ((v = advance()) != null)
6620 >                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6621 >                result = r;
6622 >                for (MapReduceMappingsToDoubleTask<K,V> t = this, s;;) {
6623 >                    int c; BulkTask<K,V,?> par;
6624 >                    if ((c = t.pending) == 0) {
6625 >                        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;
6637                  }
6638 <                else if (p.casPending(c, 0))
6639 <                    break;
6638 >            } catch (Throwable ex) {
6639 >                return tryCompleteComputation(ex);
6640 >            }
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;
6649          }
6650          public final Double getRawResult() { return result; }
6651      }
6652  
6653 <    @SuppressWarnings("serial")
6213 <    static final class MapReduceKeysToLongTask<K,V>
6653 >    @SuppressWarnings("serial") static final class MapReduceKeysToLongTask<K,V>
6654          extends BulkTask<K,V,Long> {
6655          final ObjectToLong<? super K> transformer;
6656          final LongByLongToLong reducer;
6657          final long basis;
6658          long result;
6659 <        MapReduceKeysToLongTask<K,V> sibling;
6659 >        MapReduceKeysToLongTask<K,V> rights, nextRight;
6660          MapReduceKeysToLongTask
6661 <            (ConcurrentHashMapV8<K,V> m,
6661 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6662 >             MapReduceKeysToLongTask<K,V> nextRight,
6663               ObjectToLong<? super K> transformer,
6664               long basis,
6665               LongByLongToLong reducer) {
6666 <            super(m);
6666 >            super(m, p, b); this.nextRight = nextRight;
6667              this.transformer = transformer;
6668              this.basis = basis; this.reducer = reducer;
6669          }
6670 <        MapReduceKeysToLongTask
6230 <            (BulkTask<K,V,?> p, int b, boolean split,
6231 <             ObjectToLong<? super K> transformer,
6232 <             long basis,
6233 <             LongByLongToLong reducer) {
6234 <            super(p, b, split);
6235 <            this.transformer = transformer;
6236 <            this.basis = basis; this.reducer = reducer;
6237 <        }
6238 <        @SuppressWarnings("unchecked") public final void compute() {
6239 <            MapReduceKeysToLongTask<K,V> t = this;
6670 >        @SuppressWarnings("unchecked") public final boolean exec() {
6671              final ObjectToLong<? super K> transformer =
6672                  this.transformer;
6673              final LongByLongToLong reducer = this.reducer;
6674              if (transformer == null || reducer == null)
6675 <                throw new Error(NullFunctionMessage);
6676 <            final long id = this.basis;
6677 <            int b = batch();
6678 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6679 <                b >>>= 1;
6680 <                t.pending = 1;
6681 <                MapReduceKeysToLongTask<K,V> rt =
6682 <                    new MapReduceKeysToLongTask<K,V>
6683 <                    (t, b, true, transformer, id, reducer);
6684 <                t = new MapReduceKeysToLongTask<K,V>
6685 <                    (t, b, false, transformer, id, reducer);
6686 <                t.sibling = rt;
6687 <                rt.sibling = t;
6688 <                rt.fork();
6689 <            }
6690 <            long r = id;
6691 <            while (t.advance() != null)
6692 <                r = reducer.apply(r, transformer.apply((K)t.nextKey));
6693 <            t.result = r;
6694 <            for (;;) {
6695 <                int c; BulkTask<K,V,?> par; MapReduceKeysToLongTask<K,V> s, p;
6696 <                if ((par = t.parent) == null ||
6697 <                    !(par instanceof MapReduceKeysToLongTask)) {
6698 <                    t.quietlyComplete();
6699 <                    break;
6700 <                }
6701 <                else if ((c = (p = (MapReduceKeysToLongTask<K,V>)par).pending) == 0) {
6271 <                    if ((s = t.sibling) != null)
6272 <                        r = reducer.apply(r, s.result);
6273 <                    (t = p).result = r;
6675 >                return abortOnNullFunction();
6676 >            try {
6677 >                final long id = this.basis;
6678 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6679 >                    do {} while (!casPending(c = pending, c+1));
6680 >                    (rights = new MapReduceKeysToLongTask<K,V>
6681 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6682 >                }
6683 >                long r = id;
6684 >                while (advance() != null)
6685 >                    r = reducer.apply(r, transformer.apply((K)nextKey));
6686 >                result = r;
6687 >                for (MapReduceKeysToLongTask<K,V> t = this, s;;) {
6688 >                    int c; BulkTask<K,V,?> par;
6689 >                    if ((c = t.pending) == 0) {
6690 >                        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;
6702                  }
6703 <                else if (p.casPending(c, 0))
6704 <                    break;
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);
6712              }
6713 +            return false;
6714          }
6715          public final Long getRawResult() { return result; }
6716      }
6717  
6718 <    @SuppressWarnings("serial")
6283 <    static final class MapReduceValuesToLongTask<K,V>
6718 >    @SuppressWarnings("serial") static final class MapReduceValuesToLongTask<K,V>
6719          extends BulkTask<K,V,Long> {
6720          final ObjectToLong<? super V> transformer;
6721          final LongByLongToLong reducer;
6722          final long basis;
6723          long result;
6724 <        MapReduceValuesToLongTask<K,V> sibling;
6290 <        MapReduceValuesToLongTask
6291 <            (ConcurrentHashMapV8<K,V> m,
6292 <             ObjectToLong<? super V> transformer,
6293 <             long basis,
6294 <             LongByLongToLong reducer) {
6295 <            super(m);
6296 <            this.transformer = transformer;
6297 <            this.basis = basis; this.reducer = reducer;
6298 <        }
6724 >        MapReduceValuesToLongTask<K,V> rights, nextRight;
6725          MapReduceValuesToLongTask
6726 <            (BulkTask<K,V,?> p, int b, boolean split,
6726 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6727 >             MapReduceValuesToLongTask<K,V> nextRight,
6728               ObjectToLong<? super V> transformer,
6729               long basis,
6730               LongByLongToLong reducer) {
6731 <            super(p, b, split);
6731 >            super(m, p, b); this.nextRight = nextRight;
6732              this.transformer = transformer;
6733              this.basis = basis; this.reducer = reducer;
6734          }
6735 <        @SuppressWarnings("unchecked") public final void compute() {
6309 <            MapReduceValuesToLongTask<K,V> t = this;
6735 >        @SuppressWarnings("unchecked") public final boolean exec() {
6736              final ObjectToLong<? super V> transformer =
6737                  this.transformer;
6738              final LongByLongToLong reducer = this.reducer;
6739              if (transformer == null || reducer == null)
6740 <                throw new Error(NullFunctionMessage);
6741 <            final long id = this.basis;
6742 <            int b = batch();
6743 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6744 <                b >>>= 1;
6745 <                t.pending = 1;
6746 <                MapReduceValuesToLongTask<K,V> rt =
6747 <                    new MapReduceValuesToLongTask<K,V>
6748 <                    (t, b, true, transformer, id, reducer);
6749 <                t = new MapReduceValuesToLongTask<K,V>
6750 <                    (t, b, false, transformer, id, reducer);
6751 <                t.sibling = rt;
6752 <                rt.sibling = t;
6753 <                rt.fork();
6754 <            }
6755 <            long r = id;
6756 <            Object v;
6757 <            while ((v = t.advance()) != null)
6758 <                r = reducer.apply(r, transformer.apply((V)v));
6759 <            t.result = r;
6760 <            for (;;) {
6761 <                int c; BulkTask<K,V,?> par; MapReduceValuesToLongTask<K,V> s, p;
6762 <                if ((par = t.parent) == null ||
6763 <                    !(par instanceof MapReduceValuesToLongTask)) {
6764 <                    t.quietlyComplete();
6765 <                    break;
6766 <                }
6767 <                else if ((c = (p = (MapReduceValuesToLongTask<K,V>)par).pending) == 0) {
6342 <                    if ((s = t.sibling) != null)
6343 <                        r = reducer.apply(r, s.result);
6344 <                    (t = p).result = r;
6740 >                return abortOnNullFunction();
6741 >            try {
6742 >                final long id = this.basis;
6743 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6744 >                    do {} while (!casPending(c = pending, c+1));
6745 >                    (rights = new MapReduceValuesToLongTask<K,V>
6746 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6747 >                }
6748 >                long r = id;
6749 >                Object v;
6750 >                while ((v = advance()) != null)
6751 >                    r = reducer.apply(r, transformer.apply((V)v));
6752 >                result = r;
6753 >                for (MapReduceValuesToLongTask<K,V> t = this, s;;) {
6754 >                    int c; BulkTask<K,V,?> par;
6755 >                    if ((c = t.pending) == 0) {
6756 >                        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;
6768                  }
6769 <                else if (p.casPending(c, 0))
6770 <                    break;
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);
6778              }
6779 +            return false;
6780          }
6781          public final Long getRawResult() { return result; }
6782      }
6783  
6784 <    @SuppressWarnings("serial")
6354 <    static final class MapReduceEntriesToLongTask<K,V>
6784 >    @SuppressWarnings("serial") static final class MapReduceEntriesToLongTask<K,V>
6785          extends BulkTask<K,V,Long> {
6786          final ObjectToLong<Map.Entry<K,V>> transformer;
6787          final LongByLongToLong reducer;
6788          final long basis;
6789          long result;
6790 <        MapReduceEntriesToLongTask<K,V> sibling;
6361 <        MapReduceEntriesToLongTask
6362 <            (ConcurrentHashMapV8<K,V> m,
6363 <             ObjectToLong<Map.Entry<K,V>> transformer,
6364 <             long basis,
6365 <             LongByLongToLong reducer) {
6366 <            super(m);
6367 <            this.transformer = transformer;
6368 <            this.basis = basis; this.reducer = reducer;
6369 <        }
6790 >        MapReduceEntriesToLongTask<K,V> rights, nextRight;
6791          MapReduceEntriesToLongTask
6792 <            (BulkTask<K,V,?> p, int b, boolean split,
6792 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6793 >             MapReduceEntriesToLongTask<K,V> nextRight,
6794               ObjectToLong<Map.Entry<K,V>> transformer,
6795               long basis,
6796               LongByLongToLong reducer) {
6797 <            super(p, b, split);
6797 >            super(m, p, b); this.nextRight = nextRight;
6798              this.transformer = transformer;
6799              this.basis = basis; this.reducer = reducer;
6800          }
6801 <        @SuppressWarnings("unchecked") public final void compute() {
6380 <            MapReduceEntriesToLongTask<K,V> t = this;
6801 >        @SuppressWarnings("unchecked") public final boolean exec() {
6802              final ObjectToLong<Map.Entry<K,V>> transformer =
6803                  this.transformer;
6804              final LongByLongToLong reducer = this.reducer;
6805              if (transformer == null || reducer == null)
6806 <                throw new Error(NullFunctionMessage);
6807 <            final long id = this.basis;
6808 <            int b = batch();
6809 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6810 <                b >>>= 1;
6811 <                t.pending = 1;
6812 <                MapReduceEntriesToLongTask<K,V> rt =
6813 <                    new MapReduceEntriesToLongTask<K,V>
6814 <                    (t, b, true, transformer, id, reducer);
6815 <                t = new MapReduceEntriesToLongTask<K,V>
6816 <                    (t, b, false, transformer, id, reducer);
6817 <                t.sibling = rt;
6818 <                rt.sibling = t;
6819 <                rt.fork();
6820 <            }
6821 <            long r = id;
6822 <            Object v;
6823 <            while ((v = t.advance()) != null)
6824 <                r = reducer.apply(r, transformer.apply(entryFor((K)t.nextKey, (V)v)));
6825 <            t.result = r;
6826 <            for (;;) {
6827 <                int c; BulkTask<K,V,?> par; MapReduceEntriesToLongTask<K,V> s, p;
6828 <                if ((par = t.parent) == null ||
6829 <                    !(par instanceof MapReduceEntriesToLongTask)) {
6830 <                    t.quietlyComplete();
6831 <                    break;
6832 <                }
6833 <                else if ((c = (p = (MapReduceEntriesToLongTask<K,V>)par).pending) == 0) {
6413 <                    if ((s = t.sibling) != null)
6414 <                        r = reducer.apply(r, s.result);
6415 <                    (t = p).result = r;
6806 >                return abortOnNullFunction();
6807 >            try {
6808 >                final long id = this.basis;
6809 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6810 >                    do {} while (!casPending(c = pending, c+1));
6811 >                    (rights = new MapReduceEntriesToLongTask<K,V>
6812 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6813 >                }
6814 >                long r = id;
6815 >                Object v;
6816 >                while ((v = advance()) != null)
6817 >                    r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
6818 >                result = r;
6819 >                for (MapReduceEntriesToLongTask<K,V> t = this, s;;) {
6820 >                    int c; BulkTask<K,V,?> par;
6821 >                    if ((c = t.pending) == 0) {
6822 >                        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;
6834                  }
6835 <                else if (p.casPending(c, 0))
6836 <                    break;
6835 >            } catch (Throwable ex) {
6836 >                return tryCompleteComputation(ex);
6837 >            }
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;
6846          }
6847          public final Long getRawResult() { return result; }
6848      }
6849  
6850 <    @SuppressWarnings("serial")
6425 <    static final class MapReduceMappingsToLongTask<K,V>
6850 >    @SuppressWarnings("serial") static final class MapReduceMappingsToLongTask<K,V>
6851          extends BulkTask<K,V,Long> {
6852          final ObjectByObjectToLong<? super K, ? super V> transformer;
6853          final LongByLongToLong reducer;
6854          final long basis;
6855          long result;
6856 <        MapReduceMappingsToLongTask<K,V> sibling;
6432 <        MapReduceMappingsToLongTask
6433 <            (ConcurrentHashMapV8<K,V> m,
6434 <             ObjectByObjectToLong<? super K, ? super V> transformer,
6435 <             long basis,
6436 <             LongByLongToLong reducer) {
6437 <            super(m);
6438 <            this.transformer = transformer;
6439 <            this.basis = basis; this.reducer = reducer;
6440 <        }
6856 >        MapReduceMappingsToLongTask<K,V> rights, nextRight;
6857          MapReduceMappingsToLongTask
6858 <            (BulkTask<K,V,?> p, int b, boolean split,
6858 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6859 >             MapReduceMappingsToLongTask<K,V> nextRight,
6860               ObjectByObjectToLong<? super K, ? super V> transformer,
6861               long basis,
6862               LongByLongToLong reducer) {
6863 <            super(p, b, split);
6863 >            super(m, p, b); this.nextRight = nextRight;
6864              this.transformer = transformer;
6865              this.basis = basis; this.reducer = reducer;
6866          }
6867 <        @SuppressWarnings("unchecked") public final void compute() {
6451 <            MapReduceMappingsToLongTask<K,V> t = this;
6867 >        @SuppressWarnings("unchecked") public final boolean exec() {
6868              final ObjectByObjectToLong<? super K, ? super V> transformer =
6869                  this.transformer;
6870              final LongByLongToLong reducer = this.reducer;
6871              if (transformer == null || reducer == null)
6872 <                throw new Error(NullFunctionMessage);
6873 <            final long id = this.basis;
6874 <            int b = batch();
6875 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6876 <                b >>>= 1;
6877 <                t.pending = 1;
6878 <                MapReduceMappingsToLongTask<K,V> rt =
6879 <                    new MapReduceMappingsToLongTask<K,V>
6880 <                    (t, b, true, transformer, id, reducer);
6881 <                t = new MapReduceMappingsToLongTask<K,V>
6882 <                    (t, b, false, transformer, id, reducer);
6883 <                t.sibling = rt;
6884 <                rt.sibling = t;
6885 <                rt.fork();
6886 <            }
6887 <            long r = id;
6888 <            Object v;
6889 <            while ((v = t.advance()) != null)
6890 <                r = reducer.apply(r, transformer.apply((K)t.nextKey, (V)v));
6891 <            t.result = r;
6892 <            for (;;) {
6893 <                int c; BulkTask<K,V,?> par; MapReduceMappingsToLongTask<K,V> s, p;
6894 <                if ((par = t.parent) == null ||
6895 <                    !(par instanceof MapReduceMappingsToLongTask)) {
6896 <                    t.quietlyComplete();
6897 <                    break;
6898 <                }
6899 <                else if ((c = (p = (MapReduceMappingsToLongTask<K,V>)par).pending) == 0) {
6484 <                    if ((s = t.sibling) != null)
6485 <                        r = reducer.apply(r, s.result);
6486 <                    (t = p).result = r;
6872 >                return abortOnNullFunction();
6873 >            try {
6874 >                final long id = this.basis;
6875 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6876 >                    do {} while (!casPending(c = pending, c+1));
6877 >                    (rights = new MapReduceMappingsToLongTask<K,V>
6878 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6879 >                }
6880 >                long r = id;
6881 >                Object v;
6882 >                while ((v = advance()) != null)
6883 >                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6884 >                result = r;
6885 >                for (MapReduceMappingsToLongTask<K,V> t = this, s;;) {
6886 >                    int c; BulkTask<K,V,?> par;
6887 >                    if ((c = t.pending) == 0) {
6888 >                        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;
6900                  }
6901 <                else if (p.casPending(c, 0))
6902 <                    break;
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);
6910              }
6911 +            return false;
6912          }
6913          public final Long getRawResult() { return result; }
6914      }
6915  
6916 <    @SuppressWarnings("serial")
6496 <    static final class MapReduceKeysToIntTask<K,V>
6916 >    @SuppressWarnings("serial") static final class MapReduceKeysToIntTask<K,V>
6917          extends BulkTask<K,V,Integer> {
6918          final ObjectToInt<? super K> transformer;
6919          final IntByIntToInt reducer;
6920          final int basis;
6921          int result;
6922 <        MapReduceKeysToIntTask<K,V> sibling;
6922 >        MapReduceKeysToIntTask<K,V> rights, nextRight;
6923          MapReduceKeysToIntTask
6924 <            (ConcurrentHashMapV8<K,V> m,
6924 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6925 >             MapReduceKeysToIntTask<K,V> nextRight,
6926               ObjectToInt<? super K> transformer,
6927               int basis,
6928               IntByIntToInt reducer) {
6929 <            super(m);
6929 >            super(m, p, b); this.nextRight = nextRight;
6930              this.transformer = transformer;
6931              this.basis = basis; this.reducer = reducer;
6932          }
6933 <        MapReduceKeysToIntTask
6513 <            (BulkTask<K,V,?> p, int b, boolean split,
6514 <             ObjectToInt<? super K> transformer,
6515 <             int basis,
6516 <             IntByIntToInt reducer) {
6517 <            super(p, b, split);
6518 <            this.transformer = transformer;
6519 <            this.basis = basis; this.reducer = reducer;
6520 <        }
6521 <        @SuppressWarnings("unchecked") public final void compute() {
6522 <            MapReduceKeysToIntTask<K,V> t = this;
6933 >        @SuppressWarnings("unchecked") public final boolean exec() {
6934              final ObjectToInt<? super K> transformer =
6935                  this.transformer;
6936              final IntByIntToInt reducer = this.reducer;
6937              if (transformer == null || reducer == null)
6938 <                throw new Error(NullFunctionMessage);
6939 <            final int id = this.basis;
6940 <            int b = batch();
6941 <            while (b > 1 && t.baseIndex != t.baseLimit) {
6942 <                b >>>= 1;
6943 <                t.pending = 1;
6944 <                MapReduceKeysToIntTask<K,V> rt =
6945 <                    new MapReduceKeysToIntTask<K,V>
6946 <                    (t, b, true, transformer, id, reducer);
6947 <                t = new MapReduceKeysToIntTask<K,V>
6948 <                    (t, b, false, transformer, id, reducer);
6949 <                t.sibling = rt;
6950 <                rt.sibling = t;
6951 <                rt.fork();
6952 <            }
6953 <            int r = id;
6954 <            while (t.advance() != null)
6955 <                r = reducer.apply(r, transformer.apply((K)t.nextKey));
6956 <            t.result = r;
6957 <            for (;;) {
6958 <                int c; BulkTask<K,V,?> par; MapReduceKeysToIntTask<K,V> s, p;
6959 <                if ((par = t.parent) == null ||
6960 <                    !(par instanceof MapReduceKeysToIntTask)) {
6961 <                    t.quietlyComplete();
6962 <                    break;
6963 <                }
6964 <                else if ((c = (p = (MapReduceKeysToIntTask<K,V>)par).pending) == 0) {
6554 <                    if ((s = t.sibling) != null)
6555 <                        r = reducer.apply(r, s.result);
6556 <                    (t = p).result = r;
6938 >                return abortOnNullFunction();
6939 >            try {
6940 >                final int id = this.basis;
6941 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
6942 >                    do {} while (!casPending(c = pending, c+1));
6943 >                    (rights = new MapReduceKeysToIntTask<K,V>
6944 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
6945 >                }
6946 >                int r = id;
6947 >                while (advance() != null)
6948 >                    r = reducer.apply(r, transformer.apply((K)nextKey));
6949 >                result = r;
6950 >                for (MapReduceKeysToIntTask<K,V> t = this, s;;) {
6951 >                    int c; BulkTask<K,V,?> par;
6952 >                    if ((c = t.pending) == 0) {
6953 >                        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;
6965                  }
6966 <                else if (p.casPending(c, 0))
6967 <                    break;
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);
6975 +            }
6976 +            return false;
6977          }
6978          public final Integer getRawResult() { return result; }
6979      }
6980  
6981 <    @SuppressWarnings("serial")
6566 <    static final class MapReduceValuesToIntTask<K,V>
6981 >    @SuppressWarnings("serial") static final class MapReduceValuesToIntTask<K,V>
6982          extends BulkTask<K,V,Integer> {
6983          final ObjectToInt<? super V> transformer;
6984          final IntByIntToInt reducer;
6985          final int basis;
6986          int result;
6987 <        MapReduceValuesToIntTask<K,V> sibling;
6987 >        MapReduceValuesToIntTask<K,V> rights, nextRight;
6988          MapReduceValuesToIntTask
6989 <            (ConcurrentHashMapV8<K,V> m,
6989 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
6990 >             MapReduceValuesToIntTask<K,V> nextRight,
6991               ObjectToInt<? super V> transformer,
6992               int basis,
6993               IntByIntToInt reducer) {
6994 <            super(m);
6994 >            super(m, p, b); this.nextRight = nextRight;
6995              this.transformer = transformer;
6996              this.basis = basis; this.reducer = reducer;
6997          }
6998 <        MapReduceValuesToIntTask
6583 <            (BulkTask<K,V,?> p, int b, boolean split,
6584 <             ObjectToInt<? super V> transformer,
6585 <             int basis,
6586 <             IntByIntToInt reducer) {
6587 <            super(p, b, split);
6588 <            this.transformer = transformer;
6589 <            this.basis = basis; this.reducer = reducer;
6590 <        }
6591 <        @SuppressWarnings("unchecked") public final void compute() {
6592 <            MapReduceValuesToIntTask<K,V> t = this;
6998 >        @SuppressWarnings("unchecked") public final boolean exec() {
6999              final ObjectToInt<? super V> transformer =
7000                  this.transformer;
7001              final IntByIntToInt reducer = this.reducer;
7002              if (transformer == null || reducer == null)
7003 <                throw new Error(NullFunctionMessage);
7004 <            final int id = this.basis;
7005 <            int b = batch();
7006 <            while (b > 1 && t.baseIndex != t.baseLimit) {
7007 <                b >>>= 1;
7008 <                t.pending = 1;
7009 <                MapReduceValuesToIntTask<K,V> rt =
7010 <                    new MapReduceValuesToIntTask<K,V>
7011 <                    (t, b, true, transformer, id, reducer);
7012 <                t = new MapReduceValuesToIntTask<K,V>
7013 <                    (t, b, false, transformer, id, reducer);
7014 <                t.sibling = rt;
7015 <                rt.sibling = t;
7016 <                rt.fork();
7017 <            }
7018 <            int r = id;
7019 <            Object v;
7020 <            while ((v = t.advance()) != null)
7021 <                r = reducer.apply(r, transformer.apply((V)v));
7022 <            t.result = r;
7023 <            for (;;) {
7024 <                int c; BulkTask<K,V,?> par; MapReduceValuesToIntTask<K,V> s, p;
7025 <                if ((par = t.parent) == null ||
7026 <                    !(par instanceof MapReduceValuesToIntTask)) {
7027 <                    t.quietlyComplete();
7028 <                    break;
7029 <                }
7030 <                else if ((c = (p = (MapReduceValuesToIntTask<K,V>)par).pending) == 0) {
6625 <                    if ((s = t.sibling) != null)
6626 <                        r = reducer.apply(r, s.result);
6627 <                    (t = p).result = r;
7003 >                return abortOnNullFunction();
7004 >            try {
7005 >                final int id = this.basis;
7006 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
7007 >                    do {} while (!casPending(c = pending, c+1));
7008 >                    (rights = new MapReduceValuesToIntTask<K,V>
7009 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
7010 >                }
7011 >                int r = id;
7012 >                Object v;
7013 >                while ((v = advance()) != null)
7014 >                    r = reducer.apply(r, transformer.apply((V)v));
7015 >                result = r;
7016 >                for (MapReduceValuesToIntTask<K,V> t = this, s;;) {
7017 >                    int c; BulkTask<K,V,?> par;
7018 >                    if ((c = t.pending) == 0) {
7019 >                        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;
7031                  }
7032 <                else if (p.casPending(c, 0))
7033 <                    break;
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);
7041 +            }
7042 +            return false;
7043          }
7044          public final Integer getRawResult() { return result; }
7045      }
7046  
7047 <    @SuppressWarnings("serial")
6637 <    static final class MapReduceEntriesToIntTask<K,V>
7047 >    @SuppressWarnings("serial") static final class MapReduceEntriesToIntTask<K,V>
7048          extends BulkTask<K,V,Integer> {
7049          final ObjectToInt<Map.Entry<K,V>> transformer;
7050          final IntByIntToInt reducer;
7051          final int basis;
7052          int result;
7053 <        MapReduceEntriesToIntTask<K,V> sibling;
7053 >        MapReduceEntriesToIntTask<K,V> rights, nextRight;
7054          MapReduceEntriesToIntTask
7055 <            (ConcurrentHashMapV8<K,V> m,
7055 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
7056 >             MapReduceEntriesToIntTask<K,V> nextRight,
7057               ObjectToInt<Map.Entry<K,V>> transformer,
7058               int basis,
7059               IntByIntToInt reducer) {
7060 <            super(m);
7060 >            super(m, p, b); this.nextRight = nextRight;
7061              this.transformer = transformer;
7062              this.basis = basis; this.reducer = reducer;
7063          }
7064 <        MapReduceEntriesToIntTask
6654 <            (BulkTask<K,V,?> p, int b, boolean split,
6655 <             ObjectToInt<Map.Entry<K,V>> transformer,
6656 <             int basis,
6657 <             IntByIntToInt reducer) {
6658 <            super(p, b, split);
6659 <            this.transformer = transformer;
6660 <            this.basis = basis; this.reducer = reducer;
6661 <        }
6662 <        @SuppressWarnings("unchecked") public final void compute() {
6663 <            MapReduceEntriesToIntTask<K,V> t = this;
7064 >        @SuppressWarnings("unchecked") public final boolean exec() {
7065              final ObjectToInt<Map.Entry<K,V>> transformer =
7066                  this.transformer;
7067              final IntByIntToInt reducer = this.reducer;
7068              if (transformer == null || reducer == null)
7069 <                throw new Error(NullFunctionMessage);
7070 <            final int id = this.basis;
7071 <            int b = batch();
7072 <            while (b > 1 && t.baseIndex != t.baseLimit) {
7073 <                b >>>= 1;
7074 <                t.pending = 1;
7075 <                MapReduceEntriesToIntTask<K,V> rt =
7076 <                    new MapReduceEntriesToIntTask<K,V>
7077 <                    (t, b, true, transformer, id, reducer);
7078 <                t = new MapReduceEntriesToIntTask<K,V>
7079 <                    (t, b, false, transformer, id, reducer);
7080 <                t.sibling = rt;
7081 <                rt.sibling = t;
7082 <                rt.fork();
7083 <            }
7084 <            int r = id;
7085 <            Object v;
7086 <            while ((v = t.advance()) != null)
7087 <                r = reducer.apply(r, transformer.apply(entryFor((K)t.nextKey, (V)v)));
7088 <            t.result = r;
7089 <            for (;;) {
7090 <                int c; BulkTask<K,V,?> par; MapReduceEntriesToIntTask<K,V> s, p;
7091 <                if ((par = t.parent) == null ||
7092 <                    !(par instanceof MapReduceEntriesToIntTask)) {
7093 <                    t.quietlyComplete();
7094 <                    break;
7095 <                }
7096 <                else if ((c = (p = (MapReduceEntriesToIntTask<K,V>)par).pending) == 0) {
6696 <                    if ((s = t.sibling) != null)
6697 <                        r = reducer.apply(r, s.result);
6698 <                    (t = p).result = r;
7069 >                return abortOnNullFunction();
7070 >            try {
7071 >                final int id = this.basis;
7072 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
7073 >                    do {} while (!casPending(c = pending, c+1));
7074 >                    (rights = new MapReduceEntriesToIntTask<K,V>
7075 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
7076 >                }
7077 >                int r = id;
7078 >                Object v;
7079 >                while ((v = advance()) != null)
7080 >                    r = reducer.apply(r, transformer.apply(entryFor((K)nextKey, (V)v)));
7081 >                result = r;
7082 >                for (MapReduceEntriesToIntTask<K,V> t = this, s;;) {
7083 >                    int c; BulkTask<K,V,?> par;
7084 >                    if ((c = t.pending) == 0) {
7085 >                        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;
7097                  }
7098 <                else if (p.casPending(c, 0))
7099 <                    break;
7098 >            } catch (Throwable ex) {
7099 >                return tryCompleteComputation(ex);
7100 >            }
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;
7109          }
7110          public final Integer getRawResult() { return result; }
7111      }
7112  
7113 <    @SuppressWarnings("serial")
6708 <    static final class MapReduceMappingsToIntTask<K,V>
7113 >    @SuppressWarnings("serial") static final class MapReduceMappingsToIntTask<K,V>
7114          extends BulkTask<K,V,Integer> {
7115          final ObjectByObjectToInt<? super K, ? super V> transformer;
7116          final IntByIntToInt reducer;
7117          final int basis;
7118          int result;
7119 <        MapReduceMappingsToIntTask<K,V> sibling;
7119 >        MapReduceMappingsToIntTask<K,V> rights, nextRight;
7120          MapReduceMappingsToIntTask
7121 <            (ConcurrentHashMapV8<K,V> m,
7121 >            (ConcurrentHashMapV8<K,V> m, BulkTask<K,V,?> p, int b,
7122 >             MapReduceMappingsToIntTask<K,V> rights,
7123               ObjectByObjectToInt<? super K, ? super V> transformer,
7124               int basis,
7125               IntByIntToInt reducer) {
7126 <            super(m);
7126 >            super(m, p, b); this.nextRight = nextRight;
7127              this.transformer = transformer;
7128              this.basis = basis; this.reducer = reducer;
7129          }
7130 <        MapReduceMappingsToIntTask
6725 <            (BulkTask<K,V,?> p, int b, boolean split,
6726 <             ObjectByObjectToInt<? super K, ? super V> transformer,
6727 <             int basis,
6728 <             IntByIntToInt reducer) {
6729 <            super(p, b, split);
6730 <            this.transformer = transformer;
6731 <            this.basis = basis; this.reducer = reducer;
6732 <        }
6733 <        @SuppressWarnings("unchecked") public final void compute() {
6734 <            MapReduceMappingsToIntTask<K,V> t = this;
7130 >        @SuppressWarnings("unchecked") public final boolean exec() {
7131              final ObjectByObjectToInt<? super K, ? super V> transformer =
7132                  this.transformer;
7133              final IntByIntToInt reducer = this.reducer;
7134              if (transformer == null || reducer == null)
7135 <                throw new Error(NullFunctionMessage);
7136 <            final int id = this.basis;
7137 <            int b = batch();
7138 <            while (b > 1 && t.baseIndex != t.baseLimit) {
7139 <                b >>>= 1;
7140 <                t.pending = 1;
7141 <                MapReduceMappingsToIntTask<K,V> rt =
7142 <                    new MapReduceMappingsToIntTask<K,V>
7143 <                    (t, b, true, transformer, id, reducer);
7144 <                t = new MapReduceMappingsToIntTask<K,V>
7145 <                    (t, b, false, transformer, id, reducer);
7146 <                t.sibling = rt;
7147 <                rt.sibling = t;
7148 <                rt.fork();
7149 <            }
7150 <            int r = id;
7151 <            Object v;
7152 <            while ((v = t.advance()) != null)
7153 <                r = reducer.apply(r, transformer.apply((K)t.nextKey, (V)v));
7154 <            t.result = r;
7155 <            for (;;) {
7156 <                int c; BulkTask<K,V,?> par; MapReduceMappingsToIntTask<K,V> s, p;
7157 <                if ((par = t.parent) == null ||
7158 <                    !(par instanceof MapReduceMappingsToIntTask)) {
7159 <                    t.quietlyComplete();
7160 <                    break;
7161 <                }
7162 <                else if ((c = (p = (MapReduceMappingsToIntTask<K,V>)par).pending) == 0) {
6767 <                    if ((s = t.sibling) != null)
6768 <                        r = reducer.apply(r, s.result);
6769 <                    (t = p).result = r;
7135 >                return abortOnNullFunction();
7136 >            try {
7137 >                final int id = this.basis;
7138 >                for (int c, b = batch(); b > 1 && baseIndex != baseLimit;) {
7139 >                    do {} while (!casPending(c = pending, c+1));
7140 >                    (rights = new MapReduceMappingsToIntTask<K,V>
7141 >                     (map, this, b >>>= 1, rights, transformer, id, reducer)).fork();
7142 >                }
7143 >                int r = id;
7144 >                Object v;
7145 >                while ((v = advance()) != null)
7146 >                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
7147 >                result = r;
7148 >                for (MapReduceMappingsToIntTask<K,V> t = this, s;;) {
7149 >                    int c; BulkTask<K,V,?> par;
7150 >                    if ((c = t.pending) == 0) {
7151 >                        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;
7163                  }
7164 <                else if (p.casPending(c, 0))
7165 <                    break;
7164 >            } catch (Throwable ex) {
7165 >                return tryCompleteComputation(ex);
7166 >            }
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;
7175          }
7176          public final Integer getRawResult() { return result; }
7177      }
7178  
6778
7179      // Unsafe mechanics
7180      private static final sun.misc.Unsafe UNSAFE;
7181      private static final long counterOffset;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines