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.83 by jsr166, Fri Dec 14 16:33:42 2012 UTC vs.
Revision 1.84 by dl, Sat Dec 15 20:21:25 2012 UTC

# Line 100 | Line 100 | import java.io.Serializable;
100   * <p>Like {@link Hashtable} but unlike {@link HashMap}, this class
101   * does <em>not</em> allow {@code null} to be used as a key or value.
102   *
103 < * <p>ConcurrentHashMapV8s support parallel operations using the {@link
104 < * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts
105 < * are available in class {@link ForkJoinTasks}). These operations are
106 < * designed to be safely, and often sensibly, applied even with maps
107 < * that are being concurrently updated by other threads; for example,
108 < * when computing a snapshot summary of the values in a shared
109 < * registry.  There are three kinds of operation, each with four
110 < * forms, accepting functions with Keys, Values, Entries, and (Key,
111 < * Value) arguments and/or return values. (The first three forms are
112 < * also available via the {@link #keySet()}, {@link #values()} and
113 < * {@link #entrySet()} views). Because the elements of a
114 < * ConcurrentHashMapV8 are not ordered in any particular way, and may be
115 < * processed in different orders in different parallel executions, the
116 < * correctness of supplied functions should not depend on any
117 < * ordering, or on any other objects or values that may transiently
118 < * change while computation is in progress; and except for forEach
119 < * actions, should ideally be side-effect-free.
103 > * <p>ConcurrentHashMapV8s support sequential and parallel operations
104 > * bulk operations. (Parallel forms use the {@link
105 > * ForkJoinPool#commonPool()}). Tasks that may be used in other
106 > * contexts are available in class {@link ForkJoinTasks}. These
107 > * operations are designed to be safely, and often sensibly, applied
108 > * even with maps that are being concurrently updated by other
109 > * threads; for example, when computing a snapshot summary of the
110 > * values in a shared registry.  There are three kinds of operation,
111 > * each with four forms, accepting functions with Keys, Values,
112 > * Entries, and (Key, Value) arguments and/or return values. Because
113 > * the elements of a ConcurrentHashMapV8 are not ordered in any
114 > * particular way, and may be processed in different orders in
115 > * different parallel executions, the correctness of supplied
116 > * functions should not depend on any ordering, or on any other
117 > * objects or values that may transiently change while computation is
118 > * in progress; and except for forEach actions, should ideally be
119 > * side-effect-free.
120   *
121   * <ul>
122   * <li> forEach: Perform a given action on each element.
# Line 189 | Line 189 | import java.io.Serializable;
189   * exceptions, or would have done so if the first exception had
190   * not occurred.
191   *
192 < * <p>Parallel speedups for bulk operations compared to sequential
193 < * processing are common but not guaranteed.  Operations involving
194 < * brief functions on small maps may execute more slowly than
195 < * sequential loops if the underlying work to parallelize the
196 < * computation is more expensive than the computation itself.
197 < * Similarly, parallelization may not lead to much actual parallelism
198 < * if all processors are busy performing unrelated tasks.
192 > * <p>Speedups for parallel compared to sequential forms are common
193 > * but not guaranteed.  Parallel operations involving brief functions
194 > * on small maps may execute more slowly than sequential forms if the
195 > * underlying work to parallelize the computation is more expensive
196 > * than the computation itself.  Similarly, parallelization may not
197 > * lead to much actual parallelism if all processors are busy
198 > * performing unrelated tasks.
199   *
200   * <p>All arguments to all task methods must be non-null.
201   *
# Line 295 | Line 295 | public class ConcurrentHashMapV8<K, V>
295       * the same or better than java.util.HashMap, and to support high
296       * initial insertion rates on an empty table by many threads.
297       *
298 <     * Each key-value mapping is held in a Node.  Because Node fields
299 <     * can contain special values, they are defined using plain Object
300 <     * types. Similarly in turn, all internal methods that use them
301 <     * work off Object types. And similarly, so do the internal
302 <     * methods of auxiliary iterator and view classes. This also
303 <     * allows many of the public methods to be factored into a smaller
304 <     * number of internal methods (although sadly not so for the five
305 <     * variants of put-related operations). The validation-based
306 <     * approach explained below leads to a lot of code sprawl because
298 >     * Each key-value mapping is held in a Node.  Because Node key
299 >     * fields can contain special values, they are defined using plain
300 >     * Object types (not type "K"). This leads to a lot of explicit
301 >     * casting (and many explicit warning suppressions to tell
302 >     * compilers not to complain about it). It also allows some of the
303 >     * public methods to be factored into a smaller number of internal
304 >     * methods (although sadly not so for the five variants of
305 >     * put-related operations). The validation-based approach
306 >     * explained below leads to a lot of code sprawl because
307       * retry-control precludes factoring into smaller methods.
308       *
309       * The table is lazily initialized to a power-of-two size upon the
# Line 578 | Line 578 | public class ConcurrentHashMapV8<K, V>
578       * The array of bins. Lazily initialized upon first insertion.
579       * Size is always a power of two. Accessed directly by iterators.
580       */
581 <    transient volatile Node[] table;
581 >    transient volatile Node<V>[] table;
582  
583      /**
584       * The next table to use; non-null only while resizing.
585       */
586 <    private transient volatile Node[] nextTable;
586 >    private transient volatile Node<V>[] nextTable;
587  
588      /**
589       * Base counter value, used mainly when there is no contention,
# Line 644 | Line 644 | public class ConcurrentHashMapV8<K, V>
644       * inline assignments below.
645       */
646  
647 <    static final Node tabAt(Node[] tab, int i) { // used by Traverser
648 <        return (Node)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
647 >    @SuppressWarnings("unchecked") static final <V> Node<V> tabAt
648 >        (Node<V>[] tab, int i) { // used by Traverser
649 >        return (Node<V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
650      }
651  
652 <    private static final boolean casTabAt(Node[] tab, int i, Node c, Node v) {
652 >    private static final <V> boolean casTabAt
653 >        (Node<V>[] tab, int i, Node<V> c, Node<V> v) {
654          return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
655      }
656  
657 <    private static final void setTabAt(Node[] tab, int i, Node v) {
657 >    private static final <V> void setTabAt
658 >        (Node<V>[] tab, int i, Node<V> v) {
659          U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
660      }
661  
# Line 668 | Line 671 | public class ConcurrentHashMapV8<K, V>
671       * before a val, but can only be used after checking val to be
672       * non-null.
673       */
674 <    static class Node {
674 >    static class Node<V> {
675          final int hash;
676          final Object key;
677 <        volatile Object val;
678 <        volatile Node next;
677 >        volatile V val;
678 >        volatile Node<V> next;
679  
680 <        Node(int hash, Object key, Object val, Node next) {
680 >        Node(int hash, Object key, V val, Node<V> next) {
681              this.hash = hash;
682              this.key = key;
683              this.val = val;
# Line 687 | Line 690 | public class ConcurrentHashMapV8<K, V>
690      /**
691       * Nodes for use in TreeBins
692       */
693 <    static final class TreeNode extends Node {
694 <        TreeNode parent;  // red-black tree links
695 <        TreeNode left;
696 <        TreeNode right;
697 <        TreeNode prev;    // needed to unlink next upon deletion
693 >    static final class TreeNode<V> extends Node<V> {
694 >        TreeNode<V> parent;  // red-black tree links
695 >        TreeNode<V> left;
696 >        TreeNode<V> right;
697 >        TreeNode<V> prev;    // needed to unlink next upon deletion
698          boolean red;
699  
700 <        TreeNode(int hash, Object key, Object val, Node next, TreeNode parent) {
700 >        TreeNode(int hash, Object key, V val, Node<V> next, TreeNode<V> parent) {
701              super(hash, key, val, next);
702              this.parent = parent;
703          }
# Line 743 | Line 746 | public class ConcurrentHashMapV8<K, V>
746       * and writers. Since we don't need to export full Lock API, we
747       * just override the minimal AQS methods and use them directly.
748       */
749 <    static final class TreeBin extends AbstractQueuedSynchronizer {
749 >    static final class TreeBin<V> extends AbstractQueuedSynchronizer {
750          private static final long serialVersionUID = 2249069246763182397L;
751 <        transient TreeNode root;  // root of tree
752 <        transient TreeNode first; // head of next-pointer list
751 >        transient TreeNode<V> root;  // root of tree
752 >        transient TreeNode<V> first; // head of next-pointer list
753  
754          /* AQS overrides */
755          public final boolean isHeldExclusively() { return getState() > 0; }
# Line 777 | Line 780 | public class ConcurrentHashMapV8<K, V>
780          }
781  
782          /** From CLR */
783 <        private void rotateLeft(TreeNode p) {
783 >        private void rotateLeft(TreeNode<V> p) {
784              if (p != null) {
785 <                TreeNode r = p.right, pp, rl;
785 >                TreeNode<V> r = p.right, pp, rl;
786                  if ((rl = p.right = r.left) != null)
787                      rl.parent = p;
788                  if ((pp = r.parent = p.parent) == null)
# Line 794 | Line 797 | public class ConcurrentHashMapV8<K, V>
797          }
798  
799          /** From CLR */
800 <        private void rotateRight(TreeNode p) {
800 >        private void rotateRight(TreeNode<V> p) {
801              if (p != null) {
802 <                TreeNode l = p.left, pp, lr;
802 >                TreeNode<V> l = p.left, pp, lr;
803                  if ((lr = p.left = l.right) != null)
804                      lr.parent = p;
805                  if ((pp = l.parent = p.parent) == null)
# Line 814 | Line 817 | public class ConcurrentHashMapV8<K, V>
817           * Returns the TreeNode (or null if not found) for the given key
818           * starting at given root.
819           */
820 <        @SuppressWarnings("unchecked") final TreeNode getTreeNode
821 <            (int h, Object k, TreeNode p) {
820 >        @SuppressWarnings("unchecked") final TreeNode<V> getTreeNode
821 >            (int h, Object k, TreeNode<V> p) {
822              Class<?> c = k.getClass();
823              while (p != null) {
824                  int dir, ph;  Object pk; Class<?> pc;
# Line 827 | Line 830 | public class ConcurrentHashMapV8<K, V>
830                          (dir = ((Comparable)k).compareTo((Comparable)pk)) == 0) {
831                          if ((dir = (c == pc) ? 0 :
832                               c.getName().compareTo(pc.getName())) == 0) {
833 <                            TreeNode r = null, pl, pr; // check both sides
833 >                            TreeNode<V> r = null, pl, pr; // check both sides
834                              if ((pr = p.right) != null && h >= pr.hash &&
835                                  (r = getTreeNode(h, k, pr)) != null)
836                                  return r;
# Line 850 | Line 853 | public class ConcurrentHashMapV8<K, V>
853           * read-lock to call getTreeNode, but during failure to get
854           * lock, searches along next links.
855           */
856 <        final Object getValue(int h, Object k) {
857 <            Node r = null;
856 >        final V getValue(int h, Object k) {
857 >            Node<V> r = null;
858              int c = getState(); // Must read lock state first
859 <            for (Node e = first; e != null; e = e.next) {
859 >            for (Node<V> e = first; e != null; e = e.next) {
860                  if (c <= 0 && compareAndSetState(c, c - 1)) {
861                      try {
862                          r = getTreeNode(h, k, root);
# Line 876 | Line 879 | public class ConcurrentHashMapV8<K, V>
879           * Finds or adds a node.
880           * @return null if added
881           */
882 <        @SuppressWarnings("unchecked") final TreeNode putTreeNode
883 <            (int h, Object k, Object v) {
882 >        @SuppressWarnings("unchecked") final TreeNode<V> putTreeNode
883 >            (int h, Object k, V v) {
884              Class<?> c = k.getClass();
885 <            TreeNode pp = root, p = null;
885 >            TreeNode<V> pp = root, p = null;
886              int dir = 0;
887              while (pp != null) { // find existing node or leaf to insert at
888                  int ph;  Object pk; Class<?> pc;
# Line 890 | Line 893 | public class ConcurrentHashMapV8<K, V>
893                      if (c != (pc = pk.getClass()) ||
894                          !(k instanceof Comparable) ||
895                          (dir = ((Comparable)k).compareTo((Comparable)pk)) == 0) {
896 <                        TreeNode s = null, r = null, pr;
896 >                        TreeNode<V> s = null, r = null, pr;
897                          if ((dir = (c == pc) ? 0 :
898                               c.getName().compareTo(pc.getName())) == 0) {
899                              if ((pr = p.right) != null && h >= pr.hash &&
# Line 910 | Line 913 | public class ConcurrentHashMapV8<K, V>
913                  pp = (dir > 0) ? p.right : p.left;
914              }
915  
916 <            TreeNode f = first;
917 <            TreeNode x = first = new TreeNode(h, k, v, f, p);
916 >            TreeNode<V> f = first;
917 >            TreeNode<V> x = first = new TreeNode<V>(h, k, v, f, p);
918              if (p == null)
919                  root = x;
920              else { // attach and rebalance; adapted from CLR
921 <                TreeNode xp, xpp;
921 >                TreeNode<V> xp, xpp;
922                  if (f != null)
923                      f.prev = x;
924                  if (dir <= 0)
# Line 925 | Line 928 | public class ConcurrentHashMapV8<K, V>
928                  x.red = true;
929                  while (x != null && (xp = x.parent) != null && xp.red &&
930                         (xpp = xp.parent) != null) {
931 <                    TreeNode xppl = xpp.left;
931 >                    TreeNode<V> xppl = xpp.left;
932                      if (xp == xppl) {
933 <                        TreeNode y = xpp.right;
933 >                        TreeNode<V> y = xpp.right;
934                          if (y != null && y.red) {
935                              y.red = false;
936                              xp.red = false;
# Line 949 | Line 952 | public class ConcurrentHashMapV8<K, V>
952                          }
953                      }
954                      else {
955 <                        TreeNode y = xppl;
955 >                        TreeNode<V> y = xppl;
956                          if (y != null && y.red) {
957                              y.red = false;
958                              xp.red = false;
# Line 971 | Line 974 | public class ConcurrentHashMapV8<K, V>
974                          }
975                      }
976                  }
977 <                TreeNode r = root;
977 >                TreeNode<V> r = root;
978                  if (r != null && r.red)
979                      r.red = false;
980              }
# Line 986 | Line 989 | public class ConcurrentHashMapV8<K, V>
989           * that are accessible independently of lock. So instead we
990           * swap the tree linkages.
991           */
992 <        final void deleteTreeNode(TreeNode p) {
993 <            TreeNode next = (TreeNode)p.next; // unlink traversal pointers
994 <            TreeNode pred = p.prev;
992 >        final void deleteTreeNode(TreeNode<V> p) {
993 >            TreeNode<V> next = (TreeNode<V>)p.next; // unlink traversal pointers
994 >            TreeNode<V> pred = p.prev;
995              if (pred == null)
996                  first = next;
997              else
998                  pred.next = next;
999              if (next != null)
1000                  next.prev = pred;
1001 <            TreeNode replacement;
1002 <            TreeNode pl = p.left;
1003 <            TreeNode pr = p.right;
1001 >            TreeNode<V> replacement;
1002 >            TreeNode<V> pl = p.left;
1003 >            TreeNode<V> pr = p.right;
1004              if (pl != null && pr != null) {
1005 <                TreeNode s = pr, sl;
1005 >                TreeNode<V> s = pr, sl;
1006                  while ((sl = s.left) != null) // find successor
1007                      s = sl;
1008                  boolean c = s.red; s.red = p.red; p.red = c; // swap colors
1009 <                TreeNode sr = s.right;
1010 <                TreeNode pp = p.parent;
1009 >                TreeNode<V> sr = s.right;
1010 >                TreeNode<V> pp = p.parent;
1011                  if (s == pr) { // p was s's direct parent
1012                      p.parent = s;
1013                      s.right = p;
1014                  }
1015                  else {
1016 <                    TreeNode sp = s.parent;
1016 >                    TreeNode<V> sp = s.parent;
1017                      if ((p.parent = sp) != null) {
1018                          if (s == sp.left)
1019                              sp.left = p;
# Line 1035 | Line 1038 | public class ConcurrentHashMapV8<K, V>
1038              }
1039              else
1040                  replacement = (pl != null) ? pl : pr;
1041 <            TreeNode pp = p.parent;
1041 >            TreeNode<V> pp = p.parent;
1042              if (replacement == null) {
1043                  if (pp == null) {
1044                      root = null;
# Line 1054 | Line 1057 | public class ConcurrentHashMapV8<K, V>
1057                  p.left = p.right = p.parent = null;
1058              }
1059              if (!p.red) { // rebalance, from CLR
1060 <                TreeNode x = replacement;
1060 >                TreeNode<V> x = replacement;
1061                  while (x != null) {
1062 <                    TreeNode xp, xpl;
1062 >                    TreeNode<V> xp, xpl;
1063                      if (x.red || (xp = x.parent) == null) {
1064                          x.red = false;
1065                          break;
1066                      }
1067                      if (x == (xpl = xp.left)) {
1068 <                        TreeNode sib = xp.right;
1068 >                        TreeNode<V> sib = xp.right;
1069                          if (sib != null && sib.red) {
1070                              sib.red = false;
1071                              xp.red = true;
# Line 1072 | Line 1075 | public class ConcurrentHashMapV8<K, V>
1075                          if (sib == null)
1076                              x = xp;
1077                          else {
1078 <                            TreeNode sl = sib.left, sr = sib.right;
1078 >                            TreeNode<V> sl = sib.left, sr = sib.right;
1079                              if ((sr == null || !sr.red) &&
1080                                  (sl == null || !sl.red)) {
1081                                  sib.red = true;
# Line 1101 | Line 1104 | public class ConcurrentHashMapV8<K, V>
1104                          }
1105                      }
1106                      else { // symmetric
1107 <                        TreeNode sib = xpl;
1107 >                        TreeNode<V> sib = xpl;
1108                          if (sib != null && sib.red) {
1109                              sib.red = false;
1110                              xp.red = true;
# Line 1111 | Line 1114 | public class ConcurrentHashMapV8<K, V>
1114                          if (sib == null)
1115                              x = xp;
1116                          else {
1117 <                            TreeNode sl = sib.left, sr = sib.right;
1117 >                            TreeNode<V> sl = sib.left, sr = sib.right;
1118                              if ((sl == null || !sl.red) &&
1119                                  (sr == null || !sr.red)) {
1120                                  sib.red = true;
# Line 1175 | Line 1178 | public class ConcurrentHashMapV8<K, V>
1178       * Replaces a list bin with a tree bin if key is comparable.  Call
1179       * only when locked.
1180       */
1181 <    private final void replaceWithTreeBin(Node[] tab, int index, Object key) {
1181 >    private final void replaceWithTreeBin(Node<V>[] tab, int index, Object key) {
1182          if (key instanceof Comparable) {
1183 <            TreeBin t = new TreeBin();
1184 <            for (Node e = tabAt(tab, index); e != null; e = e.next)
1183 >            TreeBin<V> t = new TreeBin<V>();
1184 >            for (Node<V> e = tabAt(tab, index); e != null; e = e.next)
1185                  t.putTreeNode(e.hash, e.key, e.val);
1186 <            setTabAt(tab, index, new Node(MOVED, t, null, null));
1186 >            setTabAt(tab, index, new Node<V>(MOVED, t, null, null));
1187          }
1188      }
1189  
# Line 1189 | Line 1192 | public class ConcurrentHashMapV8<K, V>
1192      /** Implementation for get and containsKey */
1193      @SuppressWarnings("unchecked") private final V internalGet(Object k) {
1194          int h = spread(k.hashCode());
1195 <        retry: for (Node[] tab = table; tab != null;) {
1196 <            Node e; Object ek, ev; int eh;      // locals to read fields once
1195 >        retry: for (Node<V>[] tab = table; tab != null;) {
1196 >            Node<V> e; Object ek; V ev; int eh; // locals to read fields once
1197              for (e = tabAt(tab, (tab.length - 1) & h); e != null; e = e.next) {
1198                  if ((eh = e.hash) < 0) {
1199                      if ((ek = e.key) instanceof TreeBin)  // search TreeBin
1200 <                        return (V)((TreeBin)ek).getValue(h, k);
1201 <                    else {                        // restart with new table
1202 <                        tab = (Node[])ek;
1200 >                        return ((TreeBin<V>)ek).getValue(h, k);
1201 >                    else {                      // restart with new table
1202 >                        tab = (Node<V>[])ek;
1203                          continue retry;
1204                      }
1205                  }
1206                  else if (eh == h && (ev = e.val) != null &&
1207                           ((ek = e.key) == k || k.equals(ek)))
1208 <                    return (V)ev;
1208 >                    return ev;
1209              }
1210              break;
1211          }
# Line 1217 | Line 1220 | public class ConcurrentHashMapV8<K, V>
1220      @SuppressWarnings("unchecked") private final V internalReplace
1221          (Object k, V v, Object cv) {
1222          int h = spread(k.hashCode());
1223 <        Object oldVal = null;
1224 <        for (Node[] tab = table;;) {
1225 <            Node f; int i, fh; Object fk;
1223 >        V oldVal = null;
1224 >        for (Node<V>[] tab = table;;) {
1225 >            Node<V> f; int i, fh; Object fk;
1226              if (tab == null ||
1227                  (f = tabAt(tab, i = (tab.length - 1) & h)) == null)
1228                  break;
1229              else if ((fh = f.hash) < 0) {
1230                  if ((fk = f.key) instanceof TreeBin) {
1231 <                    TreeBin t = (TreeBin)fk;
1231 >                    TreeBin<V> t = (TreeBin<V>)fk;
1232                      boolean validated = false;
1233                      boolean deleted = false;
1234                      t.acquire(0);
1235                      try {
1236                          if (tabAt(tab, i) == f) {
1237                              validated = true;
1238 <                            TreeNode p = t.getTreeNode(h, k, t.root);
1238 >                            TreeNode<V> p = t.getTreeNode(h, k, t.root);
1239                              if (p != null) {
1240 <                                Object pv = p.val;
1240 >                                V pv = p.val;
1241                                  if (cv == null || cv == pv || cv.equals(pv)) {
1242                                      oldVal = pv;
1243                                      if ((p.val = v) == null) {
# Line 1254 | Line 1257 | public class ConcurrentHashMapV8<K, V>
1257                      }
1258                  }
1259                  else
1260 <                    tab = (Node[])fk;
1260 >                    tab = (Node<V>[])fk;
1261              }
1262              else if (fh != h && f.next == null) // precheck
1263                  break;                          // rules out possible existence
# Line 1264 | Line 1267 | public class ConcurrentHashMapV8<K, V>
1267                  synchronized (f) {
1268                      if (tabAt(tab, i) == f) {
1269                          validated = true;
1270 <                        for (Node e = f, pred = null;;) {
1271 <                            Object ek, ev;
1270 >                        for (Node<V> e = f, pred = null;;) {
1271 >                            Object ek; V ev;
1272                              if (e.hash == h &&
1273                                  ((ev = e.val) != null) &&
1274                                  ((ek = e.key) == k || k.equals(ek))) {
# Line 1273 | Line 1276 | public class ConcurrentHashMapV8<K, V>
1276                                      oldVal = ev;
1277                                      if ((e.val = v) == null) {
1278                                          deleted = true;
1279 <                                        Node en = e.next;
1279 >                                        Node<V> en = e.next;
1280                                          if (pred != null)
1281                                              pred.next = en;
1282                                          else
# Line 1295 | Line 1298 | public class ConcurrentHashMapV8<K, V>
1298                  }
1299              }
1300          }
1301 <        return (V)oldVal;
1301 >        return oldVal;
1302      }
1303  
1304      /*
# Line 1322 | Line 1325 | public class ConcurrentHashMapV8<K, V>
1325          if (k == null || v == null) throw new NullPointerException();
1326          int h = spread(k.hashCode());
1327          int len = 0;
1328 <        for (Node[] tab = table;;) {
1329 <            int i, fh; Node f; Object fk, fv;
1328 >        for (Node<V>[] tab = table;;) {
1329 >            int i, fh; Node<V> f; Object fk; V fv;
1330              if (tab == null)
1331                  tab = initTable();
1332              else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
1333 <                if (casTabAt(tab, i, null, new Node(h, k, v, null)))
1333 >                if (casTabAt(tab, i, null, new Node<V>(h, k, v, null)))
1334                      break;                   // no lock when adding to empty bin
1335              }
1336              else if ((fh = f.hash) < 0) {
1337                  if ((fk = f.key) instanceof TreeBin) {
1338 <                    TreeBin t = (TreeBin)fk;
1339 <                    Object oldVal = null;
1338 >                    TreeBin<V> t = (TreeBin<V>)fk;
1339 >                    V oldVal = null;
1340                      t.acquire(0);
1341                      try {
1342                          if (tabAt(tab, i) == f) {
1343                              len = 2;
1344 <                            TreeNode p = t.putTreeNode(h, k, v);
1344 >                            TreeNode<V> p = t.putTreeNode(h, k, v);
1345                              if (p != null) {
1346                                  oldVal = p.val;
1347                                  if (!onlyIfAbsent)
# Line 1350 | Line 1353 | public class ConcurrentHashMapV8<K, V>
1353                      }
1354                      if (len != 0) {
1355                          if (oldVal != null)
1356 <                            return (V)oldVal;
1356 >                            return oldVal;
1357                          break;
1358                      }
1359                  }
1360                  else
1361 <                    tab = (Node[])fk;
1361 >                    tab = (Node<V>[])fk;
1362              }
1363              else if (onlyIfAbsent && fh == h && (fv = f.val) != null &&
1364                       ((fk = f.key) == k || k.equals(fk))) // peek while nearby
1365 <                return (V)fv;
1365 >                return fv;
1366              else {
1367 <                Object oldVal = null;
1367 >                V oldVal = null;
1368                  synchronized (f) {
1369                      if (tabAt(tab, i) == f) {
1370                          len = 1;
1371 <                        for (Node e = f;; ++len) {
1372 <                            Object ek, ev;
1371 >                        for (Node<V> e = f;; ++len) {
1372 >                            Object ek; V ev;
1373                              if (e.hash == h &&
1374                                  (ev = e.val) != null &&
1375                                  ((ek = e.key) == k || k.equals(ek))) {
# Line 1375 | Line 1378 | public class ConcurrentHashMapV8<K, V>
1378                                      e.val = v;
1379                                  break;
1380                              }
1381 <                            Node last = e;
1381 >                            Node<V> last = e;
1382                              if ((e = e.next) == null) {
1383 <                                last.next = new Node(h, k, v, null);
1383 >                                last.next = new Node<V>(h, k, v, null);
1384                                  if (len >= TREE_THRESHOLD)
1385                                      replaceWithTreeBin(tab, i, k);
1386                                  break;
# Line 1387 | Line 1390 | public class ConcurrentHashMapV8<K, V>
1390                  }
1391                  if (len != 0) {
1392                      if (oldVal != null)
1393 <                        return (V)oldVal;
1393 >                        return oldVal;
1394                      break;
1395                  }
1396              }
# Line 1398 | Line 1401 | public class ConcurrentHashMapV8<K, V>
1401  
1402      /** Implementation for computeIfAbsent */
1403      @SuppressWarnings("unchecked") private final V internalComputeIfAbsent
1404 <        (K k, Fun<? super K, ?> mf) {
1404 >        (K k, Fun<? super K, ? extends V> mf) {
1405          if (k == null || mf == null)
1406              throw new NullPointerException();
1407          int h = spread(k.hashCode());
1408 <        Object val = null;
1408 >        V val = null;
1409          int len = 0;
1410 <        for (Node[] tab = table;;) {
1411 <            Node f; int i; Object fk;
1410 >        for (Node<V>[] tab = table;;) {
1411 >            Node<V> f; int i; Object fk;
1412              if (tab == null)
1413                  tab = initTable();
1414              else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
1415 <                Node node = new Node(h, k, null, null);
1415 >                Node<V> node = new Node<V>(h, k, null, null);
1416                  synchronized (node) {
1417                      if (casTabAt(tab, i, null, node)) {
1418                          len = 1;
# Line 1427 | Line 1430 | public class ConcurrentHashMapV8<K, V>
1430              }
1431              else if (f.hash < 0) {
1432                  if ((fk = f.key) instanceof TreeBin) {
1433 <                    TreeBin t = (TreeBin)fk;
1433 >                    TreeBin<V> t = (TreeBin<V>)fk;
1434                      boolean added = false;
1435                      t.acquire(0);
1436                      try {
1437                          if (tabAt(tab, i) == f) {
1438                              len = 1;
1439 <                            TreeNode p = t.getTreeNode(h, k, t.root);
1439 >                            TreeNode<V> p = t.getTreeNode(h, k, t.root);
1440                              if (p != null)
1441                                  val = p.val;
1442                              else if ((val = mf.apply(k)) != null) {
# Line 1447 | Line 1450 | public class ConcurrentHashMapV8<K, V>
1450                      }
1451                      if (len != 0) {
1452                          if (!added)
1453 <                            return (V)val;
1453 >                            return val;
1454                          break;
1455                      }
1456                  }
1457                  else
1458 <                    tab = (Node[])fk;
1458 >                    tab = (Node<V>[])fk;
1459              }
1460              else {
1461 <                for (Node e = f; e != null; e = e.next) { // prescan
1462 <                    Object ek, ev;
1461 >                for (Node<V> e = f; e != null; e = e.next) { // prescan
1462 >                    Object ek; V ev;
1463                      if (e.hash == h && (ev = e.val) != null &&
1464                          ((ek = e.key) == k || k.equals(ek)))
1465 <                        return (V)ev;
1465 >                        return ev;
1466                  }
1467                  boolean added = false;
1468                  synchronized (f) {
1469                      if (tabAt(tab, i) == f) {
1470                          len = 1;
1471 <                        for (Node e = f;; ++len) {
1472 <                            Object ek, ev;
1471 >                        for (Node<V> e = f;; ++len) {
1472 >                            Object ek; V ev;
1473                              if (e.hash == h &&
1474                                  (ev = e.val) != null &&
1475                                  ((ek = e.key) == k || k.equals(ek))) {
1476                                  val = ev;
1477                                  break;
1478                              }
1479 <                            Node last = e;
1479 >                            Node<V> last = e;
1480                              if ((e = e.next) == null) {
1481                                  if ((val = mf.apply(k)) != null) {
1482                                      added = true;
1483 <                                    last.next = new Node(h, k, val, null);
1483 >                                    last.next = new Node<V>(h, k, val, null);
1484                                      if (len >= TREE_THRESHOLD)
1485                                          replaceWithTreeBin(tab, i, k);
1486                                  }
# Line 1488 | Line 1491 | public class ConcurrentHashMapV8<K, V>
1491                  }
1492                  if (len != 0) {
1493                      if (!added)
1494 <                        return (V)val;
1494 >                        return val;
1495                      break;
1496                  }
1497              }
1498          }
1499          if (val != null)
1500              addCount(1L, len);
1501 <        return (V)val;
1501 >        return val;
1502      }
1503  
1504      /** Implementation for compute */
# Line 1505 | Line 1508 | public class ConcurrentHashMapV8<K, V>
1508          if (k == null || mf == null)
1509              throw new NullPointerException();
1510          int h = spread(k.hashCode());
1511 <        Object val = null;
1511 >        V val = null;
1512          int delta = 0;
1513          int len = 0;
1514 <        for (Node[] tab = table;;) {
1515 <            Node f; int i, fh; Object fk;
1514 >        for (Node<V>[] tab = table;;) {
1515 >            Node<V> f; int i, fh; Object fk;
1516              if (tab == null)
1517                  tab = initTable();
1518              else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
1519                  if (onlyIfPresent)
1520                      break;
1521 <                Node node = new Node(h, k, null, null);
1521 >                Node<V> node = new Node<V>(h, k, null, null);
1522                  synchronized (node) {
1523                      if (casTabAt(tab, i, null, node)) {
1524                          try {
# Line 1535 | Line 1538 | public class ConcurrentHashMapV8<K, V>
1538              }
1539              else if ((fh = f.hash) < 0) {
1540                  if ((fk = f.key) instanceof TreeBin) {
1541 <                    TreeBin t = (TreeBin)fk;
1541 >                    TreeBin<V> t = (TreeBin<V>)fk;
1542                      t.acquire(0);
1543                      try {
1544                          if (tabAt(tab, i) == f) {
1545                              len = 1;
1546 <                            TreeNode p = t.getTreeNode(h, k, t.root);
1546 >                            TreeNode<V> p = t.getTreeNode(h, k, t.root);
1547                              if (p == null && onlyIfPresent)
1548                                  break;
1549 <                            Object pv = (p == null) ? null : p.val;
1550 <                            if ((val = mf.apply(k, (V)pv)) != null) {
1549 >                            V pv = (p == null) ? null : p.val;
1550 >                            if ((val = mf.apply(k, pv)) != null) {
1551                                  if (p != null)
1552                                      p.val = val;
1553                                  else {
# Line 1565 | Line 1568 | public class ConcurrentHashMapV8<K, V>
1568                          break;
1569                  }
1570                  else
1571 <                    tab = (Node[])fk;
1571 >                    tab = (Node<V>[])fk;
1572              }
1573              else {
1574                  synchronized (f) {
1575                      if (tabAt(tab, i) == f) {
1576                          len = 1;
1577 <                        for (Node e = f, pred = null;; ++len) {
1578 <                            Object ek, ev;
1577 >                        for (Node<V> e = f, pred = null;; ++len) {
1578 >                            Object ek; V ev;
1579                              if (e.hash == h &&
1580                                  (ev = e.val) != null &&
1581                                  ((ek = e.key) == k || k.equals(ek))) {
1582 <                                val = mf.apply(k, (V)ev);
1582 >                                val = mf.apply(k, ev);
1583                                  if (val != null)
1584                                      e.val = val;
1585                                  else {
1586                                      delta = -1;
1587 <                                    Node en = e.next;
1587 >                                    Node<V> en = e.next;
1588                                      if (pred != null)
1589                                          pred.next = en;
1590                                      else
# Line 1593 | Line 1596 | public class ConcurrentHashMapV8<K, V>
1596                              if ((e = e.next) == null) {
1597                                  if (!onlyIfPresent &&
1598                                      (val = mf.apply(k, null)) != null) {
1599 <                                    pred.next = new Node(h, k, val, null);
1599 >                                    pred.next = new Node<V>(h, k, val, null);
1600                                      delta = 1;
1601                                      if (len >= TREE_THRESHOLD)
1602                                          replaceWithTreeBin(tab, i, k);
# Line 1609 | Line 1612 | public class ConcurrentHashMapV8<K, V>
1612          }
1613          if (delta != 0)
1614              addCount((long)delta, len);
1615 <        return (V)val;
1615 >        return val;
1616      }
1617  
1618      /** Implementation for merge */
# Line 1618 | Line 1621 | public class ConcurrentHashMapV8<K, V>
1621          if (k == null || v == null || mf == null)
1622              throw new NullPointerException();
1623          int h = spread(k.hashCode());
1624 <        Object val = null;
1624 >        V val = null;
1625          int delta = 0;
1626          int len = 0;
1627 <        for (Node[] tab = table;;) {
1628 <            int i; Node f; Object fk, fv;
1627 >        for (Node<V>[] tab = table;;) {
1628 >            int i; Node<V> f; Object fk; V fv;
1629              if (tab == null)
1630                  tab = initTable();
1631              else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
1632 <                if (casTabAt(tab, i, null, new Node(h, k, v, null))) {
1632 >                if (casTabAt(tab, i, null, new Node<V>(h, k, v, null))) {
1633                      delta = 1;
1634                      val = v;
1635                      break;
# Line 1634 | Line 1637 | public class ConcurrentHashMapV8<K, V>
1637              }
1638              else if (f.hash < 0) {
1639                  if ((fk = f.key) instanceof TreeBin) {
1640 <                    TreeBin t = (TreeBin)fk;
1640 >                    TreeBin<V> t = (TreeBin<V>)fk;
1641                      t.acquire(0);
1642                      try {
1643                          if (tabAt(tab, i) == f) {
1644                              len = 1;
1645 <                            TreeNode p = t.getTreeNode(h, k, t.root);
1646 <                            val = (p == null) ? v : mf.apply((V)p.val, v);
1645 >                            TreeNode<V> p = t.getTreeNode(h, k, t.root);
1646 >                            val = (p == null) ? v : mf.apply(p.val, v);
1647                              if (val != null) {
1648                                  if (p != null)
1649                                      p.val = val;
# Line 1662 | Line 1665 | public class ConcurrentHashMapV8<K, V>
1665                          break;
1666                  }
1667                  else
1668 <                    tab = (Node[])fk;
1668 >                    tab = (Node<V>[])fk;
1669              }
1670              else {
1671                  synchronized (f) {
1672                      if (tabAt(tab, i) == f) {
1673                          len = 1;
1674 <                        for (Node e = f, pred = null;; ++len) {
1675 <                            Object ek, ev;
1674 >                        for (Node<V> e = f, pred = null;; ++len) {
1675 >                            Object ek; V ev;
1676                              if (e.hash == h &&
1677                                  (ev = e.val) != null &&
1678                                  ((ek = e.key) == k || k.equals(ek))) {
1679 <                                val = mf.apply((V)ev, v);
1679 >                                val = mf.apply(ev, v);
1680                                  if (val != null)
1681                                      e.val = val;
1682                                  else {
1683                                      delta = -1;
1684 <                                    Node en = e.next;
1684 >                                    Node<V> en = e.next;
1685                                      if (pred != null)
1686                                          pred.next = en;
1687                                      else
# Line 1689 | Line 1692 | public class ConcurrentHashMapV8<K, V>
1692                              pred = e;
1693                              if ((e = e.next) == null) {
1694                                  val = v;
1695 <                                pred.next = new Node(h, k, val, null);
1695 >                                pred.next = new Node<V>(h, k, val, null);
1696                                  delta = 1;
1697                                  if (len >= TREE_THRESHOLD)
1698                                      replaceWithTreeBin(tab, i, k);
# Line 1704 | Line 1707 | public class ConcurrentHashMapV8<K, V>
1707          }
1708          if (delta != 0)
1709              addCount((long)delta, len);
1710 <        return (V)val;
1710 >        return val;
1711      }
1712  
1713      /** Implementation for putAll */
1714 <    private final void internalPutAll(Map<?, ?> m) {
1714 >    @SuppressWarnings("unchecked") private final void internalPutAll
1715 >        (Map<? extends K, ? extends V> m) {
1716          tryPresize(m.size());
1717          long delta = 0L;     // number of uncommitted additions
1718          boolean npe = false; // to throw exception on exit for nulls
1719          try {                // to clean up counts on other exceptions
1720 <            for (Map.Entry<?, ?> entry : m.entrySet()) {
1721 <                Object k, v;
1720 >            for (Map.Entry<?, ? extends V> entry : m.entrySet()) {
1721 >                Object k; V v;
1722                  if (entry == null || (k = entry.getKey()) == null ||
1723                      (v = entry.getValue()) == null) {
1724                      npe = true;
1725                      break;
1726                  }
1727                  int h = spread(k.hashCode());
1728 <                for (Node[] tab = table;;) {
1729 <                    int i; Node f; int fh; Object fk;
1728 >                for (Node<V>[] tab = table;;) {
1729 >                    int i; Node<V> f; int fh; Object fk;
1730                      if (tab == null)
1731                          tab = initTable();
1732                      else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null){
1733 <                        if (casTabAt(tab, i, null, new Node(h, k, v, null))) {
1733 >                        if (casTabAt(tab, i, null, new Node<V>(h, k, v, null))) {
1734                              ++delta;
1735                              break;
1736                          }
1737                      }
1738                      else if ((fh = f.hash) < 0) {
1739                          if ((fk = f.key) instanceof TreeBin) {
1740 <                            TreeBin t = (TreeBin)fk;
1740 >                            TreeBin<V> t = (TreeBin<V>)fk;
1741                              boolean validated = false;
1742                              t.acquire(0);
1743                              try {
1744                                  if (tabAt(tab, i) == f) {
1745                                      validated = true;
1746 <                                    TreeNode p = t.getTreeNode(h, k, t.root);
1746 >                                    TreeNode<V> p = t.getTreeNode(h, k, t.root);
1747                                      if (p != null)
1748                                          p.val = v;
1749                                      else {
# Line 1754 | Line 1758 | public class ConcurrentHashMapV8<K, V>
1758                                  break;
1759                          }
1760                          else
1761 <                            tab = (Node[])fk;
1761 >                            tab = (Node<V>[])fk;
1762                      }
1763                      else {
1764                          int len = 0;
1765                          synchronized (f) {
1766                              if (tabAt(tab, i) == f) {
1767                                  len = 1;
1768 <                                for (Node e = f;; ++len) {
1769 <                                    Object ek, ev;
1768 >                                for (Node<V> e = f;; ++len) {
1769 >                                    Object ek; V ev;
1770                                      if (e.hash == h &&
1771                                          (ev = e.val) != null &&
1772                                          ((ek = e.key) == k || k.equals(ek))) {
1773                                          e.val = v;
1774                                          break;
1775                                      }
1776 <                                    Node last = e;
1776 >                                    Node<V> last = e;
1777                                      if ((e = e.next) == null) {
1778                                          ++delta;
1779 <                                        last.next = new Node(h, k, v, null);
1779 >                                        last.next = new Node<V>(h, k, v, null);
1780                                          if (len >= TREE_THRESHOLD)
1781                                              replaceWithTreeBin(tab, i, k);
1782                                          break;
# Line 1800 | Line 1804 | public class ConcurrentHashMapV8<K, V>
1804       * Implementation for clear. Steps through each bin, removing all
1805       * nodes.
1806       */
1807 <    private final void internalClear() {
1807 >    @SuppressWarnings("unchecked") private final void internalClear() {
1808          long delta = 0L; // negative number of deletions
1809          int i = 0;
1810 <        Node[] tab = table;
1810 >        Node<V>[] tab = table;
1811          while (tab != null && i < tab.length) {
1812 <            Node f = tabAt(tab, i);
1812 >            Node<V> f = tabAt(tab, i);
1813              if (f == null)
1814                  ++i;
1815              else if (f.hash < 0) {
1816                  Object fk;
1817                  if ((fk = f.key) instanceof TreeBin) {
1818 <                    TreeBin t = (TreeBin)fk;
1818 >                    TreeBin<V> t = (TreeBin<V>)fk;
1819                      t.acquire(0);
1820                      try {
1821                          if (tabAt(tab, i) == f) {
1822 <                            for (Node p = t.first; p != null; p = p.next) {
1822 >                            for (Node<V> p = t.first; p != null; p = p.next) {
1823                                  if (p.val != null) { // (currently always true)
1824                                      p.val = null;
1825                                      --delta;
# Line 1830 | Line 1834 | public class ConcurrentHashMapV8<K, V>
1834                      }
1835                  }
1836                  else
1837 <                    tab = (Node[])fk;
1837 >                    tab = (Node<V>[])fk;
1838              }
1839              else {
1840                  synchronized (f) {
1841                      if (tabAt(tab, i) == f) {
1842 <                        for (Node e = f; e != null; e = e.next) {
1842 >                        for (Node<V> e = f; e != null; e = e.next) {
1843                              if (e.val != null) {  // (currently always true)
1844                                  e.val = null;
1845                                  --delta;
# Line 1870 | Line 1874 | public class ConcurrentHashMapV8<K, V>
1874      /**
1875       * Initializes table, using the size recorded in sizeCtl.
1876       */
1877 <    private final Node[] initTable() {
1878 <        Node[] tab; int sc;
1877 >    @SuppressWarnings("unchecked") private final Node<V>[] initTable() {
1878 >        Node<V>[] tab; int sc;
1879          while ((tab = table) == null) {
1880              if ((sc = sizeCtl) < 0)
1881                  Thread.yield(); // lost initialization race; just spin
# Line 1879 | Line 1883 | public class ConcurrentHashMapV8<K, V>
1883                  try {
1884                      if ((tab = table) == null) {
1885                          int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
1886 <                        tab = table = new Node[n];
1886 >                        @SuppressWarnings("rawtypes") Node[] tb = new Node[n];
1887 >                        table = tab = (Node<V>[])tb;
1888                          sc = n - (n >>> 2);
1889                      }
1890                  } finally {
# Line 1920 | Line 1925 | public class ConcurrentHashMapV8<K, V>
1925              s = sumCount();
1926          }
1927          if (check >= 0) {
1928 <            Node[] tab, nt; int sc;
1928 >            Node<V>[] tab, nt; int sc;
1929              while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
1930                     tab.length < MAXIMUM_CAPACITY) {
1931                  if (sc < 0) {
# Line 1942 | Line 1947 | public class ConcurrentHashMapV8<K, V>
1947       *
1948       * @param size number of elements (doesn't need to be perfectly accurate)
1949       */
1950 <    private final void tryPresize(int size) {
1950 >    @SuppressWarnings("unchecked") private final void tryPresize(int size) {
1951          int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :
1952              tableSizeFor(size + (size >>> 1) + 1);
1953          int sc;
1954          while ((sc = sizeCtl) >= 0) {
1955 <            Node[] tab = table; int n;
1955 >            Node<V>[] tab = table; int n;
1956              if (tab == null || (n = tab.length) == 0) {
1957                  n = (sc > c) ? sc : c;
1958                  if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
1959                      try {
1960                          if (table == tab) {
1961 <                            table = new Node[n];
1961 >                            @SuppressWarnings("rawtypes") Node[] tb = new Node[n];
1962 >                            table = (Node<V>[])tb;
1963                              sc = n - (n >>> 2);
1964                          }
1965                      } finally {
# Line 1973 | Line 1979 | public class ConcurrentHashMapV8<K, V>
1979       * Moves and/or copies the nodes in each bin to new table. See
1980       * above for explanation.
1981       */
1982 <    private final void transfer(Node[] tab, Node[] nextTab) {
1982 >    @SuppressWarnings("unchecked") private final void transfer
1983 >        (Node<V>[] tab, Node<V>[] nextTab) {
1984          int n = tab.length, stride;
1985          if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)
1986              stride = MIN_TRANSFER_STRIDE; // subdivide range
1987          if (nextTab == null) {            // initiating
1988              try {
1989 <                nextTab = new Node[n << 1];
1989 >                @SuppressWarnings("rawtypes") Node[] tb = new Node[n << 1];
1990 >                nextTab = (Node<V>[])tb;
1991              } catch (Throwable ex) {      // try to cope with OOME
1992                  sizeCtl = Integer.MAX_VALUE;
1993                  return;
# Line 1987 | Line 1995 | public class ConcurrentHashMapV8<K, V>
1995              nextTable = nextTab;
1996              transferOrigin = n;
1997              transferIndex = n;
1998 <            Node rev = new Node(MOVED, tab, null, null);
1998 >            Node<V> rev = new Node<V>(MOVED, tab, null, null);
1999              for (int k = n; k > 0;) {    // progressively reveal ready slots
2000                  int nextk = (k > stride) ? k - stride : 0;
2001                  for (int m = nextk; m < k; ++m)
# Line 1998 | Line 2006 | public class ConcurrentHashMapV8<K, V>
2006              }
2007          }
2008          int nextn = nextTab.length;
2009 <        Node fwd = new Node(MOVED, nextTab, null, null);
2009 >        Node<V> fwd = new Node<V>(MOVED, nextTab, null, null);
2010          boolean advance = true;
2011          for (int i = 0, bound = 0;;) {
2012 <            int nextIndex, nextBound; Node f; Object fk;
2012 >            int nextIndex, nextBound; Node<V> f; Object fk;
2013              while (advance) {
2014                  if (--i >= bound)
2015                      advance = false;
# Line 2041 | Line 2049 | public class ConcurrentHashMapV8<K, V>
2049                  synchronized (f) {
2050                      if (tabAt(tab, i) == f) {
2051                          int runBit = f.hash & n;
2052 <                        Node lastRun = f, lo = null, hi = null;
2053 <                        for (Node p = f.next; p != null; p = p.next) {
2052 >                        Node<V> lastRun = f, lo = null, hi = null;
2053 >                        for (Node<V> p = f.next; p != null; p = p.next) {
2054                              int b = p.hash & n;
2055                              if (b != runBit) {
2056                                  runBit = b;
# Line 2053 | Line 2061 | public class ConcurrentHashMapV8<K, V>
2061                              lo = lastRun;
2062                          else
2063                              hi = lastRun;
2064 <                        for (Node p = f; p != lastRun; p = p.next) {
2064 >                        for (Node<V> p = f; p != lastRun; p = p.next) {
2065                              int ph = p.hash;
2066 <                            Object pk = p.key, pv = p.val;
2066 >                            Object pk = p.key; V pv = p.val;
2067                              if ((ph & n) == 0)
2068 <                                lo = new Node(ph, pk, pv, lo);
2068 >                                lo = new Node<V>(ph, pk, pv, lo);
2069                              else
2070 <                                hi = new Node(ph, pk, pv, hi);
2070 >                                hi = new Node<V>(ph, pk, pv, hi);
2071                          }
2072                          setTabAt(nextTab, i, lo);
2073                          setTabAt(nextTab, i + n, hi);
# Line 2069 | Line 2077 | public class ConcurrentHashMapV8<K, V>
2077                  }
2078              }
2079              else if ((fk = f.key) instanceof TreeBin) {
2080 <                TreeBin t = (TreeBin)fk;
2080 >                TreeBin<V> t = (TreeBin<V>)fk;
2081                  t.acquire(0);
2082                  try {
2083                      if (tabAt(tab, i) == f) {
2084 <                        TreeBin lt = new TreeBin();
2085 <                        TreeBin ht = new TreeBin();
2084 >                        TreeBin<V> lt = new TreeBin<V>();
2085 >                        TreeBin<V> ht = new TreeBin<V>();
2086                          int lc = 0, hc = 0;
2087 <                        for (Node e = t.first; e != null; e = e.next) {
2087 >                        for (Node<V> e = t.first; e != null; e = e.next) {
2088                              int h = e.hash;
2089 <                            Object k = e.key, v = e.val;
2089 >                            Object k = e.key; V v = e.val;
2090                              if ((h & n) == 0) {
2091                                  ++lc;
2092                                  lt.putTreeNode(h, k, v);
# Line 2088 | Line 2096 | public class ConcurrentHashMapV8<K, V>
2096                                  ht.putTreeNode(h, k, v);
2097                              }
2098                          }
2099 <                        Node ln, hn; // throw away trees if too small
2099 >                        Node<V> ln, hn; // throw away trees if too small
2100                          if (lc < TREE_THRESHOLD) {
2101                              ln = null;
2102 <                            for (Node p = lt.first; p != null; p = p.next)
2103 <                                ln = new Node(p.hash, p.key, p.val, ln);
2102 >                            for (Node<V> p = lt.first; p != null; p = p.next)
2103 >                                ln = new Node<V>(p.hash, p.key, p.val, ln);
2104                          }
2105                          else
2106 <                            ln = new Node(MOVED, lt, null, null);
2106 >                            ln = new Node<V>(MOVED, lt, null, null);
2107                          setTabAt(nextTab, i, ln);
2108                          if (hc < TREE_THRESHOLD) {
2109                              hn = null;
2110 <                            for (Node p = ht.first; p != null; p = p.next)
2111 <                                hn = new Node(p.hash, p.key, p.val, hn);
2110 >                            for (Node<V> p = ht.first; p != null; p = p.next)
2111 >                                hn = new Node<V>(p.hash, p.key, p.val, hn);
2112                          }
2113                          else
2114 <                            hn = new Node(MOVED, ht, null, null);
2114 >                            hn = new Node<V>(MOVED, ht, null, null);
2115                          setTabAt(nextTab, i + n, hn);
2116                          setTabAt(tab, i, fwd);
2117                          advance = true;
# Line 2270 | Line 2278 | public class ConcurrentHashMapV8<K, V>
2278      @SuppressWarnings("serial") static class Traverser<K,V,R>
2279          extends CountedCompleter<R> {
2280          final ConcurrentHashMapV8<K, V> map;
2281 <        Node next;           // the next entry to use
2281 >        Node<V> next;        // the next entry to use
2282          Object nextKey;      // cached key field of next
2283 <        Object nextVal;      // cached val field of next
2284 <        Node[] tab;          // current table; updated if resized
2283 >        V nextVal;           // cached val field of next
2284 >        Node<V>[] tab;       // current table; updated if resized
2285          int index;           // index of bin to use next
2286          int baseIndex;       // current index of initial table
2287          int baseLimit;       // index bound for initial table
# Line 2290 | Line 2298 | public class ConcurrentHashMapV8<K, V>
2298              super(it);
2299              this.batch = batch;
2300              if ((this.map = map) != null && it != null) { // split parent
2301 <                Node[] t;
2301 >                Node<V>[] t;
2302                  if ((t = it.tab) == null &&
2303                      (t = it.tab = map.table) != null)
2304                      it.baseLimit = it.baseSize = t.length;
# Line 2306 | Line 2314 | public class ConcurrentHashMapV8<K, V>
2314           * Advances next; returns nextVal or null if terminated.
2315           * See above for explanation.
2316           */
2317 <        final Object advance() {
2318 <            Node e = next;
2319 <            Object ev = null;
2317 >        @SuppressWarnings("unchecked") final V advance() {
2318 >            Node<V> e = next;
2319 >            V ev = null;
2320              outer: do {
2321                  if (e != null)                  // advance past used/skipped node
2322                      e = e.next;
2323                  while (e == null) {             // get to next non-null bin
2324                      ConcurrentHashMapV8<K, V> m;
2325 <                    Node[] t; int b, i, n; Object ek; // checks must use locals
2325 >                    Node<V>[] t; int b, i, n; Object ek; //  must use locals
2326                      if ((t = tab) != null)
2327                          n = t.length;
2328                      else if ((m = map) != null && (t = tab = m.table) != null)
# Line 2326 | Line 2334 | public class ConcurrentHashMapV8<K, V>
2334                          break outer;
2335                      if ((e = tabAt(t, i)) != null && e.hash < 0) {
2336                          if ((ek = e.key) instanceof TreeBin)
2337 <                            e = ((TreeBin)ek).first;
2337 >                            e = ((TreeBin<V>)ek).first;
2338                          else {
2339 <                            tab = (Node[])ek;
2339 >                            tab = (Node<V>[])ek;
2340                              continue;           // restarts due to null val
2341                          }
2342                      }                           // visit upper slots if present
# Line 2366 | Line 2374 | public class ConcurrentHashMapV8<K, V>
2374           * anyway.
2375           */
2376          final int preSplit() {
2377 <            ConcurrentHashMapV8<K, V> m; int b; Node[] t;  ForkJoinPool pool;
2377 >            ConcurrentHashMapV8<K, V> m; int b; Node<V>[] t;  ForkJoinPool pool;
2378              if ((b = batch) < 0 && (m = map) != null) { // force initialization
2379                  if ((t = tab) == null && (t = tab = m.table) != null)
2380                      baseLimit = baseSize = t.length;
# Line 2586 | Line 2594 | public class ConcurrentHashMapV8<K, V>
2594      public boolean containsValue(Object value) {
2595          if (value == null)
2596              throw new NullPointerException();
2597 <        Object v;
2597 >        V v;
2598          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
2599          while ((v = it.advance()) != null) {
2600              if (v == value || value.equals(v))
# Line 2610 | Line 2618 | public class ConcurrentHashMapV8<K, V>
2618       *         {@code false} otherwise
2619       * @throws NullPointerException if the specified value is null
2620       */
2621 <    public boolean contains(Object value) {
2621 >    @Deprecated public boolean contains(Object value) {
2622          return containsValue(value);
2623      }
2624  
# Line 2983 | Line 2991 | public class ConcurrentHashMapV8<K, V>
2991      public int hashCode() {
2992          int h = 0;
2993          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
2994 <        Object v;
2994 >        V v;
2995          while ((v = it.advance()) != null) {
2996              h += it.nextKey.hashCode() ^ v.hashCode();
2997          }
# Line 3005 | Line 3013 | public class ConcurrentHashMapV8<K, V>
3013          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3014          StringBuilder sb = new StringBuilder();
3015          sb.append('{');
3016 <        Object v;
3016 >        V v;
3017          if ((v = it.advance()) != null) {
3018              for (;;) {
3019                  Object k = it.nextKey;
# Line 3036 | Line 3044 | public class ConcurrentHashMapV8<K, V>
3044                  return false;
3045              Map<?,?> m = (Map<?,?>) o;
3046              Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3047 <            Object val;
3047 >            V val;
3048              while ((val = it.advance()) != null) {
3049                  Object v = m.get(it.nextKey);
3050                  if (v == null || (v != val && !v.equals(val)))
# Line 3092 | Line 3100 | public class ConcurrentHashMapV8<K, V>
3100              return new ValueIterator<K,V>(map, this);
3101          }
3102  
3103 <        @SuppressWarnings("unchecked") public final V next() {
3104 <            Object v;
3103 >        public final V next() {
3104 >            V v;
3105              if ((v = nextVal) == null && (v = advance()) == null)
3106                  throw new NoSuchElementException();
3107              nextVal = null;
3108 <            return (V) v;
3108 >            return v;
3109          }
3110  
3111          public final V nextElement() { return next(); }
# Line 3117 | Line 3125 | public class ConcurrentHashMapV8<K, V>
3125          }
3126  
3127          @SuppressWarnings("unchecked") public final Map.Entry<K,V> next() {
3128 <            Object v;
3128 >            V v;
3129              if ((v = nextVal) == null && (v = advance()) == null)
3130                  throw new NoSuchElementException();
3131              Object k = nextKey;
3132              nextVal = null;
3133 <            return new MapEntry<K,V>((K)k, (V)v, map);
3133 >            return new MapEntry<K,V>((K)k, v, map);
3134          }
3135      }
3136  
# Line 3209 | Line 3217 | public class ConcurrentHashMapV8<K, V>
3217          }
3218          s.defaultWriteObject();
3219          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3220 <        Object v;
3220 >        V v;
3221          while ((v = it.advance()) != null) {
3222              s.writeObject(it.nextKey);
3223              s.writeObject(v);
# Line 3231 | Line 3239 | public class ConcurrentHashMapV8<K, V>
3239  
3240          // Create all nodes, then place in table once size is known
3241          long size = 0L;
3242 <        Node p = null;
3242 >        Node<V> p = null;
3243          for (;;) {
3244              K k = (K) s.readObject();
3245              V v = (V) s.readObject();
3246              if (k != null && v != null) {
3247                  int h = spread(k.hashCode());
3248 <                p = new Node(h, k, v, p);
3248 >                p = new Node<V>(h, k, v, p);
3249                  ++size;
3250              }
3251              else
# Line 3259 | Line 3267 | public class ConcurrentHashMapV8<K, V>
3267                  try {
3268                      if (table == null) {
3269                          init = true;
3270 <                        Node[] tab = new Node[n];
3270 >                        @SuppressWarnings("rawtypes") Node[] rt = new Node[n];
3271 >                        Node<V>[] tab = (Node<V>[])rt;
3272                          int mask = n - 1;
3273                          while (p != null) {
3274                              int j = p.hash & mask;
3275 <                            Node next = p.next;
3276 <                            Node q = p.next = tabAt(tab, j);
3275 >                            Node<V> next = p.next;
3276 >                            Node<V> q = p.next = tabAt(tab, j);
3277                              setTabAt(tab, j, p);
3278                              if (!collide && q != null && q.hash == p.hash)
3279                                  collide = true;
# Line 3278 | Line 3287 | public class ConcurrentHashMapV8<K, V>
3287                      sizeCtl = sc;
3288                  }
3289                  if (collide) { // rescan and convert to TreeBins
3290 <                    Node[] tab = table;
3290 >                    Node<V>[] tab = table;
3291                      for (int i = 0; i < tab.length; ++i) {
3292                          int c = 0;
3293 <                        for (Node e = tabAt(tab, i); e != null; e = e.next) {
3293 >                        for (Node<V> e = tabAt(tab, i); e != null; e = e.next) {
3294                              if (++c > TREE_THRESHOLD &&
3295                                  (e.key instanceof Comparable)) {
3296                                  replaceWithTreeBin(tab, i, e.key);
# Line 3293 | Line 3302 | public class ConcurrentHashMapV8<K, V>
3302              }
3303              if (!init) { // Can only happen if unsafely published.
3304                  while (p != null) {
3305 <                    internalPut((K)p.key, (V)p.val, false);
3305 >                    internalPut((K)p.key, p.val, false);
3306                      p = p.next;
3307                  }
3308              }
# Line 3341 | Line 3350 | public class ConcurrentHashMapV8<K, V>
3350  
3351      // -------------------------------------------------------
3352  
3353 +    // Sequential bulk operations
3354 +
3355 +    /**
3356 +     * Performs the given action for each (key, value).
3357 +     *
3358 +     * @param action the action
3359 +     */
3360 +    @SuppressWarnings("unchecked") public void forEachSequentially
3361 +        (BiAction<K,V> action) {
3362 +        if (action == null) throw new NullPointerException();
3363 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3364 +        V v;
3365 +        while ((v = it.advance()) != null)
3366 +            action.apply((K)it.nextKey, v);
3367 +    }
3368 +
3369 +    /**
3370 +     * Performs the given action for each non-null transformation
3371 +     * of each (key, value).
3372 +     *
3373 +     * @param transformer a function returning the transformation
3374 +     * for an element, or null of there is no transformation (in
3375 +     * which case the action is not applied).
3376 +     * @param action the action
3377 +     */
3378 +    @SuppressWarnings("unchecked") public <U> void forEachSequentially
3379 +        (BiFun<? super K, ? super V, ? extends U> transformer,
3380 +         Action<U> action) {
3381 +        if (transformer == null || action == null)
3382 +            throw new NullPointerException();
3383 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3384 +        V v; U u;
3385 +        while ((v = it.advance()) != null) {
3386 +            if ((u = transformer.apply((K)it.nextKey, v)) != null)
3387 +                action.apply(u);
3388 +        }
3389 +    }
3390 +
3391 +    /**
3392 +     * Returns a non-null result from applying the given search
3393 +     * function on each (key, value), or null if none.
3394 +     *
3395 +     * @param searchFunction a function returning a non-null
3396 +     * result on success, else null
3397 +     * @return a non-null result from applying the given search
3398 +     * function on each (key, value), or null if none
3399 +     */
3400 +    @SuppressWarnings("unchecked") public <U> U searchSequentially
3401 +        (BiFun<? super K, ? super V, ? extends U> searchFunction) {
3402 +        if (searchFunction == null) throw new NullPointerException();
3403 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3404 +        V v; U u;
3405 +        while ((v = it.advance()) != null) {
3406 +            if ((u = searchFunction.apply((K)it.nextKey, v)) != null)
3407 +                return u;
3408 +        }
3409 +        return null;
3410 +    }
3411 +
3412 +    /**
3413 +     * Returns the result of accumulating the given transformation
3414 +     * of all (key, value) pairs using the given reducer to
3415 +     * combine values, or null if none.
3416 +     *
3417 +     * @param transformer a function returning the transformation
3418 +     * for an element, or null of there is no transformation (in
3419 +     * which case it is not combined).
3420 +     * @param reducer a commutative associative combining function
3421 +     * @return the result of accumulating the given transformation
3422 +     * of all (key, value) pairs
3423 +     */
3424 +    @SuppressWarnings("unchecked") public <U> U reduceSequentially
3425 +        (BiFun<? super K, ? super V, ? extends U> transformer,
3426 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3427 +        if (transformer == null || reducer == null)
3428 +            throw new NullPointerException();
3429 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3430 +        U r = null, u; V v;
3431 +        while ((v = it.advance()) != null) {
3432 +            if ((u = transformer.apply((K)it.nextKey, v)) != null)
3433 +                r = (r == null) ? u : reducer.apply(r, u);
3434 +        }
3435 +        return r;
3436 +    }
3437 +
3438 +    /**
3439 +     * Returns the result of accumulating the given transformation
3440 +     * of all (key, value) pairs using the given reducer to
3441 +     * combine values, and the given basis as an identity value.
3442 +     *
3443 +     * @param transformer a function returning the transformation
3444 +     * for an element
3445 +     * @param basis the identity (initial default value) for the reduction
3446 +     * @param reducer a commutative associative combining function
3447 +     * @return the result of accumulating the given transformation
3448 +     * of all (key, value) pairs
3449 +     */
3450 +    @SuppressWarnings("unchecked") public double reduceToDoubleSequentially
3451 +        (ObjectByObjectToDouble<? super K, ? super V> transformer,
3452 +         double basis,
3453 +         DoubleByDoubleToDouble reducer) {
3454 +        if (transformer == null || reducer == null)
3455 +            throw new NullPointerException();
3456 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3457 +        double r = basis; V v;
3458 +        while ((v = it.advance()) != null)
3459 +            r = reducer.apply(r, transformer.apply((K)it.nextKey, v));
3460 +        return r;
3461 +    }
3462 +
3463 +    /**
3464 +     * Returns the result of accumulating the given transformation
3465 +     * of all (key, value) pairs using the given reducer to
3466 +     * combine values, and the given basis as an identity value.
3467 +     *
3468 +     * @param transformer a function returning the transformation
3469 +     * for an element
3470 +     * @param basis the identity (initial default value) for the reduction
3471 +     * @param reducer a commutative associative combining function
3472 +     * @return the result of accumulating the given transformation
3473 +     * of all (key, value) pairs
3474 +     */
3475 +    @SuppressWarnings("unchecked") public long reduceToLongSequentially
3476 +        (ObjectByObjectToLong<? super K, ? super V> transformer,
3477 +         long basis,
3478 +         LongByLongToLong reducer) {
3479 +        if (transformer == null || reducer == null)
3480 +            throw new NullPointerException();
3481 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3482 +        long r = basis; V v;
3483 +        while ((v = it.advance()) != null)
3484 +            r = reducer.apply(r, transformer.apply((K)it.nextKey, v));
3485 +        return r;
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, and the given basis as an identity value.
3492 +     *
3493 +     * @param transformer a function returning the transformation
3494 +     * for an element
3495 +     * @param basis the identity (initial default value) for the reduction
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 +    @SuppressWarnings("unchecked") public int reduceToIntSequentially
3501 +        (ObjectByObjectToInt<? super K, ? super V> transformer,
3502 +         int basis,
3503 +         IntByIntToInt reducer) {
3504 +        if (transformer == null || reducer == null)
3505 +            throw new NullPointerException();
3506 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3507 +        int r = basis; V v;
3508 +        while ((v = it.advance()) != null)
3509 +            r = reducer.apply(r, transformer.apply((K)it.nextKey, v));
3510 +        return r;
3511 +    }
3512 +
3513 +    /**
3514 +     * Performs the given action for each key.
3515 +     *
3516 +     * @param action the action
3517 +     */
3518 +    @SuppressWarnings("unchecked") public void forEachKeySequentially
3519 +        (Action<K> action) {
3520 +        if (action == null) throw new NullPointerException();
3521 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3522 +        while (it.advance() != null)
3523 +            action.apply((K)it.nextKey);
3524 +    }
3525 +
3526 +    /**
3527 +     * Performs the given action for each non-null transformation
3528 +     * of each key.
3529 +     *
3530 +     * @param transformer a function returning the transformation
3531 +     * for an element, or null of there is no transformation (in
3532 +     * which case the action is not applied).
3533 +     * @param action the action
3534 +     */
3535 +    @SuppressWarnings("unchecked") public <U> void forEachKeySequentially
3536 +        (Fun<? super K, ? extends U> transformer,
3537 +         Action<U> action) {
3538 +        if (transformer == null || action == null)
3539 +            throw new NullPointerException();
3540 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3541 +        U u;
3542 +        while (it.advance() != null) {
3543 +            if ((u = transformer.apply((K)it.nextKey)) != null)
3544 +                action.apply(u);
3545 +        }
3546 +        ForkJoinTasks.forEachKey
3547 +            (this, transformer, action).invoke();
3548 +    }
3549 +
3550 +    /**
3551 +     * Returns a non-null result from applying the given search
3552 +     * function on each key, or null if none.
3553 +     *
3554 +     * @param searchFunction a function returning a non-null
3555 +     * result on success, else null
3556 +     * @return a non-null result from applying the given search
3557 +     * function on each key, or null if none
3558 +     */
3559 +    @SuppressWarnings("unchecked") public <U> U searchKeysSequentially
3560 +        (Fun<? super K, ? extends U> searchFunction) {
3561 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3562 +        U u;
3563 +        while (it.advance() != null) {
3564 +            if ((u = searchFunction.apply((K)it.nextKey)) != null)
3565 +                return u;
3566 +        }
3567 +        return null;
3568 +    }
3569 +
3570 +    /**
3571 +     * Returns the result of accumulating all keys using the given
3572 +     * reducer to combine values, or null if none.
3573 +     *
3574 +     * @param reducer a commutative associative combining function
3575 +     * @return the result of accumulating all keys using the given
3576 +     * reducer to combine values, or null if none
3577 +     */
3578 +    @SuppressWarnings("unchecked") public K reduceKeysSequentially
3579 +        (BiFun<? super K, ? super K, ? extends K> reducer) {
3580 +        if (reducer == null) throw new NullPointerException();
3581 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3582 +        K r = null;
3583 +        while (it.advance() != null) {
3584 +            K u = (K)it.nextKey;
3585 +            r = (r == null) ? u : reducer.apply(r, u);
3586 +        }
3587 +        return r;
3588 +    }
3589 +
3590 +    /**
3591 +     * Returns the result of accumulating the given transformation
3592 +     * of all keys using the given reducer to combine values, or
3593 +     * null if none.
3594 +     *
3595 +     * @param transformer a function returning the transformation
3596 +     * for an element, or null of there is no transformation (in
3597 +     * which case it is not combined).
3598 +     * @param reducer a commutative associative combining function
3599 +     * @return the result of accumulating the given transformation
3600 +     * of all keys
3601 +     */
3602 +    @SuppressWarnings("unchecked") public <U> U reduceKeysSequentially
3603 +        (Fun<? super K, ? extends U> transformer,
3604 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3605 +        if (transformer == null || reducer == null)
3606 +            throw new NullPointerException();
3607 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3608 +        U r = null, u;
3609 +        while (it.advance() != null) {
3610 +            if ((u = transformer.apply((K)it.nextKey)) != null)
3611 +                r = (r == null) ? u : reducer.apply(r, u);
3612 +        }
3613 +        return r;
3614 +    }
3615 +
3616 +    /**
3617 +     * Returns the result of accumulating the given transformation
3618 +     * of all keys using the given reducer to combine values, and
3619 +     * the given basis as an identity value.
3620 +     *
3621 +     * @param transformer a function returning the transformation
3622 +     * for an element
3623 +     * @param basis the identity (initial default value) for the reduction
3624 +     * @param reducer a commutative associative combining function
3625 +     * @return  the result of accumulating the given transformation
3626 +     * of all keys
3627 +     */
3628 +    @SuppressWarnings("unchecked") public double reduceKeysToDoubleSequentially
3629 +        (ObjectToDouble<? super K> transformer,
3630 +         double basis,
3631 +         DoubleByDoubleToDouble reducer) {
3632 +        if (transformer == null || reducer == null)
3633 +            throw new NullPointerException();
3634 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3635 +        double r = basis;
3636 +        while (it.advance() != null)
3637 +            r = reducer.apply(r, transformer.apply((K)it.nextKey));
3638 +        return r;
3639 +    }
3640 +
3641 +    /**
3642 +     * Returns the result of accumulating the given transformation
3643 +     * of all keys using the given reducer to combine values, and
3644 +     * the given basis as an identity value.
3645 +     *
3646 +     * @param transformer a function returning the transformation
3647 +     * for an element
3648 +     * @param basis the identity (initial default value) for the reduction
3649 +     * @param reducer a commutative associative combining function
3650 +     * @return the result of accumulating the given transformation
3651 +     * of all keys
3652 +     */
3653 +    @SuppressWarnings("unchecked") public long reduceKeysToLongSequentially
3654 +        (ObjectToLong<? super K> transformer,
3655 +         long basis,
3656 +         LongByLongToLong reducer) {
3657 +        if (transformer == null || reducer == null)
3658 +            throw new NullPointerException();
3659 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3660 +        long r = basis;
3661 +        while (it.advance() != null)
3662 +            r = reducer.apply(r, transformer.apply((K)it.nextKey));
3663 +        return r;
3664 +    }
3665 +
3666 +    /**
3667 +     * Returns the result of accumulating the given transformation
3668 +     * of all keys using the given reducer to combine values, and
3669 +     * the given basis as an identity value.
3670 +     *
3671 +     * @param transformer a function returning the transformation
3672 +     * for an element
3673 +     * @param basis the identity (initial default value) for the reduction
3674 +     * @param reducer a commutative associative combining function
3675 +     * @return the result of accumulating the given transformation
3676 +     * of all keys
3677 +     */
3678 +    @SuppressWarnings("unchecked") public int reduceKeysToIntSequentially
3679 +        (ObjectToInt<? super K> transformer,
3680 +         int basis,
3681 +         IntByIntToInt reducer) {
3682 +        if (transformer == null || reducer == null)
3683 +            throw new NullPointerException();
3684 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3685 +        int r = basis;
3686 +        while (it.advance() != null)
3687 +            r = reducer.apply(r, transformer.apply((K)it.nextKey));
3688 +        return r;
3689 +    }
3690 +
3691 +    /**
3692 +     * Performs the given action for each value.
3693 +     *
3694 +     * @param action the action
3695 +     */
3696 +    public void forEachValueSequentially(Action<V> action) {
3697 +        if (action == null) throw new NullPointerException();
3698 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3699 +        V v;
3700 +        while ((v = it.advance()) != null)
3701 +            action.apply(v);
3702 +    }
3703 +
3704 +    /**
3705 +     * Performs the given action for each non-null transformation
3706 +     * of each value.
3707 +     *
3708 +     * @param transformer a function returning the transformation
3709 +     * for an element, or null of there is no transformation (in
3710 +     * which case the action is not applied).
3711 +     */
3712 +    public <U> void forEachValueSequentially
3713 +        (Fun<? super V, ? extends U> transformer,
3714 +         Action<U> action) {
3715 +        if (transformer == null || action == null)
3716 +            throw new NullPointerException();
3717 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3718 +        V v; U u;
3719 +        while ((v = it.advance()) != null) {
3720 +            if ((u = transformer.apply(v)) != null)
3721 +                action.apply(u);
3722 +        }
3723 +    }
3724 +
3725 +    /**
3726 +     * Returns a non-null result from applying the given search
3727 +     * function on each value, or null if none.
3728 +     *
3729 +     * @param searchFunction a function returning a non-null
3730 +     * result on success, else null
3731 +     * @return a non-null result from applying the given search
3732 +     * function on each value, or null if none
3733 +     *
3734 +     */
3735 +    public <U> U searchValuesSequentially
3736 +        (Fun<? super V, ? extends U> searchFunction) {
3737 +        if (searchFunction == null) throw new NullPointerException();
3738 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3739 +        V v; U u;
3740 +        while ((v = it.advance()) != null) {
3741 +            if ((u = searchFunction.apply(v)) != null)
3742 +                return u;
3743 +        }
3744 +        return null;
3745 +    }
3746 +
3747 +    /**
3748 +     * Returns the result of accumulating all values using the
3749 +     * given reducer to combine values, or null if none.
3750 +     *
3751 +     * @param reducer a commutative associative combining function
3752 +     * @return  the result of accumulating all values
3753 +     */
3754 +    public V reduceValuesSequentially
3755 +        (BiFun<? super V, ? super V, ? extends V> reducer) {
3756 +        if (reducer == null) throw new NullPointerException();
3757 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3758 +        V r = null; V v;
3759 +        while ((v = it.advance()) != null)
3760 +            r = (r == null) ? v : reducer.apply(r, v);
3761 +        return r;
3762 +    }
3763 +
3764 +    /**
3765 +     * Returns the result of accumulating the given transformation
3766 +     * of all values using the given reducer to combine values, or
3767 +     * null if none.
3768 +     *
3769 +     * @param transformer a function returning the transformation
3770 +     * for an element, or null of there is no transformation (in
3771 +     * which case it is not combined).
3772 +     * @param reducer a commutative associative combining function
3773 +     * @return the result of accumulating the given transformation
3774 +     * of all values
3775 +     */
3776 +    public <U> U reduceValuesSequentially
3777 +        (Fun<? super V, ? extends U> transformer,
3778 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3779 +        if (transformer == null || reducer == null)
3780 +            throw new NullPointerException();
3781 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3782 +        U r = null, u; V v;
3783 +        while ((v = it.advance()) != null) {
3784 +            if ((u = transformer.apply(v)) != null)
3785 +                r = (r == null) ? u : reducer.apply(r, u);
3786 +        }
3787 +        return r;
3788 +    }
3789 +
3790 +    /**
3791 +     * Returns the result of accumulating the given transformation
3792 +     * of all values using the given reducer to combine values,
3793 +     * and the given basis as an identity value.
3794 +     *
3795 +     * @param transformer a function returning the transformation
3796 +     * for an element
3797 +     * @param basis the identity (initial default value) for the reduction
3798 +     * @param reducer a commutative associative combining function
3799 +     * @return the result of accumulating the given transformation
3800 +     * of all values
3801 +     */
3802 +    public double reduceValuesToDoubleSequentially
3803 +        (ObjectToDouble<? super V> transformer,
3804 +         double basis,
3805 +         DoubleByDoubleToDouble reducer) {
3806 +        if (transformer == null || reducer == null)
3807 +            throw new NullPointerException();
3808 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3809 +        double r = basis; V v;
3810 +        while ((v = it.advance()) != null)
3811 +            r = reducer.apply(r, transformer.apply(v));
3812 +        return r;
3813 +    }
3814 +
3815 +    /**
3816 +     * Returns the result of accumulating the given transformation
3817 +     * of all values using the given reducer to combine values,
3818 +     * and the given basis as an identity value.
3819 +     *
3820 +     * @param transformer a function returning the transformation
3821 +     * for an element
3822 +     * @param basis the identity (initial default value) for the reduction
3823 +     * @param reducer a commutative associative combining function
3824 +     * @return the result of accumulating the given transformation
3825 +     * of all values
3826 +     */
3827 +    public long reduceValuesToLongSequentially
3828 +        (ObjectToLong<? super V> transformer,
3829 +         long basis,
3830 +         LongByLongToLong reducer) {
3831 +        if (transformer == null || reducer == null)
3832 +            throw new NullPointerException();
3833 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3834 +        long r = basis; V v;
3835 +        while ((v = it.advance()) != null)
3836 +            r = reducer.apply(r, transformer.apply(v));
3837 +        return r;
3838 +    }
3839 +
3840 +    /**
3841 +     * Returns the result of accumulating the given transformation
3842 +     * of all values using the given reducer to combine values,
3843 +     * and the given basis as an identity value.
3844 +     *
3845 +     * @param transformer a function returning the transformation
3846 +     * for an element
3847 +     * @param basis the identity (initial default value) for the reduction
3848 +     * @param reducer a commutative associative combining function
3849 +     * @return the result of accumulating the given transformation
3850 +     * of all values
3851 +     */
3852 +    public int reduceValuesToIntSequentially
3853 +        (ObjectToInt<? super V> transformer,
3854 +         int basis,
3855 +         IntByIntToInt reducer) {
3856 +        if (transformer == null || reducer == null)
3857 +            throw new NullPointerException();
3858 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3859 +        int r = basis; V v;
3860 +        while ((v = it.advance()) != null)
3861 +            r = reducer.apply(r, transformer.apply(v));
3862 +        return r;
3863 +    }
3864 +
3865 +    /**
3866 +     * Performs the given action for each entry.
3867 +     *
3868 +     * @param action the action
3869 +     */
3870 +    @SuppressWarnings("unchecked") public void forEachEntrySequentially
3871 +        (Action<Map.Entry<K,V>> action) {
3872 +        if (action == null) throw new NullPointerException();
3873 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3874 +        V v;
3875 +        while ((v = it.advance()) != null)
3876 +            action.apply(entryFor((K)it.nextKey, v));
3877 +    }
3878 +
3879 +    /**
3880 +     * Performs the given action for each non-null transformation
3881 +     * of each entry.
3882 +     *
3883 +     * @param transformer a function returning the transformation
3884 +     * for an element, or null of there is no transformation (in
3885 +     * which case the action is not applied).
3886 +     * @param action the action
3887 +     */
3888 +    @SuppressWarnings("unchecked") public <U> void forEachEntrySequentially
3889 +        (Fun<Map.Entry<K,V>, ? extends U> transformer,
3890 +         Action<U> action) {
3891 +        if (transformer == null || action == null)
3892 +            throw new NullPointerException();
3893 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3894 +        V v; U u;
3895 +        while ((v = it.advance()) != null) {
3896 +            if ((u = transformer.apply(entryFor((K)it.nextKey, v))) != null)
3897 +                action.apply(u);
3898 +        }
3899 +    }
3900 +
3901 +    /**
3902 +     * Returns a non-null result from applying the given search
3903 +     * function on each entry, or null if none.
3904 +     *
3905 +     * @param searchFunction a function returning a non-null
3906 +     * result on success, else null
3907 +     * @return a non-null result from applying the given search
3908 +     * function on each entry, or null if none
3909 +     */
3910 +    @SuppressWarnings("unchecked") public <U> U searchEntriesSequentially
3911 +        (Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
3912 +        if (searchFunction == null) throw new NullPointerException();
3913 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3914 +        V v; U u;
3915 +        while ((v = it.advance()) != null) {
3916 +            if ((u = searchFunction.apply(entryFor((K)it.nextKey, v))) != null)
3917 +                return u;
3918 +        }
3919 +        return null;
3920 +    }
3921 +
3922 +    /**
3923 +     * Returns the result of accumulating all entries using the
3924 +     * given reducer to combine values, or null if none.
3925 +     *
3926 +     * @param reducer a commutative associative combining function
3927 +     * @return the result of accumulating all entries
3928 +     */
3929 +    @SuppressWarnings("unchecked") public Map.Entry<K,V> reduceEntriesSequentially
3930 +        (BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
3931 +        if (reducer == null) throw new NullPointerException();
3932 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3933 +        Map.Entry<K,V> r = null; V v;
3934 +        while ((v = it.advance()) != null) {
3935 +            Map.Entry<K,V> u = entryFor((K)it.nextKey, v);
3936 +            r = (r == null) ? u : reducer.apply(r, u);
3937 +        }
3938 +        return r;
3939 +    }
3940 +
3941 +    /**
3942 +     * Returns the result of accumulating the given transformation
3943 +     * of all entries using the given reducer to combine values,
3944 +     * or null if none.
3945 +     *
3946 +     * @param transformer a function returning the transformation
3947 +     * for an element, or null of there is no transformation (in
3948 +     * which case it is not combined).
3949 +     * @param reducer a commutative associative combining function
3950 +     * @return the result of accumulating the given transformation
3951 +     * of all entries
3952 +     */
3953 +    @SuppressWarnings("unchecked") public <U> U reduceEntriesSequentially
3954 +        (Fun<Map.Entry<K,V>, ? extends U> transformer,
3955 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3956 +        if (transformer == null || reducer == null)
3957 +            throw new NullPointerException();
3958 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3959 +        U r = null, u; V v;
3960 +        while ((v = it.advance()) != null) {
3961 +            if ((u = transformer.apply(entryFor((K)it.nextKey, v))) != null)
3962 +                r = (r == null) ? u : reducer.apply(r, u);
3963 +        }
3964 +        return r;
3965 +    }
3966 +
3967 +    /**
3968 +     * Returns the result of accumulating the given transformation
3969 +     * of all entries using the given reducer to combine values,
3970 +     * and the given basis as an identity value.
3971 +     *
3972 +     * @param transformer a function returning the transformation
3973 +     * for an element
3974 +     * @param basis the identity (initial default value) for the reduction
3975 +     * @param reducer a commutative associative combining function
3976 +     * @return the result of accumulating the given transformation
3977 +     * of all entries
3978 +     */
3979 +    @SuppressWarnings("unchecked") public double reduceEntriesToDoubleSequentially
3980 +        (ObjectToDouble<Map.Entry<K,V>> transformer,
3981 +         double basis,
3982 +         DoubleByDoubleToDouble reducer) {
3983 +        if (transformer == null || reducer == null)
3984 +            throw new NullPointerException();
3985 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3986 +        double r = basis; V v;
3987 +        while ((v = it.advance()) != null)
3988 +            r = reducer.apply(r, transformer.apply(entryFor((K)it.nextKey, v)));
3989 +        return r;
3990 +    }
3991 +
3992 +    /**
3993 +     * Returns the result of accumulating the given transformation
3994 +     * of all entries using the given reducer to combine values,
3995 +     * and the given basis as an identity value.
3996 +     *
3997 +     * @param transformer a function returning the transformation
3998 +     * for an element
3999 +     * @param basis the identity (initial default value) for the reduction
4000 +     * @param reducer a commutative associative combining function
4001 +     * @return  the result of accumulating the given transformation
4002 +     * of all entries
4003 +     */
4004 +    @SuppressWarnings("unchecked") public long reduceEntriesToLongSequentially
4005 +        (ObjectToLong<Map.Entry<K,V>> transformer,
4006 +         long basis,
4007 +         LongByLongToLong reducer) {
4008 +        if (transformer == null || reducer == null)
4009 +            throw new NullPointerException();
4010 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
4011 +        long r = basis; V v;
4012 +        while ((v = it.advance()) != null)
4013 +            r = reducer.apply(r, transformer.apply(entryFor((K)it.nextKey, v)));
4014 +        return r;
4015 +    }
4016 +
4017 +    /**
4018 +     * Returns the result of accumulating the given transformation
4019 +     * of all entries using the given reducer to combine values,
4020 +     * and the given basis as an identity value.
4021 +     *
4022 +     * @param transformer a function returning the transformation
4023 +     * for an element
4024 +     * @param basis the identity (initial default value) for the reduction
4025 +     * @param reducer a commutative associative combining function
4026 +     * @return the result of accumulating the given transformation
4027 +     * of all entries
4028 +     */
4029 +    @SuppressWarnings("unchecked") public int reduceEntriesToIntSequentially
4030 +        (ObjectToInt<Map.Entry<K,V>> transformer,
4031 +         int basis,
4032 +         IntByIntToInt reducer) {
4033 +        if (transformer == null || reducer == null)
4034 +            throw new NullPointerException();
4035 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
4036 +        int r = basis; V v;
4037 +        while ((v = it.advance()) != null)
4038 +            r = reducer.apply(r, transformer.apply(entryFor((K)it.nextKey, v)));
4039 +        return r;
4040 +    }
4041 +
4042 +    // Parallel bulk operations
4043 +
4044      /**
4045       * Performs the given action for each (key, value).
4046       *
4047       * @param action the action
4048       */
4049 <    public void forEach(BiAction<K,V> action) {
4049 >    public void forEachInParallel(BiAction<K,V> action) {
4050          ForkJoinTasks.forEach
4051              (this, action).invoke();
4052      }
# Line 3360 | Line 4060 | public class ConcurrentHashMapV8<K, V>
4060       * which case the action is not applied).
4061       * @param action the action
4062       */
4063 <    public <U> void forEach(BiFun<? super K, ? super V, ? extends U> transformer,
4063 >    public <U> void forEachInParallel
4064 >        (BiFun<? super K, ? super V, ? extends U> transformer,
4065                              Action<U> action) {
4066          ForkJoinTasks.forEach
4067              (this, transformer, action).invoke();
# Line 3378 | Line 4079 | public class ConcurrentHashMapV8<K, V>
4079       * @return a non-null result from applying the given search
4080       * function on each (key, value), or null if none
4081       */
4082 <    public <U> U search(BiFun<? super K, ? super V, ? extends U> searchFunction) {
4082 >    public <U> U searchInParallel
4083 >        (BiFun<? super K, ? super V, ? extends U> searchFunction) {
4084          return ForkJoinTasks.search
4085              (this, searchFunction).invoke();
4086      }
# Line 3395 | Line 4097 | public class ConcurrentHashMapV8<K, V>
4097       * @return the result of accumulating the given transformation
4098       * of all (key, value) pairs
4099       */
4100 <    public <U> U reduce(BiFun<? super K, ? super V, ? extends U> transformer,
4101 <                        BiFun<? super U, ? super U, ? extends U> reducer) {
4100 >    public <U> U reduceInParallel
4101 >        (BiFun<? super K, ? super V, ? extends U> transformer,
4102 >         BiFun<? super U, ? super U, ? extends U> reducer) {
4103          return ForkJoinTasks.reduce
4104              (this, transformer, reducer).invoke();
4105      }
# Line 3413 | Line 4116 | public class ConcurrentHashMapV8<K, V>
4116       * @return the result of accumulating the given transformation
4117       * of all (key, value) pairs
4118       */
4119 <    public double reduceToDouble(ObjectByObjectToDouble<? super K, ? super V> transformer,
4120 <                                 double basis,
4121 <                                 DoubleByDoubleToDouble reducer) {
4119 >    public double reduceToDoubleInParallel
4120 >        (ObjectByObjectToDouble<? super K, ? super V> transformer,
4121 >         double basis,
4122 >         DoubleByDoubleToDouble reducer) {
4123          return ForkJoinTasks.reduceToDouble
4124              (this, transformer, basis, reducer).invoke();
4125      }
# Line 3432 | Line 4136 | public class ConcurrentHashMapV8<K, V>
4136       * @return the result of accumulating the given transformation
4137       * of all (key, value) pairs
4138       */
4139 <    public long reduceToLong(ObjectByObjectToLong<? super K, ? super V> transformer,
4140 <                             long basis,
4141 <                             LongByLongToLong reducer) {
4139 >    public long reduceToLongInParallel
4140 >        (ObjectByObjectToLong<? super K, ? super V> transformer,
4141 >         long basis,
4142 >         LongByLongToLong reducer) {
4143          return ForkJoinTasks.reduceToLong
4144              (this, transformer, basis, reducer).invoke();
4145      }
# Line 3451 | Line 4156 | public class ConcurrentHashMapV8<K, V>
4156       * @return the result of accumulating the given transformation
4157       * of all (key, value) pairs
4158       */
4159 <    public int reduceToInt(ObjectByObjectToInt<? super K, ? super V> transformer,
4160 <                           int basis,
4161 <                           IntByIntToInt reducer) {
4159 >    public int reduceToIntInParallel
4160 >        (ObjectByObjectToInt<? super K, ? super V> transformer,
4161 >         int basis,
4162 >         IntByIntToInt reducer) {
4163          return ForkJoinTasks.reduceToInt
4164              (this, transformer, basis, reducer).invoke();
4165      }
# Line 3463 | Line 4169 | public class ConcurrentHashMapV8<K, V>
4169       *
4170       * @param action the action
4171       */
4172 <    public void forEachKey(Action<K> action) {
4172 >    public void forEachKeyInParallel(Action<K> action) {
4173          ForkJoinTasks.forEachKey
4174              (this, action).invoke();
4175      }
# Line 3477 | Line 4183 | public class ConcurrentHashMapV8<K, V>
4183       * which case the action is not applied).
4184       * @param action the action
4185       */
4186 <    public <U> void forEachKey(Fun<? super K, ? extends U> transformer,
4187 <                               Action<U> action) {
4186 >    public <U> void forEachKeyInParallel
4187 >        (Fun<? super K, ? extends U> transformer,
4188 >         Action<U> action) {
4189          ForkJoinTasks.forEachKey
4190              (this, transformer, action).invoke();
4191      }
# Line 3495 | Line 4202 | public class ConcurrentHashMapV8<K, V>
4202       * @return a non-null result from applying the given search
4203       * function on each key, or null if none
4204       */
4205 <    public <U> U searchKeys(Fun<? super K, ? extends U> searchFunction) {
4205 >    public <U> U searchKeysInParallel
4206 >        (Fun<? super K, ? extends U> searchFunction) {
4207          return ForkJoinTasks.searchKeys
4208              (this, searchFunction).invoke();
4209      }
# Line 3508 | Line 4216 | public class ConcurrentHashMapV8<K, V>
4216       * @return the result of accumulating all keys using the given
4217       * reducer to combine values, or null if none
4218       */
4219 <    public K reduceKeys(BiFun<? super K, ? super K, ? extends K> reducer) {
4219 >    public K reduceKeysInParallel
4220 >        (BiFun<? super K, ? super K, ? extends K> reducer) {
4221          return ForkJoinTasks.reduceKeys
4222              (this, reducer).invoke();
4223      }
# Line 3525 | Line 4234 | public class ConcurrentHashMapV8<K, V>
4234       * @return the result of accumulating the given transformation
4235       * of all keys
4236       */
4237 <    public <U> U reduceKeys(Fun<? super K, ? extends U> transformer,
4238 <                            BiFun<? super U, ? super U, ? extends U> reducer) {
4237 >    public <U> U reduceKeysInParallel
4238 >        (Fun<? super K, ? extends U> transformer,
4239 >         BiFun<? super U, ? super U, ? extends U> reducer) {
4240          return ForkJoinTasks.reduceKeys
4241              (this, transformer, reducer).invoke();
4242      }
# Line 3543 | Line 4253 | public class ConcurrentHashMapV8<K, V>
4253       * @return  the result of accumulating the given transformation
4254       * of all keys
4255       */
4256 <    public double reduceKeysToDouble(ObjectToDouble<? super K> transformer,
4257 <                                     double basis,
4258 <                                     DoubleByDoubleToDouble reducer) {
4256 >    public double reduceKeysToDoubleInParallel
4257 >        (ObjectToDouble<? super K> transformer,
4258 >         double basis,
4259 >         DoubleByDoubleToDouble reducer) {
4260          return ForkJoinTasks.reduceKeysToDouble
4261              (this, transformer, basis, reducer).invoke();
4262      }
# Line 3562 | Line 4273 | public class ConcurrentHashMapV8<K, V>
4273       * @return the result of accumulating the given transformation
4274       * of all keys
4275       */
4276 <    public long reduceKeysToLong(ObjectToLong<? super K> transformer,
4277 <                                 long basis,
4278 <                                 LongByLongToLong reducer) {
4276 >    public long reduceKeysToLongInParallel
4277 >        (ObjectToLong<? super K> transformer,
4278 >         long basis,
4279 >         LongByLongToLong reducer) {
4280          return ForkJoinTasks.reduceKeysToLong
4281              (this, transformer, basis, reducer).invoke();
4282      }
# Line 3581 | Line 4293 | public class ConcurrentHashMapV8<K, V>
4293       * @return the result of accumulating the given transformation
4294       * of all keys
4295       */
4296 <    public int reduceKeysToInt(ObjectToInt<? super K> transformer,
4297 <                               int basis,
4298 <                               IntByIntToInt reducer) {
4296 >    public int reduceKeysToIntInParallel
4297 >        (ObjectToInt<? super K> transformer,
4298 >         int basis,
4299 >         IntByIntToInt reducer) {
4300          return ForkJoinTasks.reduceKeysToInt
4301              (this, transformer, basis, reducer).invoke();
4302      }
# Line 3593 | Line 4306 | public class ConcurrentHashMapV8<K, V>
4306       *
4307       * @param action the action
4308       */
4309 <    public void forEachValue(Action<V> action) {
4309 >    public void forEachValueInParallel(Action<V> action) {
4310          ForkJoinTasks.forEachValue
4311              (this, action).invoke();
4312      }
# Line 3606 | Line 4319 | public class ConcurrentHashMapV8<K, V>
4319       * for an element, or null of there is no transformation (in
4320       * which case the action is not applied).
4321       */
4322 <    public <U> void forEachValue(Fun<? super V, ? extends U> transformer,
4323 <                                 Action<U> action) {
4322 >    public <U> void forEachValueInParallel
4323 >        (Fun<? super V, ? extends U> transformer,
4324 >         Action<U> action) {
4325          ForkJoinTasks.forEachValue
4326              (this, transformer, action).invoke();
4327      }
# Line 3625 | Line 4339 | public class ConcurrentHashMapV8<K, V>
4339       * function on each value, or null if none
4340       *
4341       */
4342 <    public <U> U searchValues(Fun<? super V, ? extends U> searchFunction) {
4342 >    public <U> U searchValuesInParallel
4343 >        (Fun<? super V, ? extends U> searchFunction) {
4344          return ForkJoinTasks.searchValues
4345              (this, searchFunction).invoke();
4346      }
# Line 3637 | Line 4352 | public class ConcurrentHashMapV8<K, V>
4352       * @param reducer a commutative associative combining function
4353       * @return  the result of accumulating all values
4354       */
4355 <    public V reduceValues(BiFun<? super V, ? super V, ? extends V> reducer) {
4355 >    public V reduceValuesInParallel
4356 >        (BiFun<? super V, ? super V, ? extends V> reducer) {
4357          return ForkJoinTasks.reduceValues
4358              (this, reducer).invoke();
4359      }
# Line 3654 | Line 4370 | public class ConcurrentHashMapV8<K, V>
4370       * @return the result of accumulating the given transformation
4371       * of all values
4372       */
4373 <    public <U> U reduceValues(Fun<? super V, ? extends U> transformer,
4374 <                              BiFun<? super U, ? super U, ? extends U> reducer) {
4373 >    public <U> U reduceValuesInParallel
4374 >        (Fun<? super V, ? extends U> transformer,
4375 >         BiFun<? super U, ? super U, ? extends U> reducer) {
4376          return ForkJoinTasks.reduceValues
4377              (this, transformer, reducer).invoke();
4378      }
# Line 3672 | Line 4389 | public class ConcurrentHashMapV8<K, V>
4389       * @return the result of accumulating the given transformation
4390       * of all values
4391       */
4392 <    public double reduceValuesToDouble(ObjectToDouble<? super V> transformer,
4393 <                                       double basis,
4394 <                                       DoubleByDoubleToDouble reducer) {
4392 >    public double reduceValuesToDoubleInParallel
4393 >        (ObjectToDouble<? super V> transformer,
4394 >         double basis,
4395 >         DoubleByDoubleToDouble reducer) {
4396          return ForkJoinTasks.reduceValuesToDouble
4397              (this, transformer, basis, reducer).invoke();
4398      }
# Line 3691 | Line 4409 | public class ConcurrentHashMapV8<K, V>
4409       * @return the result of accumulating the given transformation
4410       * of all values
4411       */
4412 <    public long reduceValuesToLong(ObjectToLong<? super V> transformer,
4413 <                                   long basis,
4414 <                                   LongByLongToLong reducer) {
4412 >    public long reduceValuesToLongInParallel
4413 >        (ObjectToLong<? super V> transformer,
4414 >         long basis,
4415 >         LongByLongToLong reducer) {
4416          return ForkJoinTasks.reduceValuesToLong
4417              (this, transformer, basis, reducer).invoke();
4418      }
# Line 3710 | Line 4429 | public class ConcurrentHashMapV8<K, V>
4429       * @return the result of accumulating the given transformation
4430       * of all values
4431       */
4432 <    public int reduceValuesToInt(ObjectToInt<? super V> transformer,
4433 <                                 int basis,
4434 <                                 IntByIntToInt reducer) {
4432 >    public int reduceValuesToIntInParallel
4433 >        (ObjectToInt<? super V> transformer,
4434 >         int basis,
4435 >         IntByIntToInt reducer) {
4436          return ForkJoinTasks.reduceValuesToInt
4437              (this, transformer, basis, reducer).invoke();
4438      }
# Line 3722 | Line 4442 | public class ConcurrentHashMapV8<K, V>
4442       *
4443       * @param action the action
4444       */
4445 <    public void forEachEntry(Action<Map.Entry<K,V>> action) {
4445 >    public void forEachEntryInParallel(Action<Map.Entry<K,V>> action) {
4446          ForkJoinTasks.forEachEntry
4447              (this, action).invoke();
4448      }
# Line 3736 | Line 4456 | public class ConcurrentHashMapV8<K, V>
4456       * which case the action is not applied).
4457       * @param action the action
4458       */
4459 <    public <U> void forEachEntry(Fun<Map.Entry<K,V>, ? extends U> transformer,
4460 <                                 Action<U> action) {
4459 >    public <U> void forEachEntryInParallel
4460 >        (Fun<Map.Entry<K,V>, ? extends U> transformer,
4461 >         Action<U> action) {
4462          ForkJoinTasks.forEachEntry
4463              (this, transformer, action).invoke();
4464      }
# Line 3754 | Line 4475 | public class ConcurrentHashMapV8<K, V>
4475       * @return a non-null result from applying the given search
4476       * function on each entry, or null if none
4477       */
4478 <    public <U> U searchEntries(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4478 >    public <U> U searchEntriesInParallel
4479 >        (Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4480          return ForkJoinTasks.searchEntries
4481              (this, searchFunction).invoke();
4482      }
# Line 3766 | Line 4488 | public class ConcurrentHashMapV8<K, V>
4488       * @param reducer a commutative associative combining function
4489       * @return the result of accumulating all entries
4490       */
4491 <    public Map.Entry<K,V> reduceEntries(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4491 >    public Map.Entry<K,V> reduceEntriesInParallel
4492 >        (BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4493          return ForkJoinTasks.reduceEntries
4494              (this, reducer).invoke();
4495      }
# Line 3783 | Line 4506 | public class ConcurrentHashMapV8<K, V>
4506       * @return the result of accumulating the given transformation
4507       * of all entries
4508       */
4509 <    public <U> U reduceEntries(Fun<Map.Entry<K,V>, ? extends U> transformer,
4510 <                               BiFun<? super U, ? super U, ? extends U> reducer) {
4509 >    public <U> U reduceEntriesInParallel
4510 >        (Fun<Map.Entry<K,V>, ? extends U> transformer,
4511 >         BiFun<? super U, ? super U, ? extends U> reducer) {
4512          return ForkJoinTasks.reduceEntries
4513              (this, transformer, reducer).invoke();
4514      }
# Line 3801 | Line 4525 | public class ConcurrentHashMapV8<K, V>
4525       * @return the result of accumulating the given transformation
4526       * of all entries
4527       */
4528 <    public double reduceEntriesToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
4529 <                                        double basis,
4530 <                                        DoubleByDoubleToDouble reducer) {
4528 >    public double reduceEntriesToDoubleInParallel
4529 >        (ObjectToDouble<Map.Entry<K,V>> transformer,
4530 >         double basis,
4531 >         DoubleByDoubleToDouble reducer) {
4532          return ForkJoinTasks.reduceEntriesToDouble
4533              (this, transformer, basis, reducer).invoke();
4534      }
# Line 3820 | Line 4545 | public class ConcurrentHashMapV8<K, V>
4545       * @return  the result of accumulating the given transformation
4546       * of all entries
4547       */
4548 <    public long reduceEntriesToLong(ObjectToLong<Map.Entry<K,V>> transformer,
4549 <                                    long basis,
4550 <                                    LongByLongToLong reducer) {
4548 >    public long reduceEntriesToLongInParallel
4549 >        (ObjectToLong<Map.Entry<K,V>> transformer,
4550 >         long basis,
4551 >         LongByLongToLong reducer) {
4552          return ForkJoinTasks.reduceEntriesToLong
4553              (this, transformer, basis, reducer).invoke();
4554      }
# Line 3839 | Line 4565 | public class ConcurrentHashMapV8<K, V>
4565       * @return the result of accumulating the given transformation
4566       * of all entries
4567       */
4568 <    public int reduceEntriesToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4569 <                                  int basis,
4570 <                                  IntByIntToInt reducer) {
4568 >    public int reduceEntriesToIntInParallel
4569 >        (ObjectToInt<Map.Entry<K,V>> transformer,
4570 >         int basis,
4571 >         IntByIntToInt reducer) {
4572          return ForkJoinTasks.reduceEntriesToInt
4573              (this, transformer, basis, reducer).invoke();
4574      }
4575  
4576 +
4577      /* ----------------Views -------------- */
4578  
4579      /**
# Line 4052 | Line 4780 | public class ConcurrentHashMapV8<K, V>
4780                      ((c = (Set<?>)o) == this ||
4781                       (containsAll(c) && c.containsAll(this))));
4782          }
4055
4056        /**
4057         * Performs the given action for each key.
4058         *
4059         * @param action the action
4060         */
4061        public void forEach(Action<K> action) {
4062            ForkJoinTasks.forEachKey
4063                (map, action).invoke();
4064        }
4065
4066        /**
4067         * Performs the given action for each non-null transformation
4068         * of each key.
4069         *
4070         * @param transformer a function returning the transformation
4071         * for an element, or null of there is no transformation (in
4072         * which case the action is not applied).
4073         * @param action the action
4074         */
4075        public <U> void forEach(Fun<? super K, ? extends U> transformer,
4076                                Action<U> action) {
4077            ForkJoinTasks.forEachKey
4078                (map, transformer, action).invoke();
4079        }
4080
4081        /**
4082         * Returns a non-null result from applying the given search
4083         * function on each key, or null if none. Upon success,
4084         * further element processing is suppressed and the results of
4085         * any other parallel invocations of the search function are
4086         * ignored.
4087         *
4088         * @param searchFunction a function returning a non-null
4089         * result on success, else null
4090         * @return a non-null result from applying the given search
4091         * function on each key, or null if none
4092         */
4093        public <U> U search(Fun<? super K, ? extends U> searchFunction) {
4094            return ForkJoinTasks.searchKeys
4095                (map, searchFunction).invoke();
4096        }
4097
4098        /**
4099         * Returns the result of accumulating all keys using the given
4100         * reducer to combine values, or null if none.
4101         *
4102         * @param reducer a commutative associative combining function
4103         * @return the result of accumulating all keys using the given
4104         * reducer to combine values, or null if none
4105         */
4106        public K reduce(BiFun<? super K, ? super K, ? extends K> reducer) {
4107            return ForkJoinTasks.reduceKeys
4108                (map, reducer).invoke();
4109        }
4110
4111        /**
4112         * Returns the result of accumulating the given transformation
4113         * of all keys using the given reducer to combine values, and
4114         * the given basis as an identity value.
4115         *
4116         * @param transformer a function returning the transformation
4117         * for an element
4118         * @param basis the identity (initial default value) for the reduction
4119         * @param reducer a commutative associative combining function
4120         * @return  the result of accumulating the given transformation
4121         * of all keys
4122         */
4123        public double reduceToDouble(ObjectToDouble<? super K> transformer,
4124                                     double basis,
4125                                     DoubleByDoubleToDouble reducer) {
4126            return ForkJoinTasks.reduceKeysToDouble
4127                (map, transformer, basis, reducer).invoke();
4128        }
4129
4130        /**
4131         * Returns the result of accumulating the given transformation
4132         * of all keys using the given reducer to combine values, and
4133         * the given basis as an identity value.
4134         *
4135         * @param transformer a function returning the transformation
4136         * for an element
4137         * @param basis the identity (initial default value) for the reduction
4138         * @param reducer a commutative associative combining function
4139         * @return the result of accumulating the given transformation
4140         * of all keys
4141         */
4142        public long reduceToLong(ObjectToLong<? super K> transformer,
4143                                 long basis,
4144                                 LongByLongToLong reducer) {
4145            return ForkJoinTasks.reduceKeysToLong
4146                (map, transformer, basis, reducer).invoke();
4147        }
4148
4149        /**
4150         * Returns the result of accumulating the given transformation
4151         * of all keys using the given reducer to combine values, and
4152         * the given basis as an identity value.
4153         *
4154         * @param transformer a function returning the transformation
4155         * for an element
4156         * @param basis the identity (initial default value) for the reduction
4157         * @param reducer a commutative associative combining function
4158         * @return the result of accumulating the given transformation
4159         * of all keys
4160         */
4161        public int reduceToInt(ObjectToInt<? super K> transformer,
4162                               int basis,
4163                               IntByIntToInt reducer) {
4164            return ForkJoinTasks.reduceKeysToInt
4165                (map, transformer, basis, reducer).invoke();
4166        }
4167
4783      }
4784  
4785      /**
# Line 4215 | Line 4830 | public class ConcurrentHashMapV8<K, V>
4830              throw new UnsupportedOperationException();
4831          }
4832  
4218        /**
4219         * Performs the given action for each value.
4220         *
4221         * @param action the action
4222         */
4223        public void forEach(Action<V> action) {
4224            ForkJoinTasks.forEachValue
4225                (map, action).invoke();
4226        }
4227
4228        /**
4229         * Performs the given action for each non-null transformation
4230         * of each value.
4231         *
4232         * @param transformer a function returning the transformation
4233         * for an element, or null of there is no transformation (in
4234         * which case the action is not applied).
4235         */
4236        public <U> void forEach(Fun<? super V, ? extends U> transformer,
4237                                     Action<U> action) {
4238            ForkJoinTasks.forEachValue
4239                (map, transformer, action).invoke();
4240        }
4241
4242        /**
4243         * Returns a non-null result from applying the given search
4244         * function on each value, or null if none.  Upon success,
4245         * further element processing is suppressed and the results of
4246         * any other parallel invocations of the search function are
4247         * ignored.
4248         *
4249         * @param searchFunction a function returning a non-null
4250         * result on success, else null
4251         * @return a non-null result from applying the given search
4252         * function on each value, or null if none
4253         *
4254         */
4255        public <U> U search(Fun<? super V, ? extends U> searchFunction) {
4256            return ForkJoinTasks.searchValues
4257                (map, searchFunction).invoke();
4258        }
4259
4260        /**
4261         * Returns the result of accumulating all values using the
4262         * given reducer to combine values, or null if none.
4263         *
4264         * @param reducer a commutative associative combining function
4265         * @return  the result of accumulating all values
4266         */
4267        public V reduce(BiFun<? super V, ? super V, ? extends V> reducer) {
4268            return ForkJoinTasks.reduceValues
4269                (map, reducer).invoke();
4270        }
4271
4272        /**
4273         * Returns the result of accumulating the given transformation
4274         * of all values using the given reducer to combine values, or
4275         * null if none.
4276         *
4277         * @param transformer a function returning the transformation
4278         * for an element, or null of there is no transformation (in
4279         * which case it is not combined).
4280         * @param reducer a commutative associative combining function
4281         * @return the result of accumulating the given transformation
4282         * of all values
4283         */
4284        public <U> U reduce(Fun<? super V, ? extends U> transformer,
4285                            BiFun<? super U, ? super U, ? extends U> reducer) {
4286            return ForkJoinTasks.reduceValues
4287                (map, transformer, reducer).invoke();
4288        }
4289
4290        /**
4291         * Returns the result of accumulating the given transformation
4292         * of all values using the given reducer to combine values,
4293         * and the given basis as an identity value.
4294         *
4295         * @param transformer a function returning the transformation
4296         * for an element
4297         * @param basis the identity (initial default value) for the reduction
4298         * @param reducer a commutative associative combining function
4299         * @return the result of accumulating the given transformation
4300         * of all values
4301         */
4302        public double reduceToDouble(ObjectToDouble<? super V> transformer,
4303                                     double basis,
4304                                     DoubleByDoubleToDouble reducer) {
4305            return ForkJoinTasks.reduceValuesToDouble
4306                (map, transformer, basis, reducer).invoke();
4307        }
4308
4309        /**
4310         * Returns the result of accumulating the given transformation
4311         * of all values using the given reducer to combine values,
4312         * and the given basis as an identity value.
4313         *
4314         * @param transformer a function returning the transformation
4315         * for an element
4316         * @param basis the identity (initial default value) for the reduction
4317         * @param reducer a commutative associative combining function
4318         * @return the result of accumulating the given transformation
4319         * of all values
4320         */
4321        public long reduceToLong(ObjectToLong<? super V> transformer,
4322                                 long basis,
4323                                 LongByLongToLong reducer) {
4324            return ForkJoinTasks.reduceValuesToLong
4325                (map, transformer, basis, reducer).invoke();
4326        }
4327
4328        /**
4329         * Returns the result of accumulating the given transformation
4330         * of all values using the given reducer to combine values,
4331         * and the given basis as an identity value.
4332         *
4333         * @param transformer a function returning the transformation
4334         * for an element
4335         * @param basis the identity (initial default value) for the reduction
4336         * @param reducer a commutative associative combining function
4337         * @return the result of accumulating the given transformation
4338         * of all values
4339         */
4340        public int reduceToInt(ObjectToInt<? super V> transformer,
4341                               int basis,
4342                               IntByIntToInt reducer) {
4343            return ForkJoinTasks.reduceValuesToInt
4344                (map, transformer, basis, reducer).invoke();
4345        }
4346
4833      }
4834  
4835      /**
# Line 4405 | Line 4891 | public class ConcurrentHashMapV8<K, V>
4891                      ((c = (Set<?>)o) == this ||
4892                       (containsAll(c) && c.containsAll(this))));
4893          }
4408
4409        /**
4410         * Performs the given action for each entry.
4411         *
4412         * @param action the action
4413         */
4414        public void forEach(Action<Map.Entry<K,V>> action) {
4415            ForkJoinTasks.forEachEntry
4416                (map, action).invoke();
4417        }
4418
4419        /**
4420         * Performs the given action for each non-null transformation
4421         * of each entry.
4422         *
4423         * @param transformer a function returning the transformation
4424         * for an element, or null of there is no transformation (in
4425         * which case the action is not applied).
4426         * @param action the action
4427         */
4428        public <U> void forEach(Fun<Map.Entry<K,V>, ? extends U> transformer,
4429                                Action<U> action) {
4430            ForkJoinTasks.forEachEntry
4431                (map, transformer, action).invoke();
4432        }
4433
4434        /**
4435         * Returns a non-null result from applying the given search
4436         * function on each entry, or null if none.  Upon success,
4437         * further element processing is suppressed and the results of
4438         * any other parallel invocations of the search function are
4439         * ignored.
4440         *
4441         * @param searchFunction a function returning a non-null
4442         * result on success, else null
4443         * @return a non-null result from applying the given search
4444         * function on each entry, or null if none
4445         */
4446        public <U> U search(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4447            return ForkJoinTasks.searchEntries
4448                (map, searchFunction).invoke();
4449        }
4450
4451        /**
4452         * Returns the result of accumulating all entries using the
4453         * given reducer to combine values, or null if none.
4454         *
4455         * @param reducer a commutative associative combining function
4456         * @return the result of accumulating all entries
4457         */
4458        public Map.Entry<K,V> reduce(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4459            return ForkJoinTasks.reduceEntries
4460                (map, reducer).invoke();
4461        }
4462
4463        /**
4464         * Returns the result of accumulating the given transformation
4465         * of all entries using the given reducer to combine values,
4466         * or null if none.
4467         *
4468         * @param transformer a function returning the transformation
4469         * for an element, or null of there is no transformation (in
4470         * which case it is not combined).
4471         * @param reducer a commutative associative combining function
4472         * @return the result of accumulating the given transformation
4473         * of all entries
4474         */
4475        public <U> U reduce(Fun<Map.Entry<K,V>, ? extends U> transformer,
4476                            BiFun<? super U, ? super U, ? extends U> reducer) {
4477            return ForkJoinTasks.reduceEntries
4478                (map, transformer, reducer).invoke();
4479        }
4480
4481        /**
4482         * Returns the result of accumulating the given transformation
4483         * of all entries using the given reducer to combine values,
4484         * and the given basis as an identity value.
4485         *
4486         * @param transformer a function returning the transformation
4487         * for an element
4488         * @param basis the identity (initial default value) for the reduction
4489         * @param reducer a commutative associative combining function
4490         * @return the result of accumulating the given transformation
4491         * of all entries
4492         */
4493        public double reduceToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
4494                                     double basis,
4495                                     DoubleByDoubleToDouble reducer) {
4496            return ForkJoinTasks.reduceEntriesToDouble
4497                (map, transformer, basis, reducer).invoke();
4498        }
4499
4500        /**
4501         * Returns the result of accumulating the given transformation
4502         * of all entries using the given reducer to combine values,
4503         * and the given basis as an identity value.
4504         *
4505         * @param transformer a function returning the transformation
4506         * for an element
4507         * @param basis the identity (initial default value) for the reduction
4508         * @param reducer a commutative associative combining function
4509         * @return  the result of accumulating the given transformation
4510         * of all entries
4511         */
4512        public long reduceToLong(ObjectToLong<Map.Entry<K,V>> transformer,
4513                                 long basis,
4514                                 LongByLongToLong reducer) {
4515            return ForkJoinTasks.reduceEntriesToLong
4516                (map, transformer, basis, reducer).invoke();
4517        }
4518
4519        /**
4520         * Returns the result of accumulating the given transformation
4521         * of all entries using the given reducer to combine values,
4522         * and the given basis as an identity value.
4523         *
4524         * @param transformer a function returning the transformation
4525         * for an element
4526         * @param basis the identity (initial default value) for the reduction
4527         * @param reducer a commutative associative combining function
4528         * @return the result of accumulating the given transformation
4529         * of all entries
4530         */
4531        public int reduceToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4532                               int basis,
4533                               IntByIntToInt reducer) {
4534            return ForkJoinTasks.reduceEntriesToInt
4535                (map, transformer, basis, reducer).invoke();
4536        }
4537
4894      }
4895  
4896      // ---------------------------------------------------------------------
# Line 5247 | Line 5603 | public class ConcurrentHashMapV8<K, V>
5603              if ((action = this.action) != null) {
5604                  for (int b; (b = preSplit()) > 0;)
5605                      new ForEachValueTask<K,V>(map, this, b, action).fork();
5606 <                Object v;
5606 >                V v;
5607                  while ((v = advance()) != null)
5608 <                    action.apply((V)v);
5608 >                    action.apply(v);
5609                  propagateCompletion();
5610              }
5611          }
# Line 5269 | Line 5625 | public class ConcurrentHashMapV8<K, V>
5625              if ((action = this.action) != null) {
5626                  for (int b; (b = preSplit()) > 0;)
5627                      new ForEachEntryTask<K,V>(map, this, b, action).fork();
5628 <                Object v;
5628 >                V v;
5629                  while ((v = advance()) != null)
5630 <                    action.apply(entryFor((K)nextKey, (V)v));
5630 >                    action.apply(entryFor((K)nextKey, v));
5631                  propagateCompletion();
5632              }
5633          }
# Line 5291 | Line 5647 | public class ConcurrentHashMapV8<K, V>
5647              if ((action = this.action) != null) {
5648                  for (int b; (b = preSplit()) > 0;)
5649                      new ForEachMappingTask<K,V>(map, this, b, action).fork();
5650 <                Object v;
5650 >                V v;
5651                  while ((v = advance()) != null)
5652 <                    action.apply((K)nextKey, (V)v);
5652 >                    action.apply((K)nextKey, v);
5653                  propagateCompletion();
5654              }
5655          }
# Line 5345 | Line 5701 | public class ConcurrentHashMapV8<K, V>
5701                  for (int b; (b = preSplit()) > 0;)
5702                      new ForEachTransformedValueTask<K,V,U>
5703                          (map, this, b, transformer, action).fork();
5704 <                Object v; U u;
5704 >                V v; U u;
5705                  while ((v = advance()) != null) {
5706 <                    if ((u = transformer.apply((V)v)) != null)
5706 >                    if ((u = transformer.apply(v)) != null)
5707                          action.apply(u);
5708                  }
5709                  propagateCompletion();
# Line 5373 | Line 5729 | public class ConcurrentHashMapV8<K, V>
5729                  for (int b; (b = preSplit()) > 0;)
5730                      new ForEachTransformedEntryTask<K,V,U>
5731                          (map, this, b, transformer, action).fork();
5732 <                Object v; U u;
5732 >                V v; U u;
5733                  while ((v = advance()) != null) {
5734                      if ((u = transformer.apply(entryFor((K)nextKey,
5735 <                                                        (V)v))) != null)
5735 >                                                        v))) != null)
5736                          action.apply(u);
5737                  }
5738                  propagateCompletion();
# Line 5403 | Line 5759 | public class ConcurrentHashMapV8<K, V>
5759                  for (int b; (b = preSplit()) > 0;)
5760                      new ForEachTransformedMappingTask<K,V,U>
5761                          (map, this, b, transformer, action).fork();
5762 <                Object v; U u;
5762 >                V v; U u;
5763                  while ((v = advance()) != null) {
5764 <                    if ((u = transformer.apply((K)nextKey, (V)v)) != null)
5764 >                    if ((u = transformer.apply((K)nextKey, v)) != null)
5765                          action.apply(u);
5766                  }
5767                  propagateCompletion();
# Line 5480 | Line 5836 | public class ConcurrentHashMapV8<K, V>
5836                          (map, this, b, searchFunction, result).fork();
5837                  }
5838                  while (result.get() == null) {
5839 <                    Object v; U u;
5839 >                    V v; U u;
5840                      if ((v = advance()) == null) {
5841                          propagateCompletion();
5842                          break;
5843                      }
5844 <                    if ((u = searchFunction.apply((V)v)) != null) {
5844 >                    if ((u = searchFunction.apply(v)) != null) {
5845                          if (result.compareAndSet(null, u))
5846                              quietlyCompleteRoot();
5847                          break;
# Line 5521 | Line 5877 | public class ConcurrentHashMapV8<K, V>
5877                          (map, this, b, searchFunction, result).fork();
5878                  }
5879                  while (result.get() == null) {
5880 <                    Object v; U u;
5880 >                    V v; U u;
5881                      if ((v = advance()) == null) {
5882                          propagateCompletion();
5883                          break;
5884                      }
5885                      if ((u = searchFunction.apply(entryFor((K)nextKey,
5886 <                                                           (V)v))) != null) {
5886 >                                                           v))) != null) {
5887                          if (result.compareAndSet(null, u))
5888                              quietlyCompleteRoot();
5889                          return;
# Line 5563 | Line 5919 | public class ConcurrentHashMapV8<K, V>
5919                          (map, this, b, searchFunction, result).fork();
5920                  }
5921                  while (result.get() == null) {
5922 <                    Object v; U u;
5922 >                    V v; U u;
5923                      if ((v = advance()) == null) {
5924                          propagateCompletion();
5925                          break;
5926                      }
5927 <                    if ((u = searchFunction.apply((K)nextKey, (V)v)) != null) {
5927 >                    if ((u = searchFunction.apply((K)nextKey, v)) != null) {
5928                          if (result.compareAndSet(null, u))
5929                              quietlyCompleteRoot();
5930                          break;
# Line 5640 | Line 5996 | public class ConcurrentHashMapV8<K, V>
5996                      (rights = new ReduceValuesTask<K,V>
5997                       (map, this, b, rights, reducer)).fork();
5998                  V r = null;
5999 <                Object v;
5999 >                V v;
6000                  while ((v = advance()) != null) {
6001 <                    V u = (V)v;
6001 >                    V u = v;
6002                      r = (r == null) ? u : reducer.apply(r, u);
6003                  }
6004                  result = r;
# Line 5683 | Line 6039 | public class ConcurrentHashMapV8<K, V>
6039                      (rights = new ReduceEntriesTask<K,V>
6040                       (map, this, b, rights, reducer)).fork();
6041                  Map.Entry<K,V> r = null;
6042 <                Object v;
6042 >                V v;
6043                  while ((v = advance()) != null) {
6044 <                    Map.Entry<K,V> u = entryFor((K)nextKey, (V)v);
6044 >                    Map.Entry<K,V> u = entryFor((K)nextKey, v);
6045                      r = (r == null) ? u : reducer.apply(r, u);
6046                  }
6047                  result = r;
# Line 5778 | Line 6134 | public class ConcurrentHashMapV8<K, V>
6134                      (rights = new MapReduceValuesTask<K,V,U>
6135                       (map, this, b, rights, transformer, reducer)).fork();
6136                  U r = null, u;
6137 <                Object v;
6137 >                V v;
6138                  while ((v = advance()) != null) {
6139 <                    if ((u = transformer.apply((V)v)) != null)
6139 >                    if ((u = transformer.apply(v)) != null)
6140                          r = (r == null) ? u : reducer.apply(r, u);
6141                  }
6142                  result = r;
# Line 5826 | Line 6182 | public class ConcurrentHashMapV8<K, V>
6182                      (rights = new MapReduceEntriesTask<K,V,U>
6183                       (map, this, b, rights, transformer, reducer)).fork();
6184                  U r = null, u;
6185 <                Object v;
6185 >                V v;
6186                  while ((v = advance()) != null) {
6187                      if ((u = transformer.apply(entryFor((K)nextKey,
6188 <                                                        (V)v))) != null)
6188 >                                                        v))) != null)
6189                          r = (r == null) ? u : reducer.apply(r, u);
6190                  }
6191                  result = r;
# Line 5875 | Line 6231 | public class ConcurrentHashMapV8<K, V>
6231                      (rights = new MapReduceMappingsTask<K,V,U>
6232                       (map, this, b, rights, transformer, reducer)).fork();
6233                  U r = null, u;
6234 <                Object v;
6234 >                V v;
6235                  while ((v = advance()) != null) {
6236 <                    if ((u = transformer.apply((K)nextKey, (V)v)) != null)
6236 >                    if ((u = transformer.apply((K)nextKey, v)) != null)
6237                          r = (r == null) ? u : reducer.apply(r, u);
6238                  }
6239                  result = r;
# Line 5969 | Line 6325 | public class ConcurrentHashMapV8<K, V>
6325                  for (int b; (b = preSplit()) > 0;)
6326                      (rights = new MapReduceValuesToDoubleTask<K,V>
6327                       (map, this, b, rights, transformer, r, reducer)).fork();
6328 <                Object v;
6328 >                V v;
6329                  while ((v = advance()) != null)
6330 <                    r = reducer.apply(r, transformer.apply((V)v));
6330 >                    r = reducer.apply(r, transformer.apply(v));
6331                  result = r;
6332                  CountedCompleter<?> c;
6333                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6014 | Line 6370 | public class ConcurrentHashMapV8<K, V>
6370                  for (int b; (b = preSplit()) > 0;)
6371                      (rights = new MapReduceEntriesToDoubleTask<K,V>
6372                       (map, this, b, rights, transformer, r, reducer)).fork();
6373 <                Object v;
6373 >                V v;
6374                  while ((v = advance()) != null)
6375                      r = reducer.apply(r, transformer.apply(entryFor((K)nextKey,
6376 <                                                                    (V)v)));
6376 >                                                                    v)));
6377                  result = r;
6378                  CountedCompleter<?> c;
6379                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6060 | Line 6416 | public class ConcurrentHashMapV8<K, V>
6416                  for (int b; (b = preSplit()) > 0;)
6417                      (rights = new MapReduceMappingsToDoubleTask<K,V>
6418                       (map, this, b, rights, transformer, r, reducer)).fork();
6419 <                Object v;
6419 >                V v;
6420                  while ((v = advance()) != null)
6421 <                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6421 >                    r = reducer.apply(r, transformer.apply((K)nextKey, v));
6422                  result = r;
6423                  CountedCompleter<?> c;
6424                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6149 | Line 6505 | public class ConcurrentHashMapV8<K, V>
6505                  for (int b; (b = preSplit()) > 0;)
6506                      (rights = new MapReduceValuesToLongTask<K,V>
6507                       (map, this, b, rights, transformer, r, reducer)).fork();
6508 <                Object v;
6508 >                V v;
6509                  while ((v = advance()) != null)
6510 <                    r = reducer.apply(r, transformer.apply((V)v));
6510 >                    r = reducer.apply(r, transformer.apply(v));
6511                  result = r;
6512                  CountedCompleter<?> c;
6513                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6194 | Line 6550 | public class ConcurrentHashMapV8<K, V>
6550                  for (int b; (b = preSplit()) > 0;)
6551                      (rights = new MapReduceEntriesToLongTask<K,V>
6552                       (map, this, b, rights, transformer, r, reducer)).fork();
6553 <                Object v;
6553 >                V v;
6554                  while ((v = advance()) != null)
6555                      r = reducer.apply(r, transformer.apply(entryFor((K)nextKey,
6556 <                                                                    (V)v)));
6556 >                                                                    v)));
6557                  result = r;
6558                  CountedCompleter<?> c;
6559                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6240 | Line 6596 | public class ConcurrentHashMapV8<K, V>
6596                  for (int b; (b = preSplit()) > 0;)
6597                      (rights = new MapReduceMappingsToLongTask<K,V>
6598                       (map, this, b, rights, transformer, r, reducer)).fork();
6599 <                Object v;
6599 >                V v;
6600                  while ((v = advance()) != null)
6601 <                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6601 >                    r = reducer.apply(r, transformer.apply((K)nextKey, v));
6602                  result = r;
6603                  CountedCompleter<?> c;
6604                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6329 | Line 6685 | public class ConcurrentHashMapV8<K, V>
6685                  for (int b; (b = preSplit()) > 0;)
6686                      (rights = new MapReduceValuesToIntTask<K,V>
6687                       (map, this, b, rights, transformer, r, reducer)).fork();
6688 <                Object v;
6688 >                V v;
6689                  while ((v = advance()) != null)
6690 <                    r = reducer.apply(r, transformer.apply((V)v));
6690 >                    r = reducer.apply(r, transformer.apply(v));
6691                  result = r;
6692                  CountedCompleter<?> c;
6693                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6374 | Line 6730 | public class ConcurrentHashMapV8<K, V>
6730                  for (int b; (b = preSplit()) > 0;)
6731                      (rights = new MapReduceEntriesToIntTask<K,V>
6732                       (map, this, b, rights, transformer, r, reducer)).fork();
6733 <                Object v;
6733 >                V v;
6734                  while ((v = advance()) != null)
6735                      r = reducer.apply(r, transformer.apply(entryFor((K)nextKey,
6736 <                                                                    (V)v)));
6736 >                                                                    v)));
6737                  result = r;
6738                  CountedCompleter<?> c;
6739                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6420 | Line 6776 | public class ConcurrentHashMapV8<K, V>
6776                  for (int b; (b = preSplit()) > 0;)
6777                      (rights = new MapReduceMappingsToIntTask<K,V>
6778                       (map, this, b, rights, transformer, r, reducer)).fork();
6779 <                Object v;
6779 >                V v;
6780                  while ((v = advance()) != null)
6781 <                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6781 >                    r = reducer.apply(r, transformer.apply((K)nextKey, v));
6782                  result = r;
6783                  CountedCompleter<?> c;
6784                  for (c = firstComplete(); c != null; c = c.nextComplete()) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines