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.82 by dl, Thu Dec 13 20:34:00 2012 UTC vs.
Revision 1.90 by dl, Tue Jan 22 20:17:55 2013 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 567 | Line 567 | public class ConcurrentHashMapV8<K, V>
567      static final int SEED_INCREMENT = 0x61c88647;
568  
569      /**
570 <     * Per-thread counter hash codes. Shared across all instances
570 >     * Per-thread counter hash codes. Shared across all instances.
571       */
572      static final ThreadLocal<CounterHashCode> threadCounterHashCode =
573          new ThreadLocal<CounterHashCode>();
# 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
1264              else {
1265                  boolean validated = false;
1266                  boolean deleted = false;
1267 <                synchronized(f) {
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;
1368 <                synchronized(f) {
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);
1416 <                synchronized(node) {
1415 >                Node<V> node = new Node<V>(h, k, null, null);
1416 >                synchronized (node) {
1417                      if (casTabAt(tab, i, null, node)) {
1418                          len = 1;
1419                          try {
# 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) {
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);
1522 <                synchronized(node) {
1521 >                Node<V> node = new Node<V>(h, k, null, null);
1522 >                synchronized (node) {
1523                      if (casTabAt(tab, i, null, node)) {
1524                          try {
1525                              len = 1;
# 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) {
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) {
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) {
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 1781 | Line 1785 | public class ConcurrentHashMapV8<K, V>
1785                              }
1786                          }
1787                          if (len != 0) {
1788 <                            if (len > 1)
1788 >                            if (len > 1) {
1789                                  addCount(delta, len);
1790 +                                delta = 0L;
1791 +                            }
1792                              break;
1793                          }
1794                      }
# Line 1800 | Line 1806 | public class ConcurrentHashMapV8<K, V>
1806       * Implementation for clear. Steps through each bin, removing all
1807       * nodes.
1808       */
1809 <    private final void internalClear() {
1809 >    @SuppressWarnings("unchecked") private final void internalClear() {
1810          long delta = 0L; // negative number of deletions
1811          int i = 0;
1812 <        Node[] tab = table;
1812 >        Node<V>[] tab = table;
1813          while (tab != null && i < tab.length) {
1814 <            Node f = tabAt(tab, i);
1814 >            Node<V> f = tabAt(tab, i);
1815              if (f == null)
1816                  ++i;
1817              else if (f.hash < 0) {
1818                  Object fk;
1819                  if ((fk = f.key) instanceof TreeBin) {
1820 <                    TreeBin t = (TreeBin)fk;
1820 >                    TreeBin<V> t = (TreeBin<V>)fk;
1821                      t.acquire(0);
1822                      try {
1823                          if (tabAt(tab, i) == f) {
1824 <                            for (Node p = t.first; p != null; p = p.next) {
1824 >                            for (Node<V> p = t.first; p != null; p = p.next) {
1825                                  if (p.val != null) { // (currently always true)
1826                                      p.val = null;
1827                                      --delta;
# Line 1830 | Line 1836 | public class ConcurrentHashMapV8<K, V>
1836                      }
1837                  }
1838                  else
1839 <                    tab = (Node[])fk;
1839 >                    tab = (Node<V>[])fk;
1840              }
1841              else {
1842 <                synchronized(f) {
1842 >                synchronized (f) {
1843                      if (tabAt(tab, i) == f) {
1844 <                        for (Node e = f; e != null; e = e.next) {
1844 >                        for (Node<V> e = f; e != null; e = e.next) {
1845                              if (e.val != null) {  // (currently always true)
1846                                  e.val = null;
1847                                  --delta;
# Line 1870 | Line 1876 | public class ConcurrentHashMapV8<K, V>
1876      /**
1877       * Initializes table, using the size recorded in sizeCtl.
1878       */
1879 <    private final Node[] initTable() {
1880 <        Node[] tab; int sc;
1879 >    @SuppressWarnings("unchecked") private final Node<V>[] initTable() {
1880 >        Node<V>[] tab; int sc;
1881          while ((tab = table) == null) {
1882              if ((sc = sizeCtl) < 0)
1883                  Thread.yield(); // lost initialization race; just spin
# Line 1879 | Line 1885 | public class ConcurrentHashMapV8<K, V>
1885                  try {
1886                      if ((tab = table) == null) {
1887                          int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
1888 <                        tab = table = new Node[n];
1888 >                        @SuppressWarnings("rawtypes") Node[] tb = new Node[n];
1889 >                        table = tab = (Node<V>[])tb;
1890                          sc = n - (n >>> 2);
1891                      }
1892                  } finally {
# Line 1920 | Line 1927 | public class ConcurrentHashMapV8<K, V>
1927              s = sumCount();
1928          }
1929          if (check >= 0) {
1930 <            Node[] tab, nt; int sc;
1930 >            Node<V>[] tab, nt; int sc;
1931              while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
1932                     tab.length < MAXIMUM_CAPACITY) {
1933                  if (sc < 0) {
# Line 1942 | Line 1949 | public class ConcurrentHashMapV8<K, V>
1949       *
1950       * @param size number of elements (doesn't need to be perfectly accurate)
1951       */
1952 <    private final void tryPresize(int size) {
1952 >    @SuppressWarnings("unchecked") private final void tryPresize(int size) {
1953          int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :
1954              tableSizeFor(size + (size >>> 1) + 1);
1955          int sc;
1956          while ((sc = sizeCtl) >= 0) {
1957 <            Node[] tab = table; int n;
1957 >            Node<V>[] tab = table; int n;
1958              if (tab == null || (n = tab.length) == 0) {
1959                  n = (sc > c) ? sc : c;
1960                  if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
1961                      try {
1962                          if (table == tab) {
1963 <                            table = new Node[n];
1963 >                            @SuppressWarnings("rawtypes") Node[] tb = new Node[n];
1964 >                            table = (Node<V>[])tb;
1965                              sc = n - (n >>> 2);
1966                          }
1967                      } finally {
# Line 1973 | Line 1981 | public class ConcurrentHashMapV8<K, V>
1981       * Moves and/or copies the nodes in each bin to new table. See
1982       * above for explanation.
1983       */
1984 <    private final void transfer(Node[] tab, Node[] nextTab) {
1984 >    @SuppressWarnings("unchecked") private final void transfer
1985 >        (Node<V>[] tab, Node<V>[] nextTab) {
1986          int n = tab.length, stride;
1987          if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)
1988              stride = MIN_TRANSFER_STRIDE; // subdivide range
1989          if (nextTab == null) {            // initiating
1990              try {
1991 <                nextTab = new Node[n << 1];
1992 <            } catch(Throwable ex) {       // try to cope with OOME
1991 >                @SuppressWarnings("rawtypes") Node[] tb = new Node[n << 1];
1992 >                nextTab = (Node<V>[])tb;
1993 >            } catch (Throwable ex) {      // try to cope with OOME
1994                  sizeCtl = Integer.MAX_VALUE;
1995                  return;
1996              }
1997              nextTable = nextTab;
1998              transferOrigin = n;
1999              transferIndex = n;
2000 <            Node rev = new Node(MOVED, tab, null, null);
2000 >            Node<V> rev = new Node<V>(MOVED, tab, null, null);
2001              for (int k = n; k > 0;) {    // progressively reveal ready slots
2002 <                int nextk = k > stride? k - stride : 0;
2002 >                int nextk = (k > stride) ? k - stride : 0;
2003                  for (int m = nextk; m < k; ++m)
2004                      nextTab[m] = rev;
2005                  for (int m = n + nextk; m < n + k; ++m)
# Line 1998 | Line 2008 | public class ConcurrentHashMapV8<K, V>
2008              }
2009          }
2010          int nextn = nextTab.length;
2011 <        Node fwd = new Node(MOVED, nextTab, null, null);
2011 >        Node<V> fwd = new Node<V>(MOVED, nextTab, null, null);
2012          boolean advance = true;
2013          for (int i = 0, bound = 0;;) {
2014 <            int nextIndex, nextBound; Node f; Object fk;
2014 >            int nextIndex, nextBound; Node<V> f; Object fk;
2015              while (advance) {
2016                  if (--i >= bound)
2017                      advance = false;
# Line 2011 | Line 2021 | public class ConcurrentHashMapV8<K, V>
2021                  }
2022                  else if (U.compareAndSwapInt
2023                           (this, TRANSFERINDEX, nextIndex,
2024 <                          nextBound = (nextIndex > stride?
2024 >                          nextBound = (nextIndex > stride ?
2025                                         nextIndex - stride : 0))) {
2026                      bound = nextBound;
2027                      i = nextIndex - 1;
# Line 2038 | Line 2048 | public class ConcurrentHashMapV8<K, V>
2048                  }
2049              }
2050              else if (f.hash >= 0) {
2051 <                synchronized(f) {
2051 >                synchronized (f) {
2052                      if (tabAt(tab, i) == f) {
2053                          int runBit = f.hash & n;
2054 <                        Node lastRun = f, lo = null, hi = null;
2055 <                        for (Node p = f.next; p != null; p = p.next) {
2054 >                        Node<V> lastRun = f, lo = null, hi = null;
2055 >                        for (Node<V> p = f.next; p != null; p = p.next) {
2056                              int b = p.hash & n;
2057                              if (b != runBit) {
2058                                  runBit = b;
# Line 2053 | Line 2063 | public class ConcurrentHashMapV8<K, V>
2063                              lo = lastRun;
2064                          else
2065                              hi = lastRun;
2066 <                        for (Node p = f; p != lastRun; p = p.next) {
2066 >                        for (Node<V> p = f; p != lastRun; p = p.next) {
2067                              int ph = p.hash;
2068 <                            Object pk = p.key, pv = p.val;
2068 >                            Object pk = p.key; V pv = p.val;
2069                              if ((ph & n) == 0)
2070 <                                lo = new Node(ph, pk, pv, lo);
2070 >                                lo = new Node<V>(ph, pk, pv, lo);
2071                              else
2072 <                                hi = new Node(ph, pk, pv, hi);
2072 >                                hi = new Node<V>(ph, pk, pv, hi);
2073                          }
2074                          setTabAt(nextTab, i, lo);
2075                          setTabAt(nextTab, i + n, hi);
# Line 2069 | Line 2079 | public class ConcurrentHashMapV8<K, V>
2079                  }
2080              }
2081              else if ((fk = f.key) instanceof TreeBin) {
2082 <                TreeBin t = (TreeBin)fk;
2082 >                TreeBin<V> t = (TreeBin<V>)fk;
2083                  t.acquire(0);
2084                  try {
2085                      if (tabAt(tab, i) == f) {
2086 <                        TreeBin lt = new TreeBin();
2087 <                        TreeBin ht = new TreeBin();
2086 >                        TreeBin<V> lt = new TreeBin<V>();
2087 >                        TreeBin<V> ht = new TreeBin<V>();
2088                          int lc = 0, hc = 0;
2089 <                        for (Node e = t.first; e != null; e = e.next) {
2089 >                        for (Node<V> e = t.first; e != null; e = e.next) {
2090                              int h = e.hash;
2091 <                            Object k = e.key, v = e.val;
2091 >                            Object k = e.key; V v = e.val;
2092                              if ((h & n) == 0) {
2093                                  ++lc;
2094                                  lt.putTreeNode(h, k, v);
# Line 2088 | Line 2098 | public class ConcurrentHashMapV8<K, V>
2098                                  ht.putTreeNode(h, k, v);
2099                              }
2100                          }
2101 <                        Node ln, hn; // throw away trees if too small
2101 >                        Node<V> ln, hn; // throw away trees if too small
2102                          if (lc < TREE_THRESHOLD) {
2103                              ln = null;
2104 <                            for (Node p = lt.first; p != null; p = p.next)
2105 <                                ln = new Node(p.hash, p.key, p.val, ln);
2104 >                            for (Node<V> p = lt.first; p != null; p = p.next)
2105 >                                ln = new Node<V>(p.hash, p.key, p.val, ln);
2106                          }
2107                          else
2108 <                            ln = new Node(MOVED, lt, null, null);
2108 >                            ln = new Node<V>(MOVED, lt, null, null);
2109                          setTabAt(nextTab, i, ln);
2110                          if (hc < TREE_THRESHOLD) {
2111                              hn = null;
2112 <                            for (Node p = ht.first; p != null; p = p.next)
2113 <                                hn = new Node(p.hash, p.key, p.val, hn);
2112 >                            for (Node<V> p = ht.first; p != null; p = p.next)
2113 >                                hn = new Node<V>(p.hash, p.key, p.val, hn);
2114                          }
2115                          else
2116 <                            hn = new Node(MOVED, ht, null, null);
2116 >                            hn = new Node<V>(MOVED, ht, null, null);
2117                          setTabAt(nextTab, i + n, hn);
2118                          setTabAt(tab, i, fwd);
2119                          advance = true;
# Line 2270 | Line 2280 | public class ConcurrentHashMapV8<K, V>
2280      @SuppressWarnings("serial") static class Traverser<K,V,R>
2281          extends CountedCompleter<R> {
2282          final ConcurrentHashMapV8<K, V> map;
2283 <        Node next;           // the next entry to use
2283 >        Node<V> next;        // the next entry to use
2284          Object nextKey;      // cached key field of next
2285 <        Object nextVal;      // cached val field of next
2286 <        Node[] tab;          // current table; updated if resized
2285 >        V nextVal;           // cached val field of next
2286 >        Node<V>[] tab;       // current table; updated if resized
2287          int index;           // index of bin to use next
2288          int baseIndex;       // current index of initial table
2289          int baseLimit;       // index bound for initial table
# Line 2290 | Line 2300 | public class ConcurrentHashMapV8<K, V>
2300              super(it);
2301              this.batch = batch;
2302              if ((this.map = map) != null && it != null) { // split parent
2303 <                Node[] t;
2303 >                Node<V>[] t;
2304                  if ((t = it.tab) == null &&
2305                      (t = it.tab = map.table) != null)
2306                      it.baseLimit = it.baseSize = t.length;
# Line 2306 | Line 2316 | public class ConcurrentHashMapV8<K, V>
2316           * Advances next; returns nextVal or null if terminated.
2317           * See above for explanation.
2318           */
2319 <        final Object advance() {
2320 <            Node e = next;
2321 <            Object ev = null;
2319 >        @SuppressWarnings("unchecked") final V advance() {
2320 >            Node<V> e = next;
2321 >            V ev = null;
2322              outer: do {
2323                  if (e != null)                  // advance past used/skipped node
2324                      e = e.next;
2325                  while (e == null) {             // get to next non-null bin
2326                      ConcurrentHashMapV8<K, V> m;
2327 <                    Node[] t; int b, i, n; Object ek; // checks must use locals
2327 >                    Node<V>[] t; int b, i, n; Object ek; //  must use locals
2328                      if ((t = tab) != null)
2329                          n = t.length;
2330                      else if ((m = map) != null && (t = tab = m.table) != null)
# Line 2326 | Line 2336 | public class ConcurrentHashMapV8<K, V>
2336                          break outer;
2337                      if ((e = tabAt(t, i)) != null && e.hash < 0) {
2338                          if ((ek = e.key) instanceof TreeBin)
2339 <                            e = ((TreeBin)ek).first;
2339 >                            e = ((TreeBin<V>)ek).first;
2340                          else {
2341 <                            tab = (Node[])ek;
2341 >                            tab = (Node<V>[])ek;
2342                              continue;           // restarts due to null val
2343                          }
2344                      }                           // visit upper slots if present
# Line 2366 | Line 2376 | public class ConcurrentHashMapV8<K, V>
2376           * anyway.
2377           */
2378          final int preSplit() {
2379 <            ConcurrentHashMapV8<K, V> m; int b; Node[] t;  ForkJoinPool pool;
2379 >            ConcurrentHashMapV8<K, V> m; int b; Node<V>[] t;  ForkJoinPool pool;
2380              if ((b = batch) < 0 && (m = map) != null) { // force initialization
2381                  if ((t = tab) == null && (t = tab = m.table) != null)
2382                      baseLimit = baseSize = t.length;
# Line 2586 | Line 2596 | public class ConcurrentHashMapV8<K, V>
2596      public boolean containsValue(Object value) {
2597          if (value == null)
2598              throw new NullPointerException();
2599 <        Object v;
2599 >        V v;
2600          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
2601          while ((v = it.advance()) != null) {
2602              if (v == value || value.equals(v))
# Line 2610 | Line 2620 | public class ConcurrentHashMapV8<K, V>
2620       *         {@code false} otherwise
2621       * @throws NullPointerException if the specified value is null
2622       */
2623 <    public boolean contains(Object value) {
2623 >    @Deprecated public boolean contains(Object value) {
2624          return containsValue(value);
2625      }
2626  
# Line 2983 | Line 2993 | public class ConcurrentHashMapV8<K, V>
2993      public int hashCode() {
2994          int h = 0;
2995          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
2996 <        Object v;
2996 >        V v;
2997          while ((v = it.advance()) != null) {
2998              h += it.nextKey.hashCode() ^ v.hashCode();
2999          }
# Line 3005 | Line 3015 | public class ConcurrentHashMapV8<K, V>
3015          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3016          StringBuilder sb = new StringBuilder();
3017          sb.append('{');
3018 <        Object v;
3018 >        V v;
3019          if ((v = it.advance()) != null) {
3020              for (;;) {
3021                  Object k = it.nextKey;
# Line 3036 | Line 3046 | public class ConcurrentHashMapV8<K, V>
3046                  return false;
3047              Map<?,?> m = (Map<?,?>) o;
3048              Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3049 <            Object val;
3049 >            V val;
3050              while ((val = it.advance()) != null) {
3051                  Object v = m.get(it.nextKey);
3052                  if (v == null || (v != val && !v.equals(val)))
# Line 3092 | Line 3102 | public class ConcurrentHashMapV8<K, V>
3102              return new ValueIterator<K,V>(map, this);
3103          }
3104  
3105 <        @SuppressWarnings("unchecked") public final V next() {
3106 <            Object v;
3105 >        public final V next() {
3106 >            V v;
3107              if ((v = nextVal) == null && (v = advance()) == null)
3108                  throw new NoSuchElementException();
3109              nextVal = null;
3110 <            return (V) v;
3110 >            return v;
3111          }
3112  
3113          public final V nextElement() { return next(); }
# Line 3117 | Line 3127 | public class ConcurrentHashMapV8<K, V>
3127          }
3128  
3129          @SuppressWarnings("unchecked") public final Map.Entry<K,V> next() {
3130 <            Object v;
3130 >            V v;
3131              if ((v = nextVal) == null && (v = advance()) == null)
3132                  throw new NoSuchElementException();
3133              Object k = nextKey;
3134              nextVal = null;
3135 <            return new MapEntry<K,V>((K)k, (V)v, map);
3135 >            return new MapEntry<K,V>((K)k, v, map);
3136          }
3137      }
3138  
# Line 3209 | Line 3219 | public class ConcurrentHashMapV8<K, V>
3219          }
3220          s.defaultWriteObject();
3221          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3222 <        Object v;
3222 >        V v;
3223          while ((v = it.advance()) != null) {
3224              s.writeObject(it.nextKey);
3225              s.writeObject(v);
# Line 3231 | Line 3241 | public class ConcurrentHashMapV8<K, V>
3241  
3242          // Create all nodes, then place in table once size is known
3243          long size = 0L;
3244 <        Node p = null;
3244 >        Node<V> p = null;
3245          for (;;) {
3246              K k = (K) s.readObject();
3247              V v = (V) s.readObject();
3248              if (k != null && v != null) {
3249                  int h = spread(k.hashCode());
3250 <                p = new Node(h, k, v, p);
3250 >                p = new Node<V>(h, k, v, p);
3251                  ++size;
3252              }
3253              else
# Line 3259 | Line 3269 | public class ConcurrentHashMapV8<K, V>
3269                  try {
3270                      if (table == null) {
3271                          init = true;
3272 <                        Node[] tab = new Node[n];
3272 >                        @SuppressWarnings("rawtypes") Node[] rt = new Node[n];
3273 >                        Node<V>[] tab = (Node<V>[])rt;
3274                          int mask = n - 1;
3275                          while (p != null) {
3276                              int j = p.hash & mask;
3277 <                            Node next = p.next;
3278 <                            Node q = p.next = tabAt(tab, j);
3277 >                            Node<V> next = p.next;
3278 >                            Node<V> q = p.next = tabAt(tab, j);
3279                              setTabAt(tab, j, p);
3280                              if (!collide && q != null && q.hash == p.hash)
3281                                  collide = true;
# Line 3278 | Line 3289 | public class ConcurrentHashMapV8<K, V>
3289                      sizeCtl = sc;
3290                  }
3291                  if (collide) { // rescan and convert to TreeBins
3292 <                    Node[] tab = table;
3292 >                    Node<V>[] tab = table;
3293                      for (int i = 0; i < tab.length; ++i) {
3294                          int c = 0;
3295 <                        for (Node e = tabAt(tab, i); e != null; e = e.next) {
3295 >                        for (Node<V> e = tabAt(tab, i); e != null; e = e.next) {
3296                              if (++c > TREE_THRESHOLD &&
3297                                  (e.key instanceof Comparable)) {
3298                                  replaceWithTreeBin(tab, i, e.key);
# Line 3293 | Line 3304 | public class ConcurrentHashMapV8<K, V>
3304              }
3305              if (!init) { // Can only happen if unsafely published.
3306                  while (p != null) {
3307 <                    internalPut((K)p.key, (V)p.val, false);
3307 >                    internalPut((K)p.key, p.val, false);
3308                      p = p.next;
3309                  }
3310              }
# Line 3341 | Line 3352 | public class ConcurrentHashMapV8<K, V>
3352  
3353      // -------------------------------------------------------
3354  
3355 +    // Sequential bulk operations
3356 +
3357 +    /**
3358 +     * Performs the given action for each (key, value).
3359 +     *
3360 +     * @param action the action
3361 +     */
3362 +    @SuppressWarnings("unchecked") public void forEachSequentially
3363 +        (BiAction<K,V> action) {
3364 +        if (action == null) throw new NullPointerException();
3365 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3366 +        V v;
3367 +        while ((v = it.advance()) != null)
3368 +            action.apply((K)it.nextKey, v);
3369 +    }
3370 +
3371 +    /**
3372 +     * Performs the given action for each non-null transformation
3373 +     * of each (key, value).
3374 +     *
3375 +     * @param transformer a function returning the transformation
3376 +     * for an element, or null of there is no transformation (in
3377 +     * which case the action is not applied).
3378 +     * @param action the action
3379 +     */
3380 +    @SuppressWarnings("unchecked") public <U> void forEachSequentially
3381 +        (BiFun<? super K, ? super V, ? extends U> transformer,
3382 +         Action<U> action) {
3383 +        if (transformer == null || action == null)
3384 +            throw new NullPointerException();
3385 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3386 +        V v; U u;
3387 +        while ((v = it.advance()) != null) {
3388 +            if ((u = transformer.apply((K)it.nextKey, v)) != null)
3389 +                action.apply(u);
3390 +        }
3391 +    }
3392 +
3393 +    /**
3394 +     * Returns a non-null result from applying the given search
3395 +     * function on each (key, value), or null if none.
3396 +     *
3397 +     * @param searchFunction a function returning a non-null
3398 +     * result on success, else null
3399 +     * @return a non-null result from applying the given search
3400 +     * function on each (key, value), or null if none
3401 +     */
3402 +    @SuppressWarnings("unchecked") public <U> U searchSequentially
3403 +        (BiFun<? super K, ? super V, ? extends U> searchFunction) {
3404 +        if (searchFunction == null) throw new NullPointerException();
3405 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3406 +        V v; U u;
3407 +        while ((v = it.advance()) != null) {
3408 +            if ((u = searchFunction.apply((K)it.nextKey, v)) != null)
3409 +                return u;
3410 +        }
3411 +        return null;
3412 +    }
3413 +
3414 +    /**
3415 +     * Returns the result of accumulating the given transformation
3416 +     * of all (key, value) pairs using the given reducer to
3417 +     * combine values, or null if none.
3418 +     *
3419 +     * @param transformer a function returning the transformation
3420 +     * for an element, or null of there is no transformation (in
3421 +     * which case it is not combined).
3422 +     * @param reducer a commutative associative combining function
3423 +     * @return the result of accumulating the given transformation
3424 +     * of all (key, value) pairs
3425 +     */
3426 +    @SuppressWarnings("unchecked") public <U> U reduceSequentially
3427 +        (BiFun<? super K, ? super V, ? extends U> transformer,
3428 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3429 +        if (transformer == null || reducer == null)
3430 +            throw new NullPointerException();
3431 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3432 +        U r = null, u; V v;
3433 +        while ((v = it.advance()) != null) {
3434 +            if ((u = transformer.apply((K)it.nextKey, v)) != null)
3435 +                r = (r == null) ? u : reducer.apply(r, u);
3436 +        }
3437 +        return r;
3438 +    }
3439 +
3440 +    /**
3441 +     * Returns the result of accumulating the given transformation
3442 +     * of all (key, value) pairs using the given reducer to
3443 +     * combine values, and the given basis as an identity value.
3444 +     *
3445 +     * @param transformer a function returning the transformation
3446 +     * for an element
3447 +     * @param basis the identity (initial default value) for the reduction
3448 +     * @param reducer a commutative associative combining function
3449 +     * @return the result of accumulating the given transformation
3450 +     * of all (key, value) pairs
3451 +     */
3452 +    @SuppressWarnings("unchecked") public double reduceToDoubleSequentially
3453 +        (ObjectByObjectToDouble<? super K, ? super V> transformer,
3454 +         double basis,
3455 +         DoubleByDoubleToDouble reducer) {
3456 +        if (transformer == null || reducer == null)
3457 +            throw new NullPointerException();
3458 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3459 +        double r = basis; V v;
3460 +        while ((v = it.advance()) != null)
3461 +            r = reducer.apply(r, transformer.apply((K)it.nextKey, v));
3462 +        return r;
3463 +    }
3464 +
3465 +    /**
3466 +     * Returns the result of accumulating the given transformation
3467 +     * of all (key, value) pairs using the given reducer to
3468 +     * combine values, and the given basis as an identity value.
3469 +     *
3470 +     * @param transformer a function returning the transformation
3471 +     * for an element
3472 +     * @param basis the identity (initial default value) for the reduction
3473 +     * @param reducer a commutative associative combining function
3474 +     * @return the result of accumulating the given transformation
3475 +     * of all (key, value) pairs
3476 +     */
3477 +    @SuppressWarnings("unchecked") public long reduceToLongSequentially
3478 +        (ObjectByObjectToLong<? super K, ? super V> transformer,
3479 +         long basis,
3480 +         LongByLongToLong reducer) {
3481 +        if (transformer == null || reducer == null)
3482 +            throw new NullPointerException();
3483 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3484 +        long r = basis; V v;
3485 +        while ((v = it.advance()) != null)
3486 +            r = reducer.apply(r, transformer.apply((K)it.nextKey, v));
3487 +        return r;
3488 +    }
3489 +
3490 +    /**
3491 +     * Returns the result of accumulating the given transformation
3492 +     * of all (key, value) pairs using the given reducer to
3493 +     * combine values, and the given basis as an identity value.
3494 +     *
3495 +     * @param transformer a function returning the transformation
3496 +     * for an element
3497 +     * @param basis the identity (initial default value) for the reduction
3498 +     * @param reducer a commutative associative combining function
3499 +     * @return the result of accumulating the given transformation
3500 +     * of all (key, value) pairs
3501 +     */
3502 +    @SuppressWarnings("unchecked") public int reduceToIntSequentially
3503 +        (ObjectByObjectToInt<? super K, ? super V> transformer,
3504 +         int basis,
3505 +         IntByIntToInt reducer) {
3506 +        if (transformer == null || reducer == null)
3507 +            throw new NullPointerException();
3508 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3509 +        int r = basis; V v;
3510 +        while ((v = it.advance()) != null)
3511 +            r = reducer.apply(r, transformer.apply((K)it.nextKey, v));
3512 +        return r;
3513 +    }
3514 +
3515 +    /**
3516 +     * Performs the given action for each key.
3517 +     *
3518 +     * @param action the action
3519 +     */
3520 +    @SuppressWarnings("unchecked") public void forEachKeySequentially
3521 +        (Action<K> action) {
3522 +        if (action == null) throw new NullPointerException();
3523 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3524 +        while (it.advance() != null)
3525 +            action.apply((K)it.nextKey);
3526 +    }
3527 +
3528 +    /**
3529 +     * Performs the given action for each non-null transformation
3530 +     * of each key.
3531 +     *
3532 +     * @param transformer a function returning the transformation
3533 +     * for an element, or null of there is no transformation (in
3534 +     * which case the action is not applied).
3535 +     * @param action the action
3536 +     */
3537 +    @SuppressWarnings("unchecked") public <U> void forEachKeySequentially
3538 +        (Fun<? super K, ? extends U> transformer,
3539 +         Action<U> action) {
3540 +        if (transformer == null || action == null)
3541 +            throw new NullPointerException();
3542 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3543 +        U u;
3544 +        while (it.advance() != null) {
3545 +            if ((u = transformer.apply((K)it.nextKey)) != null)
3546 +                action.apply(u);
3547 +        }
3548 +        ForkJoinTasks.forEachKey
3549 +            (this, transformer, action).invoke();
3550 +    }
3551 +
3552 +    /**
3553 +     * Returns a non-null result from applying the given search
3554 +     * function on each key, or null if none.
3555 +     *
3556 +     * @param searchFunction a function returning a non-null
3557 +     * result on success, else null
3558 +     * @return a non-null result from applying the given search
3559 +     * function on each key, or null if none
3560 +     */
3561 +    @SuppressWarnings("unchecked") public <U> U searchKeysSequentially
3562 +        (Fun<? super K, ? extends U> searchFunction) {
3563 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3564 +        U u;
3565 +        while (it.advance() != null) {
3566 +            if ((u = searchFunction.apply((K)it.nextKey)) != null)
3567 +                return u;
3568 +        }
3569 +        return null;
3570 +    }
3571 +
3572 +    /**
3573 +     * Returns the result of accumulating all keys using the given
3574 +     * reducer to combine values, or null if none.
3575 +     *
3576 +     * @param reducer a commutative associative combining function
3577 +     * @return the result of accumulating all keys using the given
3578 +     * reducer to combine values, or null if none
3579 +     */
3580 +    @SuppressWarnings("unchecked") public K reduceKeysSequentially
3581 +        (BiFun<? super K, ? super K, ? extends K> reducer) {
3582 +        if (reducer == null) throw new NullPointerException();
3583 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3584 +        K r = null;
3585 +        while (it.advance() != null) {
3586 +            K u = (K)it.nextKey;
3587 +            r = (r == null) ? u : reducer.apply(r, u);
3588 +        }
3589 +        return r;
3590 +    }
3591 +
3592 +    /**
3593 +     * Returns the result of accumulating the given transformation
3594 +     * of all keys using the given reducer to combine values, or
3595 +     * null if none.
3596 +     *
3597 +     * @param transformer a function returning the transformation
3598 +     * for an element, or null of there is no transformation (in
3599 +     * which case it is not combined).
3600 +     * @param reducer a commutative associative combining function
3601 +     * @return the result of accumulating the given transformation
3602 +     * of all keys
3603 +     */
3604 +    @SuppressWarnings("unchecked") public <U> U reduceKeysSequentially
3605 +        (Fun<? super K, ? extends U> transformer,
3606 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3607 +        if (transformer == null || reducer == null)
3608 +            throw new NullPointerException();
3609 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3610 +        U r = null, u;
3611 +        while (it.advance() != null) {
3612 +            if ((u = transformer.apply((K)it.nextKey)) != null)
3613 +                r = (r == null) ? u : reducer.apply(r, u);
3614 +        }
3615 +        return r;
3616 +    }
3617 +
3618 +    /**
3619 +     * Returns the result of accumulating the given transformation
3620 +     * of all keys using the given reducer to combine values, and
3621 +     * the given basis as an identity value.
3622 +     *
3623 +     * @param transformer a function returning the transformation
3624 +     * for an element
3625 +     * @param basis the identity (initial default value) for the reduction
3626 +     * @param reducer a commutative associative combining function
3627 +     * @return  the result of accumulating the given transformation
3628 +     * of all keys
3629 +     */
3630 +    @SuppressWarnings("unchecked") public double reduceKeysToDoubleSequentially
3631 +        (ObjectToDouble<? super K> transformer,
3632 +         double basis,
3633 +         DoubleByDoubleToDouble reducer) {
3634 +        if (transformer == null || reducer == null)
3635 +            throw new NullPointerException();
3636 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3637 +        double r = basis;
3638 +        while (it.advance() != null)
3639 +            r = reducer.apply(r, transformer.apply((K)it.nextKey));
3640 +        return r;
3641 +    }
3642 +
3643 +    /**
3644 +     * Returns the result of accumulating the given transformation
3645 +     * of all keys using the given reducer to combine values, and
3646 +     * the given basis as an identity value.
3647 +     *
3648 +     * @param transformer a function returning the transformation
3649 +     * for an element
3650 +     * @param basis the identity (initial default value) for the reduction
3651 +     * @param reducer a commutative associative combining function
3652 +     * @return the result of accumulating the given transformation
3653 +     * of all keys
3654 +     */
3655 +    @SuppressWarnings("unchecked") public long reduceKeysToLongSequentially
3656 +        (ObjectToLong<? super K> transformer,
3657 +         long basis,
3658 +         LongByLongToLong reducer) {
3659 +        if (transformer == null || reducer == null)
3660 +            throw new NullPointerException();
3661 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3662 +        long r = basis;
3663 +        while (it.advance() != null)
3664 +            r = reducer.apply(r, transformer.apply((K)it.nextKey));
3665 +        return r;
3666 +    }
3667 +
3668 +    /**
3669 +     * Returns the result of accumulating the given transformation
3670 +     * of all keys using the given reducer to combine values, and
3671 +     * the given basis as an identity value.
3672 +     *
3673 +     * @param transformer a function returning the transformation
3674 +     * for an element
3675 +     * @param basis the identity (initial default value) for the reduction
3676 +     * @param reducer a commutative associative combining function
3677 +     * @return the result of accumulating the given transformation
3678 +     * of all keys
3679 +     */
3680 +    @SuppressWarnings("unchecked") public int reduceKeysToIntSequentially
3681 +        (ObjectToInt<? super K> transformer,
3682 +         int basis,
3683 +         IntByIntToInt reducer) {
3684 +        if (transformer == null || reducer == null)
3685 +            throw new NullPointerException();
3686 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3687 +        int r = basis;
3688 +        while (it.advance() != null)
3689 +            r = reducer.apply(r, transformer.apply((K)it.nextKey));
3690 +        return r;
3691 +    }
3692 +
3693 +    /**
3694 +     * Performs the given action for each value.
3695 +     *
3696 +     * @param action the action
3697 +     */
3698 +    public void forEachValueSequentially(Action<V> action) {
3699 +        if (action == null) throw new NullPointerException();
3700 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3701 +        V v;
3702 +        while ((v = it.advance()) != null)
3703 +            action.apply(v);
3704 +    }
3705 +
3706 +    /**
3707 +     * Performs the given action for each non-null transformation
3708 +     * of each value.
3709 +     *
3710 +     * @param transformer a function returning the transformation
3711 +     * for an element, or null of there is no transformation (in
3712 +     * which case the action is not applied).
3713 +     */
3714 +    public <U> void forEachValueSequentially
3715 +        (Fun<? super V, ? extends U> transformer,
3716 +         Action<U> action) {
3717 +        if (transformer == null || action == null)
3718 +            throw new NullPointerException();
3719 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3720 +        V v; U u;
3721 +        while ((v = it.advance()) != null) {
3722 +            if ((u = transformer.apply(v)) != null)
3723 +                action.apply(u);
3724 +        }
3725 +    }
3726 +
3727 +    /**
3728 +     * Returns a non-null result from applying the given search
3729 +     * function on each value, or null if none.
3730 +     *
3731 +     * @param searchFunction a function returning a non-null
3732 +     * result on success, else null
3733 +     * @return a non-null result from applying the given search
3734 +     * function on each value, or null if none
3735 +     */
3736 +    public <U> U searchValuesSequentially
3737 +        (Fun<? super V, ? extends U> searchFunction) {
3738 +        if (searchFunction == null) throw new NullPointerException();
3739 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3740 +        V v; U u;
3741 +        while ((v = it.advance()) != null) {
3742 +            if ((u = searchFunction.apply(v)) != null)
3743 +                return u;
3744 +        }
3745 +        return null;
3746 +    }
3747 +
3748 +    /**
3749 +     * Returns the result of accumulating all values using the
3750 +     * given reducer to combine values, or null if none.
3751 +     *
3752 +     * @param reducer a commutative associative combining function
3753 +     * @return  the result of accumulating all values
3754 +     */
3755 +    public V reduceValuesSequentially
3756 +        (BiFun<? super V, ? super V, ? extends V> reducer) {
3757 +        if (reducer == null) throw new NullPointerException();
3758 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3759 +        V r = null; V v;
3760 +        while ((v = it.advance()) != null)
3761 +            r = (r == null) ? v : reducer.apply(r, v);
3762 +        return r;
3763 +    }
3764 +
3765 +    /**
3766 +     * Returns the result of accumulating the given transformation
3767 +     * of all values using the given reducer to combine values, or
3768 +     * null if none.
3769 +     *
3770 +     * @param transformer a function returning the transformation
3771 +     * for an element, or null of there is no transformation (in
3772 +     * which case it is not combined).
3773 +     * @param reducer a commutative associative combining function
3774 +     * @return the result of accumulating the given transformation
3775 +     * of all values
3776 +     */
3777 +    public <U> U reduceValuesSequentially
3778 +        (Fun<? super V, ? extends U> transformer,
3779 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3780 +        if (transformer == null || reducer == null)
3781 +            throw new NullPointerException();
3782 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3783 +        U r = null, u; V v;
3784 +        while ((v = it.advance()) != null) {
3785 +            if ((u = transformer.apply(v)) != null)
3786 +                r = (r == null) ? u : reducer.apply(r, u);
3787 +        }
3788 +        return r;
3789 +    }
3790 +
3791 +    /**
3792 +     * Returns the result of accumulating the given transformation
3793 +     * of all values using the given reducer to combine values,
3794 +     * and the given basis as an identity value.
3795 +     *
3796 +     * @param transformer a function returning the transformation
3797 +     * for an element
3798 +     * @param basis the identity (initial default value) for the reduction
3799 +     * @param reducer a commutative associative combining function
3800 +     * @return the result of accumulating the given transformation
3801 +     * of all values
3802 +     */
3803 +    public double reduceValuesToDoubleSequentially
3804 +        (ObjectToDouble<? super V> transformer,
3805 +         double basis,
3806 +         DoubleByDoubleToDouble reducer) {
3807 +        if (transformer == null || reducer == null)
3808 +            throw new NullPointerException();
3809 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3810 +        double r = basis; V v;
3811 +        while ((v = it.advance()) != null)
3812 +            r = reducer.apply(r, transformer.apply(v));
3813 +        return r;
3814 +    }
3815 +
3816 +    /**
3817 +     * Returns the result of accumulating the given transformation
3818 +     * of all values using the given reducer to combine values,
3819 +     * and the given basis as an identity value.
3820 +     *
3821 +     * @param transformer a function returning the transformation
3822 +     * for an element
3823 +     * @param basis the identity (initial default value) for the reduction
3824 +     * @param reducer a commutative associative combining function
3825 +     * @return the result of accumulating the given transformation
3826 +     * of all values
3827 +     */
3828 +    public long reduceValuesToLongSequentially
3829 +        (ObjectToLong<? super V> transformer,
3830 +         long basis,
3831 +         LongByLongToLong reducer) {
3832 +        if (transformer == null || reducer == null)
3833 +            throw new NullPointerException();
3834 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3835 +        long r = basis; V v;
3836 +        while ((v = it.advance()) != null)
3837 +            r = reducer.apply(r, transformer.apply(v));
3838 +        return r;
3839 +    }
3840 +
3841 +    /**
3842 +     * Returns the result of accumulating the given transformation
3843 +     * of all values using the given reducer to combine values,
3844 +     * and the given basis as an identity value.
3845 +     *
3846 +     * @param transformer a function returning the transformation
3847 +     * for an element
3848 +     * @param basis the identity (initial default value) for the reduction
3849 +     * @param reducer a commutative associative combining function
3850 +     * @return the result of accumulating the given transformation
3851 +     * of all values
3852 +     */
3853 +    public int reduceValuesToIntSequentially
3854 +        (ObjectToInt<? super V> transformer,
3855 +         int basis,
3856 +         IntByIntToInt reducer) {
3857 +        if (transformer == null || reducer == null)
3858 +            throw new NullPointerException();
3859 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3860 +        int r = basis; V v;
3861 +        while ((v = it.advance()) != null)
3862 +            r = reducer.apply(r, transformer.apply(v));
3863 +        return r;
3864 +    }
3865 +
3866 +    /**
3867 +     * Performs the given action for each entry.
3868 +     *
3869 +     * @param action the action
3870 +     */
3871 +    @SuppressWarnings("unchecked") public void forEachEntrySequentially
3872 +        (Action<Map.Entry<K,V>> action) {
3873 +        if (action == null) throw new NullPointerException();
3874 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3875 +        V v;
3876 +        while ((v = it.advance()) != null)
3877 +            action.apply(entryFor((K)it.nextKey, v));
3878 +    }
3879 +
3880 +    /**
3881 +     * Performs the given action for each non-null transformation
3882 +     * of each entry.
3883 +     *
3884 +     * @param transformer a function returning the transformation
3885 +     * for an element, or null of there is no transformation (in
3886 +     * which case the action is not applied).
3887 +     * @param action the action
3888 +     */
3889 +    @SuppressWarnings("unchecked") public <U> void forEachEntrySequentially
3890 +        (Fun<Map.Entry<K,V>, ? extends U> transformer,
3891 +         Action<U> action) {
3892 +        if (transformer == null || action == null)
3893 +            throw new NullPointerException();
3894 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3895 +        V v; U u;
3896 +        while ((v = it.advance()) != null) {
3897 +            if ((u = transformer.apply(entryFor((K)it.nextKey, v))) != null)
3898 +                action.apply(u);
3899 +        }
3900 +    }
3901 +
3902 +    /**
3903 +     * Returns a non-null result from applying the given search
3904 +     * function on each entry, or null if none.
3905 +     *
3906 +     * @param searchFunction a function returning a non-null
3907 +     * result on success, else null
3908 +     * @return a non-null result from applying the given search
3909 +     * function on each entry, or null if none
3910 +     */
3911 +    @SuppressWarnings("unchecked") public <U> U searchEntriesSequentially
3912 +        (Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
3913 +        if (searchFunction == null) throw new NullPointerException();
3914 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3915 +        V v; U u;
3916 +        while ((v = it.advance()) != null) {
3917 +            if ((u = searchFunction.apply(entryFor((K)it.nextKey, v))) != null)
3918 +                return u;
3919 +        }
3920 +        return null;
3921 +    }
3922 +
3923 +    /**
3924 +     * Returns the result of accumulating all entries using the
3925 +     * given reducer to combine values, or null if none.
3926 +     *
3927 +     * @param reducer a commutative associative combining function
3928 +     * @return the result of accumulating all entries
3929 +     */
3930 +    @SuppressWarnings("unchecked") public Map.Entry<K,V> reduceEntriesSequentially
3931 +        (BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
3932 +        if (reducer == null) throw new NullPointerException();
3933 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3934 +        Map.Entry<K,V> r = null; V v;
3935 +        while ((v = it.advance()) != null) {
3936 +            Map.Entry<K,V> u = entryFor((K)it.nextKey, v);
3937 +            r = (r == null) ? u : reducer.apply(r, u);
3938 +        }
3939 +        return r;
3940 +    }
3941 +
3942 +    /**
3943 +     * Returns the result of accumulating the given transformation
3944 +     * of all entries using the given reducer to combine values,
3945 +     * or null if none.
3946 +     *
3947 +     * @param transformer a function returning the transformation
3948 +     * for an element, or null of there is no transformation (in
3949 +     * which case it is not combined).
3950 +     * @param reducer a commutative associative combining function
3951 +     * @return the result of accumulating the given transformation
3952 +     * of all entries
3953 +     */
3954 +    @SuppressWarnings("unchecked") public <U> U reduceEntriesSequentially
3955 +        (Fun<Map.Entry<K,V>, ? extends U> transformer,
3956 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3957 +        if (transformer == null || reducer == null)
3958 +            throw new NullPointerException();
3959 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3960 +        U r = null, u; V v;
3961 +        while ((v = it.advance()) != null) {
3962 +            if ((u = transformer.apply(entryFor((K)it.nextKey, v))) != null)
3963 +                r = (r == null) ? u : reducer.apply(r, u);
3964 +        }
3965 +        return r;
3966 +    }
3967 +
3968 +    /**
3969 +     * Returns the result of accumulating the given transformation
3970 +     * of all entries using the given reducer to combine values,
3971 +     * and the given basis as an identity value.
3972 +     *
3973 +     * @param transformer a function returning the transformation
3974 +     * for an element
3975 +     * @param basis the identity (initial default value) for the reduction
3976 +     * @param reducer a commutative associative combining function
3977 +     * @return the result of accumulating the given transformation
3978 +     * of all entries
3979 +     */
3980 +    @SuppressWarnings("unchecked") public double reduceEntriesToDoubleSequentially
3981 +        (ObjectToDouble<Map.Entry<K,V>> transformer,
3982 +         double basis,
3983 +         DoubleByDoubleToDouble reducer) {
3984 +        if (transformer == null || reducer == null)
3985 +            throw new NullPointerException();
3986 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3987 +        double r = basis; V v;
3988 +        while ((v = it.advance()) != null)
3989 +            r = reducer.apply(r, transformer.apply(entryFor((K)it.nextKey, v)));
3990 +        return r;
3991 +    }
3992 +
3993 +    /**
3994 +     * Returns the result of accumulating the given transformation
3995 +     * of all entries using the given reducer to combine values,
3996 +     * and the given basis as an identity value.
3997 +     *
3998 +     * @param transformer a function returning the transformation
3999 +     * for an element
4000 +     * @param basis the identity (initial default value) for the reduction
4001 +     * @param reducer a commutative associative combining function
4002 +     * @return  the result of accumulating the given transformation
4003 +     * of all entries
4004 +     */
4005 +    @SuppressWarnings("unchecked") public long reduceEntriesToLongSequentially
4006 +        (ObjectToLong<Map.Entry<K,V>> transformer,
4007 +         long basis,
4008 +         LongByLongToLong reducer) {
4009 +        if (transformer == null || reducer == null)
4010 +            throw new NullPointerException();
4011 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
4012 +        long r = basis; V v;
4013 +        while ((v = it.advance()) != null)
4014 +            r = reducer.apply(r, transformer.apply(entryFor((K)it.nextKey, v)));
4015 +        return r;
4016 +    }
4017 +
4018 +    /**
4019 +     * Returns the result of accumulating the given transformation
4020 +     * of all entries using the given reducer to combine values,
4021 +     * and the given basis as an identity value.
4022 +     *
4023 +     * @param transformer a function returning the transformation
4024 +     * for an element
4025 +     * @param basis the identity (initial default value) for the reduction
4026 +     * @param reducer a commutative associative combining function
4027 +     * @return the result of accumulating the given transformation
4028 +     * of all entries
4029 +     */
4030 +    @SuppressWarnings("unchecked") public int reduceEntriesToIntSequentially
4031 +        (ObjectToInt<Map.Entry<K,V>> transformer,
4032 +         int basis,
4033 +         IntByIntToInt reducer) {
4034 +        if (transformer == null || reducer == null)
4035 +            throw new NullPointerException();
4036 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
4037 +        int r = basis; V v;
4038 +        while ((v = it.advance()) != null)
4039 +            r = reducer.apply(r, transformer.apply(entryFor((K)it.nextKey, v)));
4040 +        return r;
4041 +    }
4042 +
4043 +    // Parallel bulk operations
4044 +
4045      /**
4046       * Performs the given action for each (key, value).
4047       *
4048       * @param action the action
4049       */
4050 <    public void forEach(BiAction<K,V> action) {
4050 >    public void forEachInParallel(BiAction<K,V> action) {
4051          ForkJoinTasks.forEach
4052              (this, action).invoke();
4053      }
# Line 3360 | Line 4061 | public class ConcurrentHashMapV8<K, V>
4061       * which case the action is not applied).
4062       * @param action the action
4063       */
4064 <    public <U> void forEach(BiFun<? super K, ? super V, ? extends U> transformer,
4064 >    public <U> void forEachInParallel
4065 >        (BiFun<? super K, ? super V, ? extends U> transformer,
4066                              Action<U> action) {
4067          ForkJoinTasks.forEach
4068              (this, transformer, action).invoke();
# Line 3378 | Line 4080 | public class ConcurrentHashMapV8<K, V>
4080       * @return a non-null result from applying the given search
4081       * function on each (key, value), or null if none
4082       */
4083 <    public <U> U search(BiFun<? super K, ? super V, ? extends U> searchFunction) {
4083 >    public <U> U searchInParallel
4084 >        (BiFun<? super K, ? super V, ? extends U> searchFunction) {
4085          return ForkJoinTasks.search
4086              (this, searchFunction).invoke();
4087      }
# Line 3395 | Line 4098 | public class ConcurrentHashMapV8<K, V>
4098       * @return the result of accumulating the given transformation
4099       * of all (key, value) pairs
4100       */
4101 <    public <U> U reduce(BiFun<? super K, ? super V, ? extends U> transformer,
4102 <                        BiFun<? super U, ? super U, ? extends U> reducer) {
4101 >    public <U> U reduceInParallel
4102 >        (BiFun<? super K, ? super V, ? extends U> transformer,
4103 >         BiFun<? super U, ? super U, ? extends U> reducer) {
4104          return ForkJoinTasks.reduce
4105              (this, transformer, reducer).invoke();
4106      }
# Line 3413 | Line 4117 | public class ConcurrentHashMapV8<K, V>
4117       * @return the result of accumulating the given transformation
4118       * of all (key, value) pairs
4119       */
4120 <    public double reduceToDouble(ObjectByObjectToDouble<? super K, ? super V> transformer,
4121 <                                 double basis,
4122 <                                 DoubleByDoubleToDouble reducer) {
4120 >    public double reduceToDoubleInParallel
4121 >        (ObjectByObjectToDouble<? super K, ? super V> transformer,
4122 >         double basis,
4123 >         DoubleByDoubleToDouble reducer) {
4124          return ForkJoinTasks.reduceToDouble
4125              (this, transformer, basis, reducer).invoke();
4126      }
# Line 3432 | Line 4137 | public class ConcurrentHashMapV8<K, V>
4137       * @return the result of accumulating the given transformation
4138       * of all (key, value) pairs
4139       */
4140 <    public long reduceToLong(ObjectByObjectToLong<? super K, ? super V> transformer,
4141 <                             long basis,
4142 <                             LongByLongToLong reducer) {
4140 >    public long reduceToLongInParallel
4141 >        (ObjectByObjectToLong<? super K, ? super V> transformer,
4142 >         long basis,
4143 >         LongByLongToLong reducer) {
4144          return ForkJoinTasks.reduceToLong
4145              (this, transformer, basis, reducer).invoke();
4146      }
# Line 3451 | Line 4157 | public class ConcurrentHashMapV8<K, V>
4157       * @return the result of accumulating the given transformation
4158       * of all (key, value) pairs
4159       */
4160 <    public int reduceToInt(ObjectByObjectToInt<? super K, ? super V> transformer,
4161 <                           int basis,
4162 <                           IntByIntToInt reducer) {
4160 >    public int reduceToIntInParallel
4161 >        (ObjectByObjectToInt<? super K, ? super V> transformer,
4162 >         int basis,
4163 >         IntByIntToInt reducer) {
4164          return ForkJoinTasks.reduceToInt
4165              (this, transformer, basis, reducer).invoke();
4166      }
# Line 3463 | Line 4170 | public class ConcurrentHashMapV8<K, V>
4170       *
4171       * @param action the action
4172       */
4173 <    public void forEachKey(Action<K> action) {
4173 >    public void forEachKeyInParallel(Action<K> action) {
4174          ForkJoinTasks.forEachKey
4175              (this, action).invoke();
4176      }
# Line 3477 | Line 4184 | public class ConcurrentHashMapV8<K, V>
4184       * which case the action is not applied).
4185       * @param action the action
4186       */
4187 <    public <U> void forEachKey(Fun<? super K, ? extends U> transformer,
4188 <                               Action<U> action) {
4187 >    public <U> void forEachKeyInParallel
4188 >        (Fun<? super K, ? extends U> transformer,
4189 >         Action<U> action) {
4190          ForkJoinTasks.forEachKey
4191              (this, transformer, action).invoke();
4192      }
# Line 3495 | Line 4203 | public class ConcurrentHashMapV8<K, V>
4203       * @return a non-null result from applying the given search
4204       * function on each key, or null if none
4205       */
4206 <    public <U> U searchKeys(Fun<? super K, ? extends U> searchFunction) {
4206 >    public <U> U searchKeysInParallel
4207 >        (Fun<? super K, ? extends U> searchFunction) {
4208          return ForkJoinTasks.searchKeys
4209              (this, searchFunction).invoke();
4210      }
# Line 3508 | Line 4217 | public class ConcurrentHashMapV8<K, V>
4217       * @return the result of accumulating all keys using the given
4218       * reducer to combine values, or null if none
4219       */
4220 <    public K reduceKeys(BiFun<? super K, ? super K, ? extends K> reducer) {
4220 >    public K reduceKeysInParallel
4221 >        (BiFun<? super K, ? super K, ? extends K> reducer) {
4222          return ForkJoinTasks.reduceKeys
4223              (this, reducer).invoke();
4224      }
# Line 3525 | Line 4235 | public class ConcurrentHashMapV8<K, V>
4235       * @return the result of accumulating the given transformation
4236       * of all keys
4237       */
4238 <    public <U> U reduceKeys(Fun<? super K, ? extends U> transformer,
4239 <                            BiFun<? super U, ? super U, ? extends U> reducer) {
4238 >    public <U> U reduceKeysInParallel
4239 >        (Fun<? super K, ? extends U> transformer,
4240 >         BiFun<? super U, ? super U, ? extends U> reducer) {
4241          return ForkJoinTasks.reduceKeys
4242              (this, transformer, reducer).invoke();
4243      }
# Line 3543 | Line 4254 | public class ConcurrentHashMapV8<K, V>
4254       * @return  the result of accumulating the given transformation
4255       * of all keys
4256       */
4257 <    public double reduceKeysToDouble(ObjectToDouble<? super K> transformer,
4258 <                                     double basis,
4259 <                                     DoubleByDoubleToDouble reducer) {
4257 >    public double reduceKeysToDoubleInParallel
4258 >        (ObjectToDouble<? super K> transformer,
4259 >         double basis,
4260 >         DoubleByDoubleToDouble reducer) {
4261          return ForkJoinTasks.reduceKeysToDouble
4262              (this, transformer, basis, reducer).invoke();
4263      }
# Line 3562 | Line 4274 | public class ConcurrentHashMapV8<K, V>
4274       * @return the result of accumulating the given transformation
4275       * of all keys
4276       */
4277 <    public long reduceKeysToLong(ObjectToLong<? super K> transformer,
4278 <                                 long basis,
4279 <                                 LongByLongToLong reducer) {
4277 >    public long reduceKeysToLongInParallel
4278 >        (ObjectToLong<? super K> transformer,
4279 >         long basis,
4280 >         LongByLongToLong reducer) {
4281          return ForkJoinTasks.reduceKeysToLong
4282              (this, transformer, basis, reducer).invoke();
4283      }
# Line 3581 | Line 4294 | public class ConcurrentHashMapV8<K, V>
4294       * @return the result of accumulating the given transformation
4295       * of all keys
4296       */
4297 <    public int reduceKeysToInt(ObjectToInt<? super K> transformer,
4298 <                               int basis,
4299 <                               IntByIntToInt reducer) {
4297 >    public int reduceKeysToIntInParallel
4298 >        (ObjectToInt<? super K> transformer,
4299 >         int basis,
4300 >         IntByIntToInt reducer) {
4301          return ForkJoinTasks.reduceKeysToInt
4302              (this, transformer, basis, reducer).invoke();
4303      }
# Line 3593 | Line 4307 | public class ConcurrentHashMapV8<K, V>
4307       *
4308       * @param action the action
4309       */
4310 <    public void forEachValue(Action<V> action) {
4310 >    public void forEachValueInParallel(Action<V> action) {
4311          ForkJoinTasks.forEachValue
4312              (this, action).invoke();
4313      }
# Line 3606 | Line 4320 | public class ConcurrentHashMapV8<K, V>
4320       * for an element, or null of there is no transformation (in
4321       * which case the action is not applied).
4322       */
4323 <    public <U> void forEachValue(Fun<? super V, ? extends U> transformer,
4324 <                                 Action<U> action) {
4323 >    public <U> void forEachValueInParallel
4324 >        (Fun<? super V, ? extends U> transformer,
4325 >         Action<U> action) {
4326          ForkJoinTasks.forEachValue
4327              (this, transformer, action).invoke();
4328      }
# Line 3623 | Line 4338 | public class ConcurrentHashMapV8<K, V>
4338       * result on success, else null
4339       * @return a non-null result from applying the given search
4340       * function on each value, or null if none
3626     *
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      /**
4580       * Base class for views.
4581       */
4582 <    static abstract class CHMView<K, V> {
4582 >    abstract static class CHMView<K, V> {
4583          final ConcurrentHashMapV8<K, V> map;
4584          CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
4585  
# Line 3867 | Line 4595 | public class ConcurrentHashMapV8<K, V>
4595          public final void clear()               { map.clear(); }
4596  
4597          // implementations below rely on concrete classes supplying these
4598 <        abstract public Iterator<?> iterator();
4599 <        abstract public boolean contains(Object o);
4600 <        abstract public boolean remove(Object o);
4598 >        public abstract Iterator<?> iterator();
4599 >        public abstract boolean contains(Object o);
4600 >        public abstract boolean remove(Object o);
4601  
4602          private static final String oomeMsg = "Required array size too large";
4603  
# 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()) {
# Line 6450 | Line 6806 | public class ConcurrentHashMapV8<K, V>
6806      private static final int ASHIFT;
6807  
6808      static {
6453        int ss;
6809          try {
6810              U = getUnsafe();
6811              Class<?> k = ConcurrentHashMapV8.class;
# Line 6469 | Line 6824 | public class ConcurrentHashMapV8<K, V>
6824                  (ck.getDeclaredField("value"));
6825              Class<?> sc = Node[].class;
6826              ABASE = U.arrayBaseOffset(sc);
6827 <            ss = U.arrayIndexScale(sc);
6828 <            ASHIFT = 31 - Integer.numberOfLeadingZeros(ss);
6827 >            int scale = U.arrayIndexScale(sc);
6828 >            if ((scale & (scale - 1)) != 0)
6829 >                throw new Error("data type scale not a power of two");
6830 >            ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
6831          } catch (Exception e) {
6832              throw new Error(e);
6833          }
6477        if ((ss & (ss-1)) != 0)
6478            throw new Error("data type scale not a power of two");
6834      }
6835  
6836      /**
# Line 6488 | Line 6843 | public class ConcurrentHashMapV8<K, V>
6843      private static sun.misc.Unsafe getUnsafe() {
6844          try {
6845              return sun.misc.Unsafe.getUnsafe();
6846 <        } catch (SecurityException se) {
6847 <            try {
6848 <                return java.security.AccessController.doPrivileged
6849 <                    (new java.security
6850 <                     .PrivilegedExceptionAction<sun.misc.Unsafe>() {
6851 <                        public sun.misc.Unsafe run() throws Exception {
6852 <                            java.lang.reflect.Field f = sun.misc
6853 <                                .Unsafe.class.getDeclaredField("theUnsafe");
6854 <                            f.setAccessible(true);
6855 <                            return (sun.misc.Unsafe) f.get(null);
6856 <                        }});
6857 <            } catch (java.security.PrivilegedActionException e) {
6858 <                throw new RuntimeException("Could not initialize intrinsics",
6859 <                                           e.getCause());
6860 <            }
6846 >        } catch (SecurityException tryReflectionInstead) {}
6847 >        try {
6848 >            return java.security.AccessController.doPrivileged
6849 >            (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
6850 >                public sun.misc.Unsafe run() throws Exception {
6851 >                    Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
6852 >                    for (java.lang.reflect.Field f : k.getDeclaredFields()) {
6853 >                        f.setAccessible(true);
6854 >                        Object x = f.get(null);
6855 >                        if (k.isInstance(x))
6856 >                            return k.cast(x);
6857 >                    }
6858 >                    throw new NoSuchFieldError("the Unsafe");
6859 >                }});
6860 >        } catch (java.security.PrivilegedActionException e) {
6861 >            throw new RuntimeException("Could not initialize intrinsics",
6862 >                                       e.getCause());
6863          }
6864      }
6865   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines