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.101 by jsr166, Tue Jun 18 17:57:21 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 212 | Line 212 | import java.io.Serializable;
212   * @param <K> the type of keys maintained by this map
213   * @param <V> the type of mapped values
214   */
215 < public class ConcurrentHashMapV8<K, V>
216 <    implements ConcurrentMap<K, V>, Serializable {
215 > public class ConcurrentHashMapV8<K,V>
216 >    implements ConcurrentMap<K,V>, Serializable {
217      private static final long serialVersionUID = 7249069246763182397L;
218  
219      /**
# 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 1969 | Line 1977 | public class ConcurrentHashMapV8<K, V>
1977          }
1978      }
1979  
1980 <    /*
1980 >    /**
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 2269 | Line 2279 | public class ConcurrentHashMapV8<K, V>
2279       */
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
2282 >        final ConcurrentHashMapV8<K,V> map;
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 2281 | Line 2291 | public class ConcurrentHashMapV8<K, V>
2291          int batch;           // split control
2292  
2293          /** Creates iterator for all entries in the table. */
2294 <        Traverser(ConcurrentHashMapV8<K, V> map) {
2294 >        Traverser(ConcurrentHashMapV8<K,V> map) {
2295              this.map = map;
2296          }
2297  
# 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
2326 >                    ConcurrentHashMapV8<K,V> m;
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 2563 | Line 2573 | public class ConcurrentHashMapV8<K, V>
2573      /**
2574       * Tests if the specified object is a key in this table.
2575       *
2576 <     * @param  key   possible key
2576 >     * @param  key possible key
2577       * @return {@code true} if and only if the specified object
2578       *         is a key in this table, as determined by the
2579       *         {@code equals} method; {@code false} otherwise
# 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 2677 | Line 2687 | public class ConcurrentHashMapV8<K, V>
2687       * memoized result, as in:
2688       *
2689       *  <pre> {@code
2690 <     * map.computeIfAbsent(key, new Fun<K, V>() {
2690 >     * map.computeIfAbsent(key, new Fun<K,V>() {
2691       *   public V map(K k) { return new Value(f(k)); }});}</pre>
2692       *
2693       * @param key key with which the specified value is to be associated
# Line 2884 | Line 2894 | public class ConcurrentHashMapV8<K, V>
2894       * course only appropriate if it is acceptable to use the same
2895       * value for all additions from this view.
2896       *
2897 <     * @param mappedValue the mapped value to use for any
2888 <     * additions.
2897 >     * @param mappedValue the mapped value to use for any additions
2898       * @return the set view
2899       * @throws NullPointerException if the mappedValue is null
2900       */
# Line 2983 | Line 2992 | public class ConcurrentHashMapV8<K, V>
2992      public int hashCode() {
2993          int h = 0;
2994          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
2995 <        Object v;
2995 >        V v;
2996          while ((v = it.advance()) != null) {
2997              h += it.nextKey.hashCode() ^ v.hashCode();
2998          }
# Line 3005 | Line 3014 | public class ConcurrentHashMapV8<K, V>
3014          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3015          StringBuilder sb = new StringBuilder();
3016          sb.append('{');
3017 <        Object v;
3017 >        V v;
3018          if ((v = it.advance()) != null) {
3019              for (;;) {
3020                  Object k = it.nextKey;
# Line 3036 | Line 3045 | public class ConcurrentHashMapV8<K, V>
3045                  return false;
3046              Map<?,?> m = (Map<?,?>) o;
3047              Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3048 <            Object val;
3048 >            V val;
3049              while ((val = it.advance()) != null) {
3050                  Object v = m.get(it.nextKey);
3051                  if (v == null || (v != val && !v.equals(val)))
# Line 3059 | Line 3068 | public class ConcurrentHashMapV8<K, V>
3068      @SuppressWarnings("serial") static final class KeyIterator<K,V>
3069          extends Traverser<K,V,Object>
3070          implements Spliterator<K>, Enumeration<K> {
3071 <        KeyIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3072 <        KeyIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3071 >        KeyIterator(ConcurrentHashMapV8<K,V> map) { super(map); }
3072 >        KeyIterator(ConcurrentHashMapV8<K,V> map, Traverser<K,V,Object> it) {
3073              super(map, it, -1);
3074          }
3075          public KeyIterator<K,V> split() {
# Line 3082 | Line 3091 | public class ConcurrentHashMapV8<K, V>
3091      @SuppressWarnings("serial") static final class ValueIterator<K,V>
3092          extends Traverser<K,V,Object>
3093          implements Spliterator<V>, Enumeration<V> {
3094 <        ValueIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3095 <        ValueIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3094 >        ValueIterator(ConcurrentHashMapV8<K,V> map) { super(map); }
3095 >        ValueIterator(ConcurrentHashMapV8<K,V> map, Traverser<K,V,Object> it) {
3096              super(map, it, -1);
3097          }
3098          public ValueIterator<K,V> split() {
# Line 3092 | Line 3101 | public class ConcurrentHashMapV8<K, V>
3101              return new ValueIterator<K,V>(map, this);
3102          }
3103  
3104 <        @SuppressWarnings("unchecked") public final V next() {
3105 <            Object v;
3104 >        public final V next() {
3105 >            V v;
3106              if ((v = nextVal) == null && (v = advance()) == null)
3107                  throw new NoSuchElementException();
3108              nextVal = null;
3109 <            return (V) v;
3109 >            return v;
3110          }
3111  
3112          public final V nextElement() { return next(); }
# Line 3106 | Line 3115 | public class ConcurrentHashMapV8<K, V>
3115      @SuppressWarnings("serial") static final class EntryIterator<K,V>
3116          extends Traverser<K,V,Object>
3117          implements Spliterator<Map.Entry<K,V>> {
3118 <        EntryIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
3119 <        EntryIterator(ConcurrentHashMapV8<K, V> map, Traverser<K,V,Object> it) {
3118 >        EntryIterator(ConcurrentHashMapV8<K,V> map) { super(map); }
3119 >        EntryIterator(ConcurrentHashMapV8<K,V> map, Traverser<K,V,Object> it) {
3120              super(map, it, -1);
3121          }
3122          public EntryIterator<K,V> split() {
# Line 3117 | Line 3126 | public class ConcurrentHashMapV8<K, V>
3126          }
3127  
3128          @SuppressWarnings("unchecked") public final Map.Entry<K,V> next() {
3129 <            Object v;
3129 >            V v;
3130              if ((v = nextVal) == null && (v = advance()) == null)
3131                  throw new NoSuchElementException();
3132              Object k = nextKey;
3133              nextVal = null;
3134 <            return new MapEntry<K,V>((K)k, (V)v, map);
3134 >            return new MapEntry<K,V>((K)k, v, map);
3135          }
3136      }
3137  
3138      /**
3139       * Exported Entry for iterators
3140       */
3141 <    static final class MapEntry<K,V> implements Map.Entry<K, V> {
3141 >    static final class MapEntry<K,V> implements Map.Entry<K,V> {
3142          final K key; // non-null
3143          V val;       // non-null
3144 <        final ConcurrentHashMapV8<K, V> map;
3145 <        MapEntry(K key, V val, ConcurrentHashMapV8<K, V> map) {
3144 >        final ConcurrentHashMapV8<K,V> map;
3145 >        MapEntry(K key, V val, ConcurrentHashMapV8<K,V> map) {
3146              this.key = key;
3147              this.val = val;
3148              this.map = map;
# Line 3209 | Line 3218 | public class ConcurrentHashMapV8<K, V>
3218          }
3219          s.defaultWriteObject();
3220          Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3221 <        Object v;
3221 >        V v;
3222          while ((v = it.advance()) != null) {
3223              s.writeObject(it.nextKey);
3224              s.writeObject(v);
# Line 3231 | Line 3240 | public class ConcurrentHashMapV8<K, V>
3240  
3241          // Create all nodes, then place in table once size is known
3242          long size = 0L;
3243 <        Node p = null;
3243 >        Node<V> p = null;
3244          for (;;) {
3245              K k = (K) s.readObject();
3246              V v = (V) s.readObject();
3247              if (k != null && v != null) {
3248                  int h = spread(k.hashCode());
3249 <                p = new Node(h, k, v, p);
3249 >                p = new Node<V>(h, k, v, p);
3250                  ++size;
3251              }
3252              else
# Line 3259 | Line 3268 | public class ConcurrentHashMapV8<K, V>
3268                  try {
3269                      if (table == null) {
3270                          init = true;
3271 <                        Node[] tab = new Node[n];
3271 >                        @SuppressWarnings("rawtypes") Node[] rt = new Node[n];
3272 >                        Node<V>[] tab = (Node<V>[])rt;
3273                          int mask = n - 1;
3274                          while (p != null) {
3275                              int j = p.hash & mask;
3276 <                            Node next = p.next;
3277 <                            Node q = p.next = tabAt(tab, j);
3276 >                            Node<V> next = p.next;
3277 >                            Node<V> q = p.next = tabAt(tab, j);
3278                              setTabAt(tab, j, p);
3279                              if (!collide && q != null && q.hash == p.hash)
3280                                  collide = true;
# Line 3278 | Line 3288 | public class ConcurrentHashMapV8<K, V>
3288                      sizeCtl = sc;
3289                  }
3290                  if (collide) { // rescan and convert to TreeBins
3291 <                    Node[] tab = table;
3291 >                    Node<V>[] tab = table;
3292                      for (int i = 0; i < tab.length; ++i) {
3293                          int c = 0;
3294 <                        for (Node e = tabAt(tab, i); e != null; e = e.next) {
3294 >                        for (Node<V> e = tabAt(tab, i); e != null; e = e.next) {
3295                              if (++c > TREE_THRESHOLD &&
3296                                  (e.key instanceof Comparable)) {
3297                                  replaceWithTreeBin(tab, i, e.key);
# Line 3293 | Line 3303 | public class ConcurrentHashMapV8<K, V>
3303              }
3304              if (!init) { // Can only happen if unsafely published.
3305                  while (p != null) {
3306 <                    internalPut((K)p.key, (V)p.val, false);
3306 >                    internalPut((K)p.key, p.val, false);
3307                      p = p.next;
3308                  }
3309              }
# Line 3341 | Line 3351 | public class ConcurrentHashMapV8<K, V>
3351  
3352      // -------------------------------------------------------
3353  
3354 +    // Sequential bulk operations
3355 +
3356 +    /**
3357 +     * Performs the given action for each (key, value).
3358 +     *
3359 +     * @param action the action
3360 +     */
3361 +    @SuppressWarnings("unchecked") public void forEachSequentially
3362 +        (BiAction<K,V> action) {
3363 +        if (action == null) throw new NullPointerException();
3364 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3365 +        V v;
3366 +        while ((v = it.advance()) != null)
3367 +            action.apply((K)it.nextKey, v);
3368 +    }
3369 +
3370 +    /**
3371 +     * Performs the given action for each non-null transformation
3372 +     * of each (key, value).
3373 +     *
3374 +     * @param transformer a function returning the transformation
3375 +     * for an element, or null if there is no transformation (in
3376 +     * which case the action is not applied)
3377 +     * @param action the action
3378 +     */
3379 +    @SuppressWarnings("unchecked") public <U> void forEachSequentially
3380 +        (BiFun<? super K, ? super V, ? extends U> transformer,
3381 +         Action<U> action) {
3382 +        if (transformer == null || action == null)
3383 +            throw new NullPointerException();
3384 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3385 +        V v; U u;
3386 +        while ((v = it.advance()) != null) {
3387 +            if ((u = transformer.apply((K)it.nextKey, v)) != null)
3388 +                action.apply(u);
3389 +        }
3390 +    }
3391 +
3392 +    /**
3393 +     * Returns a non-null result from applying the given search
3394 +     * function on each (key, value), or null if none.
3395 +     *
3396 +     * @param searchFunction a function returning a non-null
3397 +     * result on success, else null
3398 +     * @return a non-null result from applying the given search
3399 +     * function on each (key, value), or null if none
3400 +     */
3401 +    @SuppressWarnings("unchecked") public <U> U searchSequentially
3402 +        (BiFun<? super K, ? super V, ? extends U> searchFunction) {
3403 +        if (searchFunction == null) throw new NullPointerException();
3404 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3405 +        V v; U u;
3406 +        while ((v = it.advance()) != null) {
3407 +            if ((u = searchFunction.apply((K)it.nextKey, v)) != null)
3408 +                return u;
3409 +        }
3410 +        return null;
3411 +    }
3412 +
3413 +    /**
3414 +     * Returns the result of accumulating the given transformation
3415 +     * of all (key, value) pairs using the given reducer to
3416 +     * combine values, or null if none.
3417 +     *
3418 +     * @param transformer a function returning the transformation
3419 +     * for an element, or null if there is no transformation (in
3420 +     * which case it is not combined)
3421 +     * @param reducer a commutative associative combining function
3422 +     * @return the result of accumulating the given transformation
3423 +     * of all (key, value) pairs
3424 +     */
3425 +    @SuppressWarnings("unchecked") public <U> U reduceSequentially
3426 +        (BiFun<? super K, ? super V, ? extends U> transformer,
3427 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3428 +        if (transformer == null || reducer == null)
3429 +            throw new NullPointerException();
3430 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3431 +        U r = null, u; V v;
3432 +        while ((v = it.advance()) != null) {
3433 +            if ((u = transformer.apply((K)it.nextKey, v)) != null)
3434 +                r = (r == null) ? u : reducer.apply(r, u);
3435 +        }
3436 +        return r;
3437 +    }
3438 +
3439 +    /**
3440 +     * Returns the result of accumulating the given transformation
3441 +     * of all (key, value) pairs using the given reducer to
3442 +     * combine values, and the given basis as an identity value.
3443 +     *
3444 +     * @param transformer a function returning the transformation
3445 +     * for an element
3446 +     * @param basis the identity (initial default value) for the reduction
3447 +     * @param reducer a commutative associative combining function
3448 +     * @return the result of accumulating the given transformation
3449 +     * of all (key, value) pairs
3450 +     */
3451 +    @SuppressWarnings("unchecked") public double reduceToDoubleSequentially
3452 +        (ObjectByObjectToDouble<? super K, ? super V> transformer,
3453 +         double basis,
3454 +         DoubleByDoubleToDouble reducer) {
3455 +        if (transformer == null || reducer == null)
3456 +            throw new NullPointerException();
3457 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3458 +        double r = basis; V v;
3459 +        while ((v = it.advance()) != null)
3460 +            r = reducer.apply(r, transformer.apply((K)it.nextKey, v));
3461 +        return r;
3462 +    }
3463 +
3464 +    /**
3465 +     * Returns the result of accumulating the given transformation
3466 +     * of all (key, value) pairs using the given reducer to
3467 +     * combine values, and the given basis as an identity value.
3468 +     *
3469 +     * @param transformer a function returning the transformation
3470 +     * for an element
3471 +     * @param basis the identity (initial default value) for the reduction
3472 +     * @param reducer a commutative associative combining function
3473 +     * @return the result of accumulating the given transformation
3474 +     * of all (key, value) pairs
3475 +     */
3476 +    @SuppressWarnings("unchecked") public long reduceToLongSequentially
3477 +        (ObjectByObjectToLong<? super K, ? super V> transformer,
3478 +         long basis,
3479 +         LongByLongToLong reducer) {
3480 +        if (transformer == null || reducer == null)
3481 +            throw new NullPointerException();
3482 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3483 +        long r = basis; V v;
3484 +        while ((v = it.advance()) != null)
3485 +            r = reducer.apply(r, transformer.apply((K)it.nextKey, v));
3486 +        return r;
3487 +    }
3488 +
3489 +    /**
3490 +     * Returns the result of accumulating the given transformation
3491 +     * of all (key, value) pairs using the given reducer to
3492 +     * combine values, and the given basis as an identity value.
3493 +     *
3494 +     * @param transformer a function returning the transformation
3495 +     * for an element
3496 +     * @param basis the identity (initial default value) for the reduction
3497 +     * @param reducer a commutative associative combining function
3498 +     * @return the result of accumulating the given transformation
3499 +     * of all (key, value) pairs
3500 +     */
3501 +    @SuppressWarnings("unchecked") public int reduceToIntSequentially
3502 +        (ObjectByObjectToInt<? super K, ? super V> transformer,
3503 +         int basis,
3504 +         IntByIntToInt reducer) {
3505 +        if (transformer == null || reducer == null)
3506 +            throw new NullPointerException();
3507 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3508 +        int r = basis; V v;
3509 +        while ((v = it.advance()) != null)
3510 +            r = reducer.apply(r, transformer.apply((K)it.nextKey, v));
3511 +        return r;
3512 +    }
3513 +
3514 +    /**
3515 +     * Performs the given action for each key.
3516 +     *
3517 +     * @param action the action
3518 +     */
3519 +    @SuppressWarnings("unchecked") public void forEachKeySequentially
3520 +        (Action<K> action) {
3521 +        if (action == null) throw new NullPointerException();
3522 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3523 +        while (it.advance() != null)
3524 +            action.apply((K)it.nextKey);
3525 +    }
3526 +
3527 +    /**
3528 +     * Performs the given action for each non-null transformation
3529 +     * of each key.
3530 +     *
3531 +     * @param transformer a function returning the transformation
3532 +     * for an element, or null if there is no transformation (in
3533 +     * which case the action is not applied)
3534 +     * @param action the action
3535 +     */
3536 +    @SuppressWarnings("unchecked") public <U> void forEachKeySequentially
3537 +        (Fun<? super K, ? extends U> transformer,
3538 +         Action<U> action) {
3539 +        if (transformer == null || action == null)
3540 +            throw new NullPointerException();
3541 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3542 +        U u;
3543 +        while (it.advance() != null) {
3544 +            if ((u = transformer.apply((K)it.nextKey)) != null)
3545 +                action.apply(u);
3546 +        }
3547 +        ForkJoinTasks.forEachKey
3548 +            (this, transformer, action).invoke();
3549 +    }
3550 +
3551 +    /**
3552 +     * Returns a non-null result from applying the given search
3553 +     * function on each key, or null if none.
3554 +     *
3555 +     * @param searchFunction a function returning a non-null
3556 +     * result on success, else null
3557 +     * @return a non-null result from applying the given search
3558 +     * function on each key, or null if none
3559 +     */
3560 +    @SuppressWarnings("unchecked") public <U> U searchKeysSequentially
3561 +        (Fun<? super K, ? extends U> searchFunction) {
3562 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3563 +        U u;
3564 +        while (it.advance() != null) {
3565 +            if ((u = searchFunction.apply((K)it.nextKey)) != null)
3566 +                return u;
3567 +        }
3568 +        return null;
3569 +    }
3570 +
3571 +    /**
3572 +     * Returns the result of accumulating all keys using the given
3573 +     * reducer to combine values, or null if none.
3574 +     *
3575 +     * @param reducer a commutative associative combining function
3576 +     * @return the result of accumulating all keys using the given
3577 +     * reducer to combine values, or null if none
3578 +     */
3579 +    @SuppressWarnings("unchecked") public K reduceKeysSequentially
3580 +        (BiFun<? super K, ? super K, ? extends K> reducer) {
3581 +        if (reducer == null) throw new NullPointerException();
3582 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3583 +        K r = null;
3584 +        while (it.advance() != null) {
3585 +            K u = (K)it.nextKey;
3586 +            r = (r == null) ? u : reducer.apply(r, u);
3587 +        }
3588 +        return r;
3589 +    }
3590 +
3591 +    /**
3592 +     * Returns the result of accumulating the given transformation
3593 +     * of all keys using the given reducer to combine values, or
3594 +     * null if none.
3595 +     *
3596 +     * @param transformer a function returning the transformation
3597 +     * for an element, or null if there is no transformation (in
3598 +     * which case it is not combined)
3599 +     * @param reducer a commutative associative combining function
3600 +     * @return the result of accumulating the given transformation
3601 +     * of all keys
3602 +     */
3603 +    @SuppressWarnings("unchecked") public <U> U reduceKeysSequentially
3604 +        (Fun<? super K, ? extends U> transformer,
3605 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3606 +        if (transformer == null || reducer == null)
3607 +            throw new NullPointerException();
3608 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3609 +        U r = null, u;
3610 +        while (it.advance() != null) {
3611 +            if ((u = transformer.apply((K)it.nextKey)) != null)
3612 +                r = (r == null) ? u : reducer.apply(r, u);
3613 +        }
3614 +        return r;
3615 +    }
3616 +
3617 +    /**
3618 +     * Returns the result of accumulating the given transformation
3619 +     * of all keys using the given reducer to combine values, and
3620 +     * the given basis as an identity value.
3621 +     *
3622 +     * @param transformer a function returning the transformation
3623 +     * for an element
3624 +     * @param basis the identity (initial default value) for the reduction
3625 +     * @param reducer a commutative associative combining function
3626 +     * @return  the result of accumulating the given transformation
3627 +     * of all keys
3628 +     */
3629 +    @SuppressWarnings("unchecked") public double reduceKeysToDoubleSequentially
3630 +        (ObjectToDouble<? super K> transformer,
3631 +         double basis,
3632 +         DoubleByDoubleToDouble reducer) {
3633 +        if (transformer == null || reducer == null)
3634 +            throw new NullPointerException();
3635 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3636 +        double r = basis;
3637 +        while (it.advance() != null)
3638 +            r = reducer.apply(r, transformer.apply((K)it.nextKey));
3639 +        return r;
3640 +    }
3641 +
3642 +    /**
3643 +     * Returns the result of accumulating the given transformation
3644 +     * of all keys using the given reducer to combine values, and
3645 +     * the given basis as an identity value.
3646 +     *
3647 +     * @param transformer a function returning the transformation
3648 +     * for an element
3649 +     * @param basis the identity (initial default value) for the reduction
3650 +     * @param reducer a commutative associative combining function
3651 +     * @return the result of accumulating the given transformation
3652 +     * of all keys
3653 +     */
3654 +    @SuppressWarnings("unchecked") public long reduceKeysToLongSequentially
3655 +        (ObjectToLong<? super K> transformer,
3656 +         long basis,
3657 +         LongByLongToLong reducer) {
3658 +        if (transformer == null || reducer == null)
3659 +            throw new NullPointerException();
3660 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3661 +        long r = basis;
3662 +        while (it.advance() != null)
3663 +            r = reducer.apply(r, transformer.apply((K)it.nextKey));
3664 +        return r;
3665 +    }
3666 +
3667 +    /**
3668 +     * Returns the result of accumulating the given transformation
3669 +     * of all keys using the given reducer to combine values, and
3670 +     * the given basis as an identity value.
3671 +     *
3672 +     * @param transformer a function returning the transformation
3673 +     * for an element
3674 +     * @param basis the identity (initial default value) for the reduction
3675 +     * @param reducer a commutative associative combining function
3676 +     * @return the result of accumulating the given transformation
3677 +     * of all keys
3678 +     */
3679 +    @SuppressWarnings("unchecked") public int reduceKeysToIntSequentially
3680 +        (ObjectToInt<? super K> transformer,
3681 +         int basis,
3682 +         IntByIntToInt reducer) {
3683 +        if (transformer == null || reducer == null)
3684 +            throw new NullPointerException();
3685 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3686 +        int r = basis;
3687 +        while (it.advance() != null)
3688 +            r = reducer.apply(r, transformer.apply((K)it.nextKey));
3689 +        return r;
3690 +    }
3691 +
3692 +    /**
3693 +     * Performs the given action for each value.
3694 +     *
3695 +     * @param action the action
3696 +     */
3697 +    public void forEachValueSequentially(Action<V> action) {
3698 +        if (action == null) throw new NullPointerException();
3699 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3700 +        V v;
3701 +        while ((v = it.advance()) != null)
3702 +            action.apply(v);
3703 +    }
3704 +
3705 +    /**
3706 +     * Performs the given action for each non-null transformation
3707 +     * of each value.
3708 +     *
3709 +     * @param transformer a function returning the transformation
3710 +     * for an element, or null if there is no transformation (in
3711 +     * which case the action is not applied)
3712 +     */
3713 +    public <U> void forEachValueSequentially
3714 +        (Fun<? super V, ? extends U> transformer,
3715 +         Action<U> action) {
3716 +        if (transformer == null || action == null)
3717 +            throw new NullPointerException();
3718 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3719 +        V v; U u;
3720 +        while ((v = it.advance()) != null) {
3721 +            if ((u = transformer.apply(v)) != null)
3722 +                action.apply(u);
3723 +        }
3724 +    }
3725 +
3726 +    /**
3727 +     * Returns a non-null result from applying the given search
3728 +     * function on each value, or null if none.
3729 +     *
3730 +     * @param searchFunction a function returning a non-null
3731 +     * result on success, else null
3732 +     * @return a non-null result from applying the given search
3733 +     * function on each value, or null if none
3734 +     */
3735 +    public <U> U searchValuesSequentially
3736 +        (Fun<? super V, ? extends U> searchFunction) {
3737 +        if (searchFunction == null) throw new NullPointerException();
3738 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3739 +        V v; U u;
3740 +        while ((v = it.advance()) != null) {
3741 +            if ((u = searchFunction.apply(v)) != null)
3742 +                return u;
3743 +        }
3744 +        return null;
3745 +    }
3746 +
3747 +    /**
3748 +     * Returns the result of accumulating all values using the
3749 +     * given reducer to combine values, or null if none.
3750 +     *
3751 +     * @param reducer a commutative associative combining function
3752 +     * @return  the result of accumulating all values
3753 +     */
3754 +    public V reduceValuesSequentially
3755 +        (BiFun<? super V, ? super V, ? extends V> reducer) {
3756 +        if (reducer == null) throw new NullPointerException();
3757 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3758 +        V r = null; V v;
3759 +        while ((v = it.advance()) != null)
3760 +            r = (r == null) ? v : reducer.apply(r, v);
3761 +        return r;
3762 +    }
3763 +
3764 +    /**
3765 +     * Returns the result of accumulating the given transformation
3766 +     * of all values using the given reducer to combine values, or
3767 +     * null if none.
3768 +     *
3769 +     * @param transformer a function returning the transformation
3770 +     * for an element, or null if there is no transformation (in
3771 +     * which case it is not combined)
3772 +     * @param reducer a commutative associative combining function
3773 +     * @return the result of accumulating the given transformation
3774 +     * of all values
3775 +     */
3776 +    public <U> U reduceValuesSequentially
3777 +        (Fun<? super V, ? extends U> transformer,
3778 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3779 +        if (transformer == null || reducer == null)
3780 +            throw new NullPointerException();
3781 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3782 +        U r = null, u; V v;
3783 +        while ((v = it.advance()) != null) {
3784 +            if ((u = transformer.apply(v)) != null)
3785 +                r = (r == null) ? u : reducer.apply(r, u);
3786 +        }
3787 +        return r;
3788 +    }
3789 +
3790 +    /**
3791 +     * Returns the result of accumulating the given transformation
3792 +     * of all values using the given reducer to combine values,
3793 +     * and the given basis as an identity value.
3794 +     *
3795 +     * @param transformer a function returning the transformation
3796 +     * for an element
3797 +     * @param basis the identity (initial default value) for the reduction
3798 +     * @param reducer a commutative associative combining function
3799 +     * @return the result of accumulating the given transformation
3800 +     * of all values
3801 +     */
3802 +    public double reduceValuesToDoubleSequentially
3803 +        (ObjectToDouble<? super V> transformer,
3804 +         double basis,
3805 +         DoubleByDoubleToDouble reducer) {
3806 +        if (transformer == null || reducer == null)
3807 +            throw new NullPointerException();
3808 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3809 +        double r = basis; V v;
3810 +        while ((v = it.advance()) != null)
3811 +            r = reducer.apply(r, transformer.apply(v));
3812 +        return r;
3813 +    }
3814 +
3815 +    /**
3816 +     * Returns the result of accumulating the given transformation
3817 +     * of all values using the given reducer to combine values,
3818 +     * and the given basis as an identity value.
3819 +     *
3820 +     * @param transformer a function returning the transformation
3821 +     * for an element
3822 +     * @param basis the identity (initial default value) for the reduction
3823 +     * @param reducer a commutative associative combining function
3824 +     * @return the result of accumulating the given transformation
3825 +     * of all values
3826 +     */
3827 +    public long reduceValuesToLongSequentially
3828 +        (ObjectToLong<? super V> transformer,
3829 +         long basis,
3830 +         LongByLongToLong reducer) {
3831 +        if (transformer == null || reducer == null)
3832 +            throw new NullPointerException();
3833 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3834 +        long r = basis; V v;
3835 +        while ((v = it.advance()) != null)
3836 +            r = reducer.apply(r, transformer.apply(v));
3837 +        return r;
3838 +    }
3839 +
3840 +    /**
3841 +     * Returns the result of accumulating the given transformation
3842 +     * of all values using the given reducer to combine values,
3843 +     * and the given basis as an identity value.
3844 +     *
3845 +     * @param transformer a function returning the transformation
3846 +     * for an element
3847 +     * @param basis the identity (initial default value) for the reduction
3848 +     * @param reducer a commutative associative combining function
3849 +     * @return the result of accumulating the given transformation
3850 +     * of all values
3851 +     */
3852 +    public int reduceValuesToIntSequentially
3853 +        (ObjectToInt<? super V> transformer,
3854 +         int basis,
3855 +         IntByIntToInt reducer) {
3856 +        if (transformer == null || reducer == null)
3857 +            throw new NullPointerException();
3858 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3859 +        int r = basis; V v;
3860 +        while ((v = it.advance()) != null)
3861 +            r = reducer.apply(r, transformer.apply(v));
3862 +        return r;
3863 +    }
3864 +
3865 +    /**
3866 +     * Performs the given action for each entry.
3867 +     *
3868 +     * @param action the action
3869 +     */
3870 +    @SuppressWarnings("unchecked") public void forEachEntrySequentially
3871 +        (Action<Map.Entry<K,V>> action) {
3872 +        if (action == null) throw new NullPointerException();
3873 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3874 +        V v;
3875 +        while ((v = it.advance()) != null)
3876 +            action.apply(entryFor((K)it.nextKey, v));
3877 +    }
3878 +
3879 +    /**
3880 +     * Performs the given action for each non-null transformation
3881 +     * of each entry.
3882 +     *
3883 +     * @param transformer a function returning the transformation
3884 +     * for an element, or null if there is no transformation (in
3885 +     * which case the action is not applied)
3886 +     * @param action the action
3887 +     */
3888 +    @SuppressWarnings("unchecked") public <U> void forEachEntrySequentially
3889 +        (Fun<Map.Entry<K,V>, ? extends U> transformer,
3890 +         Action<U> action) {
3891 +        if (transformer == null || action == null)
3892 +            throw new NullPointerException();
3893 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3894 +        V v; U u;
3895 +        while ((v = it.advance()) != null) {
3896 +            if ((u = transformer.apply(entryFor((K)it.nextKey, v))) != null)
3897 +                action.apply(u);
3898 +        }
3899 +    }
3900 +
3901 +    /**
3902 +     * Returns a non-null result from applying the given search
3903 +     * function on each entry, or null if none.
3904 +     *
3905 +     * @param searchFunction a function returning a non-null
3906 +     * result on success, else null
3907 +     * @return a non-null result from applying the given search
3908 +     * function on each entry, or null if none
3909 +     */
3910 +    @SuppressWarnings("unchecked") public <U> U searchEntriesSequentially
3911 +        (Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
3912 +        if (searchFunction == null) throw new NullPointerException();
3913 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3914 +        V v; U u;
3915 +        while ((v = it.advance()) != null) {
3916 +            if ((u = searchFunction.apply(entryFor((K)it.nextKey, v))) != null)
3917 +                return u;
3918 +        }
3919 +        return null;
3920 +    }
3921 +
3922 +    /**
3923 +     * Returns the result of accumulating all entries using the
3924 +     * given reducer to combine values, or null if none.
3925 +     *
3926 +     * @param reducer a commutative associative combining function
3927 +     * @return the result of accumulating all entries
3928 +     */
3929 +    @SuppressWarnings("unchecked") public Map.Entry<K,V> reduceEntriesSequentially
3930 +        (BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
3931 +        if (reducer == null) throw new NullPointerException();
3932 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3933 +        Map.Entry<K,V> r = null; V v;
3934 +        while ((v = it.advance()) != null) {
3935 +            Map.Entry<K,V> u = entryFor((K)it.nextKey, v);
3936 +            r = (r == null) ? u : reducer.apply(r, u);
3937 +        }
3938 +        return r;
3939 +    }
3940 +
3941 +    /**
3942 +     * Returns the result of accumulating the given transformation
3943 +     * of all entries using the given reducer to combine values,
3944 +     * or null if none.
3945 +     *
3946 +     * @param transformer a function returning the transformation
3947 +     * for an element, or null if there is no transformation (in
3948 +     * which case it is not combined)
3949 +     * @param reducer a commutative associative combining function
3950 +     * @return the result of accumulating the given transformation
3951 +     * of all entries
3952 +     */
3953 +    @SuppressWarnings("unchecked") public <U> U reduceEntriesSequentially
3954 +        (Fun<Map.Entry<K,V>, ? extends U> transformer,
3955 +         BiFun<? super U, ? super U, ? extends U> reducer) {
3956 +        if (transformer == null || reducer == null)
3957 +            throw new NullPointerException();
3958 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3959 +        U r = null, u; V v;
3960 +        while ((v = it.advance()) != null) {
3961 +            if ((u = transformer.apply(entryFor((K)it.nextKey, v))) != null)
3962 +                r = (r == null) ? u : reducer.apply(r, u);
3963 +        }
3964 +        return r;
3965 +    }
3966 +
3967 +    /**
3968 +     * Returns the result of accumulating the given transformation
3969 +     * of all entries using the given reducer to combine values,
3970 +     * and the given basis as an identity value.
3971 +     *
3972 +     * @param transformer a function returning the transformation
3973 +     * for an element
3974 +     * @param basis the identity (initial default value) for the reduction
3975 +     * @param reducer a commutative associative combining function
3976 +     * @return the result of accumulating the given transformation
3977 +     * of all entries
3978 +     */
3979 +    @SuppressWarnings("unchecked") public double reduceEntriesToDoubleSequentially
3980 +        (ObjectToDouble<Map.Entry<K,V>> transformer,
3981 +         double basis,
3982 +         DoubleByDoubleToDouble reducer) {
3983 +        if (transformer == null || reducer == null)
3984 +            throw new NullPointerException();
3985 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
3986 +        double r = basis; V v;
3987 +        while ((v = it.advance()) != null)
3988 +            r = reducer.apply(r, transformer.apply(entryFor((K)it.nextKey, v)));
3989 +        return r;
3990 +    }
3991 +
3992 +    /**
3993 +     * Returns the result of accumulating the given transformation
3994 +     * of all entries using the given reducer to combine values,
3995 +     * and the given basis as an identity value.
3996 +     *
3997 +     * @param transformer a function returning the transformation
3998 +     * for an element
3999 +     * @param basis the identity (initial default value) for the reduction
4000 +     * @param reducer a commutative associative combining function
4001 +     * @return  the result of accumulating the given transformation
4002 +     * of all entries
4003 +     */
4004 +    @SuppressWarnings("unchecked") public long reduceEntriesToLongSequentially
4005 +        (ObjectToLong<Map.Entry<K,V>> transformer,
4006 +         long basis,
4007 +         LongByLongToLong reducer) {
4008 +        if (transformer == null || reducer == null)
4009 +            throw new NullPointerException();
4010 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
4011 +        long r = basis; V v;
4012 +        while ((v = it.advance()) != null)
4013 +            r = reducer.apply(r, transformer.apply(entryFor((K)it.nextKey, v)));
4014 +        return r;
4015 +    }
4016 +
4017 +    /**
4018 +     * Returns the result of accumulating the given transformation
4019 +     * of all entries using the given reducer to combine values,
4020 +     * and the given basis as an identity value.
4021 +     *
4022 +     * @param transformer a function returning the transformation
4023 +     * for an element
4024 +     * @param basis the identity (initial default value) for the reduction
4025 +     * @param reducer a commutative associative combining function
4026 +     * @return the result of accumulating the given transformation
4027 +     * of all entries
4028 +     */
4029 +    @SuppressWarnings("unchecked") public int reduceEntriesToIntSequentially
4030 +        (ObjectToInt<Map.Entry<K,V>> transformer,
4031 +         int basis,
4032 +         IntByIntToInt reducer) {
4033 +        if (transformer == null || reducer == null)
4034 +            throw new NullPointerException();
4035 +        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
4036 +        int r = basis; V v;
4037 +        while ((v = it.advance()) != null)
4038 +            r = reducer.apply(r, transformer.apply(entryFor((K)it.nextKey, v)));
4039 +        return r;
4040 +    }
4041 +
4042 +    // Parallel bulk operations
4043 +
4044      /**
4045       * Performs the given action for each (key, value).
4046       *
4047       * @param action the action
4048       */
4049 <    public void forEach(BiAction<K,V> action) {
4049 >    public void forEachInParallel(BiAction<K,V> action) {
4050          ForkJoinTasks.forEach
4051              (this, action).invoke();
4052      }
# Line 3356 | Line 4056 | public class ConcurrentHashMapV8<K, V>
4056       * of each (key, value).
4057       *
4058       * @param transformer a function returning the transformation
4059 <     * for an element, or null of there is no transformation (in
4060 <     * which case the action is not applied).
4059 >     * for an element, or null if there is no transformation (in
4060 >     * which case the action is not applied)
4061       * @param action the action
4062       */
4063 <    public <U> void forEach(BiFun<? super K, ? super V, ? extends U> transformer,
4063 >    public <U> void forEachInParallel
4064 >        (BiFun<? super K, ? super V, ? extends U> transformer,
4065                              Action<U> action) {
4066          ForkJoinTasks.forEach
4067              (this, transformer, action).invoke();
# Line 3378 | Line 4079 | public class ConcurrentHashMapV8<K, V>
4079       * @return a non-null result from applying the given search
4080       * function on each (key, value), or null if none
4081       */
4082 <    public <U> U search(BiFun<? super K, ? super V, ? extends U> searchFunction) {
4082 >    public <U> U searchInParallel
4083 >        (BiFun<? super K, ? super V, ? extends U> searchFunction) {
4084          return ForkJoinTasks.search
4085              (this, searchFunction).invoke();
4086      }
# Line 3389 | Line 4091 | public class ConcurrentHashMapV8<K, V>
4091       * combine values, or null if none.
4092       *
4093       * @param transformer a function returning the transformation
4094 <     * for an element, or null of there is no transformation (in
4095 <     * which case it is not combined).
4094 >     * for an element, or null if there is no transformation (in
4095 >     * which case it is not combined)
4096       * @param reducer a commutative associative combining function
4097       * @return the result of accumulating the given transformation
4098       * of all (key, value) pairs
4099       */
4100 <    public <U> U reduce(BiFun<? super K, ? super V, ? extends U> transformer,
4101 <                        BiFun<? super U, ? super U, ? extends U> reducer) {
4100 >    public <U> U reduceInParallel
4101 >        (BiFun<? super K, ? super V, ? extends U> transformer,
4102 >         BiFun<? super U, ? super U, ? extends U> reducer) {
4103          return ForkJoinTasks.reduce
4104              (this, transformer, reducer).invoke();
4105      }
# Line 3413 | Line 4116 | public class ConcurrentHashMapV8<K, V>
4116       * @return the result of accumulating the given transformation
4117       * of all (key, value) pairs
4118       */
4119 <    public double reduceToDouble(ObjectByObjectToDouble<? super K, ? super V> transformer,
4120 <                                 double basis,
4121 <                                 DoubleByDoubleToDouble reducer) {
4119 >    public double reduceToDoubleInParallel
4120 >        (ObjectByObjectToDouble<? super K, ? super V> transformer,
4121 >         double basis,
4122 >         DoubleByDoubleToDouble reducer) {
4123          return ForkJoinTasks.reduceToDouble
4124              (this, transformer, basis, reducer).invoke();
4125      }
# Line 3432 | Line 4136 | public class ConcurrentHashMapV8<K, V>
4136       * @return the result of accumulating the given transformation
4137       * of all (key, value) pairs
4138       */
4139 <    public long reduceToLong(ObjectByObjectToLong<? super K, ? super V> transformer,
4140 <                             long basis,
4141 <                             LongByLongToLong reducer) {
4139 >    public long reduceToLongInParallel
4140 >        (ObjectByObjectToLong<? super K, ? super V> transformer,
4141 >         long basis,
4142 >         LongByLongToLong reducer) {
4143          return ForkJoinTasks.reduceToLong
4144              (this, transformer, basis, reducer).invoke();
4145      }
# Line 3451 | Line 4156 | public class ConcurrentHashMapV8<K, V>
4156       * @return the result of accumulating the given transformation
4157       * of all (key, value) pairs
4158       */
4159 <    public int reduceToInt(ObjectByObjectToInt<? super K, ? super V> transformer,
4160 <                           int basis,
4161 <                           IntByIntToInt reducer) {
4159 >    public int reduceToIntInParallel
4160 >        (ObjectByObjectToInt<? super K, ? super V> transformer,
4161 >         int basis,
4162 >         IntByIntToInt reducer) {
4163          return ForkJoinTasks.reduceToInt
4164              (this, transformer, basis, reducer).invoke();
4165      }
# Line 3463 | Line 4169 | public class ConcurrentHashMapV8<K, V>
4169       *
4170       * @param action the action
4171       */
4172 <    public void forEachKey(Action<K> action) {
4172 >    public void forEachKeyInParallel(Action<K> action) {
4173          ForkJoinTasks.forEachKey
4174              (this, action).invoke();
4175      }
# Line 3473 | Line 4179 | public class ConcurrentHashMapV8<K, V>
4179       * of each key.
4180       *
4181       * @param transformer a function returning the transformation
4182 <     * for an element, or null of there is no transformation (in
4183 <     * which case the action is not applied).
4182 >     * for an element, or null if there is no transformation (in
4183 >     * which case the action is not applied)
4184       * @param action the action
4185       */
4186 <    public <U> void forEachKey(Fun<? super K, ? extends U> transformer,
4187 <                               Action<U> action) {
4186 >    public <U> void forEachKeyInParallel
4187 >        (Fun<? super K, ? extends U> transformer,
4188 >         Action<U> action) {
4189          ForkJoinTasks.forEachKey
4190              (this, transformer, action).invoke();
4191      }
# Line 3495 | Line 4202 | public class ConcurrentHashMapV8<K, V>
4202       * @return a non-null result from applying the given search
4203       * function on each key, or null if none
4204       */
4205 <    public <U> U searchKeys(Fun<? super K, ? extends U> searchFunction) {
4205 >    public <U> U searchKeysInParallel
4206 >        (Fun<? super K, ? extends U> searchFunction) {
4207          return ForkJoinTasks.searchKeys
4208              (this, searchFunction).invoke();
4209      }
# Line 3508 | Line 4216 | public class ConcurrentHashMapV8<K, V>
4216       * @return the result of accumulating all keys using the given
4217       * reducer to combine values, or null if none
4218       */
4219 <    public K reduceKeys(BiFun<? super K, ? super K, ? extends K> reducer) {
4219 >    public K reduceKeysInParallel
4220 >        (BiFun<? super K, ? super K, ? extends K> reducer) {
4221          return ForkJoinTasks.reduceKeys
4222              (this, reducer).invoke();
4223      }
# Line 3519 | Line 4228 | public class ConcurrentHashMapV8<K, V>
4228       * null if none.
4229       *
4230       * @param transformer a function returning the transformation
4231 <     * for an element, or null of there is no transformation (in
4232 <     * which case it is not combined).
4231 >     * for an element, or null if there is no transformation (in
4232 >     * which case it is not combined)
4233       * @param reducer a commutative associative combining function
4234       * @return the result of accumulating the given transformation
4235       * of all keys
4236       */
4237 <    public <U> U reduceKeys(Fun<? super K, ? extends U> transformer,
4238 <                            BiFun<? super U, ? super U, ? extends U> reducer) {
4237 >    public <U> U reduceKeysInParallel
4238 >        (Fun<? super K, ? extends U> transformer,
4239 >         BiFun<? super U, ? super U, ? extends U> reducer) {
4240          return ForkJoinTasks.reduceKeys
4241              (this, transformer, reducer).invoke();
4242      }
# Line 3543 | Line 4253 | public class ConcurrentHashMapV8<K, V>
4253       * @return  the result of accumulating the given transformation
4254       * of all keys
4255       */
4256 <    public double reduceKeysToDouble(ObjectToDouble<? super K> transformer,
4257 <                                     double basis,
4258 <                                     DoubleByDoubleToDouble reducer) {
4256 >    public double reduceKeysToDoubleInParallel
4257 >        (ObjectToDouble<? super K> transformer,
4258 >         double basis,
4259 >         DoubleByDoubleToDouble reducer) {
4260          return ForkJoinTasks.reduceKeysToDouble
4261              (this, transformer, basis, reducer).invoke();
4262      }
# Line 3562 | Line 4273 | public class ConcurrentHashMapV8<K, V>
4273       * @return the result of accumulating the given transformation
4274       * of all keys
4275       */
4276 <    public long reduceKeysToLong(ObjectToLong<? super K> transformer,
4277 <                                 long basis,
4278 <                                 LongByLongToLong reducer) {
4276 >    public long reduceKeysToLongInParallel
4277 >        (ObjectToLong<? super K> transformer,
4278 >         long basis,
4279 >         LongByLongToLong reducer) {
4280          return ForkJoinTasks.reduceKeysToLong
4281              (this, transformer, basis, reducer).invoke();
4282      }
# Line 3581 | Line 4293 | public class ConcurrentHashMapV8<K, V>
4293       * @return the result of accumulating the given transformation
4294       * of all keys
4295       */
4296 <    public int reduceKeysToInt(ObjectToInt<? super K> transformer,
4297 <                               int basis,
4298 <                               IntByIntToInt reducer) {
4296 >    public int reduceKeysToIntInParallel
4297 >        (ObjectToInt<? super K> transformer,
4298 >         int basis,
4299 >         IntByIntToInt reducer) {
4300          return ForkJoinTasks.reduceKeysToInt
4301              (this, transformer, basis, reducer).invoke();
4302      }
# Line 3593 | Line 4306 | public class ConcurrentHashMapV8<K, V>
4306       *
4307       * @param action the action
4308       */
4309 <    public void forEachValue(Action<V> action) {
4309 >    public void forEachValueInParallel(Action<V> action) {
4310          ForkJoinTasks.forEachValue
4311              (this, action).invoke();
4312      }
# Line 3603 | Line 4316 | public class ConcurrentHashMapV8<K, V>
4316       * of each value.
4317       *
4318       * @param transformer a function returning the transformation
4319 <     * for an element, or null of there is no transformation (in
4320 <     * which case the action is not applied).
4319 >     * for an element, or null if there is no transformation (in
4320 >     * which case the action is not applied)
4321       */
4322 <    public <U> void forEachValue(Fun<? super V, ? extends U> transformer,
4323 <                                 Action<U> action) {
4322 >    public <U> void forEachValueInParallel
4323 >        (Fun<? super V, ? extends U> transformer,
4324 >         Action<U> action) {
4325          ForkJoinTasks.forEachValue
4326              (this, transformer, action).invoke();
4327      }
# Line 3623 | Line 4337 | public class ConcurrentHashMapV8<K, V>
4337       * result on success, else null
4338       * @return a non-null result from applying the given search
4339       * function on each value, or null if none
3626     *
4340       */
4341 <    public <U> U searchValues(Fun<? super V, ? extends U> searchFunction) {
4341 >    public <U> U searchValuesInParallel
4342 >        (Fun<? super V, ? extends U> searchFunction) {
4343          return ForkJoinTasks.searchValues
4344              (this, searchFunction).invoke();
4345      }
# Line 3637 | Line 4351 | public class ConcurrentHashMapV8<K, V>
4351       * @param reducer a commutative associative combining function
4352       * @return  the result of accumulating all values
4353       */
4354 <    public V reduceValues(BiFun<? super V, ? super V, ? extends V> reducer) {
4354 >    public V reduceValuesInParallel
4355 >        (BiFun<? super V, ? super V, ? extends V> reducer) {
4356          return ForkJoinTasks.reduceValues
4357              (this, reducer).invoke();
4358      }
# Line 3648 | Line 4363 | public class ConcurrentHashMapV8<K, V>
4363       * null if none.
4364       *
4365       * @param transformer a function returning the transformation
4366 <     * for an element, or null of there is no transformation (in
4367 <     * which case it is not combined).
4366 >     * for an element, or null if there is no transformation (in
4367 >     * which case it is not combined)
4368       * @param reducer a commutative associative combining function
4369       * @return the result of accumulating the given transformation
4370       * of all values
4371       */
4372 <    public <U> U reduceValues(Fun<? super V, ? extends U> transformer,
4373 <                              BiFun<? super U, ? super U, ? extends U> reducer) {
4372 >    public <U> U reduceValuesInParallel
4373 >        (Fun<? super V, ? extends U> transformer,
4374 >         BiFun<? super U, ? super U, ? extends U> reducer) {
4375          return ForkJoinTasks.reduceValues
4376              (this, transformer, reducer).invoke();
4377      }
# Line 3672 | Line 4388 | public class ConcurrentHashMapV8<K, V>
4388       * @return the result of accumulating the given transformation
4389       * of all values
4390       */
4391 <    public double reduceValuesToDouble(ObjectToDouble<? super V> transformer,
4392 <                                       double basis,
4393 <                                       DoubleByDoubleToDouble reducer) {
4391 >    public double reduceValuesToDoubleInParallel
4392 >        (ObjectToDouble<? super V> transformer,
4393 >         double basis,
4394 >         DoubleByDoubleToDouble reducer) {
4395          return ForkJoinTasks.reduceValuesToDouble
4396              (this, transformer, basis, reducer).invoke();
4397      }
# Line 3691 | Line 4408 | public class ConcurrentHashMapV8<K, V>
4408       * @return the result of accumulating the given transformation
4409       * of all values
4410       */
4411 <    public long reduceValuesToLong(ObjectToLong<? super V> transformer,
4412 <                                   long basis,
4413 <                                   LongByLongToLong reducer) {
4411 >    public long reduceValuesToLongInParallel
4412 >        (ObjectToLong<? super V> transformer,
4413 >         long basis,
4414 >         LongByLongToLong reducer) {
4415          return ForkJoinTasks.reduceValuesToLong
4416              (this, transformer, basis, reducer).invoke();
4417      }
# Line 3710 | Line 4428 | public class ConcurrentHashMapV8<K, V>
4428       * @return the result of accumulating the given transformation
4429       * of all values
4430       */
4431 <    public int reduceValuesToInt(ObjectToInt<? super V> transformer,
4432 <                                 int basis,
4433 <                                 IntByIntToInt reducer) {
4431 >    public int reduceValuesToIntInParallel
4432 >        (ObjectToInt<? super V> transformer,
4433 >         int basis,
4434 >         IntByIntToInt reducer) {
4435          return ForkJoinTasks.reduceValuesToInt
4436              (this, transformer, basis, reducer).invoke();
4437      }
# Line 3722 | Line 4441 | public class ConcurrentHashMapV8<K, V>
4441       *
4442       * @param action the action
4443       */
4444 <    public void forEachEntry(Action<Map.Entry<K,V>> action) {
4444 >    public void forEachEntryInParallel(Action<Map.Entry<K,V>> action) {
4445          ForkJoinTasks.forEachEntry
4446              (this, action).invoke();
4447      }
# Line 3732 | Line 4451 | public class ConcurrentHashMapV8<K, V>
4451       * of each entry.
4452       *
4453       * @param transformer a function returning the transformation
4454 <     * for an element, or null of there is no transformation (in
4455 <     * which case the action is not applied).
4454 >     * for an element, or null if there is no transformation (in
4455 >     * which case the action is not applied)
4456       * @param action the action
4457       */
4458 <    public <U> void forEachEntry(Fun<Map.Entry<K,V>, ? extends U> transformer,
4459 <                                 Action<U> action) {
4458 >    public <U> void forEachEntryInParallel
4459 >        (Fun<Map.Entry<K,V>, ? extends U> transformer,
4460 >         Action<U> action) {
4461          ForkJoinTasks.forEachEntry
4462              (this, transformer, action).invoke();
4463      }
# Line 3754 | Line 4474 | public class ConcurrentHashMapV8<K, V>
4474       * @return a non-null result from applying the given search
4475       * function on each entry, or null if none
4476       */
4477 <    public <U> U searchEntries(Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4477 >    public <U> U searchEntriesInParallel
4478 >        (Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4479          return ForkJoinTasks.searchEntries
4480              (this, searchFunction).invoke();
4481      }
# Line 3766 | Line 4487 | public class ConcurrentHashMapV8<K, V>
4487       * @param reducer a commutative associative combining function
4488       * @return the result of accumulating all entries
4489       */
4490 <    public Map.Entry<K,V> reduceEntries(BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4490 >    public Map.Entry<K,V> reduceEntriesInParallel
4491 >        (BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4492          return ForkJoinTasks.reduceEntries
4493              (this, reducer).invoke();
4494      }
# Line 3777 | Line 4499 | public class ConcurrentHashMapV8<K, V>
4499       * or null if none.
4500       *
4501       * @param transformer a function returning the transformation
4502 <     * for an element, or null of there is no transformation (in
4503 <     * which case it is not combined).
4502 >     * for an element, or null if there is no transformation (in
4503 >     * which case it is not combined)
4504       * @param reducer a commutative associative combining function
4505       * @return the result of accumulating the given transformation
4506       * of all entries
4507       */
4508 <    public <U> U reduceEntries(Fun<Map.Entry<K,V>, ? extends U> transformer,
4509 <                               BiFun<? super U, ? super U, ? extends U> reducer) {
4508 >    public <U> U reduceEntriesInParallel
4509 >        (Fun<Map.Entry<K,V>, ? extends U> transformer,
4510 >         BiFun<? super U, ? super U, ? extends U> reducer) {
4511          return ForkJoinTasks.reduceEntries
4512              (this, transformer, reducer).invoke();
4513      }
# Line 3801 | Line 4524 | public class ConcurrentHashMapV8<K, V>
4524       * @return the result of accumulating the given transformation
4525       * of all entries
4526       */
4527 <    public double reduceEntriesToDouble(ObjectToDouble<Map.Entry<K,V>> transformer,
4528 <                                        double basis,
4529 <                                        DoubleByDoubleToDouble reducer) {
4527 >    public double reduceEntriesToDoubleInParallel
4528 >        (ObjectToDouble<Map.Entry<K,V>> transformer,
4529 >         double basis,
4530 >         DoubleByDoubleToDouble reducer) {
4531          return ForkJoinTasks.reduceEntriesToDouble
4532              (this, transformer, basis, reducer).invoke();
4533      }
# Line 3820 | Line 4544 | public class ConcurrentHashMapV8<K, V>
4544       * @return  the result of accumulating the given transformation
4545       * of all entries
4546       */
4547 <    public long reduceEntriesToLong(ObjectToLong<Map.Entry<K,V>> transformer,
4548 <                                    long basis,
4549 <                                    LongByLongToLong reducer) {
4547 >    public long reduceEntriesToLongInParallel
4548 >        (ObjectToLong<Map.Entry<K,V>> transformer,
4549 >         long basis,
4550 >         LongByLongToLong reducer) {
4551          return ForkJoinTasks.reduceEntriesToLong
4552              (this, transformer, basis, reducer).invoke();
4553      }
# Line 3839 | Line 4564 | public class ConcurrentHashMapV8<K, V>
4564       * @return the result of accumulating the given transformation
4565       * of all entries
4566       */
4567 <    public int reduceEntriesToInt(ObjectToInt<Map.Entry<K,V>> transformer,
4568 <                                  int basis,
4569 <                                  IntByIntToInt reducer) {
4567 >    public int reduceEntriesToIntInParallel
4568 >        (ObjectToInt<Map.Entry<K,V>> transformer,
4569 >         int basis,
4570 >         IntByIntToInt reducer) {
4571          return ForkJoinTasks.reduceEntriesToInt
4572              (this, transformer, basis, reducer).invoke();
4573      }
4574  
4575 +
4576      /* ----------------Views -------------- */
4577  
4578      /**
4579       * Base class for views.
4580       */
4581 <    static abstract class CHMView<K, V> {
4582 <        final ConcurrentHashMapV8<K, V> map;
4583 <        CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
4581 >    abstract static class CHMView<K,V> {
4582 >        final ConcurrentHashMapV8<K,V> map;
4583 >        CHMView(ConcurrentHashMapV8<K,V> map)  { this.map = map; }
4584  
4585          /**
4586           * Returns the map backing this view.
# Line 3867 | Line 4594 | public class ConcurrentHashMapV8<K, V>
4594          public final void clear()               { map.clear(); }
4595  
4596          // implementations below rely on concrete classes supplying these
4597 <        abstract public Iterator<?> iterator();
4598 <        abstract public boolean contains(Object o);
4599 <        abstract public boolean remove(Object o);
4597 >        public abstract Iterator<?> iterator();
4598 >        public abstract boolean contains(Object o);
4599 >        public abstract boolean remove(Object o);
4600  
4601          private static final String oomeMsg = "Required array size too large";
4602  
# Line 3988 | Line 4715 | public class ConcurrentHashMapV8<K, V>
4715       * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in
4716       * which additions may optionally be enabled by mapping to a
4717       * common value.  This class cannot be directly instantiated. See
4718 <     * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
4718 >     * {@link #keySet()}, {@link #keySet(Object)}, {@link #newKeySet()},
4719       * {@link #newKeySet(int)}.
4720       */
4721      public static class KeySetView<K,V> extends CHMView<K,V>
4722          implements Set<K>, java.io.Serializable {
4723          private static final long serialVersionUID = 7249069246763182397L;
4724          private final V value;
4725 <        KeySetView(ConcurrentHashMapV8<K, V> map, V value) {  // non-public
4725 >        KeySetView(ConcurrentHashMapV8<K,V> map, V value) {  // non-public
4726              super(map);
4727              this.value = value;
4728          }
# Line 4005 | Line 4732 | public class ConcurrentHashMapV8<K, V>
4732           * or {@code null} if additions are not supported.
4733           *
4734           * @return the default mapped value for additions, or {@code null}
4735 <         * if not supported.
4735 >         * if not supported
4736           */
4737          public V getMappedValue() { return value; }
4738  
# Line 4029 | Line 4756 | public class ConcurrentHashMapV8<K, V>
4756              V v;
4757              if ((v = value) == null)
4758                  throw new UnsupportedOperationException();
4032            if (e == null)
4033                throw new NullPointerException();
4759              return map.internalPut(e, v, true) == null;
4760          }
4761          public boolean addAll(Collection<? extends K> c) {
# Line 4039 | Line 4764 | public class ConcurrentHashMapV8<K, V>
4764              if ((v = value) == null)
4765                  throw new UnsupportedOperationException();
4766              for (K e : c) {
4042                if (e == null)
4043                    throw new NullPointerException();
4767                  if (map.internalPut(e, v, true) == null)
4768                      added = true;
4769              }
# Line 4052 | Line 4775 | public class ConcurrentHashMapV8<K, V>
4775                      ((c = (Set<?>)o) == this ||
4776                       (containsAll(c) && c.containsAll(this))));
4777          }
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
4778      }
4779  
4780      /**
4781       * A view of a ConcurrentHashMapV8 as a {@link Collection} of
4782       * values, in which additions are disabled. This class cannot be
4783 <     * directly instantiated. See {@link #values},
4783 >     * directly instantiated. See {@link #values()}.
4784       *
4785       * <p>The view's {@code iterator} is a "weakly consistent" iterator
4786       * that will never throw {@link ConcurrentModificationException},
# Line 4180 | Line 4790 | public class ConcurrentHashMapV8<K, V>
4790       */
4791      public static final class ValuesView<K,V> extends CHMView<K,V>
4792          implements Collection<V> {
4793 <        ValuesView(ConcurrentHashMapV8<K, V> map)   { super(map); }
4793 >        ValuesView(ConcurrentHashMapV8<K,V> map)   { super(map); }
4794          public final boolean contains(Object o) { return map.containsValue(o); }
4795          public final boolean remove(Object o) {
4796              if (o != null) {
# Line 4215 | Line 4825 | public class ConcurrentHashMapV8<K, V>
4825              throw new UnsupportedOperationException();
4826          }
4827  
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
4828      }
4829  
4830      /**
4831       * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value)
4832       * entries.  This class cannot be directly instantiated. See
4833 <     * {@link #entrySet}.
4833 >     * {@link #entrySet()}.
4834       */
4835      public static final class EntrySetView<K,V> extends CHMView<K,V>
4836          implements Set<Map.Entry<K,V>> {
4837 <        EntrySetView(ConcurrentHashMapV8<K, V> map) { super(map); }
4837 >        EntrySetView(ConcurrentHashMapV8<K,V> map) { super(map); }
4838          public final boolean contains(Object o) {
4839              Object k, v, r; Map.Entry<?,?> e;
4840              return ((o instanceof Map.Entry) &&
# Line 4385 | Line 4866 | public class ConcurrentHashMapV8<K, V>
4866          }
4867  
4868          public final boolean add(Entry<K,V> e) {
4869 <            K key = e.getKey();
4389 <            V value = e.getValue();
4390 <            if (key == null || value == null)
4391 <                throw new NullPointerException();
4392 <            return map.internalPut(key, value, false) == null;
4869 >            return map.internalPut(e.getKey(), e.getValue(), false) == null;
4870          }
4871          public final boolean addAll(Collection<? extends Entry<K,V>> c) {
4872              boolean added = false;
# Line 4405 | Line 4882 | public class ConcurrentHashMapV8<K, V>
4882                      ((c = (Set<?>)o) == this ||
4883                       (containsAll(c) && c.containsAll(this))));
4884          }
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
4885      }
4886  
4887      // ---------------------------------------------------------------------
# Line 4616 | Line 4963 | public class ConcurrentHashMapV8<K, V>
4963           * @param map the map
4964           * @param transformer a function returning the transformation
4965           * for an element, or null if there is no transformation (in
4966 <         * which case it is not combined).
4966 >         * which case it is not combined)
4967           * @param reducer a commutative associative combining function
4968           * @return the task
4969           */
# Line 4783 | Line 5130 | public class ConcurrentHashMapV8<K, V>
5130           * @param map the map
5131           * @param transformer a function returning the transformation
5132           * for an element, or null if there is no transformation (in
5133 <         * which case it is not combined).
5133 >         * which case it is not combined)
5134           * @param reducer a commutative associative combining function
5135           * @return the task
5136           */
# Line 4949 | Line 5296 | public class ConcurrentHashMapV8<K, V>
5296           * @param map the map
5297           * @param transformer a function returning the transformation
5298           * for an element, or null if there is no transformation (in
5299 <         * which case it is not combined).
5299 >         * which case it is not combined)
5300           * @param reducer a commutative associative combining function
5301           * @return the task
5302           */
# Line 5115 | Line 5462 | public class ConcurrentHashMapV8<K, V>
5462           * @param map the map
5463           * @param transformer a function returning the transformation
5464           * for an element, or null if there is no transformation (in
5465 <         * which case it is not combined).
5465 >         * which case it is not combined)
5466           * @param reducer a commutative associative combining function
5467           * @return the task
5468           */
# Line 5247 | Line 5594 | public class ConcurrentHashMapV8<K, V>
5594              if ((action = this.action) != null) {
5595                  for (int b; (b = preSplit()) > 0;)
5596                      new ForEachValueTask<K,V>(map, this, b, action).fork();
5597 <                Object v;
5597 >                V v;
5598                  while ((v = advance()) != null)
5599 <                    action.apply((V)v);
5599 >                    action.apply(v);
5600                  propagateCompletion();
5601              }
5602          }
# Line 5269 | Line 5616 | public class ConcurrentHashMapV8<K, V>
5616              if ((action = this.action) != null) {
5617                  for (int b; (b = preSplit()) > 0;)
5618                      new ForEachEntryTask<K,V>(map, this, b, action).fork();
5619 <                Object v;
5619 >                V v;
5620                  while ((v = advance()) != null)
5621 <                    action.apply(entryFor((K)nextKey, (V)v));
5621 >                    action.apply(entryFor((K)nextKey, v));
5622                  propagateCompletion();
5623              }
5624          }
# Line 5291 | Line 5638 | public class ConcurrentHashMapV8<K, V>
5638              if ((action = this.action) != null) {
5639                  for (int b; (b = preSplit()) > 0;)
5640                      new ForEachMappingTask<K,V>(map, this, b, action).fork();
5641 <                Object v;
5641 >                V v;
5642                  while ((v = advance()) != null)
5643 <                    action.apply((K)nextKey, (V)v);
5643 >                    action.apply((K)nextKey, v);
5644                  propagateCompletion();
5645              }
5646          }
# Line 5345 | Line 5692 | public class ConcurrentHashMapV8<K, V>
5692                  for (int b; (b = preSplit()) > 0;)
5693                      new ForEachTransformedValueTask<K,V,U>
5694                          (map, this, b, transformer, action).fork();
5695 <                Object v; U u;
5695 >                V v; U u;
5696                  while ((v = advance()) != null) {
5697 <                    if ((u = transformer.apply((V)v)) != null)
5697 >                    if ((u = transformer.apply(v)) != null)
5698                          action.apply(u);
5699                  }
5700                  propagateCompletion();
# Line 5373 | Line 5720 | public class ConcurrentHashMapV8<K, V>
5720                  for (int b; (b = preSplit()) > 0;)
5721                      new ForEachTransformedEntryTask<K,V,U>
5722                          (map, this, b, transformer, action).fork();
5723 <                Object v; U u;
5723 >                V v; U u;
5724                  while ((v = advance()) != null) {
5725                      if ((u = transformer.apply(entryFor((K)nextKey,
5726 <                                                        (V)v))) != null)
5726 >                                                        v))) != null)
5727                          action.apply(u);
5728                  }
5729                  propagateCompletion();
# Line 5403 | Line 5750 | public class ConcurrentHashMapV8<K, V>
5750                  for (int b; (b = preSplit()) > 0;)
5751                      new ForEachTransformedMappingTask<K,V,U>
5752                          (map, this, b, transformer, action).fork();
5753 <                Object v; U u;
5753 >                V v; U u;
5754                  while ((v = advance()) != null) {
5755 <                    if ((u = transformer.apply((K)nextKey, (V)v)) != null)
5755 >                    if ((u = transformer.apply((K)nextKey, v)) != null)
5756                          action.apply(u);
5757                  }
5758                  propagateCompletion();
# Line 5480 | Line 5827 | public class ConcurrentHashMapV8<K, V>
5827                          (map, this, b, searchFunction, result).fork();
5828                  }
5829                  while (result.get() == null) {
5830 <                    Object v; U u;
5830 >                    V v; U u;
5831                      if ((v = advance()) == null) {
5832                          propagateCompletion();
5833                          break;
5834                      }
5835 <                    if ((u = searchFunction.apply((V)v)) != null) {
5835 >                    if ((u = searchFunction.apply(v)) != null) {
5836                          if (result.compareAndSet(null, u))
5837                              quietlyCompleteRoot();
5838                          break;
# Line 5521 | Line 5868 | public class ConcurrentHashMapV8<K, V>
5868                          (map, this, b, searchFunction, result).fork();
5869                  }
5870                  while (result.get() == null) {
5871 <                    Object v; U u;
5871 >                    V v; U u;
5872                      if ((v = advance()) == null) {
5873                          propagateCompletion();
5874                          break;
5875                      }
5876                      if ((u = searchFunction.apply(entryFor((K)nextKey,
5877 <                                                           (V)v))) != null) {
5877 >                                                           v))) != null) {
5878                          if (result.compareAndSet(null, u))
5879                              quietlyCompleteRoot();
5880                          return;
# Line 5563 | Line 5910 | public class ConcurrentHashMapV8<K, V>
5910                          (map, this, b, searchFunction, result).fork();
5911                  }
5912                  while (result.get() == null) {
5913 <                    Object v; U u;
5913 >                    V v; U u;
5914                      if ((v = advance()) == null) {
5915                          propagateCompletion();
5916                          break;
5917                      }
5918 <                    if ((u = searchFunction.apply((K)nextKey, (V)v)) != null) {
5918 >                    if ((u = searchFunction.apply((K)nextKey, v)) != null) {
5919                          if (result.compareAndSet(null, u))
5920                              quietlyCompleteRoot();
5921                          break;
# Line 5640 | Line 5987 | public class ConcurrentHashMapV8<K, V>
5987                      (rights = new ReduceValuesTask<K,V>
5988                       (map, this, b, rights, reducer)).fork();
5989                  V r = null;
5990 <                Object v;
5990 >                V v;
5991                  while ((v = advance()) != null) {
5992 <                    V u = (V)v;
5992 >                    V u = v;
5993                      r = (r == null) ? u : reducer.apply(r, u);
5994                  }
5995                  result = r;
# Line 5683 | Line 6030 | public class ConcurrentHashMapV8<K, V>
6030                      (rights = new ReduceEntriesTask<K,V>
6031                       (map, this, b, rights, reducer)).fork();
6032                  Map.Entry<K,V> r = null;
6033 <                Object v;
6033 >                V v;
6034                  while ((v = advance()) != null) {
6035 <                    Map.Entry<K,V> u = entryFor((K)nextKey, (V)v);
6035 >                    Map.Entry<K,V> u = entryFor((K)nextKey, v);
6036                      r = (r == null) ? u : reducer.apply(r, u);
6037                  }
6038                  result = r;
# Line 5778 | Line 6125 | public class ConcurrentHashMapV8<K, V>
6125                      (rights = new MapReduceValuesTask<K,V,U>
6126                       (map, this, b, rights, transformer, reducer)).fork();
6127                  U r = null, u;
6128 <                Object v;
6128 >                V v;
6129                  while ((v = advance()) != null) {
6130 <                    if ((u = transformer.apply((V)v)) != null)
6130 >                    if ((u = transformer.apply(v)) != null)
6131                          r = (r == null) ? u : reducer.apply(r, u);
6132                  }
6133                  result = r;
# Line 5826 | Line 6173 | public class ConcurrentHashMapV8<K, V>
6173                      (rights = new MapReduceEntriesTask<K,V,U>
6174                       (map, this, b, rights, transformer, reducer)).fork();
6175                  U r = null, u;
6176 <                Object v;
6176 >                V v;
6177                  while ((v = advance()) != null) {
6178                      if ((u = transformer.apply(entryFor((K)nextKey,
6179 <                                                        (V)v))) != null)
6179 >                                                        v))) != null)
6180                          r = (r == null) ? u : reducer.apply(r, u);
6181                  }
6182                  result = r;
# Line 5875 | Line 6222 | public class ConcurrentHashMapV8<K, V>
6222                      (rights = new MapReduceMappingsTask<K,V,U>
6223                       (map, this, b, rights, transformer, reducer)).fork();
6224                  U r = null, u;
6225 <                Object v;
6225 >                V v;
6226                  while ((v = advance()) != null) {
6227 <                    if ((u = transformer.apply((K)nextKey, (V)v)) != null)
6227 >                    if ((u = transformer.apply((K)nextKey, v)) != null)
6228                          r = (r == null) ? u : reducer.apply(r, u);
6229                  }
6230                  result = r;
# Line 5969 | Line 6316 | public class ConcurrentHashMapV8<K, V>
6316                  for (int b; (b = preSplit()) > 0;)
6317                      (rights = new MapReduceValuesToDoubleTask<K,V>
6318                       (map, this, b, rights, transformer, r, reducer)).fork();
6319 <                Object v;
6319 >                V v;
6320                  while ((v = advance()) != null)
6321 <                    r = reducer.apply(r, transformer.apply((V)v));
6321 >                    r = reducer.apply(r, transformer.apply(v));
6322                  result = r;
6323                  CountedCompleter<?> c;
6324                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6014 | Line 6361 | public class ConcurrentHashMapV8<K, V>
6361                  for (int b; (b = preSplit()) > 0;)
6362                      (rights = new MapReduceEntriesToDoubleTask<K,V>
6363                       (map, this, b, rights, transformer, r, reducer)).fork();
6364 <                Object v;
6364 >                V v;
6365                  while ((v = advance()) != null)
6366                      r = reducer.apply(r, transformer.apply(entryFor((K)nextKey,
6367 <                                                                    (V)v)));
6367 >                                                                    v)));
6368                  result = r;
6369                  CountedCompleter<?> c;
6370                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6060 | Line 6407 | public class ConcurrentHashMapV8<K, V>
6407                  for (int b; (b = preSplit()) > 0;)
6408                      (rights = new MapReduceMappingsToDoubleTask<K,V>
6409                       (map, this, b, rights, transformer, r, reducer)).fork();
6410 <                Object v;
6410 >                V v;
6411                  while ((v = advance()) != null)
6412 <                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6412 >                    r = reducer.apply(r, transformer.apply((K)nextKey, v));
6413                  result = r;
6414                  CountedCompleter<?> c;
6415                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6149 | Line 6496 | public class ConcurrentHashMapV8<K, V>
6496                  for (int b; (b = preSplit()) > 0;)
6497                      (rights = new MapReduceValuesToLongTask<K,V>
6498                       (map, this, b, rights, transformer, r, reducer)).fork();
6499 <                Object v;
6499 >                V v;
6500                  while ((v = advance()) != null)
6501 <                    r = reducer.apply(r, transformer.apply((V)v));
6501 >                    r = reducer.apply(r, transformer.apply(v));
6502                  result = r;
6503                  CountedCompleter<?> c;
6504                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6194 | Line 6541 | public class ConcurrentHashMapV8<K, V>
6541                  for (int b; (b = preSplit()) > 0;)
6542                      (rights = new MapReduceEntriesToLongTask<K,V>
6543                       (map, this, b, rights, transformer, r, reducer)).fork();
6544 <                Object v;
6544 >                V v;
6545                  while ((v = advance()) != null)
6546                      r = reducer.apply(r, transformer.apply(entryFor((K)nextKey,
6547 <                                                                    (V)v)));
6547 >                                                                    v)));
6548                  result = r;
6549                  CountedCompleter<?> c;
6550                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6240 | Line 6587 | public class ConcurrentHashMapV8<K, V>
6587                  for (int b; (b = preSplit()) > 0;)
6588                      (rights = new MapReduceMappingsToLongTask<K,V>
6589                       (map, this, b, rights, transformer, r, reducer)).fork();
6590 <                Object v;
6590 >                V v;
6591                  while ((v = advance()) != null)
6592 <                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6592 >                    r = reducer.apply(r, transformer.apply((K)nextKey, v));
6593                  result = r;
6594                  CountedCompleter<?> c;
6595                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6329 | Line 6676 | public class ConcurrentHashMapV8<K, V>
6676                  for (int b; (b = preSplit()) > 0;)
6677                      (rights = new MapReduceValuesToIntTask<K,V>
6678                       (map, this, b, rights, transformer, r, reducer)).fork();
6679 <                Object v;
6679 >                V v;
6680                  while ((v = advance()) != null)
6681 <                    r = reducer.apply(r, transformer.apply((V)v));
6681 >                    r = reducer.apply(r, transformer.apply(v));
6682                  result = r;
6683                  CountedCompleter<?> c;
6684                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6374 | Line 6721 | public class ConcurrentHashMapV8<K, V>
6721                  for (int b; (b = preSplit()) > 0;)
6722                      (rights = new MapReduceEntriesToIntTask<K,V>
6723                       (map, this, b, rights, transformer, r, reducer)).fork();
6724 <                Object v;
6724 >                V v;
6725                  while ((v = advance()) != null)
6726                      r = reducer.apply(r, transformer.apply(entryFor((K)nextKey,
6727 <                                                                    (V)v)));
6727 >                                                                    v)));
6728                  result = r;
6729                  CountedCompleter<?> c;
6730                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6420 | Line 6767 | public class ConcurrentHashMapV8<K, V>
6767                  for (int b; (b = preSplit()) > 0;)
6768                      (rights = new MapReduceMappingsToIntTask<K,V>
6769                       (map, this, b, rights, transformer, r, reducer)).fork();
6770 <                Object v;
6770 >                V v;
6771                  while ((v = advance()) != null)
6772 <                    r = reducer.apply(r, transformer.apply((K)nextKey, (V)v));
6772 >                    r = reducer.apply(r, transformer.apply((K)nextKey, v));
6773                  result = r;
6774                  CountedCompleter<?> c;
6775                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
# Line 6450 | Line 6797 | public class ConcurrentHashMapV8<K, V>
6797      private static final int ASHIFT;
6798  
6799      static {
6453        int ss;
6800          try {
6801              U = getUnsafe();
6802              Class<?> k = ConcurrentHashMapV8.class;
# Line 6467 | Line 6813 | public class ConcurrentHashMapV8<K, V>
6813              Class<?> ck = CounterCell.class;
6814              CELLVALUE = U.objectFieldOffset
6815                  (ck.getDeclaredField("value"));
6816 <            Class<?> sc = Node[].class;
6817 <            ABASE = U.arrayBaseOffset(sc);
6818 <            ss = U.arrayIndexScale(sc);
6819 <            ASHIFT = 31 - Integer.numberOfLeadingZeros(ss);
6816 >            Class<?> ak = Node[].class;
6817 >            ABASE = U.arrayBaseOffset(ak);
6818 >            int scale = U.arrayIndexScale(ak);
6819 >            if ((scale & (scale - 1)) != 0)
6820 >                throw new Error("data type scale not a power of two");
6821 >            ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
6822          } catch (Exception e) {
6823              throw new Error(e);
6824          }
6477        if ((ss & (ss-1)) != 0)
6478            throw new Error("data type scale not a power of two");
6825      }
6826  
6827      /**
# Line 6488 | Line 6834 | public class ConcurrentHashMapV8<K, V>
6834      private static sun.misc.Unsafe getUnsafe() {
6835          try {
6836              return sun.misc.Unsafe.getUnsafe();
6837 <        } catch (SecurityException se) {
6838 <            try {
6839 <                return java.security.AccessController.doPrivileged
6840 <                    (new java.security
6841 <                     .PrivilegedExceptionAction<sun.misc.Unsafe>() {
6842 <                        public sun.misc.Unsafe run() throws Exception {
6843 <                            java.lang.reflect.Field f = sun.misc
6844 <                                .Unsafe.class.getDeclaredField("theUnsafe");
6845 <                            f.setAccessible(true);
6846 <                            return (sun.misc.Unsafe) f.get(null);
6847 <                        }});
6848 <            } catch (java.security.PrivilegedActionException e) {
6849 <                throw new RuntimeException("Could not initialize intrinsics",
6850 <                                           e.getCause());
6851 <            }
6837 >        } catch (SecurityException tryReflectionInstead) {}
6838 >        try {
6839 >            return java.security.AccessController.doPrivileged
6840 >            (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
6841 >                public sun.misc.Unsafe run() throws Exception {
6842 >                    Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
6843 >                    for (java.lang.reflect.Field f : k.getDeclaredFields()) {
6844 >                        f.setAccessible(true);
6845 >                        Object x = f.get(null);
6846 >                        if (k.isInstance(x))
6847 >                            return k.cast(x);
6848 >                    }
6849 >                    throw new NoSuchFieldError("the Unsafe");
6850 >                }});
6851 >        } catch (java.security.PrivilegedActionException e) {
6852 >            throw new RuntimeException("Could not initialize intrinsics",
6853 >                                       e.getCause());
6854          }
6855      }
6856   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines