--- jsr166/src/jsr166e/ConcurrentHashMapV8.java 2013/06/19 17:11:57 1.106 +++ jsr166/src/jsr166e/ConcurrentHashMapV8.java 2013/07/03 18:16:31 1.109 @@ -299,7 +299,7 @@ public class ConcurrentHashMapV8 * because they have negative hash fields and null key and value * fields. (These special nodes are either uncommon or transient, * so the impact of carrying around some unused fields is - * insignficant.) + * insignificant.) * * The table is lazily initialized to a power-of-two size upon the * first insertion. Each bin in the table normally contains a @@ -462,7 +462,7 @@ public class ConcurrentHashMapV8 * * TreeBins also require an additional locking mechanism. While * list traversal is always possible by readers even during - * updates, tree traversal is not, mainly beause of tree-rotations + * updates, tree traversal is not, mainly because of tree-rotations * that may change the root node and/or its linkages. TreeBins * include a simple read-write lock mechanism parasitic on the * main bin-synchronization strategy: Structural adjustments @@ -568,9 +568,9 @@ public class ConcurrentHashMapV8 /* * Encodings for Node hash fields. See above for explanation. */ - static final int MOVED = 0x8fffffff; // (-1) hash for forwarding nodes - static final int TREEBIN = 0x80000000; // hash for heads of treea - static final int RESERVED = 0x80000001; // hash for transient reservations + static final int MOVED = -1; // hash for forwarding nodes + static final int TREEBIN = -2; // hash for roots of trees + static final int RESERVED = -3; // hash for transient reservations static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash /** Number of CPUS, to place bounds on some sizings */ @@ -589,7 +589,7 @@ public class ConcurrentHashMapV8 * Key-value entry. This class is never exported out as a * user-mutable Map.Entry (i.e., one supporting setValue; see * MapEntry below), but can be used for read-only traversals used - * in bulk tasks. Subclasses of Node with a negativehash field + * in bulk tasks. Subclasses of Node with a negative hash field * are special, and contain null keys and values (but are never * exported). Otherwise, keys and vals are never null. */ @@ -597,7 +597,7 @@ public class ConcurrentHashMapV8 final int hash; final K key; volatile V val; - Node next; + volatile Node next; Node(int hash, K key, V val, Node next) { this.hash = hash; @@ -722,8 +722,9 @@ public class ConcurrentHashMapV8 * errors by users, these checks must operate on local variables, * which accounts for some odd-looking inline assignments below. * Note that calls to setTabAt always occur within locked regions, - * and so do not need full volatile semantics, but still require - * ordering to maintain concurrent readability. + * and so in principle require only release ordering, not need + * full volatile semantics, but are currently coded as volatile + * writes to be conservative. */ @SuppressWarnings("unchecked") @@ -737,7 +738,7 @@ public class ConcurrentHashMapV8 } static final void setTabAt(Node[] tab, int i, Node v) { - U.putOrderedObject(tab, ((long)i << ASHIFT) + ABASE, v); + U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v); } /* ---------------- Fields -------------- */ @@ -2395,6 +2396,10 @@ public class ConcurrentHashMapV8 else hn = new Node(ph, pk, pv, hn); } + setTabAt(nextTab, i, ln); + setTabAt(nextTab, i + n, hn); + setTabAt(tab, i, fwd); + advance = true; } else if (f instanceof TreeBin) { TreeBin t = (TreeBin)f; @@ -2426,13 +2431,11 @@ public class ConcurrentHashMapV8 (hc != 0) ? new TreeBin(lo) : t; hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) : (lc != 0) ? new TreeBin(hi) : t; + setTabAt(nextTab, i, ln); + setTabAt(nextTab, i + n, hn); + setTabAt(tab, i, fwd); + advance = true; } - else - ln = hn = null; - setTabAt(nextTab, i, ln); - setTabAt(nextTab, i + n, hn); - setTabAt(tab, i, fwd); - advance = true; } } } @@ -2453,7 +2456,7 @@ public class ConcurrentHashMapV8 U.compareAndSwapInt(this, SIZECTL, sc, -2)) transfer(tab, null); } - else if ((b = tabAt(tab, index)) != null) { + else if ((b = tabAt(tab, index)) != null && b.hash >= 0) { synchronized (b) { if (tabAt(tab, index) == b) { TreeNode hd = null, tl = null; @@ -2653,7 +2656,7 @@ public class ConcurrentHashMapV8 /** * Returns matching node or null if none. Tries to search - * using tree compareisons from root, but continues linear + * using tree comparisons from root, but continues linear * search when lock not available. */ final Node find(int h, Object k) { @@ -3498,10 +3501,10 @@ public class ConcurrentHashMapV8 * of all (key, value) pairs * @since 1.8 */ - public double reduceToDoubleIn(long parallelismThreshold, - ObjectByObjectToDouble transformer, - double basis, - DoubleByDoubleToDouble reducer) { + public double reduceToDouble(long parallelismThreshold, + ObjectByObjectToDouble transformer, + double basis, + DoubleByDoubleToDouble reducer) { if (transformer == null || reducer == null) throw new NullPointerException(); return new MapReduceMappingsToDoubleTask