383 * either stay at same index, or move with a power of two |
383 * either stay at same index, or move with a power of two |
384 * offset. We eliminate unnecessary node creation by catching |
384 * offset. We eliminate unnecessary node creation by catching |
385 * cases where old nodes can be reused because their next fields |
385 * cases where old nodes can be reused because their next fields |
386 * won't change. On average, only about one-sixth of them need |
386 * won't change. On average, only about one-sixth of them need |
387 * cloning when a table doubles. The nodes they replace will be |
387 * cloning when a table doubles. The nodes they replace will be |
388 * garbage collectable as soon as they are no longer referenced by |
388 * garbage collectible as soon as they are no longer referenced by |
389 * any reader thread that may be in the midst of concurrently |
389 * any reader thread that may be in the midst of concurrently |
390 * traversing table. Upon transfer, the old table bin contains |
390 * traversing table. Upon transfer, the old table bin contains |
391 * only a special forwarding node (with hash field "MOVED") that |
391 * only a special forwarding node (with hash field "MOVED") that |
392 * contains the next table as its key. On encountering a |
392 * contains the next table as its key. On encountering a |
393 * forwarding node, access and update operations restart, using |
393 * forwarding node, access and update operations restart, using |
3284 if (tr != null && !checkInvariants(tr)) |
3284 if (tr != null && !checkInvariants(tr)) |
3285 return false; |
3285 return false; |
3286 return true; |
3286 return true; |
3287 } |
3287 } |
3288 |
3288 |
3289 private static final Unsafe U = Unsafe.getUnsafe(); |
|
3290 private static final long LOCKSTATE |
3289 private static final long LOCKSTATE |
3291 = U.objectFieldOffset(TreeBin.class, "lockState"); |
3290 = U.objectFieldOffset(TreeBin.class, "lockState"); |
3292 } |
3291 } |
3293 |
3292 |
3294 /* ----------------Table Traversal -------------- */ |
3293 /* ----------------Table Traversal -------------- */ |
3295 |
3294 |
3296 /** |
3295 /** |
6343 } |
6342 } |
6344 } |
6343 } |
6345 |
6344 |
6346 // Unsafe mechanics |
6345 // Unsafe mechanics |
6347 private static final Unsafe U = Unsafe.getUnsafe(); |
6346 private static final Unsafe U = Unsafe.getUnsafe(); |
6348 private static final long SIZECTL; |
6347 private static final long SIZECTL |
6349 private static final long TRANSFERINDEX; |
6348 = U.objectFieldOffset(ConcurrentHashMap.class, "sizeCtl"); |
6350 private static final long BASECOUNT; |
6349 private static final long TRANSFERINDEX |
6351 private static final long CELLSBUSY; |
6350 = U.objectFieldOffset(ConcurrentHashMap.class, "transferIndex"); |
6352 private static final long CELLVALUE; |
6351 private static final long BASECOUNT |
6353 private static final int ABASE; |
6352 = U.objectFieldOffset(ConcurrentHashMap.class, "baseCount"); |
|
6353 private static final long CELLSBUSY |
|
6354 = U.objectFieldOffset(ConcurrentHashMap.class, "cellsBusy"); |
|
6355 private static final long CELLVALUE |
|
6356 = U.objectFieldOffset(CounterCell.class, "value"); |
|
6357 private static final int ABASE = U.arrayBaseOffset(Node[].class); |
6354 private static final int ASHIFT; |
6358 private static final int ASHIFT; |
6355 |
6359 |
6356 static { |
6360 static { |
6357 SIZECTL = U.objectFieldOffset |
|
6358 (ConcurrentHashMap.class, "sizeCtl"); |
|
6359 TRANSFERINDEX = U.objectFieldOffset |
|
6360 (ConcurrentHashMap.class, "transferIndex"); |
|
6361 BASECOUNT = U.objectFieldOffset |
|
6362 (ConcurrentHashMap.class, "baseCount"); |
|
6363 CELLSBUSY = U.objectFieldOffset |
|
6364 (ConcurrentHashMap.class, "cellsBusy"); |
|
6365 |
|
6366 CELLVALUE = U.objectFieldOffset |
|
6367 (CounterCell.class, "value"); |
|
6368 |
|
6369 ABASE = U.arrayBaseOffset(Node[].class); |
|
6370 int scale = U.arrayIndexScale(Node[].class); |
6361 int scale = U.arrayIndexScale(Node[].class); |
6371 if ((scale & (scale - 1)) != 0) |
6362 if ((scale & (scale - 1)) != 0) |
6372 throw new ExceptionInInitializerError("array index scale not a power of two"); |
6363 throw new ExceptionInInitializerError("array index scale not a power of two"); |
6373 ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); |
6364 ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); |
6374 |
6365 |