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.245 by jsr166, Fri Aug 23 20:12:21 2013 UTC vs.
Revision 1.246 by dl, Sat Aug 31 19:41:39 2013 UTC

# Line 349 | Line 349 | public class ConcurrentHashMap<K,V> exte
349       * proceed with insertions etc.  The use of TreeBins shields us
350       * from the worst case effects of overfilling while resizes are in
351       * progress.  Resizing proceeds by transferring bins, one by one,
352 <     * from the table to the next table. To enable concurrency, the
353 <     * next table must be (incrementally) prefilled with place-holders
354 <     * serving as reverse forwarders to the old table.  Because we are
355 <     * using power-of-two expansion, the elements from each bin must
356 <     * either stay at same index, or move with a power of two
357 <     * offset. We eliminate unnecessary node creation by catching
358 <     * cases where old nodes can be reused because their next fields
359 <     * won't change.  On average, only about one-sixth of them need
360 <     * cloning when a table doubles. The nodes they replace will be
361 <     * garbage collectable as soon as they are no longer referenced by
362 <     * any reader thread that may be in the midst of concurrently
363 <     * traversing table.  Upon transfer, the old table bin contains
364 <     * only a special forwarding node (with hash field "MOVED") that
365 <     * contains the next table as its key. On encountering a
366 <     * forwarding node, access and update operations restart, using
367 <     * the new table.
352 >     * from the table to the next table. However, threads claim small
353 >     * blocks of indices to transfer (via field transferIndex) before
354 >     * doing so, reducing contention.  Because we are using
355 >     * power-of-two expansion, the elements from each bin must either
356 >     * stay at same index, or move with a power of two offset. We
357 >     * eliminate unnecessary node creation by catching cases where old
358 >     * nodes can be reused because their next fields won't change.  On
359 >     * average, only about one-sixth of them need cloning when a table
360 >     * doubles. The nodes they replace will be garbage collectable as
361 >     * soon as they are no longer referenced by any reader thread that
362 >     * may be in the midst of concurrently traversing table.  Upon
363 >     * transfer, the old table bin contains only a special forwarding
364 >     * node (with hash field "MOVED") that contains the next table as
365 >     * its key. On encountering a forwarding node, access and update
366 >     * operations restart, using the new table.
367       *
368       * Each bin transfer requires its bin lock, which can stall
369       * waiting for locks while resizing. However, because other
# Line 372 | Line 371 | public class ConcurrentHashMap<K,V> exte
371       * locks, average aggregate waits become shorter as resizing
372       * progresses.  The transfer operation must also ensure that all
373       * accessible bins in both the old and new table are usable by any
374 <     * traversal.  This is arranged by proceeding from the last bin
375 <     * (table.length - 1) up towards the first.  Upon seeing a
376 <     * forwarding node, traversals (see class Traverser) arrange to
377 <     * move to the new table without revisiting nodes.  However, to
378 <     * ensure that no intervening nodes are skipped, bin splitting can
379 <     * only begin after the associated reverse-forwarders are in
380 <     * place.
374 >     * traversal.  This is arranged in part by proceeding from the
375 >     * last bin (table.length - 1) up towards the first.  Upon seeing
376 >     * a forwarding node, traversals (see class Traverser) arrange to
377 >     * move to the new table without revisiting nodes.  To ensure that
378 >     * no intervening nodes are skipped even when moved out of order,
379 >     * a stack (see class TableStack) is created on first encounter of
380 >     * a forwarding node during a traversal, to maintain its place if
381 >     * later processing the current table. The need for these
382 >     * save/restore mechanics is relatively rare, but when one
383 >     * forwwarding node is encountered, typically many more will be.
384 >     * So Traversers use a simple caching scheme to avoid creating so
385 >     * many new TableStack nodes. (Thanks to Peter Levart for
386 >     * suggesting use of a stack here.)
387       *
388       * The traversal scheme also applies to partial traversals of
389       * ranges of bins (via an alternate Traverser constructor)
# Line 747 | Line 752 | public class ConcurrentHashMap<K,V> exte
752      private transient volatile int transferIndex;
753  
754      /**
750     * The least available table index to split while resizing.
751     */
752    private transient volatile int transferOrigin;
753
754    /**
755       * Spinlock (locked via CAS) used when resizing and/or creating CounterCells.
756       */
757      private transient volatile int cellsBusy;
# Line 1347 | Line 1347 | public class ConcurrentHashMap<K,V> exte
1347          }
1348          int segmentShift = 32 - sshift;
1349          int segmentMask = ssize - 1;
1350 <        @SuppressWarnings("unchecked") Segment<K,V>[] segments = (Segment<K,V>[])
1350 >        @SuppressWarnings("unchecked")
1351 >        Segment<K,V>[] segments = (Segment<K,V>[])
1352              new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL];
1353          for (int i = 0; i < segments.length; ++i)
1354              segments[i] = new Segment<K,V>(LOAD_FACTOR);
# Line 1390 | Line 1391 | public class ConcurrentHashMap<K,V> exte
1391          long size = 0L;
1392          Node<K,V> p = null;
1393          for (;;) {
1394 <            @SuppressWarnings("unchecked") K k = (K) s.readObject();
1395 <            @SuppressWarnings("unchecked") V v = (V) s.readObject();
1394 >            @SuppressWarnings("unchecked")
1395 >            K k = (K) s.readObject();
1396 >            @SuppressWarnings("unchecked")
1397 >            V v = (V) s.readObject();
1398              if (k != null && v != null) {
1399                  p = new Node<K,V>(spread(k.hashCode()), k, v, p);
1400                  ++size;
# Line 1410 | Line 1413 | public class ConcurrentHashMap<K,V> exte
1413                  n = tableSizeFor(sz + (sz >>> 1) + 1);
1414              }
1415              @SuppressWarnings("unchecked")
1416 <                Node<K,V>[] tab = (Node<K,V>[])new Node<?,?>[n];
1416 >            Node<K,V>[] tab = (Node<K,V>[])new Node<?,?>[n];
1417              int mask = n - 1;
1418              long added = 0L;
1419              while (p != null) {
# Line 2012 | Line 2015 | public class ConcurrentHashMap<K,V> exte
2015       *         {@code false} otherwise
2016       * @throws NullPointerException if the specified value is null
2017       */
2018 <    @Deprecated public boolean contains(Object value) {
2018 >    @Deprecated
2019 >    public boolean contains(Object value) {
2020          return containsValue(value);
2021      }
2022  
# Line 2171 | Line 2175 | public class ConcurrentHashMap<K,V> exte
2175                      if ((tab = table) == null || tab.length == 0) {
2176                          int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
2177                          @SuppressWarnings("unchecked")
2178 <                            Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
2178 >                        Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
2179                          table = tab = nt;
2180                          sc = n - (n >>> 2);
2181                      }
# Line 2216 | Line 2220 | public class ConcurrentHashMap<K,V> exte
2220              while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
2221                     tab.length < MAXIMUM_CAPACITY) {
2222                  if (sc < 0) {
2223 <                    if (sc == -1 || transferIndex <= transferOrigin ||
2223 >                    if (sc == -1 || transferIndex <= 0 ||
2224                          (nt = nextTable) == null)
2225                          break;
2226                      if (U.compareAndSwapInt(this, SIZECTL, sc, sc - 1))
# Line 2236 | Line 2240 | public class ConcurrentHashMap<K,V> exte
2240          Node<K,V>[] nextTab; int sc;
2241          if ((f instanceof ForwardingNode) &&
2242              (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
2243 <            if (nextTab == nextTable && tab == table &&
2244 <                transferIndex > transferOrigin && (sc = sizeCtl) < -1 &&
2245 <                U.compareAndSwapInt(this, SIZECTL, sc, sc - 1))
2246 <                transfer(tab, nextTab);
2243 >            while (transferIndex > 0 && nextTab == nextTable &&
2244 >                   (sc = sizeCtl) < -1) {
2245 >                if (U.compareAndSwapInt(this, SIZECTL, sc, sc - 1)) {
2246 >                    transfer(tab, nextTab);
2247 >                    break;
2248 >                }
2249 >            }
2250              return nextTab;
2251          }
2252          return table;
# Line 2262 | Line 2269 | public class ConcurrentHashMap<K,V> exte
2269                      try {
2270                          if (table == tab) {
2271                              @SuppressWarnings("unchecked")
2272 <                                Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
2272 >                            Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
2273                              table = nt;
2274                              sc = n - (n >>> 2);
2275                          }
# Line 2290 | Line 2297 | public class ConcurrentHashMap<K,V> exte
2297          if (nextTab == null) {            // initiating
2298              try {
2299                  @SuppressWarnings("unchecked")
2300 <                    Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1];
2300 >                Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1];
2301                  nextTab = nt;
2302              } catch (Throwable ex) {      // try to cope with OOME
2303                  sizeCtl = Integer.MAX_VALUE;
2304                  return;
2305              }
2306              nextTable = nextTab;
2300            transferOrigin = n;
2307              transferIndex = n;
2302            ForwardingNode<K,V> rev = new ForwardingNode<K,V>(tab);
2303            for (int k = n; k > 0;) {    // progressively reveal ready slots
2304                int nextk = (k > stride) ? k - stride : 0;
2305                for (int m = nextk; m < k; ++m)
2306                    nextTab[m] = rev;
2307                for (int m = n + nextk; m < n + k; ++m)
2308                    nextTab[m] = rev;
2309                U.putOrderedInt(this, TRANSFERORIGIN, k = nextk);
2310            }
2308          }
2309          int nextn = nextTab.length;
2310          ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab);
2311          boolean advance = true;
2312          boolean finishing = false; // to ensure sweep before committing nextTab
2313          for (int i = 0, bound = 0;;) {
2314 <            int nextIndex, nextBound, fh; Node<K,V> f;
2314 >            Node<K,V> f; int fh;
2315              while (advance) {
2316 +                int nextIndex, nextBound;
2317                  if (--i >= bound || finishing)
2318                      advance = false;
2319 <                else if ((nextIndex = transferIndex) <= transferOrigin) {
2319 >                else if ((nextIndex = transferIndex) <= 0) {
2320                      i = -1;
2321                      advance = false;
2322                  }
# Line 2332 | Line 2330 | public class ConcurrentHashMap<K,V> exte
2330                  }
2331              }
2332              if (i < 0 || i >= n || i + n >= nextn) {
2333 +                int sc;
2334                  if (finishing) {
2335                      nextTable = null;
2336                      table = nextTab;
2337                      sizeCtl = (n << 1) - (n >>> 1);
2338                      return;
2339                  }
2340 <                for (int sc;;) {
2341 <                    if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) {
2342 <                        if (sc != -1)
2343 <                            return;
2344 <                        finishing = advance = true;
2346 <                        i = n; // recheck before commit
2347 <                        break;
2348 <                    }
2349 <                }
2350 <            }
2351 <            else if ((f = tabAt(tab, i)) == null) {
2352 <                if (casTabAt(tab, i, null, fwd)) {
2353 <                    setTabAt(nextTab, i, null);
2354 <                    setTabAt(nextTab, i + n, null);
2355 <                    advance = true;
2340 >                if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) {
2341 >                    if (sc != -1)
2342 >                        return;
2343 >                    finishing = advance = true;
2344 >                    i = n; // recheck before commit
2345                  }
2346              }
2347 +            else if ((f = tabAt(tab, i)) == null)
2348 +                advance = casTabAt(tab, i, null, fwd);
2349              else if ((fh = f.hash) == MOVED)
2350                  advance = true; // already processed
2351              else {
# Line 3193 | Line 3184 | public class ConcurrentHashMap<K,V> exte
3184  
3185      /* ----------------Table Traversal -------------- */
3186  
3187 +   /**
3188 +    * Records the table, its length, and current traversal index for a
3189 +    * traverser that must process a region of a forwarded table before
3190 +    * proceeding with current table.
3191 +    */
3192 +    final static class TableStack<K,V> {
3193 +        int length;
3194 +        int index;
3195 +        Node<K,V>[] tab;
3196 +        TableStack<K, V> next;
3197 +    }
3198 +
3199      /**
3200       * Encapsulates traversal for methods such as containsValue; also
3201       * serves as a base class for other iterators and spliterators.
# Line 3217 | Line 3220 | public class ConcurrentHashMap<K,V> exte
3220      static class Traverser<K,V> {
3221          Node<K,V>[] tab;        // current table; updated if resized
3222          Node<K,V> next;         // the next entry to use
3223 +        TableStack<K,V> stack, spare; // to save/restore on ForwardingNodes
3224          int index;              // index of bin to use next
3225          int baseIndex;          // current index of initial table
3226          int baseLimit;          // index bound for initial table
# Line 3238 | Line 3242 | public class ConcurrentHashMap<K,V> exte
3242              if ((e = next) != null)
3243                  e = e.next;
3244              for (;;) {
3245 <                Node<K,V>[] t; int i, n; K ek;  // must use locals in checks
3245 >                Node<K,V>[] t; int i, n;  // must use locals in checks
3246                  if (e != null)
3247                      return next = e;
3248                  if (baseIndex >= baseLimit || (t = tab) == null ||
3249                      (n = t.length) <= (i = index) || i < 0)
3250                      return next = null;
3251 <                if ((e = tabAt(t, index)) != null && e.hash < 0) {
3251 >                if ((e = tabAt(t, i)) != null && e.hash < 0) {
3252                      if (e instanceof ForwardingNode) {
3253                          tab = ((ForwardingNode<K,V>)e).nextTable;
3254                          e = null;
3255 +                        pushState(t, i, n);
3256                          continue;
3257                      }
3258                      else if (e instanceof TreeBin)
# Line 3255 | Line 3260 | public class ConcurrentHashMap<K,V> exte
3260                      else
3261                          e = null;
3262                  }
3263 <                if ((index += baseSize) >= n)
3264 <                    index = ++baseIndex;    // visit upper slots if present
3263 >                if (stack != null)
3264 >                    recoverState(n);
3265 >                else if ((index = i + baseSize) >= n)
3266 >                    index = ++baseIndex; // visit upper slots if present
3267              }
3268          }
3269 +
3270 +        /**
3271 +         * Save traversal state upon encountering a forwarding node.
3272 +         */
3273 +        private void pushState(Node<K,V>[] t, int i, int n) {
3274 +            TableStack<K,V> s = spare;  // reuse if possible
3275 +            if (s != null)
3276 +                spare = s.next;
3277 +            else
3278 +                s = new TableStack<K,V>();
3279 +            s.tab = t;
3280 +            s.length = n;
3281 +            s.index = i;
3282 +            s.next = stack;
3283 +            stack = s;
3284 +        }
3285 +
3286 +        /**
3287 +         * Possibly pop traversal state
3288 +         *
3289 +         * @param n length of current table
3290 +         */
3291 +        private void recoverState(int n) {
3292 +            TableStack<K,V> s; int len;
3293 +            while ((s = stack) != null && (index += (len = s.length)) >= n) {
3294 +                n = len;
3295 +                index = s.index;
3296 +                tab = s.tab;
3297 +                s.tab = null;
3298 +                TableStack<K,V> next = s.next;
3299 +                s.next = spare; // save for reuse
3300 +                stack = next;
3301 +                spare = s;
3302 +            }
3303 +            if (s == null && (index += baseSize) >= n)
3304 +                index = ++baseIndex;
3305 +        }
3306      }
3307  
3308      /**
# Line 4690 | Line 4734 | public class ConcurrentHashMap<K,V> exte
4734      abstract static class BulkTask<K,V,R> extends CountedCompleter<R> {
4735          Node<K,V>[] tab;        // same as Traverser
4736          Node<K,V> next;
4737 +        TableStack<K,V> stack, spare;
4738          int index;
4739          int baseIndex;
4740          int baseLimit;
# Line 4718 | Line 4763 | public class ConcurrentHashMap<K,V> exte
4763              if ((e = next) != null)
4764                  e = e.next;
4765              for (;;) {
4766 <                Node<K,V>[] t; int i, n; K ek;  // must use locals in checks
4766 >                Node<K,V>[] t; int i, n;
4767                  if (e != null)
4768                      return next = e;
4769                  if (baseIndex >= baseLimit || (t = tab) == null ||
4770                      (n = t.length) <= (i = index) || i < 0)
4771                      return next = null;
4772 <                if ((e = tabAt(t, index)) != null && e.hash < 0) {
4772 >                if ((e = tabAt(t, i)) != null && e.hash < 0) {
4773                      if (e instanceof ForwardingNode) {
4774                          tab = ((ForwardingNode<K,V>)e).nextTable;
4775                          e = null;
4776 +                        pushState(t, i, n);
4777                          continue;
4778                      }
4779                      else if (e instanceof TreeBin)
# Line 4735 | Line 4781 | public class ConcurrentHashMap<K,V> exte
4781                      else
4782                          e = null;
4783                  }
4784 <                if ((index += baseSize) >= n)
4785 <                    index = ++baseIndex;    // visit upper slots if present
4784 >                if (stack != null)
4785 >                    recoverState(n);
4786 >                else if ((index = i + baseSize) >= n)
4787 >                    index = ++baseIndex;
4788 >            }
4789 >        }
4790 >
4791 >        private void pushState(Node<K,V>[] t, int i, int n) {
4792 >            TableStack<K,V> s = spare;
4793 >            if (s != null)
4794 >                spare = s.next;
4795 >            else
4796 >                s = new TableStack<K,V>();
4797 >            s.tab = t;
4798 >            s.length = n;
4799 >            s.index = i;
4800 >            s.next = stack;
4801 >            stack = s;
4802 >        }
4803 >
4804 >        private void recoverState(int n) {
4805 >            TableStack<K,V> s; int len;
4806 >            while ((s = stack) != null && (index += (len = s.length)) >= n) {
4807 >                n = len;
4808 >                index = s.index;
4809 >                tab = s.tab;
4810 >                s.tab = null;
4811 >                TableStack<K,V> next = s.next;
4812 >                s.next = spare; // save for reuse
4813 >                stack = next;
4814 >                spare = s;
4815              }
4816 +            if (s == null && (index += baseSize) >= n)
4817 +                index = ++baseIndex;
4818          }
4819      }
4820  
# Line 5197 | Line 5274 | public class ConcurrentHashMap<K,V> exte
5274                  result = r;
5275                  CountedCompleter<?> c;
5276                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5277 <                    @SuppressWarnings("unchecked") ReduceKeysTask<K,V>
5277 >                    @SuppressWarnings("unchecked")
5278 >                    ReduceKeysTask<K,V>
5279                          t = (ReduceKeysTask<K,V>)c,
5280                          s = t.rights;
5281                      while (s != null) {
# Line 5244 | Line 5322 | public class ConcurrentHashMap<K,V> exte
5322                  result = r;
5323                  CountedCompleter<?> c;
5324                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5325 <                    @SuppressWarnings("unchecked") ReduceValuesTask<K,V>
5325 >                    @SuppressWarnings("unchecked")
5326 >                    ReduceValuesTask<K,V>
5327                          t = (ReduceValuesTask<K,V>)c,
5328                          s = t.rights;
5329                      while (s != null) {
# Line 5289 | Line 5368 | public class ConcurrentHashMap<K,V> exte
5368                  result = r;
5369                  CountedCompleter<?> c;
5370                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5371 <                    @SuppressWarnings("unchecked") ReduceEntriesTask<K,V>
5371 >                    @SuppressWarnings("unchecked")
5372 >                    ReduceEntriesTask<K,V>
5373                          t = (ReduceEntriesTask<K,V>)c,
5374                          s = t.rights;
5375                      while (s != null) {
# Line 5342 | Line 5422 | public class ConcurrentHashMap<K,V> exte
5422                  result = r;
5423                  CountedCompleter<?> c;
5424                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5425 <                    @SuppressWarnings("unchecked") MapReduceKeysTask<K,V,U>
5425 >                    @SuppressWarnings("unchecked")
5426 >                    MapReduceKeysTask<K,V,U>
5427                          t = (MapReduceKeysTask<K,V,U>)c,
5428                          s = t.rights;
5429                      while (s != null) {
# Line 5395 | Line 5476 | public class ConcurrentHashMap<K,V> exte
5476                  result = r;
5477                  CountedCompleter<?> c;
5478                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5479 <                    @SuppressWarnings("unchecked") MapReduceValuesTask<K,V,U>
5479 >                    @SuppressWarnings("unchecked")
5480 >                    MapReduceValuesTask<K,V,U>
5481                          t = (MapReduceValuesTask<K,V,U>)c,
5482                          s = t.rights;
5483                      while (s != null) {
# Line 5448 | Line 5530 | public class ConcurrentHashMap<K,V> exte
5530                  result = r;
5531                  CountedCompleter<?> c;
5532                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5533 <                    @SuppressWarnings("unchecked") MapReduceEntriesTask<K,V,U>
5533 >                    @SuppressWarnings("unchecked")
5534 >                    MapReduceEntriesTask<K,V,U>
5535                          t = (MapReduceEntriesTask<K,V,U>)c,
5536                          s = t.rights;
5537                      while (s != null) {
# Line 5501 | Line 5584 | public class ConcurrentHashMap<K,V> exte
5584                  result = r;
5585                  CountedCompleter<?> c;
5586                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5587 <                    @SuppressWarnings("unchecked") MapReduceMappingsTask<K,V,U>
5587 >                    @SuppressWarnings("unchecked")
5588 >                    MapReduceMappingsTask<K,V,U>
5589                          t = (MapReduceMappingsTask<K,V,U>)c,
5590                          s = t.rights;
5591                      while (s != null) {
# Line 5553 | Line 5637 | public class ConcurrentHashMap<K,V> exte
5637                  result = r;
5638                  CountedCompleter<?> c;
5639                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5640 <                    @SuppressWarnings("unchecked") MapReduceKeysToDoubleTask<K,V>
5640 >                    @SuppressWarnings("unchecked")
5641 >                    MapReduceKeysToDoubleTask<K,V>
5642                          t = (MapReduceKeysToDoubleTask<K,V>)c,
5643                          s = t.rights;
5644                      while (s != null) {
# Line 5602 | Line 5687 | public class ConcurrentHashMap<K,V> exte
5687                  result = r;
5688                  CountedCompleter<?> c;
5689                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5690 <                    @SuppressWarnings("unchecked") MapReduceValuesToDoubleTask<K,V>
5690 >                    @SuppressWarnings("unchecked")
5691 >                    MapReduceValuesToDoubleTask<K,V>
5692                          t = (MapReduceValuesToDoubleTask<K,V>)c,
5693                          s = t.rights;
5694                      while (s != null) {
# Line 5651 | Line 5737 | public class ConcurrentHashMap<K,V> exte
5737                  result = r;
5738                  CountedCompleter<?> c;
5739                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5740 <                    @SuppressWarnings("unchecked") MapReduceEntriesToDoubleTask<K,V>
5740 >                    @SuppressWarnings("unchecked")
5741 >                    MapReduceEntriesToDoubleTask<K,V>
5742                          t = (MapReduceEntriesToDoubleTask<K,V>)c,
5743                          s = t.rights;
5744                      while (s != null) {
# Line 5700 | Line 5787 | public class ConcurrentHashMap<K,V> exte
5787                  result = r;
5788                  CountedCompleter<?> c;
5789                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5790 <                    @SuppressWarnings("unchecked") MapReduceMappingsToDoubleTask<K,V>
5790 >                    @SuppressWarnings("unchecked")
5791 >                    MapReduceMappingsToDoubleTask<K,V>
5792                          t = (MapReduceMappingsToDoubleTask<K,V>)c,
5793                          s = t.rights;
5794                      while (s != null) {
# Line 5749 | Line 5837 | public class ConcurrentHashMap<K,V> exte
5837                  result = r;
5838                  CountedCompleter<?> c;
5839                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5840 <                    @SuppressWarnings("unchecked") MapReduceKeysToLongTask<K,V>
5840 >                    @SuppressWarnings("unchecked")
5841 >                    MapReduceKeysToLongTask<K,V>
5842                          t = (MapReduceKeysToLongTask<K,V>)c,
5843                          s = t.rights;
5844                      while (s != null) {
# Line 5798 | Line 5887 | public class ConcurrentHashMap<K,V> exte
5887                  result = r;
5888                  CountedCompleter<?> c;
5889                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5890 <                    @SuppressWarnings("unchecked") MapReduceValuesToLongTask<K,V>
5890 >                    @SuppressWarnings("unchecked")
5891 >                    MapReduceValuesToLongTask<K,V>
5892                          t = (MapReduceValuesToLongTask<K,V>)c,
5893                          s = t.rights;
5894                      while (s != null) {
# Line 5847 | Line 5937 | public class ConcurrentHashMap<K,V> exte
5937                  result = r;
5938                  CountedCompleter<?> c;
5939                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5940 <                    @SuppressWarnings("unchecked") MapReduceEntriesToLongTask<K,V>
5940 >                    @SuppressWarnings("unchecked")
5941 >                    MapReduceEntriesToLongTask<K,V>
5942                          t = (MapReduceEntriesToLongTask<K,V>)c,
5943                          s = t.rights;
5944                      while (s != null) {
# Line 5896 | Line 5987 | public class ConcurrentHashMap<K,V> exte
5987                  result = r;
5988                  CountedCompleter<?> c;
5989                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5990 <                    @SuppressWarnings("unchecked") MapReduceMappingsToLongTask<K,V>
5990 >                    @SuppressWarnings("unchecked")
5991 >                    MapReduceMappingsToLongTask<K,V>
5992                          t = (MapReduceMappingsToLongTask<K,V>)c,
5993                          s = t.rights;
5994                      while (s != null) {
# Line 5945 | Line 6037 | public class ConcurrentHashMap<K,V> exte
6037                  result = r;
6038                  CountedCompleter<?> c;
6039                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6040 <                    @SuppressWarnings("unchecked") MapReduceKeysToIntTask<K,V>
6040 >                    @SuppressWarnings("unchecked")
6041 >                    MapReduceKeysToIntTask<K,V>
6042                          t = (MapReduceKeysToIntTask<K,V>)c,
6043                          s = t.rights;
6044                      while (s != null) {
# Line 5994 | Line 6087 | public class ConcurrentHashMap<K,V> exte
6087                  result = r;
6088                  CountedCompleter<?> c;
6089                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6090 <                    @SuppressWarnings("unchecked") MapReduceValuesToIntTask<K,V>
6090 >                    @SuppressWarnings("unchecked")
6091 >                    MapReduceValuesToIntTask<K,V>
6092                          t = (MapReduceValuesToIntTask<K,V>)c,
6093                          s = t.rights;
6094                      while (s != null) {
# Line 6043 | Line 6137 | public class ConcurrentHashMap<K,V> exte
6137                  result = r;
6138                  CountedCompleter<?> c;
6139                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6140 <                    @SuppressWarnings("unchecked") MapReduceEntriesToIntTask<K,V>
6140 >                    @SuppressWarnings("unchecked")
6141 >                    MapReduceEntriesToIntTask<K,V>
6142                          t = (MapReduceEntriesToIntTask<K,V>)c,
6143                          s = t.rights;
6144                      while (s != null) {
# Line 6092 | Line 6187 | public class ConcurrentHashMap<K,V> exte
6187                  result = r;
6188                  CountedCompleter<?> c;
6189                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6190 <                    @SuppressWarnings("unchecked") MapReduceMappingsToIntTask<K,V>
6190 >                    @SuppressWarnings("unchecked")
6191 >                    MapReduceMappingsToIntTask<K,V>
6192                          t = (MapReduceMappingsToIntTask<K,V>)c,
6193                          s = t.rights;
6194                      while (s != null) {
# Line 6108 | Line 6204 | public class ConcurrentHashMap<K,V> exte
6204      private static final sun.misc.Unsafe U;
6205      private static final long SIZECTL;
6206      private static final long TRANSFERINDEX;
6111    private static final long TRANSFERORIGIN;
6207      private static final long BASECOUNT;
6208      private static final long CELLSBUSY;
6209      private static final long CELLVALUE;
# Line 6123 | Line 6218 | public class ConcurrentHashMap<K,V> exte
6218                  (k.getDeclaredField("sizeCtl"));
6219              TRANSFERINDEX = U.objectFieldOffset
6220                  (k.getDeclaredField("transferIndex"));
6126            TRANSFERORIGIN = U.objectFieldOffset
6127                (k.getDeclaredField("transferOrigin"));
6221              BASECOUNT = U.objectFieldOffset
6222                  (k.getDeclaredField("baseCount"));
6223              CELLSBUSY = U.objectFieldOffset

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines