ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java (file contents):
Revision 1.159 by jsr166, Sun Jan 6 20:05:51 2013 UTC vs.
Revision 1.160 by dl, Thu Jan 10 15:03:25 2013 UTC

# Line 479 | Line 479 | public class ConcurrentHashMap<K, V>
479          Cell(long x) { value = x; }
480      }
481  
482    /**
483     * Holder for the thread-local hash code determining which
484     * Cell to use. The code is initialized via the
485     * cellHashCodeGenerator, but may be moved upon collisions.
486     */
487    static final class CellHashCode {
488        int code;
489    }
490
491    /**
492     * Generates initial value for per-thread CellHashCodes
493     */
494    static final AtomicInteger cellHashCodeGenerator = new AtomicInteger();
495
496    /**
497     * Increment for cellHashCodeGenerator. See class ThreadLocal
498     * for explanation.
499     */
500    static final int SEED_INCREMENT = 0x61c88647;
501
502    /**
503     * Per-thread counter hash codes. Shared across all instances.
504     */
505    static final ThreadLocal<CellHashCode> threadCellHashCode =
506        new ThreadLocal<CellHashCode>();
507
482      /* ---------------- Fields -------------- */
483  
484      /**
# Line 1843 | Line 1817 | public class ConcurrentHashMap<K, V>
1817          Cell[] as; long b, s;
1818          if ((as = counterCells) != null ||
1819              !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) {
1820 <            CellHashCode hc; Cell a; long v; int m;
1820 >            Cell a; long v; int m;
1821              boolean uncontended = true;
1822 <            if ((hc = threadCellHashCode.get()) == null ||
1823 <                as == null || (m = as.length - 1) < 0 ||
1850 <                (a = as[m & hc.code]) == null ||
1822 >            if (as == null || (m = as.length - 1) < 0 ||
1823 >                (a = as[ThreadLocalRandom.getProbe() & m]) == null ||
1824                  !(uncontended =
1825                    U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) {
1826 <                fullAddCount(x, hc, uncontended);
1826 >                fullAddCount(x, uncontended);
1827                  return;
1828              }
1829              if (check <= 1)
# Line 2073 | Line 2046 | public class ConcurrentHashMap<K, V>
2046      }
2047  
2048      // See LongAdder version for explanation
2049 <    private final void fullAddCount(long x, CellHashCode hc,
2077 <                                    boolean wasUncontended) {
2049 >    private final void fullAddCount(long x, boolean wasUncontended) {
2050          int h;
2051 <        if (hc == null) {
2052 <            hc = new CellHashCode();
2053 <            int s = cellHashCodeGenerator.addAndGet(SEED_INCREMENT);
2054 <            h = hc.code = (s == 0) ? 1 : s; // Avoid zero
2083 <            threadCellHashCode.set(hc);
2051 >        if ((h = ThreadLocalRandom.getProbe()) == 0) {
2052 >            ThreadLocalRandom.localInit();      // force initialization
2053 >            h = ThreadLocalRandom.getProbe();
2054 >            wasUncontended = true;
2055          }
2085        else
2086            h = hc.code;
2056          boolean collide = false;                // True if last slot nonempty
2057          for (;;) {
2058              Cell[] as; Cell a; int n; long v;
# Line 2135 | Line 2104 | public class ConcurrentHashMap<K, V>
2104                      collide = false;
2105                      continue;                   // Retry with expanded table
2106                  }
2107 <                h ^= h << 13;                   // Rehash
2139 <                h ^= h >>> 17;
2140 <                h ^= h << 5;
2107 >                h = ThreadLocalRandom.advanceProbe(h);
2108              }
2109              else if (cellsBusy == 0 && counterCells == as &&
2110                       U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
# Line 2158 | Line 2125 | public class ConcurrentHashMap<K, V>
2125              else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x))
2126                  break;                          // Fall back on using base
2127          }
2161        hc.code = h;                            // Record index for next time
2128      }
2129  
2130      /* ----------------Table Traversal -------------- */
# Line 2359 | Line 2325 | public class ConcurrentHashMap<K, V>
2325  
2326          // spliterator support
2327  
2328 <        public long exactSizeIfKnown() {
2329 <            return -1;
2328 >        public boolean hasExactSize() {
2329 >            return false;
2330          }
2331  
2332          public boolean hasExactSplits() {
# Line 2981 | Line 2947 | public class ConcurrentHashMap<K, V>
2947  
2948          public final K nextElement() { return next(); }
2949  
2950 <        public Iterator<K> iterator() { return this; }
2950 >        public Iterator<K> asIterator() { return this; }
2951  
2952          public void forEach(Block<? super K> action) {
2953              if (action == null) throw new NullPointerException();
2954              while (advance() != null)
2955                  action.accept((K)nextKey);
2956          }
2957 +
2958 +        public boolean tryAdvance(Block<? super K> block) {
2959 +            if (block == null) throw new NullPointerException();
2960 +            if (advance() == null)
2961 +                return false;
2962 +            block.accept((K)nextKey);
2963 +            return true;
2964 +        }
2965      }
2966  
2967      @SuppressWarnings("serial") static final class ValueIterator<K,V>
# Line 3013 | Line 2987 | public class ConcurrentHashMap<K, V>
2987  
2988          public final V nextElement() { return next(); }
2989  
2990 <        public Iterator<V> iterator() { return this; }
2990 >        public Iterator<V> asIterator() { return this; }
2991  
2992          public void forEach(Block<? super V> action) {
2993              if (action == null) throw new NullPointerException();
# Line 3021 | Line 2995 | public class ConcurrentHashMap<K, V>
2995              while ((v = advance()) != null)
2996                  action.accept(v);
2997          }
2998 +
2999 +        public boolean tryAdvance(Block<? super V> block) {
3000 +            V v;
3001 +            if (block == null) throw new NullPointerException();
3002 +            if ((v = advance()) == null)
3003 +                return false;
3004 +            block.accept(v);
3005 +            return true;
3006 +        }
3007 +    
3008      }
3009  
3010      @SuppressWarnings("serial") static final class EntryIterator<K,V>
# Line 3045 | Line 3029 | public class ConcurrentHashMap<K, V>
3029              return new MapEntry<K,V>((K)k, v, map);
3030          }
3031  
3032 <        public Iterator<Map.Entry<K,V>> iterator() { return this; }
3032 >        public Iterator<Map.Entry<K,V>> asIterator() { return this; }
3033  
3034          public void forEach(Block<? super Map.Entry<K,V>> action) {
3035              if (action == null) throw new NullPointerException();
# Line 3053 | Line 3037 | public class ConcurrentHashMap<K, V>
3037              while ((v = advance()) != null)
3038                  action.accept(entryFor((K)nextKey, v));
3039          }
3040 +
3041 +        public boolean tryAdvance(Block<? super Map.Entry<K,V>> block) {
3042 +            V v;
3043 +            if (block == null) throw new NullPointerException();
3044 +            if ((v = advance()) == null)
3045 +                return false;
3046 +            block.accept(entryFor((K)nextKey, v));
3047 +            return true;
3048 +        }
3049 +
3050      }
3051  
3052      /**

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines