1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * Written by Doug Lea with assistance from members of JCP JSR-166 32 * Expert Group and released to the public domain, as explained at 33 * http://creativecommons.org/publicdomain/zero/1.0/ 34 */ 35 36 package java.util.concurrent; 37 38 import java.io.ObjectStreamField; 39 import java.io.Serializable; 40 import java.lang.reflect.ParameterizedType; 41 import java.lang.reflect.Type; 42 import java.util.AbstractMap; 43 import java.util.Arrays; 44 import java.util.Collection; 45 import java.util.Enumeration; 46 import java.util.HashMap; 47 import java.util.Hashtable; 48 import java.util.Iterator; 49 import java.util.Map; 50 import java.util.NoSuchElementException; 51 import java.util.Set; 52 import java.util.Spliterator; 53 import java.util.concurrent.atomic.AtomicReference; 54 import java.util.concurrent.locks.LockSupport; 55 import java.util.concurrent.locks.ReentrantLock; 56 import java.util.function.BiConsumer; 57 import java.util.function.BiFunction; 58 import java.util.function.Consumer; 59 import java.util.function.DoubleBinaryOperator; 60 import java.util.function.Function; 61 import java.util.function.IntBinaryOperator; 62 import java.util.function.LongBinaryOperator; 63 import java.util.function.Predicate; 64 import java.util.function.ToDoubleBiFunction; 65 import java.util.function.ToDoubleFunction; 66 import java.util.function.ToIntBiFunction; 67 import java.util.function.ToIntFunction; 68 import java.util.function.ToLongBiFunction; 69 import java.util.function.ToLongFunction; 70 import java.util.stream.Stream; 71 import jdk.internal.misc.Unsafe; 72 73 /** 74 * A hash table supporting full concurrency of retrievals and 75 * high expected concurrency for updates. This class obeys the 76 * same functional specification as {@link java.util.Hashtable}, and 77 * includes versions of methods corresponding to each method of 78 * {@code Hashtable}. However, even though all operations are 79 * thread-safe, retrieval operations do <em>not</em> entail locking, 80 * and there is <em>not</em> any support for locking the entire table 81 * in a way that prevents all access. This class is fully 82 * interoperable with {@code Hashtable} in programs that rely on its 83 * thread safety but not on its synchronization details. 84 * 85 * <p>Retrieval operations (including {@code get}) generally do not 86 * block, so may overlap with update operations (including {@code put} 87 * and {@code remove}). Retrievals reflect the results of the most 88 * recently <em>completed</em> update operations holding upon their 89 * onset. (More formally, an update operation for a given key bears a 90 * <em>happens-before</em> relation with any (non-null) retrieval for 91 * that key reporting the updated value.) For aggregate operations 92 * such as {@code putAll} and {@code clear}, concurrent retrievals may 93 * reflect insertion or removal of only some entries. Similarly, 94 * Iterators, Spliterators and Enumerations return elements reflecting the 95 * state of the hash table at some point at or since the creation of the 96 * iterator/enumeration. They do <em>not</em> throw {@link 97 * java.util.ConcurrentModificationException ConcurrentModificationException}. 98 * However, iterators are designed to be used by only one thread at a time. 99 * Bear in mind that the results of aggregate status methods including 100 * {@code size}, {@code isEmpty}, and {@code containsValue} are typically 101 * useful only when a map is not undergoing concurrent updates in other threads. 102 * Otherwise the results of these methods reflect transient states 103 * that may be adequate for monitoring or estimation purposes, but not 104 * for program control. 105 * 106 * <p>The table is dynamically expanded when there are too many 107 * collisions (i.e., keys that have distinct hash codes but fall into 108 * the same slot modulo the table size), with the expected average 109 * effect of maintaining roughly two bins per mapping (corresponding 110 * to a 0.75 load factor threshold for resizing). There may be much 111 * variance around this average as mappings are added and removed, but 112 * overall, this maintains a commonly accepted time/space tradeoff for 113 * hash tables. However, resizing this or any other kind of hash 114 * table may be a relatively slow operation. When possible, it is a 115 * good idea to provide a size estimate as an optional {@code 116 * initialCapacity} constructor argument. An additional optional 117 * {@code loadFactor} constructor argument provides a further means of 118 * customizing initial table capacity by specifying the table density 119 * to be used in calculating the amount of space to allocate for the 120 * given number of elements. Also, for compatibility with previous 121 * versions of this class, constructors may optionally specify an 122 * expected {@code concurrencyLevel} as an additional hint for 123 * internal sizing. Note that using many keys with exactly the same 124 * {@code hashCode()} is a sure way to slow down performance of any 125 * hash table. To ameliorate impact, when keys are {@link Comparable}, 126 * this class may use comparison order among keys to help break ties. 127 * 128 * <p>A {@link Set} projection of a ConcurrentHashMap may be created 129 * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed 130 * (using {@link #keySet(Object)} when only keys are of interest, and the 131 * mapped values are (perhaps transiently) not used or all take the 132 * same mapping value. 133 * 134 * <p>A ConcurrentHashMap can be used as a scalable frequency map (a 135 * form of histogram or multiset) by using {@link 136 * java.util.concurrent.atomic.LongAdder} values and initializing via 137 * {@link #computeIfAbsent computeIfAbsent}. For example, to add a count 138 * to a {@code ConcurrentHashMap<String,LongAdder> freqs}, you can use 139 * {@code freqs.computeIfAbsent(key, k -> new LongAdder()).increment();} 140 * 141 * <p>This class and its views and iterators implement all of the 142 * <em>optional</em> methods of the {@link Map} and {@link Iterator} 143 * interfaces. 144 * 145 * <p>Like {@link Hashtable} but unlike {@link HashMap}, this class 146 * does <em>not</em> allow {@code null} to be used as a key or value. 147 * 148 * <p>ConcurrentHashMaps support a set of sequential and parallel bulk 149 * operations that, unlike most {@link Stream} methods, are designed 150 * to be safely, and often sensibly, applied even with maps that are 151 * being concurrently updated by other threads; for example, when 152 * computing a snapshot summary of the values in a shared registry. 153 * There are three kinds of operation, each with four forms, accepting 154 * functions with keys, values, entries, and (key, value) pairs as 155 * arguments and/or return values. Because the elements of a 156 * ConcurrentHashMap are not ordered in any particular way, and may be 157 * processed in different orders in different parallel executions, the 158 * correctness of supplied functions should not depend on any 159 * ordering, or on any other objects or values that may transiently 160 * change while computation is in progress; and except for forEach 161 * actions, should ideally be side-effect-free. Bulk operations on 162 * {@link Map.Entry} objects do not support method {@code setValue}. 163 * 164 * <ul> 165 * <li>forEach: Performs a given action on each element. 166 * A variant form applies a given transformation on each element 167 * before performing the action. 168 * 169 * <li>search: Returns the first available non-null result of 170 * applying a given function on each element; skipping further 171 * search when a result is found. 172 * 173 * <li>reduce: Accumulates each element. The supplied reduction 174 * function cannot rely on ordering (more formally, it should be 175 * both associative and commutative). There are five variants: 176 * 177 * <ul> 178 * 179 * <li>Plain reductions. (There is not a form of this method for 180 * (key, value) function arguments since there is no corresponding 181 * return type.) 182 * 183 * <li>Mapped reductions that accumulate the results of a given 184 * function applied to each element. 185 * 186 * <li>Reductions to scalar doubles, longs, and ints, using a 187 * given basis value. 188 * 189 * </ul> 190 * </ul> 191 * 192 * <p>These bulk operations accept a {@code parallelismThreshold} 193 * argument. Methods proceed sequentially if the current map size is 194 * estimated to be less than the given threshold. Using a value of 195 * {@code Long.MAX_VALUE} suppresses all parallelism. Using a value 196 * of {@code 1} results in maximal parallelism by partitioning into 197 * enough subtasks to fully utilize the {@link 198 * ForkJoinPool#commonPool()} that is used for all parallel 199 * computations. Normally, you would initially choose one of these 200 * extreme values, and then measure performance of using in-between 201 * values that trade off overhead versus throughput. 202 * 203 * <p>The concurrency properties of bulk operations follow 204 * from those of ConcurrentHashMap: Any non-null result returned 205 * from {@code get(key)} and related access methods bears a 206 * happens-before relation with the associated insertion or 207 * update. The result of any bulk operation reflects the 208 * composition of these per-element relations (but is not 209 * necessarily atomic with respect to the map as a whole unless it 210 * is somehow known to be quiescent). Conversely, because keys 211 * and values in the map are never null, null serves as a reliable 212 * atomic indicator of the current lack of any result. To 213 * maintain this property, null serves as an implicit basis for 214 * all non-scalar reduction operations. For the double, long, and 215 * int versions, the basis should be one that, when combined with 216 * any other value, returns that other value (more formally, it 217 * should be the identity element for the reduction). Most common 218 * reductions have these properties; for example, computing a sum 219 * with basis 0 or a minimum with basis MAX_VALUE. 220 * 221 * <p>Search and transformation functions provided as arguments 222 * should similarly return null to indicate the lack of any result 223 * (in which case it is not used). In the case of mapped 224 * reductions, this also enables transformations to serve as 225 * filters, returning null (or, in the case of primitive 226 * specializations, the identity basis) if the element should not 227 * be combined. You can create compound transformations and 228 * filterings by composing them yourself under this "null means 229 * there is nothing there now" rule before using them in search or 230 * reduce operations. 231 * 232 * <p>Methods accepting and/or returning Entry arguments maintain 233 * key-value associations. They may be useful for example when 234 * finding the key for the greatest value. Note that "plain" Entry 235 * arguments can be supplied using {@code new 236 * AbstractMap.SimpleEntry(k,v)}. 237 * 238 * <p>Bulk operations may complete abruptly, throwing an 239 * exception encountered in the application of a supplied 240 * function. Bear in mind when handling such exceptions that other 241 * concurrently executing functions could also have thrown 242 * exceptions, or would have done so if the first exception had 243 * not occurred. 244 * 245 * <p>Speedups for parallel compared to sequential forms are common 246 * but not guaranteed. Parallel operations involving brief functions 247 * on small maps may execute more slowly than sequential forms if the 248 * underlying work to parallelize the computation is more expensive 249 * than the computation itself. Similarly, parallelization may not 250 * lead to much actual parallelism if all processors are busy 251 * performing unrelated tasks. 252 * 253 * <p>All arguments to all task methods must be non-null. 254 * 255 * <p>This class is a member of the 256 * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework"> 257 * Java Collections Framework</a>. 258 * 259 * @since 1.5 260 * @author Doug Lea 261 * @param <K> the type of keys maintained by this map 262 * @param <V> the type of mapped values 263 */ 264 public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> 265 implements ConcurrentMap<K,V>, Serializable { 266 private static final long serialVersionUID = 7249069246763182397L; 267 268 /* 269 * Overview: 270 * 271 * The primary design goal of this hash table is to maintain 272 * concurrent readability (typically method get(), but also 273 * iterators and related methods) while minimizing update 274 * contention. Secondary goals are to keep space consumption about 275 * the same or better than java.util.HashMap, and to support high 276 * initial insertion rates on an empty table by many threads. 277 * 278 * This map usually acts as a binned (bucketed) hash table. Each 279 * key-value mapping is held in a Node. Most nodes are instances 280 * of the basic Node class with hash, key, value, and next 281 * fields. However, various subclasses exist: TreeNodes are 282 * arranged in balanced trees, not lists. TreeBins hold the roots 283 * of sets of TreeNodes. ForwardingNodes are placed at the heads 284 * of bins during resizing. ReservationNodes are used as 285 * placeholders while establishing values in computeIfAbsent and 286 * related methods. The types TreeBin, ForwardingNode, and 287 * ReservationNode do not hold normal user keys, values, or 288 * hashes, and are readily distinguishable during search etc 289 * because they have negative hash fields and null key and value 290 * fields. (These special nodes are either uncommon or transient, 291 * so the impact of carrying around some unused fields is 292 * insignificant.) 293 * 294 * The table is lazily initialized to a power-of-two size upon the 295 * first insertion. Each bin in the table normally contains a 296 * list of Nodes (most often, the list has only zero or one Node). 297 * Table accesses require volatile/atomic reads, writes, and 298 * CASes. Because there is no other way to arrange this without 299 * adding further indirections, we use intrinsics 300 * (jdk.internal.misc.Unsafe) operations. 301 * 302 * We use the top (sign) bit of Node hash fields for control 303 * purposes -- it is available anyway because of addressing 304 * constraints. Nodes with negative hash fields are specially 305 * handled or ignored in map methods. 306 * 307 * Insertion (via put or its variants) of the first node in an 308 * empty bin is performed by just CASing it to the bin. This is 309 * by far the most common case for put operations under most 310 * key/hash distributions. Other update operations (insert, 311 * delete, and replace) require locks. We do not want to waste 312 * the space required to associate a distinct lock object with 313 * each bin, so instead use the first node of a bin list itself as 314 * a lock. Locking support for these locks relies on builtin 315 * "synchronized" monitors. 316 * 317 * Using the first node of a list as a lock does not by itself 318 * suffice though: When a node is locked, any update must first 319 * validate that it is still the first node after locking it, and 320 * retry if not. Because new nodes are always appended to lists, 321 * once a node is first in a bin, it remains first until deleted 322 * or the bin becomes invalidated (upon resizing). 323 * 324 * The main disadvantage of per-bin locks is that other update 325 * operations on other nodes in a bin list protected by the same 326 * lock can stall, for example when user equals() or mapping 327 * functions take a long time. However, statistically, under 328 * random hash codes, this is not a common problem. Ideally, the 329 * frequency of nodes in bins follows a Poisson distribution 330 * (http://en.wikipedia.org/wiki/Poisson_distribution) with a 331 * parameter of about 0.5 on average, given the resizing threshold 332 * of 0.75, although with a large variance because of resizing 333 * granularity. Ignoring variance, the expected occurrences of 334 * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The 335 * first values are: 336 * 337 * 0: 0.60653066 338 * 1: 0.30326533 339 * 2: 0.07581633 340 * 3: 0.01263606 341 * 4: 0.00157952 342 * 5: 0.00015795 343 * 6: 0.00001316 344 * 7: 0.00000094 345 * 8: 0.00000006 346 * more: less than 1 in ten million 347 * 348 * Lock contention probability for two threads accessing distinct 349 * elements is roughly 1 / (8 * #elements) under random hashes. 350 * 351 * Actual hash code distributions encountered in practice 352 * sometimes deviate significantly from uniform randomness. This 353 * includes the case when N > (1<<30), so some keys MUST collide. 354 * Similarly for dumb or hostile usages in which multiple keys are 355 * designed to have identical hash codes or ones that differs only 356 * in masked-out high bits. So we use a secondary strategy that 357 * applies when the number of nodes in a bin exceeds a 358 * threshold. These TreeBins use a balanced tree to hold nodes (a 359 * specialized form of red-black trees), bounding search time to 360 * O(log N). Each search step in a TreeBin is at least twice as 361 * slow as in a regular list, but given that N cannot exceed 362 * (1<<64) (before running out of addresses) this bounds search 363 * steps, lock hold times, etc, to reasonable constants (roughly 364 * 100 nodes inspected per operation worst case) so long as keys 365 * are Comparable (which is very common -- String, Long, etc). 366 * TreeBin nodes (TreeNodes) also maintain the same "next" 367 * traversal pointers as regular nodes, so can be traversed in 368 * iterators in the same way. 369 * 370 * The table is resized when occupancy exceeds a percentage 371 * threshold (nominally, 0.75, but see below). Any thread 372 * noticing an overfull bin may assist in resizing after the 373 * initiating thread allocates and sets up the replacement array. 374 * However, rather than stalling, these other threads may proceed 375 * with insertions etc. The use of TreeBins shields us from the 376 * worst case effects of overfilling while resizes are in 377 * progress. Resizing proceeds by transferring bins, one by one, 378 * from the table to the next table. However, threads claim small 379 * blocks of indices to transfer (via field transferIndex) before 380 * doing so, reducing contention. A generation stamp in field 381 * sizeCtl ensures that resizings do not overlap. Because we are 382 * using power-of-two expansion, the elements from each bin must 383 * either stay at same index, or move with a power of two 384 * offset. We eliminate unnecessary node creation by catching 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 387 * cloning when a table doubles. The nodes they replace will be 388 * garbage collectable as soon as they are no longer referenced by 389 * any reader thread that may be in the midst of concurrently 390 * traversing table. Upon transfer, the old table bin contains 391 * only a special forwarding node (with hash field "MOVED") that 392 * contains the next table as its key. On encountering a 393 * forwarding node, access and update operations restart, using 394 * the new table. 395 * 396 * Each bin transfer requires its bin lock, which can stall 397 * waiting for locks while resizing. However, because other 398 * threads can join in and help resize rather than contend for 399 * locks, average aggregate waits become shorter as resizing 400 * progresses. The transfer operation must also ensure that all 401 * accessible bins in both the old and new table are usable by any 402 * traversal. This is arranged in part by proceeding from the 403 * last bin (table.length - 1) up towards the first. Upon seeing 404 * a forwarding node, traversals (see class Traverser) arrange to 405 * move to the new table without revisiting nodes. To ensure that 406 * no intervening nodes are skipped even when moved out of order, 407 * a stack (see class TableStack) is created on first encounter of 408 * a forwarding node during a traversal, to maintain its place if 409 * later processing the current table. The need for these 410 * save/restore mechanics is relatively rare, but when one 411 * forwarding node is encountered, typically many more will be. 412 * So Traversers use a simple caching scheme to avoid creating so 413 * many new TableStack nodes. (Thanks to Peter Levart for 414 * suggesting use of a stack here.) 415 * 416 * The traversal scheme also applies to partial traversals of 417 * ranges of bins (via an alternate Traverser constructor) 418 * to support partitioned aggregate operations. Also, read-only 419 * operations give up if ever forwarded to a null table, which 420 * provides support for shutdown-style clearing, which is also not 421 * currently implemented. 422 * 423 * Lazy table initialization minimizes footprint until first use, 424 * and also avoids resizings when the first operation is from a 425 * putAll, constructor with map argument, or deserialization. 426 * These cases attempt to override the initial capacity settings, 427 * but harmlessly fail to take effect in cases of races. 428 * 429 * The element count is maintained using a specialization of 430 * LongAdder. We need to incorporate a specialization rather than 431 * just use a LongAdder in order to access implicit 432 * contention-sensing that leads to creation of multiple 433 * CounterCells. The counter mechanics avoid contention on 434 * updates but can encounter cache thrashing if read too 435 * frequently during concurrent access. To avoid reading so often, 436 * resizing under contention is attempted only upon adding to a 437 * bin already holding two or more nodes. Under uniform hash 438 * distributions, the probability of this occurring at threshold 439 * is around 13%, meaning that only about 1 in 8 puts check 440 * threshold (and after resizing, many fewer do so). 441 * 442 * TreeBins use a special form of comparison for search and 443 * related operations (which is the main reason we cannot use 444 * existing collections such as TreeMaps). TreeBins contain 445 * Comparable elements, but may contain others, as well as 446 * elements that are Comparable but not necessarily Comparable for 447 * the same T, so we cannot invoke compareTo among them. To handle 448 * this, the tree is ordered primarily by hash value, then by 449 * Comparable.compareTo order if applicable. On lookup at a node, 450 * if elements are not comparable or compare as 0 then both left 451 * and right children may need to be searched in the case of tied 452 * hash values. (This corresponds to the full list search that 453 * would be necessary if all elements were non-Comparable and had 454 * tied hashes.) On insertion, to keep a total ordering (or as 455 * close as is required here) across rebalancings, we compare 456 * classes and identityHashCodes as tie-breakers. The red-black 457 * balancing code is updated from pre-jdk-collections 458 * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) 459 * based in turn on Cormen, Leiserson, and Rivest "Introduction to 460 * Algorithms" (CLR). 461 * 462 * TreeBins also require an additional locking mechanism. While 463 * list traversal is always possible by readers even during 464 * updates, tree traversal is not, mainly because of tree-rotations 465 * that may change the root node and/or its linkages. TreeBins 466 * include a simple read-write lock mechanism parasitic on the 467 * main bin-synchronization strategy: Structural adjustments 468 * associated with an insertion or removal are already bin-locked 469 * (and so cannot conflict with other writers) but must wait for 470 * ongoing readers to finish. Since there can be only one such 471 * waiter, we use a simple scheme using a single "waiter" field to 472 * block writers. However, readers need never block. If the root 473 * lock is held, they proceed along the slow traversal path (via 474 * next-pointers) until the lock becomes available or the list is 475 * exhausted, whichever comes first. These cases are not fast, but 476 * maximize aggregate expected throughput. 477 * 478 * Maintaining API and serialization compatibility with previous 479 * versions of this class introduces several oddities. Mainly: We 480 * leave untouched but unused constructor arguments referring to 481 * concurrencyLevel. We accept a loadFactor constructor argument, 482 * but apply it only to initial table capacity (which is the only 483 * time that we can guarantee to honor it.) We also declare an 484 * unused "Segment" class that is instantiated in minimal form 485 * only when serializing. 486 * 487 * Also, solely for compatibility with previous versions of this 488 * class, it extends AbstractMap, even though all of its methods 489 * are overridden, so it is just useless baggage. 490 * 491 * This file is organized to make things a little easier to follow 492 * while reading than they might otherwise: First the main static 493 * declarations and utilities, then fields, then main public 494 * methods (with a few factorings of multiple public methods into 495 * internal ones), then sizing methods, trees, traversers, and 496 * bulk operations. 497 */ 498 499 /* ---------------- Constants -------------- */ 500 501 /** 502 * The largest possible table capacity. This value must be 503 * exactly 1<<30 to stay within Java array allocation and indexing 504 * bounds for power of two table sizes, and is further required 505 * because the top two bits of 32bit hash fields are used for 506 * control purposes. 507 */ 508 private static final int MAXIMUM_CAPACITY = 1 << 30; 509 510 /** 511 * The default initial table capacity. Must be a power of 2 512 * (i.e., at least 1) and at most MAXIMUM_CAPACITY. 513 */ 514 private static final int DEFAULT_CAPACITY = 16; 515 516 /** 517 * The largest possible (non-power of two) array size. 518 * Needed by toArray and related methods. 519 */ 520 static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 521 522 /** 523 * The default concurrency level for this table. Unused but 524 * defined for compatibility with previous versions of this class. 525 */ 526 private static final int DEFAULT_CONCURRENCY_LEVEL = 16; 527 528 /** 529 * The load factor for this table. Overrides of this value in 530 * constructors affect only the initial table capacity. The 531 * actual floating point value isn't normally used -- it is 532 * simpler to use expressions such as {@code n - (n >>> 2)} for 533 * the associated resizing threshold. 534 */ 535 private static final float LOAD_FACTOR = 0.75f; 536 537 /** 538 * The bin count threshold for using a tree rather than list for a 539 * bin. Bins are converted to trees when adding an element to a 540 * bin with at least this many nodes. The value must be greater 541 * than 2, and should be at least 8 to mesh with assumptions in 542 * tree removal about conversion back to plain bins upon 543 * shrinkage. 544 */ 545 static final int TREEIFY_THRESHOLD = 8; 546 547 /** 548 * The bin count threshold for untreeifying a (split) bin during a 549 * resize operation. Should be less than TREEIFY_THRESHOLD, and at 550 * most 6 to mesh with shrinkage detection under removal. 551 */ 552 static final int UNTREEIFY_THRESHOLD = 6; 553 554 /** 555 * The smallest table capacity for which bins may be treeified. 556 * (Otherwise the table is resized if too many nodes in a bin.) 557 * The value should be at least 4 * TREEIFY_THRESHOLD to avoid 558 * conflicts between resizing and treeification thresholds. 559 */ 560 static final int MIN_TREEIFY_CAPACITY = 64; 561 562 /** 563 * Minimum number of rebinnings per transfer step. Ranges are 564 * subdivided to allow multiple resizer threads. This value 565 * serves as a lower bound to avoid resizers encountering 566 * excessive memory contention. The value should be at least 567 * DEFAULT_CAPACITY. 568 */ 569 private static final int MIN_TRANSFER_STRIDE = 16; 570 571 /** 572 * The number of bits used for generation stamp in sizeCtl. 573 * Must be at least 6 for 32bit arrays. 574 */ 575 private static final int RESIZE_STAMP_BITS = 16; 576 577 /** 578 * The maximum number of threads that can help resize. 579 * Must fit in 32 - RESIZE_STAMP_BITS bits. 580 */ 581 private static final int MAX_RESIZERS = (1 << (32 - RESIZE_STAMP_BITS)) - 1; 582 583 /** 584 * The bit shift for recording size stamp in sizeCtl. 585 */ 586 private static final int RESIZE_STAMP_SHIFT = 32 - RESIZE_STAMP_BITS; 587 588 /* 589 * Encodings for Node hash fields. See above for explanation. 590 */ 591 static final int MOVED = -1; // hash for forwarding nodes 592 static final int TREEBIN = -2; // hash for roots of trees 593 static final int RESERVED = -3; // hash for transient reservations 594 static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash 595 596 /** Number of CPUS, to place bounds on some sizings */ 597 static final int NCPU = Runtime.getRuntime().availableProcessors(); 598 599 /** 600 * Serialized pseudo-fields, provided only for jdk7 compatibility. 601 * @serialField segments Segment[] 602 * The segments, each of which is a specialized hash table. 603 * @serialField segmentMask int 604 * Mask value for indexing into segments. The upper bits of a 605 * key's hash code are used to choose the segment. 606 * @serialField segmentShift int 607 * Shift value for indexing within segments. 608 */ 609 private static final ObjectStreamField[] serialPersistentFields = { 610 new ObjectStreamField("segments", Segment[].class), 611 new ObjectStreamField("segmentMask", Integer.TYPE), 612 new ObjectStreamField("segmentShift", Integer.TYPE), 613 }; 614 615 /* ---------------- Nodes -------------- */ 616 617 /** 618 * Key-value entry. This class is never exported out as a 619 * user-mutable Map.Entry (i.e., one supporting setValue; see 620 * MapEntry below), but can be used for read-only traversals used 621 * in bulk tasks. Subclasses of Node with a negative hash field 622 * are special, and contain null keys and values (but are never 623 * exported). Otherwise, keys and vals are never null. 624 */ 625 static class Node<K,V> implements Map.Entry<K,V> { 626 final int hash; 627 final K key; 628 volatile V val; 629 volatile Node<K,V> next; 630 Node(int hash, K key, V val)631 Node(int hash, K key, V val) { 632 this.hash = hash; 633 this.key = key; 634 this.val = val; 635 } 636 Node(int hash, K key, V val, Node<K,V> next)637 Node(int hash, K key, V val, Node<K,V> next) { 638 this(hash, key, val); 639 this.next = next; 640 } 641 getKey()642 public final K getKey() { return key; } getValue()643 public final V getValue() { return val; } hashCode()644 public final int hashCode() { return key.hashCode() ^ val.hashCode(); } toString()645 public final String toString() { 646 return Helpers.mapEntryToString(key, val); 647 } setValue(V value)648 public final V setValue(V value) { 649 throw new UnsupportedOperationException(); 650 } 651 equals(Object o)652 public final boolean equals(Object o) { 653 Object k, v, u; Map.Entry<?,?> e; 654 return ((o instanceof Map.Entry) && 655 (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 656 (v = e.getValue()) != null && 657 (k == key || k.equals(key)) && 658 (v == (u = val) || v.equals(u))); 659 } 660 661 /** 662 * Virtualized support for map.get(); overridden in subclasses. 663 */ find(int h, Object k)664 Node<K,V> find(int h, Object k) { 665 Node<K,V> e = this; 666 if (k != null) { 667 do { 668 K ek; 669 if (e.hash == h && 670 ((ek = e.key) == k || (ek != null && k.equals(ek)))) 671 return e; 672 } while ((e = e.next) != null); 673 } 674 return null; 675 } 676 } 677 678 /* ---------------- Static utilities -------------- */ 679 680 /** 681 * Spreads (XORs) higher bits of hash to lower and also forces top 682 * bit to 0. Because the table uses power-of-two masking, sets of 683 * hashes that vary only in bits above the current mask will 684 * always collide. (Among known examples are sets of Float keys 685 * holding consecutive whole numbers in small tables.) So we 686 * apply a transform that spreads the impact of higher bits 687 * downward. There is a tradeoff between speed, utility, and 688 * quality of bit-spreading. Because many common sets of hashes 689 * are already reasonably distributed (so don't benefit from 690 * spreading), and because we use trees to handle large sets of 691 * collisions in bins, we just XOR some shifted bits in the 692 * cheapest possible way to reduce systematic lossage, as well as 693 * to incorporate impact of the highest bits that would otherwise 694 * never be used in index calculations because of table bounds. 695 */ spread(int h)696 static final int spread(int h) { 697 return (h ^ (h >>> 16)) & HASH_BITS; 698 } 699 700 /** 701 * Returns a power of two table size for the given desired capacity. 702 * See Hackers Delight, sec 3.2 703 */ tableSizeFor(int c)704 private static final int tableSizeFor(int c) { 705 int n = -1 >>> Integer.numberOfLeadingZeros(c - 1); 706 return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; 707 } 708 709 /** 710 * Returns x's Class if it is of the form "class C implements 711 * Comparable<C>", else null. 712 */ comparableClassFor(Object x)713 static Class<?> comparableClassFor(Object x) { 714 if (x instanceof Comparable) { 715 Class<?> c; Type[] ts, as; ParameterizedType p; 716 if ((c = x.getClass()) == String.class) // bypass checks 717 return c; 718 if ((ts = c.getGenericInterfaces()) != null) { 719 for (Type t : ts) { 720 if ((t instanceof ParameterizedType) && 721 ((p = (ParameterizedType)t).getRawType() == 722 Comparable.class) && 723 (as = p.getActualTypeArguments()) != null && 724 as.length == 1 && as[0] == c) // type arg is c 725 return c; 726 } 727 } 728 } 729 return null; 730 } 731 732 /** 733 * Returns k.compareTo(x) if x matches kc (k's screened comparable 734 * class), else 0. 735 */ 736 @SuppressWarnings({"rawtypes","unchecked"}) // for cast to Comparable compareComparables(Class<?> kc, Object k, Object x)737 static int compareComparables(Class<?> kc, Object k, Object x) { 738 return (x == null || x.getClass() != kc ? 0 : 739 ((Comparable)k).compareTo(x)); 740 } 741 742 /* ---------------- Table element access -------------- */ 743 744 /* 745 * Atomic access methods are used for table elements as well as 746 * elements of in-progress next table while resizing. All uses of 747 * the tab arguments must be null checked by callers. All callers 748 * also paranoically precheck that tab's length is not zero (or an 749 * equivalent check), thus ensuring that any index argument taking 750 * the form of a hash value anded with (length - 1) is a valid 751 * index. Note that, to be correct wrt arbitrary concurrency 752 * errors by users, these checks must operate on local variables, 753 * which accounts for some odd-looking inline assignments below. 754 * Note that calls to setTabAt always occur within locked regions, 755 * and so require only release ordering. 756 */ 757 758 @SuppressWarnings("unchecked") tabAt(Node<K,V>[] tab, int i)759 static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) { 760 return (Node<K,V>)U.getObjectAcquire(tab, ((long)i << ASHIFT) + ABASE); 761 } 762 casTabAt(Node<K,V>[] tab, int i, Node<K,V> c, Node<K,V> v)763 static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i, 764 Node<K,V> c, Node<K,V> v) { 765 return U.compareAndSetObject(tab, ((long)i << ASHIFT) + ABASE, c, v); 766 } 767 setTabAt(Node<K,V>[] tab, int i, Node<K,V> v)768 static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) { 769 U.putObjectRelease(tab, ((long)i << ASHIFT) + ABASE, v); 770 } 771 772 /* ---------------- Fields -------------- */ 773 774 /** 775 * The array of bins. Lazily initialized upon first insertion. 776 * Size is always a power of two. Accessed directly by iterators. 777 */ 778 transient volatile Node<K,V>[] table; 779 780 /** 781 * The next table to use; non-null only while resizing. 782 */ 783 private transient volatile Node<K,V>[] nextTable; 784 785 /** 786 * Base counter value, used mainly when there is no contention, 787 * but also as a fallback during table initialization 788 * races. Updated via CAS. 789 */ 790 private transient volatile long baseCount; 791 792 /** 793 * Table initialization and resizing control. When negative, the 794 * table is being initialized or resized: -1 for initialization, 795 * else -(1 + the number of active resizing threads). Otherwise, 796 * when table is null, holds the initial table size to use upon 797 * creation, or 0 for default. After initialization, holds the 798 * next element count value upon which to resize the table. 799 */ 800 private transient volatile int sizeCtl; 801 802 /** 803 * The next table index (plus one) to split while resizing. 804 */ 805 private transient volatile int transferIndex; 806 807 /** 808 * Spinlock (locked via CAS) used when resizing and/or creating CounterCells. 809 */ 810 private transient volatile int cellsBusy; 811 812 /** 813 * Table of counter cells. When non-null, size is a power of 2. 814 */ 815 private transient volatile CounterCell[] counterCells; 816 817 // views 818 private transient KeySetView<K,V> keySet; 819 private transient ValuesView<K,V> values; 820 private transient EntrySetView<K,V> entrySet; 821 822 823 /* ---------------- Public operations -------------- */ 824 825 /** 826 * Creates a new, empty map with the default initial table size (16). 827 */ ConcurrentHashMap()828 public ConcurrentHashMap() { 829 } 830 831 /** 832 * Creates a new, empty map with an initial table size 833 * accommodating the specified number of elements without the need 834 * to dynamically resize. 835 * 836 * @param initialCapacity The implementation performs internal 837 * sizing to accommodate this many elements. 838 * @throws IllegalArgumentException if the initial capacity of 839 * elements is negative 840 */ ConcurrentHashMap(int initialCapacity)841 public ConcurrentHashMap(int initialCapacity) { 842 this(initialCapacity, LOAD_FACTOR, 1); 843 } 844 845 /** 846 * Creates a new map with the same mappings as the given map. 847 * 848 * @param m the map 849 */ ConcurrentHashMap(Map<? extends K, ? extends V> m)850 public ConcurrentHashMap(Map<? extends K, ? extends V> m) { 851 this.sizeCtl = DEFAULT_CAPACITY; 852 putAll(m); 853 } 854 855 /** 856 * Creates a new, empty map with an initial table size based on 857 * the given number of elements ({@code initialCapacity}) and 858 * initial table density ({@code loadFactor}). 859 * 860 * @param initialCapacity the initial capacity. The implementation 861 * performs internal sizing to accommodate this many elements, 862 * given the specified load factor. 863 * @param loadFactor the load factor (table density) for 864 * establishing the initial table size 865 * @throws IllegalArgumentException if the initial capacity of 866 * elements is negative or the load factor is nonpositive 867 * 868 * @since 1.6 869 */ ConcurrentHashMap(int initialCapacity, float loadFactor)870 public ConcurrentHashMap(int initialCapacity, float loadFactor) { 871 this(initialCapacity, loadFactor, 1); 872 } 873 874 /** 875 * Creates a new, empty map with an initial table size based on 876 * the given number of elements ({@code initialCapacity}), initial 877 * table density ({@code loadFactor}), and number of concurrently 878 * updating threads ({@code concurrencyLevel}). 879 * 880 * @param initialCapacity the initial capacity. The implementation 881 * performs internal sizing to accommodate this many elements, 882 * given the specified load factor. 883 * @param loadFactor the load factor (table density) for 884 * establishing the initial table size 885 * @param concurrencyLevel the estimated number of concurrently 886 * updating threads. The implementation may use this value as 887 * a sizing hint. 888 * @throws IllegalArgumentException if the initial capacity is 889 * negative or the load factor or concurrencyLevel are 890 * nonpositive 891 */ ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel)892 public ConcurrentHashMap(int initialCapacity, 893 float loadFactor, int concurrencyLevel) { 894 if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) 895 throw new IllegalArgumentException(); 896 if (initialCapacity < concurrencyLevel) // Use at least as many bins 897 initialCapacity = concurrencyLevel; // as estimated threads 898 long size = (long)(1.0 + (long)initialCapacity / loadFactor); 899 int cap = (size >= (long)MAXIMUM_CAPACITY) ? 900 MAXIMUM_CAPACITY : tableSizeFor((int)size); 901 this.sizeCtl = cap; 902 } 903 904 // Original (since JDK1.2) Map methods 905 906 /** 907 * {@inheritDoc} 908 */ size()909 public int size() { 910 long n = sumCount(); 911 return ((n < 0L) ? 0 : 912 (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : 913 (int)n); 914 } 915 916 /** 917 * {@inheritDoc} 918 */ isEmpty()919 public boolean isEmpty() { 920 return sumCount() <= 0L; // ignore transient negative values 921 } 922 923 /** 924 * Returns the value to which the specified key is mapped, 925 * or {@code null} if this map contains no mapping for the key. 926 * 927 * <p>More formally, if this map contains a mapping from a key 928 * {@code k} to a value {@code v} such that {@code key.equals(k)}, 929 * then this method returns {@code v}; otherwise it returns 930 * {@code null}. (There can be at most one such mapping.) 931 * 932 * @throws NullPointerException if the specified key is null 933 */ get(Object key)934 public V get(Object key) { 935 Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek; 936 int h = spread(key.hashCode()); 937 if ((tab = table) != null && (n = tab.length) > 0 && 938 (e = tabAt(tab, (n - 1) & h)) != null) { 939 if ((eh = e.hash) == h) { 940 if ((ek = e.key) == key || (ek != null && key.equals(ek))) 941 return e.val; 942 } 943 else if (eh < 0) 944 return (p = e.find(h, key)) != null ? p.val : null; 945 while ((e = e.next) != null) { 946 if (e.hash == h && 947 ((ek = e.key) == key || (ek != null && key.equals(ek)))) 948 return e.val; 949 } 950 } 951 return null; 952 } 953 954 /** 955 * Tests if the specified object is a key in this table. 956 * 957 * @param key possible key 958 * @return {@code true} if and only if the specified object 959 * is a key in this table, as determined by the 960 * {@code equals} method; {@code false} otherwise 961 * @throws NullPointerException if the specified key is null 962 */ containsKey(Object key)963 public boolean containsKey(Object key) { 964 return get(key) != null; 965 } 966 967 /** 968 * Returns {@code true} if this map maps one or more keys to the 969 * specified value. Note: This method may require a full traversal 970 * of the map, and is much slower than method {@code containsKey}. 971 * 972 * @param value value whose presence in this map is to be tested 973 * @return {@code true} if this map maps one or more keys to the 974 * specified value 975 * @throws NullPointerException if the specified value is null 976 */ containsValue(Object value)977 public boolean containsValue(Object value) { 978 if (value == null) 979 throw new NullPointerException(); 980 Node<K,V>[] t; 981 if ((t = table) != null) { 982 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 983 for (Node<K,V> p; (p = it.advance()) != null; ) { 984 V v; 985 if ((v = p.val) == value || (v != null && value.equals(v))) 986 return true; 987 } 988 } 989 return false; 990 } 991 992 /** 993 * Maps the specified key to the specified value in this table. 994 * Neither the key nor the value can be null. 995 * 996 * <p>The value can be retrieved by calling the {@code get} method 997 * with a key that is equal to the original key. 998 * 999 * @param key key with which the specified value is to be associated 1000 * @param value value to be associated with the specified key 1001 * @return the previous value associated with {@code key}, or 1002 * {@code null} if there was no mapping for {@code key} 1003 * @throws NullPointerException if the specified key or value is null 1004 */ put(K key, V value)1005 public V put(K key, V value) { 1006 return putVal(key, value, false); 1007 } 1008 1009 /** Implementation for put and putIfAbsent */ putVal(K key, V value, boolean onlyIfAbsent)1010 final V putVal(K key, V value, boolean onlyIfAbsent) { 1011 if (key == null || value == null) throw new NullPointerException(); 1012 int hash = spread(key.hashCode()); 1013 int binCount = 0; 1014 for (Node<K,V>[] tab = table;;) { 1015 Node<K,V> f; int n, i, fh; K fk; V fv; 1016 if (tab == null || (n = tab.length) == 0) 1017 tab = initTable(); 1018 else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { 1019 if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value))) 1020 break; // no lock when adding to empty bin 1021 } 1022 else if ((fh = f.hash) == MOVED) 1023 tab = helpTransfer(tab, f); 1024 else if (onlyIfAbsent // check first node without acquiring lock 1025 && fh == hash 1026 && ((fk = f.key) == key || (fk != null && key.equals(fk))) 1027 && (fv = f.val) != null) 1028 return fv; 1029 else { 1030 V oldVal = null; 1031 synchronized (f) { 1032 if (tabAt(tab, i) == f) { 1033 if (fh >= 0) { 1034 binCount = 1; 1035 for (Node<K,V> e = f;; ++binCount) { 1036 K ek; 1037 if (e.hash == hash && 1038 ((ek = e.key) == key || 1039 (ek != null && key.equals(ek)))) { 1040 oldVal = e.val; 1041 if (!onlyIfAbsent) 1042 e.val = value; 1043 break; 1044 } 1045 Node<K,V> pred = e; 1046 if ((e = e.next) == null) { 1047 pred.next = new Node<K,V>(hash, key, value); 1048 break; 1049 } 1050 } 1051 } 1052 else if (f instanceof TreeBin) { 1053 Node<K,V> p; 1054 binCount = 2; 1055 if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, 1056 value)) != null) { 1057 oldVal = p.val; 1058 if (!onlyIfAbsent) 1059 p.val = value; 1060 } 1061 } 1062 else if (f instanceof ReservationNode) 1063 throw new IllegalStateException("Recursive update"); 1064 } 1065 } 1066 if (binCount != 0) { 1067 if (binCount >= TREEIFY_THRESHOLD) 1068 treeifyBin(tab, i); 1069 if (oldVal != null) 1070 return oldVal; 1071 break; 1072 } 1073 } 1074 } 1075 addCount(1L, binCount); 1076 return null; 1077 } 1078 1079 /** 1080 * Copies all of the mappings from the specified map to this one. 1081 * These mappings replace any mappings that this map had for any of the 1082 * keys currently in the specified map. 1083 * 1084 * @param m mappings to be stored in this map 1085 */ putAll(Map<? extends K, ? extends V> m)1086 public void putAll(Map<? extends K, ? extends V> m) { 1087 tryPresize(m.size()); 1088 for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) 1089 putVal(e.getKey(), e.getValue(), false); 1090 } 1091 1092 /** 1093 * Removes the key (and its corresponding value) from this map. 1094 * This method does nothing if the key is not in the map. 1095 * 1096 * @param key the key that needs to be removed 1097 * @return the previous value associated with {@code key}, or 1098 * {@code null} if there was no mapping for {@code key} 1099 * @throws NullPointerException if the specified key is null 1100 */ remove(Object key)1101 public V remove(Object key) { 1102 return replaceNode(key, null, null); 1103 } 1104 1105 /** 1106 * Implementation for the four public remove/replace methods: 1107 * Replaces node value with v, conditional upon match of cv if 1108 * non-null. If resulting value is null, delete. 1109 */ replaceNode(Object key, V value, Object cv)1110 final V replaceNode(Object key, V value, Object cv) { 1111 int hash = spread(key.hashCode()); 1112 for (Node<K,V>[] tab = table;;) { 1113 Node<K,V> f; int n, i, fh; 1114 if (tab == null || (n = tab.length) == 0 || 1115 (f = tabAt(tab, i = (n - 1) & hash)) == null) 1116 break; 1117 else if ((fh = f.hash) == MOVED) 1118 tab = helpTransfer(tab, f); 1119 else { 1120 V oldVal = null; 1121 boolean validated = false; 1122 synchronized (f) { 1123 if (tabAt(tab, i) == f) { 1124 if (fh >= 0) { 1125 validated = true; 1126 for (Node<K,V> e = f, pred = null;;) { 1127 K ek; 1128 if (e.hash == hash && 1129 ((ek = e.key) == key || 1130 (ek != null && key.equals(ek)))) { 1131 V ev = e.val; 1132 if (cv == null || cv == ev || 1133 (ev != null && cv.equals(ev))) { 1134 oldVal = ev; 1135 if (value != null) 1136 e.val = value; 1137 else if (pred != null) 1138 pred.next = e.next; 1139 else 1140 setTabAt(tab, i, e.next); 1141 } 1142 break; 1143 } 1144 pred = e; 1145 if ((e = e.next) == null) 1146 break; 1147 } 1148 } 1149 else if (f instanceof TreeBin) { 1150 validated = true; 1151 TreeBin<K,V> t = (TreeBin<K,V>)f; 1152 TreeNode<K,V> r, p; 1153 if ((r = t.root) != null && 1154 (p = r.findTreeNode(hash, key, null)) != null) { 1155 V pv = p.val; 1156 if (cv == null || cv == pv || 1157 (pv != null && cv.equals(pv))) { 1158 oldVal = pv; 1159 if (value != null) 1160 p.val = value; 1161 else if (t.removeTreeNode(p)) 1162 setTabAt(tab, i, untreeify(t.first)); 1163 } 1164 } 1165 } 1166 else if (f instanceof ReservationNode) 1167 throw new IllegalStateException("Recursive update"); 1168 } 1169 } 1170 if (validated) { 1171 if (oldVal != null) { 1172 if (value == null) 1173 addCount(-1L, -1); 1174 return oldVal; 1175 } 1176 break; 1177 } 1178 } 1179 } 1180 return null; 1181 } 1182 1183 /** 1184 * Removes all of the mappings from this map. 1185 */ clear()1186 public void clear() { 1187 long delta = 0L; // negative number of deletions 1188 int i = 0; 1189 Node<K,V>[] tab = table; 1190 while (tab != null && i < tab.length) { 1191 int fh; 1192 Node<K,V> f = tabAt(tab, i); 1193 if (f == null) 1194 ++i; 1195 else if ((fh = f.hash) == MOVED) { 1196 tab = helpTransfer(tab, f); 1197 i = 0; // restart 1198 } 1199 else { 1200 synchronized (f) { 1201 if (tabAt(tab, i) == f) { 1202 Node<K,V> p = (fh >= 0 ? f : 1203 (f instanceof TreeBin) ? 1204 ((TreeBin<K,V>)f).first : null); 1205 while (p != null) { 1206 --delta; 1207 p = p.next; 1208 } 1209 setTabAt(tab, i++, null); 1210 } 1211 } 1212 } 1213 } 1214 if (delta != 0L) 1215 addCount(delta, -1); 1216 } 1217 1218 /** 1219 * Returns a {@link Set} view of the keys contained in this map. 1220 * The set is backed by the map, so changes to the map are 1221 * reflected in the set, and vice-versa. The set supports element 1222 * removal, which removes the corresponding mapping from this map, 1223 * via the {@code Iterator.remove}, {@code Set.remove}, 1224 * {@code removeAll}, {@code retainAll}, and {@code clear} 1225 * operations. It does not support the {@code add} or 1226 * {@code addAll} operations. 1227 * 1228 * <p> The set returned by this method is guaranteed to an instance of 1229 * {@link KeySetView}. 1230 * 1231 * <p>The view's iterators and spliterators are 1232 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 1233 * 1234 * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT}, 1235 * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}. 1236 * 1237 * @return the set view 1238 */ 1239 // Android-changed: Return type for backwards compat. Was KeySetView<K,V>. http://b/28099367 1240 @dalvik.annotation.codegen.CovariantReturnType(returnType = KeySetView.class, presentAfter = 28) keySet()1241 public Set<K> keySet() { 1242 KeySetView<K,V> ks; 1243 if ((ks = keySet) != null) return ks; 1244 return keySet = new KeySetView<K,V>(this, null); 1245 } 1246 1247 /** 1248 * Returns a {@link Collection} view of the values contained in this map. 1249 * The collection is backed by the map, so changes to the map are 1250 * reflected in the collection, and vice-versa. The collection 1251 * supports element removal, which removes the corresponding 1252 * mapping from this map, via the {@code Iterator.remove}, 1253 * {@code Collection.remove}, {@code removeAll}, 1254 * {@code retainAll}, and {@code clear} operations. It does not 1255 * support the {@code add} or {@code addAll} operations. 1256 * 1257 * <p>The view's iterators and spliterators are 1258 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 1259 * 1260 * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT} 1261 * and {@link Spliterator#NONNULL}. 1262 * 1263 * @return the collection view 1264 */ values()1265 public Collection<V> values() { 1266 ValuesView<K,V> vs; 1267 if ((vs = values) != null) return vs; 1268 return values = new ValuesView<K,V>(this); 1269 } 1270 1271 /** 1272 * Returns a {@link Set} view of the mappings contained in this map. 1273 * The set is backed by the map, so changes to the map are 1274 * reflected in the set, and vice-versa. The set supports element 1275 * removal, which removes the corresponding mapping from the map, 1276 * via the {@code Iterator.remove}, {@code Set.remove}, 1277 * {@code removeAll}, {@code retainAll}, and {@code clear} 1278 * operations. 1279 * 1280 * <p>The view's iterators and spliterators are 1281 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 1282 * 1283 * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT}, 1284 * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}. 1285 * 1286 * @return the set view 1287 */ entrySet()1288 public Set<Map.Entry<K,V>> entrySet() { 1289 EntrySetView<K,V> es; 1290 if ((es = entrySet) != null) return es; 1291 return entrySet = new EntrySetView<K,V>(this); 1292 } 1293 1294 /** 1295 * Returns the hash code value for this {@link Map}, i.e., 1296 * the sum of, for each key-value pair in the map, 1297 * {@code key.hashCode() ^ value.hashCode()}. 1298 * 1299 * @return the hash code value for this map 1300 */ hashCode()1301 public int hashCode() { 1302 int h = 0; 1303 Node<K,V>[] t; 1304 if ((t = table) != null) { 1305 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 1306 for (Node<K,V> p; (p = it.advance()) != null; ) 1307 h += p.key.hashCode() ^ p.val.hashCode(); 1308 } 1309 return h; 1310 } 1311 1312 /** 1313 * Returns a string representation of this map. The string 1314 * representation consists of a list of key-value mappings (in no 1315 * particular order) enclosed in braces ("{@code {}}"). Adjacent 1316 * mappings are separated by the characters {@code ", "} (comma 1317 * and space). Each key-value mapping is rendered as the key 1318 * followed by an equals sign ("{@code =}") followed by the 1319 * associated value. 1320 * 1321 * @return a string representation of this map 1322 */ toString()1323 public String toString() { 1324 Node<K,V>[] t; 1325 int f = (t = table) == null ? 0 : t.length; 1326 Traverser<K,V> it = new Traverser<K,V>(t, f, 0, f); 1327 StringBuilder sb = new StringBuilder(); 1328 sb.append('{'); 1329 Node<K,V> p; 1330 if ((p = it.advance()) != null) { 1331 for (;;) { 1332 K k = p.key; 1333 V v = p.val; 1334 sb.append(k == this ? "(this Map)" : k); 1335 sb.append('='); 1336 sb.append(v == this ? "(this Map)" : v); 1337 if ((p = it.advance()) == null) 1338 break; 1339 sb.append(',').append(' '); 1340 } 1341 } 1342 return sb.append('}').toString(); 1343 } 1344 1345 /** 1346 * Compares the specified object with this map for equality. 1347 * Returns {@code true} if the given object is a map with the same 1348 * mappings as this map. This operation may return misleading 1349 * results if either map is concurrently modified during execution 1350 * of this method. 1351 * 1352 * @param o object to be compared for equality with this map 1353 * @return {@code true} if the specified object is equal to this map 1354 */ equals(Object o)1355 public boolean equals(Object o) { 1356 if (o != this) { 1357 if (!(o instanceof Map)) 1358 return false; 1359 Map<?,?> m = (Map<?,?>) o; 1360 Node<K,V>[] t; 1361 int f = (t = table) == null ? 0 : t.length; 1362 Traverser<K,V> it = new Traverser<K,V>(t, f, 0, f); 1363 for (Node<K,V> p; (p = it.advance()) != null; ) { 1364 V val = p.val; 1365 Object v = m.get(p.key); 1366 if (v == null || (v != val && !v.equals(val))) 1367 return false; 1368 } 1369 for (Map.Entry<?,?> e : m.entrySet()) { 1370 Object mk, mv, v; 1371 if ((mk = e.getKey()) == null || 1372 (mv = e.getValue()) == null || 1373 (v = get(mk)) == null || 1374 (mv != v && !mv.equals(v))) 1375 return false; 1376 } 1377 } 1378 return true; 1379 } 1380 1381 /** 1382 * Stripped-down version of helper class used in previous version, 1383 * declared for the sake of serialization compatibility. 1384 */ 1385 static class Segment<K,V> extends ReentrantLock implements Serializable { 1386 private static final long serialVersionUID = 2249069246763182397L; 1387 final float loadFactor; Segment(float lf)1388 Segment(float lf) { this.loadFactor = lf; } 1389 } 1390 1391 /** 1392 * Saves this map to a stream (that is, serializes it). 1393 * 1394 * @param s the stream 1395 * @throws java.io.IOException if an I/O error occurs 1396 * @serialData 1397 * the serialized fields, followed by the key (Object) and value 1398 * (Object) for each key-value mapping, followed by a null pair. 1399 * The key-value mappings are emitted in no particular order. 1400 */ writeObject(java.io.ObjectOutputStream s)1401 private void writeObject(java.io.ObjectOutputStream s) 1402 throws java.io.IOException { 1403 // For serialization compatibility 1404 // Emulate segment calculation from previous version of this class 1405 int sshift = 0; 1406 int ssize = 1; 1407 while (ssize < DEFAULT_CONCURRENCY_LEVEL) { 1408 ++sshift; 1409 ssize <<= 1; 1410 } 1411 int segmentShift = 32 - sshift; 1412 int segmentMask = ssize - 1; 1413 @SuppressWarnings("unchecked") 1414 Segment<K,V>[] segments = (Segment<K,V>[]) 1415 new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL]; 1416 for (int i = 0; i < segments.length; ++i) 1417 segments[i] = new Segment<K,V>(LOAD_FACTOR); 1418 java.io.ObjectOutputStream.PutField streamFields = s.putFields(); 1419 streamFields.put("segments", segments); 1420 streamFields.put("segmentShift", segmentShift); 1421 streamFields.put("segmentMask", segmentMask); 1422 s.writeFields(); 1423 1424 Node<K,V>[] t; 1425 if ((t = table) != null) { 1426 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 1427 for (Node<K,V> p; (p = it.advance()) != null; ) { 1428 s.writeObject(p.key); 1429 s.writeObject(p.val); 1430 } 1431 } 1432 s.writeObject(null); 1433 s.writeObject(null); 1434 } 1435 1436 /** 1437 * Reconstitutes this map from a stream (that is, deserializes it). 1438 * @param s the stream 1439 * @throws ClassNotFoundException if the class of a serialized object 1440 * could not be found 1441 * @throws java.io.IOException if an I/O error occurs 1442 */ readObject(java.io.ObjectInputStream s)1443 private void readObject(java.io.ObjectInputStream s) 1444 throws java.io.IOException, ClassNotFoundException { 1445 /* 1446 * To improve performance in typical cases, we create nodes 1447 * while reading, then place in table once size is known. 1448 * However, we must also validate uniqueness and deal with 1449 * overpopulated bins while doing so, which requires 1450 * specialized versions of putVal mechanics. 1451 */ 1452 sizeCtl = -1; // force exclusion for table construction 1453 s.defaultReadObject(); 1454 long size = 0L; 1455 Node<K,V> p = null; 1456 for (;;) { 1457 @SuppressWarnings("unchecked") 1458 K k = (K) s.readObject(); 1459 @SuppressWarnings("unchecked") 1460 V v = (V) s.readObject(); 1461 if (k != null && v != null) { 1462 p = new Node<K,V>(spread(k.hashCode()), k, v, p); 1463 ++size; 1464 } 1465 else 1466 break; 1467 } 1468 if (size == 0L) 1469 sizeCtl = 0; 1470 else { 1471 long ts = (long)(1.0 + size / LOAD_FACTOR); 1472 int n = (ts >= (long)MAXIMUM_CAPACITY) ? 1473 MAXIMUM_CAPACITY : tableSizeFor((int)ts); 1474 @SuppressWarnings("unchecked") 1475 Node<K,V>[] tab = (Node<K,V>[])new Node<?,?>[n]; 1476 int mask = n - 1; 1477 long added = 0L; 1478 while (p != null) { 1479 boolean insertAtFront; 1480 Node<K,V> next = p.next, first; 1481 int h = p.hash, j = h & mask; 1482 if ((first = tabAt(tab, j)) == null) 1483 insertAtFront = true; 1484 else { 1485 K k = p.key; 1486 if (first.hash < 0) { 1487 TreeBin<K,V> t = (TreeBin<K,V>)first; 1488 if (t.putTreeVal(h, k, p.val) == null) 1489 ++added; 1490 insertAtFront = false; 1491 } 1492 else { 1493 int binCount = 0; 1494 insertAtFront = true; 1495 Node<K,V> q; K qk; 1496 for (q = first; q != null; q = q.next) { 1497 if (q.hash == h && 1498 ((qk = q.key) == k || 1499 (qk != null && k.equals(qk)))) { 1500 insertAtFront = false; 1501 break; 1502 } 1503 ++binCount; 1504 } 1505 if (insertAtFront && binCount >= TREEIFY_THRESHOLD) { 1506 insertAtFront = false; 1507 ++added; 1508 p.next = first; 1509 TreeNode<K,V> hd = null, tl = null; 1510 for (q = p; q != null; q = q.next) { 1511 TreeNode<K,V> t = new TreeNode<K,V> 1512 (q.hash, q.key, q.val, null, null); 1513 if ((t.prev = tl) == null) 1514 hd = t; 1515 else 1516 tl.next = t; 1517 tl = t; 1518 } 1519 setTabAt(tab, j, new TreeBin<K,V>(hd)); 1520 } 1521 } 1522 } 1523 if (insertAtFront) { 1524 ++added; 1525 p.next = first; 1526 setTabAt(tab, j, p); 1527 } 1528 p = next; 1529 } 1530 table = tab; 1531 sizeCtl = n - (n >>> 2); 1532 baseCount = added; 1533 } 1534 } 1535 1536 // ConcurrentMap methods 1537 1538 /** 1539 * {@inheritDoc} 1540 * 1541 * @return the previous value associated with the specified key, 1542 * or {@code null} if there was no mapping for the key 1543 * @throws NullPointerException if the specified key or value is null 1544 */ putIfAbsent(K key, V value)1545 public V putIfAbsent(K key, V value) { 1546 return putVal(key, value, true); 1547 } 1548 1549 /** 1550 * {@inheritDoc} 1551 * 1552 * @throws NullPointerException if the specified key is null 1553 */ remove(Object key, Object value)1554 public boolean remove(Object key, Object value) { 1555 if (key == null) 1556 throw new NullPointerException(); 1557 return value != null && replaceNode(key, null, value) != null; 1558 } 1559 1560 /** 1561 * {@inheritDoc} 1562 * 1563 * @throws NullPointerException if any of the arguments are null 1564 */ replace(K key, V oldValue, V newValue)1565 public boolean replace(K key, V oldValue, V newValue) { 1566 if (key == null || oldValue == null || newValue == null) 1567 throw new NullPointerException(); 1568 return replaceNode(key, newValue, oldValue) != null; 1569 } 1570 1571 /** 1572 * {@inheritDoc} 1573 * 1574 * @return the previous value associated with the specified key, 1575 * or {@code null} if there was no mapping for the key 1576 * @throws NullPointerException if the specified key or value is null 1577 */ replace(K key, V value)1578 public V replace(K key, V value) { 1579 if (key == null || value == null) 1580 throw new NullPointerException(); 1581 return replaceNode(key, value, null); 1582 } 1583 1584 // Overrides of JDK8+ Map extension method defaults 1585 1586 /** 1587 * Returns the value to which the specified key is mapped, or the 1588 * given default value if this map contains no mapping for the 1589 * key. 1590 * 1591 * @param key the key whose associated value is to be returned 1592 * @param defaultValue the value to return if this map contains 1593 * no mapping for the given key 1594 * @return the mapping for the key, if present; else the default value 1595 * @throws NullPointerException if the specified key is null 1596 */ getOrDefault(Object key, V defaultValue)1597 public V getOrDefault(Object key, V defaultValue) { 1598 V v; 1599 return (v = get(key)) == null ? defaultValue : v; 1600 } 1601 forEach(BiConsumer<? super K, ? super V> action)1602 public void forEach(BiConsumer<? super K, ? super V> action) { 1603 if (action == null) throw new NullPointerException(); 1604 Node<K,V>[] t; 1605 if ((t = table) != null) { 1606 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 1607 for (Node<K,V> p; (p = it.advance()) != null; ) { 1608 action.accept(p.key, p.val); 1609 } 1610 } 1611 } 1612 replaceAll(BiFunction<? super K, ? super V, ? extends V> function)1613 public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { 1614 if (function == null) throw new NullPointerException(); 1615 Node<K,V>[] t; 1616 if ((t = table) != null) { 1617 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 1618 for (Node<K,V> p; (p = it.advance()) != null; ) { 1619 V oldValue = p.val; 1620 for (K key = p.key;;) { 1621 V newValue = function.apply(key, oldValue); 1622 if (newValue == null) 1623 throw new NullPointerException(); 1624 if (replaceNode(key, newValue, oldValue) != null || 1625 (oldValue = get(key)) == null) 1626 break; 1627 } 1628 } 1629 } 1630 } 1631 1632 /** 1633 * Helper method for EntrySetView.removeIf. 1634 */ removeEntryIf(Predicate<? super Entry<K,V>> function)1635 boolean removeEntryIf(Predicate<? super Entry<K,V>> function) { 1636 if (function == null) throw new NullPointerException(); 1637 Node<K,V>[] t; 1638 boolean removed = false; 1639 if ((t = table) != null) { 1640 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 1641 for (Node<K,V> p; (p = it.advance()) != null; ) { 1642 K k = p.key; 1643 V v = p.val; 1644 Map.Entry<K,V> e = new AbstractMap.SimpleImmutableEntry<>(k, v); 1645 if (function.test(e) && replaceNode(k, null, v) != null) 1646 removed = true; 1647 } 1648 } 1649 return removed; 1650 } 1651 1652 /** 1653 * Helper method for ValuesView.removeIf. 1654 */ removeValueIf(Predicate<? super V> function)1655 boolean removeValueIf(Predicate<? super V> function) { 1656 if (function == null) throw new NullPointerException(); 1657 Node<K,V>[] t; 1658 boolean removed = false; 1659 if ((t = table) != null) { 1660 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 1661 for (Node<K,V> p; (p = it.advance()) != null; ) { 1662 K k = p.key; 1663 V v = p.val; 1664 if (function.test(v) && replaceNode(k, null, v) != null) 1665 removed = true; 1666 } 1667 } 1668 return removed; 1669 } 1670 1671 /** 1672 * If the specified key is not already associated with a value, 1673 * attempts to compute its value using the given mapping function 1674 * and enters it into this map unless {@code null}. The entire 1675 * method invocation is performed atomically, so the function is 1676 * applied at most once per key. Some attempted update operations 1677 * on this map by other threads may be blocked while computation 1678 * is in progress, so the computation should be short and simple, 1679 * and must not attempt to update any other mappings of this map. 1680 * 1681 * @param key key with which the specified value is to be associated 1682 * @param mappingFunction the function to compute a value 1683 * @return the current (existing or computed) value associated with 1684 * the specified key, or null if the computed value is null 1685 * @throws NullPointerException if the specified key or mappingFunction 1686 * is null 1687 * @throws IllegalStateException if the computation detectably 1688 * attempts a recursive update to this map that would 1689 * otherwise never complete 1690 * @throws RuntimeException or Error if the mappingFunction does so, 1691 * in which case the mapping is left unestablished 1692 */ computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)1693 public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { 1694 if (key == null || mappingFunction == null) 1695 throw new NullPointerException(); 1696 int h = spread(key.hashCode()); 1697 V val = null; 1698 int binCount = 0; 1699 for (Node<K,V>[] tab = table;;) { 1700 Node<K,V> f; int n, i, fh; K fk; V fv; 1701 if (tab == null || (n = tab.length) == 0) 1702 tab = initTable(); 1703 else if ((f = tabAt(tab, i = (n - 1) & h)) == null) { 1704 Node<K,V> r = new ReservationNode<K,V>(); 1705 synchronized (r) { 1706 if (casTabAt(tab, i, null, r)) { 1707 binCount = 1; 1708 Node<K,V> node = null; 1709 try { 1710 if ((val = mappingFunction.apply(key)) != null) 1711 node = new Node<K,V>(h, key, val); 1712 } finally { 1713 setTabAt(tab, i, node); 1714 } 1715 } 1716 } 1717 if (binCount != 0) 1718 break; 1719 } 1720 else if ((fh = f.hash) == MOVED) 1721 tab = helpTransfer(tab, f); 1722 else if (fh == h // check first node without acquiring lock 1723 && ((fk = f.key) == key || (fk != null && key.equals(fk))) 1724 && (fv = f.val) != null) 1725 return fv; 1726 else { 1727 boolean added = false; 1728 synchronized (f) { 1729 if (tabAt(tab, i) == f) { 1730 if (fh >= 0) { 1731 binCount = 1; 1732 for (Node<K,V> e = f;; ++binCount) { 1733 K ek; 1734 if (e.hash == h && 1735 ((ek = e.key) == key || 1736 (ek != null && key.equals(ek)))) { 1737 val = e.val; 1738 break; 1739 } 1740 Node<K,V> pred = e; 1741 if ((e = e.next) == null) { 1742 if ((val = mappingFunction.apply(key)) != null) { 1743 if (pred.next != null) 1744 throw new IllegalStateException("Recursive update"); 1745 added = true; 1746 pred.next = new Node<K,V>(h, key, val); 1747 } 1748 break; 1749 } 1750 } 1751 } 1752 else if (f instanceof TreeBin) { 1753 binCount = 2; 1754 TreeBin<K,V> t = (TreeBin<K,V>)f; 1755 TreeNode<K,V> r, p; 1756 if ((r = t.root) != null && 1757 (p = r.findTreeNode(h, key, null)) != null) 1758 val = p.val; 1759 else if ((val = mappingFunction.apply(key)) != null) { 1760 added = true; 1761 t.putTreeVal(h, key, val); 1762 } 1763 } 1764 else if (f instanceof ReservationNode) 1765 throw new IllegalStateException("Recursive update"); 1766 } 1767 } 1768 if (binCount != 0) { 1769 if (binCount >= TREEIFY_THRESHOLD) 1770 treeifyBin(tab, i); 1771 if (!added) 1772 return val; 1773 break; 1774 } 1775 } 1776 } 1777 if (val != null) 1778 addCount(1L, binCount); 1779 return val; 1780 } 1781 1782 /** 1783 * If the value for the specified key is present, attempts to 1784 * compute a new mapping given the key and its current mapped 1785 * value. The entire method invocation is performed atomically. 1786 * Some attempted update operations on this map by other threads 1787 * may be blocked while computation is in progress, so the 1788 * computation should be short and simple, and must not attempt to 1789 * update any other mappings of this map. 1790 * 1791 * @param key key with which a value may be associated 1792 * @param remappingFunction the function to compute a value 1793 * @return the new value associated with the specified key, or null if none 1794 * @throws NullPointerException if the specified key or remappingFunction 1795 * is null 1796 * @throws IllegalStateException if the computation detectably 1797 * attempts a recursive update to this map that would 1798 * otherwise never complete 1799 * @throws RuntimeException or Error if the remappingFunction does so, 1800 * in which case the mapping is unchanged 1801 */ computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)1802 public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 1803 if (key == null || remappingFunction == null) 1804 throw new NullPointerException(); 1805 int h = spread(key.hashCode()); 1806 V val = null; 1807 int delta = 0; 1808 int binCount = 0; 1809 for (Node<K,V>[] tab = table;;) { 1810 Node<K,V> f; int n, i, fh; 1811 if (tab == null || (n = tab.length) == 0) 1812 tab = initTable(); 1813 else if ((f = tabAt(tab, i = (n - 1) & h)) == null) 1814 break; 1815 else if ((fh = f.hash) == MOVED) 1816 tab = helpTransfer(tab, f); 1817 else { 1818 synchronized (f) { 1819 if (tabAt(tab, i) == f) { 1820 if (fh >= 0) { 1821 binCount = 1; 1822 for (Node<K,V> e = f, pred = null;; ++binCount) { 1823 K ek; 1824 if (e.hash == h && 1825 ((ek = e.key) == key || 1826 (ek != null && key.equals(ek)))) { 1827 val = remappingFunction.apply(key, e.val); 1828 if (val != null) 1829 e.val = val; 1830 else { 1831 delta = -1; 1832 Node<K,V> en = e.next; 1833 if (pred != null) 1834 pred.next = en; 1835 else 1836 setTabAt(tab, i, en); 1837 } 1838 break; 1839 } 1840 pred = e; 1841 if ((e = e.next) == null) 1842 break; 1843 } 1844 } 1845 else if (f instanceof TreeBin) { 1846 binCount = 2; 1847 TreeBin<K,V> t = (TreeBin<K,V>)f; 1848 TreeNode<K,V> r, p; 1849 if ((r = t.root) != null && 1850 (p = r.findTreeNode(h, key, null)) != null) { 1851 val = remappingFunction.apply(key, p.val); 1852 if (val != null) 1853 p.val = val; 1854 else { 1855 delta = -1; 1856 if (t.removeTreeNode(p)) 1857 setTabAt(tab, i, untreeify(t.first)); 1858 } 1859 } 1860 } 1861 else if (f instanceof ReservationNode) 1862 throw new IllegalStateException("Recursive update"); 1863 } 1864 } 1865 if (binCount != 0) 1866 break; 1867 } 1868 } 1869 if (delta != 0) 1870 addCount((long)delta, binCount); 1871 return val; 1872 } 1873 1874 /** 1875 * Attempts to compute a mapping for the specified key and its 1876 * current mapped value (or {@code null} if there is no current 1877 * mapping). The entire method invocation is performed atomically. 1878 * Some attempted update operations on this map by other threads 1879 * may be blocked while computation is in progress, so the 1880 * computation should be short and simple, and must not attempt to 1881 * update any other mappings of this Map. 1882 * 1883 * @param key key with which the specified value is to be associated 1884 * @param remappingFunction the function to compute a value 1885 * @return the new value associated with the specified key, or null if none 1886 * @throws NullPointerException if the specified key or remappingFunction 1887 * is null 1888 * @throws IllegalStateException if the computation detectably 1889 * attempts a recursive update to this map that would 1890 * otherwise never complete 1891 * @throws RuntimeException or Error if the remappingFunction does so, 1892 * in which case the mapping is unchanged 1893 */ compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)1894 public V compute(K key, 1895 BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 1896 if (key == null || remappingFunction == null) 1897 throw new NullPointerException(); 1898 int h = spread(key.hashCode()); 1899 V val = null; 1900 int delta = 0; 1901 int binCount = 0; 1902 for (Node<K,V>[] tab = table;;) { 1903 Node<K,V> f; int n, i, fh; 1904 if (tab == null || (n = tab.length) == 0) 1905 tab = initTable(); 1906 else if ((f = tabAt(tab, i = (n - 1) & h)) == null) { 1907 Node<K,V> r = new ReservationNode<K,V>(); 1908 synchronized (r) { 1909 if (casTabAt(tab, i, null, r)) { 1910 binCount = 1; 1911 Node<K,V> node = null; 1912 try { 1913 if ((val = remappingFunction.apply(key, null)) != null) { 1914 delta = 1; 1915 node = new Node<K,V>(h, key, val); 1916 } 1917 } finally { 1918 setTabAt(tab, i, node); 1919 } 1920 } 1921 } 1922 if (binCount != 0) 1923 break; 1924 } 1925 else if ((fh = f.hash) == MOVED) 1926 tab = helpTransfer(tab, f); 1927 else { 1928 synchronized (f) { 1929 if (tabAt(tab, i) == f) { 1930 if (fh >= 0) { 1931 binCount = 1; 1932 for (Node<K,V> e = f, pred = null;; ++binCount) { 1933 K ek; 1934 if (e.hash == h && 1935 ((ek = e.key) == key || 1936 (ek != null && key.equals(ek)))) { 1937 val = remappingFunction.apply(key, e.val); 1938 if (val != null) 1939 e.val = val; 1940 else { 1941 delta = -1; 1942 Node<K,V> en = e.next; 1943 if (pred != null) 1944 pred.next = en; 1945 else 1946 setTabAt(tab, i, en); 1947 } 1948 break; 1949 } 1950 pred = e; 1951 if ((e = e.next) == null) { 1952 val = remappingFunction.apply(key, null); 1953 if (val != null) { 1954 if (pred.next != null) 1955 throw new IllegalStateException("Recursive update"); 1956 delta = 1; 1957 pred.next = new Node<K,V>(h, key, val); 1958 } 1959 break; 1960 } 1961 } 1962 } 1963 else if (f instanceof TreeBin) { 1964 binCount = 1; 1965 TreeBin<K,V> t = (TreeBin<K,V>)f; 1966 TreeNode<K,V> r, p; 1967 if ((r = t.root) != null) 1968 p = r.findTreeNode(h, key, null); 1969 else 1970 p = null; 1971 V pv = (p == null) ? null : p.val; 1972 val = remappingFunction.apply(key, pv); 1973 if (val != null) { 1974 if (p != null) 1975 p.val = val; 1976 else { 1977 delta = 1; 1978 t.putTreeVal(h, key, val); 1979 } 1980 } 1981 else if (p != null) { 1982 delta = -1; 1983 if (t.removeTreeNode(p)) 1984 setTabAt(tab, i, untreeify(t.first)); 1985 } 1986 } 1987 else if (f instanceof ReservationNode) 1988 throw new IllegalStateException("Recursive update"); 1989 } 1990 } 1991 if (binCount != 0) { 1992 if (binCount >= TREEIFY_THRESHOLD) 1993 treeifyBin(tab, i); 1994 break; 1995 } 1996 } 1997 } 1998 if (delta != 0) 1999 addCount((long)delta, binCount); 2000 return val; 2001 } 2002 2003 /** 2004 * If the specified key is not already associated with a 2005 * (non-null) value, associates it with the given value. 2006 * Otherwise, replaces the value with the results of the given 2007 * remapping function, or removes if {@code null}. The entire 2008 * method invocation is performed atomically. Some attempted 2009 * update operations on this map by other threads may be blocked 2010 * while computation is in progress, so the computation should be 2011 * short and simple, and must not attempt to update any other 2012 * mappings of this Map. 2013 * 2014 * @param key key with which the specified value is to be associated 2015 * @param value the value to use if absent 2016 * @param remappingFunction the function to recompute a value if present 2017 * @return the new value associated with the specified key, or null if none 2018 * @throws NullPointerException if the specified key or the 2019 * remappingFunction is null 2020 * @throws RuntimeException or Error if the remappingFunction does so, 2021 * in which case the mapping is unchanged 2022 */ merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)2023 public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { 2024 if (key == null || value == null || remappingFunction == null) 2025 throw new NullPointerException(); 2026 int h = spread(key.hashCode()); 2027 V val = null; 2028 int delta = 0; 2029 int binCount = 0; 2030 for (Node<K,V>[] tab = table;;) { 2031 Node<K,V> f; int n, i, fh; 2032 if (tab == null || (n = tab.length) == 0) 2033 tab = initTable(); 2034 else if ((f = tabAt(tab, i = (n - 1) & h)) == null) { 2035 if (casTabAt(tab, i, null, new Node<K,V>(h, key, value))) { 2036 delta = 1; 2037 val = value; 2038 break; 2039 } 2040 } 2041 else if ((fh = f.hash) == MOVED) 2042 tab = helpTransfer(tab, f); 2043 else { 2044 synchronized (f) { 2045 if (tabAt(tab, i) == f) { 2046 if (fh >= 0) { 2047 binCount = 1; 2048 for (Node<K,V> e = f, pred = null;; ++binCount) { 2049 K ek; 2050 if (e.hash == h && 2051 ((ek = e.key) == key || 2052 (ek != null && key.equals(ek)))) { 2053 val = remappingFunction.apply(e.val, value); 2054 if (val != null) 2055 e.val = val; 2056 else { 2057 delta = -1; 2058 Node<K,V> en = e.next; 2059 if (pred != null) 2060 pred.next = en; 2061 else 2062 setTabAt(tab, i, en); 2063 } 2064 break; 2065 } 2066 pred = e; 2067 if ((e = e.next) == null) { 2068 delta = 1; 2069 val = value; 2070 pred.next = new Node<K,V>(h, key, val); 2071 break; 2072 } 2073 } 2074 } 2075 else if (f instanceof TreeBin) { 2076 binCount = 2; 2077 TreeBin<K,V> t = (TreeBin<K,V>)f; 2078 TreeNode<K,V> r = t.root; 2079 TreeNode<K,V> p = (r == null) ? null : 2080 r.findTreeNode(h, key, null); 2081 val = (p == null) ? value : 2082 remappingFunction.apply(p.val, value); 2083 if (val != null) { 2084 if (p != null) 2085 p.val = val; 2086 else { 2087 delta = 1; 2088 t.putTreeVal(h, key, val); 2089 } 2090 } 2091 else if (p != null) { 2092 delta = -1; 2093 if (t.removeTreeNode(p)) 2094 setTabAt(tab, i, untreeify(t.first)); 2095 } 2096 } 2097 else if (f instanceof ReservationNode) 2098 throw new IllegalStateException("Recursive update"); 2099 } 2100 } 2101 if (binCount != 0) { 2102 if (binCount >= TREEIFY_THRESHOLD) 2103 treeifyBin(tab, i); 2104 break; 2105 } 2106 } 2107 } 2108 if (delta != 0) 2109 addCount((long)delta, binCount); 2110 return val; 2111 } 2112 2113 // Hashtable legacy methods 2114 2115 /** 2116 * Tests if some key maps into the specified value in this table. 2117 * 2118 * <p>Note that this method is identical in functionality to 2119 * {@link #containsValue(Object)}, and exists solely to ensure 2120 * full compatibility with class {@link java.util.Hashtable}, 2121 * which supported this method prior to introduction of the 2122 * Java Collections Framework. 2123 * 2124 * @param value a value to search for 2125 * @return {@code true} if and only if some key maps to the 2126 * {@code value} argument in this table as 2127 * determined by the {@code equals} method; 2128 * {@code false} otherwise 2129 * @throws NullPointerException if the specified value is null 2130 */ contains(Object value)2131 public boolean contains(Object value) { 2132 return containsValue(value); 2133 } 2134 2135 /** 2136 * Returns an enumeration of the keys in this table. 2137 * 2138 * @return an enumeration of the keys in this table 2139 * @see #keySet() 2140 */ keys()2141 public Enumeration<K> keys() { 2142 Node<K,V>[] t; 2143 int f = (t = table) == null ? 0 : t.length; 2144 return new KeyIterator<K,V>(t, f, 0, f, this); 2145 } 2146 2147 /** 2148 * Returns an enumeration of the values in this table. 2149 * 2150 * @return an enumeration of the values in this table 2151 * @see #values() 2152 */ elements()2153 public Enumeration<V> elements() { 2154 Node<K,V>[] t; 2155 int f = (t = table) == null ? 0 : t.length; 2156 return new ValueIterator<K,V>(t, f, 0, f, this); 2157 } 2158 2159 // ConcurrentHashMap-only methods 2160 2161 /** 2162 * Returns the number of mappings. This method should be used 2163 * instead of {@link #size} because a ConcurrentHashMap may 2164 * contain more mappings than can be represented as an int. The 2165 * value returned is an estimate; the actual count may differ if 2166 * there are concurrent insertions or removals. 2167 * 2168 * @return the number of mappings 2169 * @since 1.8 2170 */ mappingCount()2171 public long mappingCount() { 2172 long n = sumCount(); 2173 return (n < 0L) ? 0L : n; // ignore transient negative values 2174 } 2175 2176 /** 2177 * Creates a new {@link Set} backed by a ConcurrentHashMap 2178 * from the given type to {@code Boolean.TRUE}. 2179 * 2180 * @param <K> the element type of the returned set 2181 * @return the new set 2182 * @since 1.8 2183 */ newKeySet()2184 public static <K> KeySetView<K,Boolean> newKeySet() { 2185 return new KeySetView<K,Boolean> 2186 (new ConcurrentHashMap<K,Boolean>(), Boolean.TRUE); 2187 } 2188 2189 /** 2190 * Creates a new {@link Set} backed by a ConcurrentHashMap 2191 * from the given type to {@code Boolean.TRUE}. 2192 * 2193 * @param initialCapacity The implementation performs internal 2194 * sizing to accommodate this many elements. 2195 * @param <K> the element type of the returned set 2196 * @return the new set 2197 * @throws IllegalArgumentException if the initial capacity of 2198 * elements is negative 2199 * @since 1.8 2200 */ newKeySet(int initialCapacity)2201 public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) { 2202 return new KeySetView<K,Boolean> 2203 (new ConcurrentHashMap<K,Boolean>(initialCapacity), Boolean.TRUE); 2204 } 2205 2206 /** 2207 * Returns a {@link Set} view of the keys in this map, using the 2208 * given common mapped value for any additions (i.e., {@link 2209 * Collection#add} and {@link Collection#addAll(Collection)}). 2210 * This is of course only appropriate if it is acceptable to use 2211 * the same value for all additions from this view. 2212 * 2213 * @param mappedValue the mapped value to use for any additions 2214 * @return the set view 2215 * @throws NullPointerException if the mappedValue is null 2216 */ keySet(V mappedValue)2217 public KeySetView<K,V> keySet(V mappedValue) { 2218 if (mappedValue == null) 2219 throw new NullPointerException(); 2220 return new KeySetView<K,V>(this, mappedValue); 2221 } 2222 2223 /* ---------------- Special Nodes -------------- */ 2224 2225 /** 2226 * A node inserted at head of bins during transfer operations. 2227 */ 2228 static final class ForwardingNode<K,V> extends Node<K,V> { 2229 final Node<K,V>[] nextTable; ForwardingNode(Node<K,V>[] tab)2230 ForwardingNode(Node<K,V>[] tab) { 2231 super(MOVED, null, null); 2232 this.nextTable = tab; 2233 } 2234 find(int h, Object k)2235 Node<K,V> find(int h, Object k) { 2236 // loop to avoid arbitrarily deep recursion on forwarding nodes 2237 outer: for (Node<K,V>[] tab = nextTable;;) { 2238 Node<K,V> e; int n; 2239 if (k == null || tab == null || (n = tab.length) == 0 || 2240 (e = tabAt(tab, (n - 1) & h)) == null) 2241 return null; 2242 for (;;) { 2243 int eh; K ek; 2244 if ((eh = e.hash) == h && 2245 ((ek = e.key) == k || (ek != null && k.equals(ek)))) 2246 return e; 2247 if (eh < 0) { 2248 if (e instanceof ForwardingNode) { 2249 tab = ((ForwardingNode<K,V>)e).nextTable; 2250 continue outer; 2251 } 2252 else 2253 return e.find(h, k); 2254 } 2255 if ((e = e.next) == null) 2256 return null; 2257 } 2258 } 2259 } 2260 } 2261 2262 /** 2263 * A place-holder node used in computeIfAbsent and compute. 2264 */ 2265 static final class ReservationNode<K,V> extends Node<K,V> { ReservationNode()2266 ReservationNode() { 2267 super(RESERVED, null, null); 2268 } 2269 find(int h, Object k)2270 Node<K,V> find(int h, Object k) { 2271 return null; 2272 } 2273 } 2274 2275 /* ---------------- Table Initialization and Resizing -------------- */ 2276 2277 /** 2278 * Returns the stamp bits for resizing a table of size n. 2279 * Must be negative when shifted left by RESIZE_STAMP_SHIFT. 2280 */ resizeStamp(int n)2281 static final int resizeStamp(int n) { 2282 return Integer.numberOfLeadingZeros(n) | (1 << (RESIZE_STAMP_BITS - 1)); 2283 } 2284 2285 /** 2286 * Initializes table, using the size recorded in sizeCtl. 2287 */ initTable()2288 private final Node<K,V>[] initTable() { 2289 Node<K,V>[] tab; int sc; 2290 while ((tab = table) == null || tab.length == 0) { 2291 if ((sc = sizeCtl) < 0) 2292 Thread.yield(); // lost initialization race; just spin 2293 else if (U.compareAndSetInt(this, SIZECTL, sc, -1)) { 2294 try { 2295 if ((tab = table) == null || tab.length == 0) { 2296 int n = (sc > 0) ? sc : DEFAULT_CAPACITY; 2297 @SuppressWarnings("unchecked") 2298 Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n]; 2299 table = tab = nt; 2300 sc = n - (n >>> 2); 2301 } 2302 } finally { 2303 sizeCtl = sc; 2304 } 2305 break; 2306 } 2307 } 2308 return tab; 2309 } 2310 2311 /** 2312 * Adds to count, and if table is too small and not already 2313 * resizing, initiates transfer. If already resizing, helps 2314 * perform transfer if work is available. Rechecks occupancy 2315 * after a transfer to see if another resize is already needed 2316 * because resizings are lagging additions. 2317 * 2318 * @param x the count to add 2319 * @param check if <0, don't check resize, if <= 1 only check if uncontended 2320 */ addCount(long x, int check)2321 private final void addCount(long x, int check) { 2322 CounterCell[] cs; long b, s; 2323 if ((cs = counterCells) != null || 2324 !U.compareAndSetLong(this, BASECOUNT, b = baseCount, s = b + x)) { 2325 CounterCell c; long v; int m; 2326 boolean uncontended = true; 2327 if (cs == null || (m = cs.length - 1) < 0 || 2328 (c = cs[ThreadLocalRandom.getProbe() & m]) == null || 2329 !(uncontended = 2330 U.compareAndSetLong(c, CELLVALUE, v = c.value, v + x))) { 2331 fullAddCount(x, uncontended); 2332 return; 2333 } 2334 if (check <= 1) 2335 return; 2336 s = sumCount(); 2337 } 2338 if (check >= 0) { 2339 Node<K,V>[] tab, nt; int n, sc; 2340 while (s >= (long)(sc = sizeCtl) && (tab = table) != null && 2341 (n = tab.length) < MAXIMUM_CAPACITY) { 2342 int rs = resizeStamp(n); 2343 if (sc < 0) { 2344 if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || 2345 sc == rs + MAX_RESIZERS || (nt = nextTable) == null || 2346 transferIndex <= 0) 2347 break; 2348 if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1)) 2349 transfer(tab, nt); 2350 } 2351 else if (U.compareAndSetInt(this, SIZECTL, sc, 2352 (rs << RESIZE_STAMP_SHIFT) + 2)) 2353 transfer(tab, null); 2354 s = sumCount(); 2355 } 2356 } 2357 } 2358 2359 /** 2360 * Helps transfer if a resize is in progress. 2361 */ helpTransfer(Node<K,V>[] tab, Node<K,V> f)2362 final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) { 2363 Node<K,V>[] nextTab; int sc; 2364 if (tab != null && (f instanceof ForwardingNode) && 2365 (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) { 2366 int rs = resizeStamp(tab.length); 2367 while (nextTab == nextTable && table == tab && 2368 (sc = sizeCtl) < 0) { 2369 if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || 2370 sc == rs + MAX_RESIZERS || transferIndex <= 0) 2371 break; 2372 if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1)) { 2373 transfer(tab, nextTab); 2374 break; 2375 } 2376 } 2377 return nextTab; 2378 } 2379 return table; 2380 } 2381 2382 /** 2383 * Tries to presize table to accommodate the given number of elements. 2384 * 2385 * @param size number of elements (doesn't need to be perfectly accurate) 2386 */ tryPresize(int size)2387 private final void tryPresize(int size) { 2388 int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY : 2389 tableSizeFor(size + (size >>> 1) + 1); 2390 int sc; 2391 while ((sc = sizeCtl) >= 0) { 2392 Node<K,V>[] tab = table; int n; 2393 if (tab == null || (n = tab.length) == 0) { 2394 n = (sc > c) ? sc : c; 2395 if (U.compareAndSetInt(this, SIZECTL, sc, -1)) { 2396 try { 2397 if (table == tab) { 2398 @SuppressWarnings("unchecked") 2399 Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n]; 2400 table = nt; 2401 sc = n - (n >>> 2); 2402 } 2403 } finally { 2404 sizeCtl = sc; 2405 } 2406 } 2407 } 2408 else if (c <= sc || n >= MAXIMUM_CAPACITY) 2409 break; 2410 else if (tab == table) { 2411 int rs = resizeStamp(n); 2412 if (U.compareAndSetInt(this, SIZECTL, sc, 2413 (rs << RESIZE_STAMP_SHIFT) + 2)) 2414 transfer(tab, null); 2415 } 2416 } 2417 } 2418 2419 /** 2420 * Moves and/or copies the nodes in each bin to new table. See 2421 * above for explanation. 2422 */ transfer(Node<K,V>[] tab, Node<K,V>[] nextTab)2423 private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) { 2424 int n = tab.length, stride; 2425 if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE) 2426 stride = MIN_TRANSFER_STRIDE; // subdivide range 2427 if (nextTab == null) { // initiating 2428 try { 2429 @SuppressWarnings("unchecked") 2430 Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1]; 2431 nextTab = nt; 2432 } catch (Throwable ex) { // try to cope with OOME 2433 sizeCtl = Integer.MAX_VALUE; 2434 return; 2435 } 2436 nextTable = nextTab; 2437 transferIndex = n; 2438 } 2439 int nextn = nextTab.length; 2440 ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab); 2441 boolean advance = true; 2442 boolean finishing = false; // to ensure sweep before committing nextTab 2443 for (int i = 0, bound = 0;;) { 2444 Node<K,V> f; int fh; 2445 while (advance) { 2446 int nextIndex, nextBound; 2447 if (--i >= bound || finishing) 2448 advance = false; 2449 else if ((nextIndex = transferIndex) <= 0) { 2450 i = -1; 2451 advance = false; 2452 } 2453 else if (U.compareAndSetInt 2454 (this, TRANSFERINDEX, nextIndex, 2455 nextBound = (nextIndex > stride ? 2456 nextIndex - stride : 0))) { 2457 bound = nextBound; 2458 i = nextIndex - 1; 2459 advance = false; 2460 } 2461 } 2462 if (i < 0 || i >= n || i + n >= nextn) { 2463 int sc; 2464 if (finishing) { 2465 nextTable = null; 2466 table = nextTab; 2467 sizeCtl = (n << 1) - (n >>> 1); 2468 return; 2469 } 2470 if (U.compareAndSetInt(this, SIZECTL, sc = sizeCtl, sc - 1)) { 2471 if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT) 2472 return; 2473 finishing = advance = true; 2474 i = n; // recheck before commit 2475 } 2476 } 2477 else if ((f = tabAt(tab, i)) == null) 2478 advance = casTabAt(tab, i, null, fwd); 2479 else if ((fh = f.hash) == MOVED) 2480 advance = true; // already processed 2481 else { 2482 synchronized (f) { 2483 if (tabAt(tab, i) == f) { 2484 Node<K,V> ln, hn; 2485 if (fh >= 0) { 2486 int runBit = fh & n; 2487 Node<K,V> lastRun = f; 2488 for (Node<K,V> p = f.next; p != null; p = p.next) { 2489 int b = p.hash & n; 2490 if (b != runBit) { 2491 runBit = b; 2492 lastRun = p; 2493 } 2494 } 2495 if (runBit == 0) { 2496 ln = lastRun; 2497 hn = null; 2498 } 2499 else { 2500 hn = lastRun; 2501 ln = null; 2502 } 2503 for (Node<K,V> p = f; p != lastRun; p = p.next) { 2504 int ph = p.hash; K pk = p.key; V pv = p.val; 2505 if ((ph & n) == 0) 2506 ln = new Node<K,V>(ph, pk, pv, ln); 2507 else 2508 hn = new Node<K,V>(ph, pk, pv, hn); 2509 } 2510 setTabAt(nextTab, i, ln); 2511 setTabAt(nextTab, i + n, hn); 2512 setTabAt(tab, i, fwd); 2513 advance = true; 2514 } 2515 else if (f instanceof TreeBin) { 2516 TreeBin<K,V> t = (TreeBin<K,V>)f; 2517 TreeNode<K,V> lo = null, loTail = null; 2518 TreeNode<K,V> hi = null, hiTail = null; 2519 int lc = 0, hc = 0; 2520 for (Node<K,V> e = t.first; e != null; e = e.next) { 2521 int h = e.hash; 2522 TreeNode<K,V> p = new TreeNode<K,V> 2523 (h, e.key, e.val, null, null); 2524 if ((h & n) == 0) { 2525 if ((p.prev = loTail) == null) 2526 lo = p; 2527 else 2528 loTail.next = p; 2529 loTail = p; 2530 ++lc; 2531 } 2532 else { 2533 if ((p.prev = hiTail) == null) 2534 hi = p; 2535 else 2536 hiTail.next = p; 2537 hiTail = p; 2538 ++hc; 2539 } 2540 } 2541 ln = (lc <= UNTREEIFY_THRESHOLD) ? untreeify(lo) : 2542 (hc != 0) ? new TreeBin<K,V>(lo) : t; 2543 hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) : 2544 (lc != 0) ? new TreeBin<K,V>(hi) : t; 2545 setTabAt(nextTab, i, ln); 2546 setTabAt(nextTab, i + n, hn); 2547 setTabAt(tab, i, fwd); 2548 advance = true; 2549 } 2550 } 2551 } 2552 } 2553 } 2554 } 2555 2556 /* ---------------- Counter support -------------- */ 2557 2558 /** 2559 * A padded cell for distributing counts. Adapted from LongAdder 2560 * and Striped64. See their internal docs for explanation. 2561 */ 2562 @jdk.internal.vm.annotation.Contended 2563 static final class CounterCell { 2564 volatile long value; CounterCell(long x)2565 CounterCell(long x) { value = x; } 2566 } 2567 sumCount()2568 final long sumCount() { 2569 CounterCell[] cs = counterCells; 2570 long sum = baseCount; 2571 if (cs != null) { 2572 for (CounterCell c : cs) 2573 if (c != null) 2574 sum += c.value; 2575 } 2576 return sum; 2577 } 2578 2579 // See LongAdder version for explanation fullAddCount(long x, boolean wasUncontended)2580 private final void fullAddCount(long x, boolean wasUncontended) { 2581 int h; 2582 if ((h = ThreadLocalRandom.getProbe()) == 0) { 2583 ThreadLocalRandom.localInit(); // force initialization 2584 h = ThreadLocalRandom.getProbe(); 2585 wasUncontended = true; 2586 } 2587 boolean collide = false; // True if last slot nonempty 2588 for (;;) { 2589 CounterCell[] cs; CounterCell c; int n; long v; 2590 if ((cs = counterCells) != null && (n = cs.length) > 0) { 2591 if ((c = cs[(n - 1) & h]) == null) { 2592 if (cellsBusy == 0) { // Try to attach new Cell 2593 CounterCell r = new CounterCell(x); // Optimistic create 2594 if (cellsBusy == 0 && 2595 U.compareAndSetInt(this, CELLSBUSY, 0, 1)) { 2596 boolean created = false; 2597 try { // Recheck under lock 2598 CounterCell[] rs; int m, j; 2599 if ((rs = counterCells) != null && 2600 (m = rs.length) > 0 && 2601 rs[j = (m - 1) & h] == null) { 2602 rs[j] = r; 2603 created = true; 2604 } 2605 } finally { 2606 cellsBusy = 0; 2607 } 2608 if (created) 2609 break; 2610 continue; // Slot is now non-empty 2611 } 2612 } 2613 collide = false; 2614 } 2615 else if (!wasUncontended) // CAS already known to fail 2616 wasUncontended = true; // Continue after rehash 2617 else if (U.compareAndSetLong(c, CELLVALUE, v = c.value, v + x)) 2618 break; 2619 else if (counterCells != cs || n >= NCPU) 2620 collide = false; // At max size or stale 2621 else if (!collide) 2622 collide = true; 2623 else if (cellsBusy == 0 && 2624 U.compareAndSetInt(this, CELLSBUSY, 0, 1)) { 2625 try { 2626 if (counterCells == cs) // Expand table unless stale 2627 counterCells = Arrays.copyOf(cs, n << 1); 2628 } finally { 2629 cellsBusy = 0; 2630 } 2631 collide = false; 2632 continue; // Retry with expanded table 2633 } 2634 h = ThreadLocalRandom.advanceProbe(h); 2635 } 2636 else if (cellsBusy == 0 && counterCells == cs && 2637 U.compareAndSetInt(this, CELLSBUSY, 0, 1)) { 2638 boolean init = false; 2639 try { // Initialize table 2640 if (counterCells == cs) { 2641 CounterCell[] rs = new CounterCell[2]; 2642 rs[h & 1] = new CounterCell(x); 2643 counterCells = rs; 2644 init = true; 2645 } 2646 } finally { 2647 cellsBusy = 0; 2648 } 2649 if (init) 2650 break; 2651 } 2652 else if (U.compareAndSetLong(this, BASECOUNT, v = baseCount, v + x)) 2653 break; // Fall back on using base 2654 } 2655 } 2656 2657 /* ---------------- Conversion from/to TreeBins -------------- */ 2658 2659 /** 2660 * Replaces all linked nodes in bin at given index unless table is 2661 * too small, in which case resizes instead. 2662 */ treeifyBin(Node<K,V>[] tab, int index)2663 private final void treeifyBin(Node<K,V>[] tab, int index) { 2664 Node<K,V> b; int n; 2665 if (tab != null) { 2666 if ((n = tab.length) < MIN_TREEIFY_CAPACITY) 2667 tryPresize(n << 1); 2668 else if ((b = tabAt(tab, index)) != null && b.hash >= 0) { 2669 synchronized (b) { 2670 if (tabAt(tab, index) == b) { 2671 TreeNode<K,V> hd = null, tl = null; 2672 for (Node<K,V> e = b; e != null; e = e.next) { 2673 TreeNode<K,V> p = 2674 new TreeNode<K,V>(e.hash, e.key, e.val, 2675 null, null); 2676 if ((p.prev = tl) == null) 2677 hd = p; 2678 else 2679 tl.next = p; 2680 tl = p; 2681 } 2682 setTabAt(tab, index, new TreeBin<K,V>(hd)); 2683 } 2684 } 2685 } 2686 } 2687 } 2688 2689 /** 2690 * Returns a list of non-TreeNodes replacing those in given list. 2691 */ untreeify(Node<K,V> b)2692 static <K,V> Node<K,V> untreeify(Node<K,V> b) { 2693 Node<K,V> hd = null, tl = null; 2694 for (Node<K,V> q = b; q != null; q = q.next) { 2695 Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val); 2696 if (tl == null) 2697 hd = p; 2698 else 2699 tl.next = p; 2700 tl = p; 2701 } 2702 return hd; 2703 } 2704 2705 /* ---------------- TreeNodes -------------- */ 2706 2707 /** 2708 * Nodes for use in TreeBins. 2709 */ 2710 static final class TreeNode<K,V> extends Node<K,V> { 2711 TreeNode<K,V> parent; // red-black tree links 2712 TreeNode<K,V> left; 2713 TreeNode<K,V> right; 2714 TreeNode<K,V> prev; // needed to unlink next upon deletion 2715 boolean red; 2716 TreeNode(int hash, K key, V val, Node<K,V> next, TreeNode<K,V> parent)2717 TreeNode(int hash, K key, V val, Node<K,V> next, 2718 TreeNode<K,V> parent) { 2719 super(hash, key, val, next); 2720 this.parent = parent; 2721 } 2722 find(int h, Object k)2723 Node<K,V> find(int h, Object k) { 2724 return findTreeNode(h, k, null); 2725 } 2726 2727 /** 2728 * Returns the TreeNode (or null if not found) for the given key 2729 * starting at given root. 2730 */ findTreeNode(int h, Object k, Class<?> kc)2731 final TreeNode<K,V> findTreeNode(int h, Object k, Class<?> kc) { 2732 if (k != null) { 2733 TreeNode<K,V> p = this; 2734 do { 2735 int ph, dir; K pk; TreeNode<K,V> q; 2736 TreeNode<K,V> pl = p.left, pr = p.right; 2737 if ((ph = p.hash) > h) 2738 p = pl; 2739 else if (ph < h) 2740 p = pr; 2741 else if ((pk = p.key) == k || (pk != null && k.equals(pk))) 2742 return p; 2743 else if (pl == null) 2744 p = pr; 2745 else if (pr == null) 2746 p = pl; 2747 else if ((kc != null || 2748 (kc = comparableClassFor(k)) != null) && 2749 (dir = compareComparables(kc, k, pk)) != 0) 2750 p = (dir < 0) ? pl : pr; 2751 else if ((q = pr.findTreeNode(h, k, kc)) != null) 2752 return q; 2753 else 2754 p = pl; 2755 } while (p != null); 2756 } 2757 return null; 2758 } 2759 } 2760 2761 /* ---------------- TreeBins -------------- */ 2762 2763 /** 2764 * TreeNodes used at the heads of bins. TreeBins do not hold user 2765 * keys or values, but instead point to list of TreeNodes and 2766 * their root. They also maintain a parasitic read-write lock 2767 * forcing writers (who hold bin lock) to wait for readers (who do 2768 * not) to complete before tree restructuring operations. 2769 */ 2770 static final class TreeBin<K,V> extends Node<K,V> { 2771 TreeNode<K,V> root; 2772 volatile TreeNode<K,V> first; 2773 volatile Thread waiter; 2774 volatile int lockState; 2775 // values for lockState 2776 static final int WRITER = 1; // set while holding write lock 2777 static final int WAITER = 2; // set when waiting for write lock 2778 static final int READER = 4; // increment value for setting read lock 2779 2780 /** 2781 * Tie-breaking utility for ordering insertions when equal 2782 * hashCodes and non-comparable. We don't require a total 2783 * order, just a consistent insertion rule to maintain 2784 * equivalence across rebalancings. Tie-breaking further than 2785 * necessary simplifies testing a bit. 2786 */ tieBreakOrder(Object a, Object b)2787 static int tieBreakOrder(Object a, Object b) { 2788 int d; 2789 if (a == null || b == null || 2790 (d = a.getClass().getName(). 2791 compareTo(b.getClass().getName())) == 0) 2792 d = (System.identityHashCode(a) <= System.identityHashCode(b) ? 2793 -1 : 1); 2794 return d; 2795 } 2796 2797 /** 2798 * Creates bin with initial set of nodes headed by b. 2799 */ TreeBin(TreeNode<K,V> b)2800 TreeBin(TreeNode<K,V> b) { 2801 super(TREEBIN, null, null); 2802 this.first = b; 2803 TreeNode<K,V> r = null; 2804 for (TreeNode<K,V> x = b, next; x != null; x = next) { 2805 next = (TreeNode<K,V>)x.next; 2806 x.left = x.right = null; 2807 if (r == null) { 2808 x.parent = null; 2809 x.red = false; 2810 r = x; 2811 } 2812 else { 2813 K k = x.key; 2814 int h = x.hash; 2815 Class<?> kc = null; 2816 for (TreeNode<K,V> p = r;;) { 2817 int dir, ph; 2818 K pk = p.key; 2819 if ((ph = p.hash) > h) 2820 dir = -1; 2821 else if (ph < h) 2822 dir = 1; 2823 else if ((kc == null && 2824 (kc = comparableClassFor(k)) == null) || 2825 (dir = compareComparables(kc, k, pk)) == 0) 2826 dir = tieBreakOrder(k, pk); 2827 TreeNode<K,V> xp = p; 2828 if ((p = (dir <= 0) ? p.left : p.right) == null) { 2829 x.parent = xp; 2830 if (dir <= 0) 2831 xp.left = x; 2832 else 2833 xp.right = x; 2834 r = balanceInsertion(r, x); 2835 break; 2836 } 2837 } 2838 } 2839 } 2840 this.root = r; 2841 assert checkInvariants(root); 2842 } 2843 2844 /** 2845 * Acquires write lock for tree restructuring. 2846 */ lockRoot()2847 private final void lockRoot() { 2848 if (!U.compareAndSetInt(this, LOCKSTATE, 0, WRITER)) 2849 contendedLock(); // offload to separate method 2850 } 2851 2852 /** 2853 * Releases write lock for tree restructuring. 2854 */ unlockRoot()2855 private final void unlockRoot() { 2856 lockState = 0; 2857 } 2858 2859 /** 2860 * Possibly blocks awaiting root lock. 2861 */ contendedLock()2862 private final void contendedLock() { 2863 boolean waiting = false; 2864 for (int s;;) { 2865 if (((s = lockState) & ~WAITER) == 0) { 2866 if (U.compareAndSetInt(this, LOCKSTATE, s, WRITER)) { 2867 if (waiting) 2868 waiter = null; 2869 return; 2870 } 2871 } 2872 else if ((s & WAITER) == 0) { 2873 if (U.compareAndSetInt(this, LOCKSTATE, s, s | WAITER)) { 2874 waiting = true; 2875 waiter = Thread.currentThread(); 2876 } 2877 } 2878 else if (waiting) 2879 LockSupport.park(this); 2880 } 2881 } 2882 2883 /** 2884 * Returns matching node or null if none. Tries to search 2885 * using tree comparisons from root, but continues linear 2886 * search when lock not available. 2887 */ find(int h, Object k)2888 final Node<K,V> find(int h, Object k) { 2889 if (k != null) { 2890 for (Node<K,V> e = first; e != null; ) { 2891 int s; K ek; 2892 if (((s = lockState) & (WAITER|WRITER)) != 0) { 2893 if (e.hash == h && 2894 ((ek = e.key) == k || (ek != null && k.equals(ek)))) 2895 return e; 2896 e = e.next; 2897 } 2898 else if (U.compareAndSetInt(this, LOCKSTATE, s, 2899 s + READER)) { 2900 TreeNode<K,V> r, p; 2901 try { 2902 p = ((r = root) == null ? null : 2903 r.findTreeNode(h, k, null)); 2904 } finally { 2905 Thread w; 2906 if (U.getAndAddInt(this, LOCKSTATE, -READER) == 2907 (READER|WAITER) && (w = waiter) != null) 2908 LockSupport.unpark(w); 2909 } 2910 return p; 2911 } 2912 } 2913 } 2914 return null; 2915 } 2916 2917 /** 2918 * Finds or adds a node. 2919 * @return null if added 2920 */ putTreeVal(int h, K k, V v)2921 final TreeNode<K,V> putTreeVal(int h, K k, V v) { 2922 Class<?> kc = null; 2923 boolean searched = false; 2924 for (TreeNode<K,V> p = root;;) { 2925 int dir, ph; K pk; 2926 if (p == null) { 2927 first = root = new TreeNode<K,V>(h, k, v, null, null); 2928 break; 2929 } 2930 else if ((ph = p.hash) > h) 2931 dir = -1; 2932 else if (ph < h) 2933 dir = 1; 2934 else if ((pk = p.key) == k || (pk != null && k.equals(pk))) 2935 return p; 2936 else if ((kc == null && 2937 (kc = comparableClassFor(k)) == null) || 2938 (dir = compareComparables(kc, k, pk)) == 0) { 2939 if (!searched) { 2940 TreeNode<K,V> q, ch; 2941 searched = true; 2942 if (((ch = p.left) != null && 2943 (q = ch.findTreeNode(h, k, kc)) != null) || 2944 ((ch = p.right) != null && 2945 (q = ch.findTreeNode(h, k, kc)) != null)) 2946 return q; 2947 } 2948 dir = tieBreakOrder(k, pk); 2949 } 2950 2951 TreeNode<K,V> xp = p; 2952 if ((p = (dir <= 0) ? p.left : p.right) == null) { 2953 TreeNode<K,V> x, f = first; 2954 first = x = new TreeNode<K,V>(h, k, v, f, xp); 2955 if (f != null) 2956 f.prev = x; 2957 if (dir <= 0) 2958 xp.left = x; 2959 else 2960 xp.right = x; 2961 if (!xp.red) 2962 x.red = true; 2963 else { 2964 lockRoot(); 2965 try { 2966 root = balanceInsertion(root, x); 2967 } finally { 2968 unlockRoot(); 2969 } 2970 } 2971 break; 2972 } 2973 } 2974 assert checkInvariants(root); 2975 return null; 2976 } 2977 2978 /** 2979 * Removes the given node, that must be present before this 2980 * call. This is messier than typical red-black deletion code 2981 * because we cannot swap the contents of an interior node 2982 * with a leaf successor that is pinned by "next" pointers 2983 * that are accessible independently of lock. So instead we 2984 * swap the tree linkages. 2985 * 2986 * @return true if now too small, so should be untreeified 2987 */ removeTreeNode(TreeNode<K,V> p)2988 final boolean removeTreeNode(TreeNode<K,V> p) { 2989 TreeNode<K,V> next = (TreeNode<K,V>)p.next; 2990 TreeNode<K,V> pred = p.prev; // unlink traversal pointers 2991 TreeNode<K,V> r, rl; 2992 if (pred == null) 2993 first = next; 2994 else 2995 pred.next = next; 2996 if (next != null) 2997 next.prev = pred; 2998 if (first == null) { 2999 root = null; 3000 return true; 3001 } 3002 if ((r = root) == null || r.right == null || // too small 3003 (rl = r.left) == null || rl.left == null) 3004 return true; 3005 lockRoot(); 3006 try { 3007 TreeNode<K,V> replacement; 3008 TreeNode<K,V> pl = p.left; 3009 TreeNode<K,V> pr = p.right; 3010 if (pl != null && pr != null) { 3011 TreeNode<K,V> s = pr, sl; 3012 while ((sl = s.left) != null) // find successor 3013 s = sl; 3014 boolean c = s.red; s.red = p.red; p.red = c; // swap colors 3015 TreeNode<K,V> sr = s.right; 3016 TreeNode<K,V> pp = p.parent; 3017 if (s == pr) { // p was s's direct parent 3018 p.parent = s; 3019 s.right = p; 3020 } 3021 else { 3022 TreeNode<K,V> sp = s.parent; 3023 if ((p.parent = sp) != null) { 3024 if (s == sp.left) 3025 sp.left = p; 3026 else 3027 sp.right = p; 3028 } 3029 if ((s.right = pr) != null) 3030 pr.parent = s; 3031 } 3032 p.left = null; 3033 if ((p.right = sr) != null) 3034 sr.parent = p; 3035 if ((s.left = pl) != null) 3036 pl.parent = s; 3037 if ((s.parent = pp) == null) 3038 r = s; 3039 else if (p == pp.left) 3040 pp.left = s; 3041 else 3042 pp.right = s; 3043 if (sr != null) 3044 replacement = sr; 3045 else 3046 replacement = p; 3047 } 3048 else if (pl != null) 3049 replacement = pl; 3050 else if (pr != null) 3051 replacement = pr; 3052 else 3053 replacement = p; 3054 if (replacement != p) { 3055 TreeNode<K,V> pp = replacement.parent = p.parent; 3056 if (pp == null) 3057 r = replacement; 3058 else if (p == pp.left) 3059 pp.left = replacement; 3060 else 3061 pp.right = replacement; 3062 p.left = p.right = p.parent = null; 3063 } 3064 3065 root = (p.red) ? r : balanceDeletion(r, replacement); 3066 3067 if (p == replacement) { // detach pointers 3068 TreeNode<K,V> pp; 3069 if ((pp = p.parent) != null) { 3070 if (p == pp.left) 3071 pp.left = null; 3072 else if (p == pp.right) 3073 pp.right = null; 3074 p.parent = null; 3075 } 3076 } 3077 } finally { 3078 unlockRoot(); 3079 } 3080 assert checkInvariants(root); 3081 return false; 3082 } 3083 3084 /* ------------------------------------------------------------ */ 3085 // Red-black tree methods, all adapted from CLR 3086 rotateLeft(TreeNode<K,V> root, TreeNode<K,V> p)3087 static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root, 3088 TreeNode<K,V> p) { 3089 TreeNode<K,V> r, pp, rl; 3090 if (p != null && (r = p.right) != null) { 3091 if ((rl = p.right = r.left) != null) 3092 rl.parent = p; 3093 if ((pp = r.parent = p.parent) == null) 3094 (root = r).red = false; 3095 else if (pp.left == p) 3096 pp.left = r; 3097 else 3098 pp.right = r; 3099 r.left = p; 3100 p.parent = r; 3101 } 3102 return root; 3103 } 3104 rotateRight(TreeNode<K,V> root, TreeNode<K,V> p)3105 static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root, 3106 TreeNode<K,V> p) { 3107 TreeNode<K,V> l, pp, lr; 3108 if (p != null && (l = p.left) != null) { 3109 if ((lr = p.left = l.right) != null) 3110 lr.parent = p; 3111 if ((pp = l.parent = p.parent) == null) 3112 (root = l).red = false; 3113 else if (pp.right == p) 3114 pp.right = l; 3115 else 3116 pp.left = l; 3117 l.right = p; 3118 p.parent = l; 3119 } 3120 return root; 3121 } 3122 balanceInsertion(TreeNode<K,V> root, TreeNode<K,V> x)3123 static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root, 3124 TreeNode<K,V> x) { 3125 x.red = true; 3126 for (TreeNode<K,V> xp, xpp, xppl, xppr;;) { 3127 if ((xp = x.parent) == null) { 3128 x.red = false; 3129 return x; 3130 } 3131 else if (!xp.red || (xpp = xp.parent) == null) 3132 return root; 3133 if (xp == (xppl = xpp.left)) { 3134 if ((xppr = xpp.right) != null && xppr.red) { 3135 xppr.red = false; 3136 xp.red = false; 3137 xpp.red = true; 3138 x = xpp; 3139 } 3140 else { 3141 if (x == xp.right) { 3142 root = rotateLeft(root, x = xp); 3143 xpp = (xp = x.parent) == null ? null : xp.parent; 3144 } 3145 if (xp != null) { 3146 xp.red = false; 3147 if (xpp != null) { 3148 xpp.red = true; 3149 root = rotateRight(root, xpp); 3150 } 3151 } 3152 } 3153 } 3154 else { 3155 if (xppl != null && xppl.red) { 3156 xppl.red = false; 3157 xp.red = false; 3158 xpp.red = true; 3159 x = xpp; 3160 } 3161 else { 3162 if (x == xp.left) { 3163 root = rotateRight(root, x = xp); 3164 xpp = (xp = x.parent) == null ? null : xp.parent; 3165 } 3166 if (xp != null) { 3167 xp.red = false; 3168 if (xpp != null) { 3169 xpp.red = true; 3170 root = rotateLeft(root, xpp); 3171 } 3172 } 3173 } 3174 } 3175 } 3176 } 3177 balanceDeletion(TreeNode<K,V> root, TreeNode<K,V> x)3178 static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root, 3179 TreeNode<K,V> x) { 3180 for (TreeNode<K,V> xp, xpl, xpr;;) { 3181 if (x == null || x == root) 3182 return root; 3183 else if ((xp = x.parent) == null) { 3184 x.red = false; 3185 return x; 3186 } 3187 else if (x.red) { 3188 x.red = false; 3189 return root; 3190 } 3191 else if ((xpl = xp.left) == x) { 3192 if ((xpr = xp.right) != null && xpr.red) { 3193 xpr.red = false; 3194 xp.red = true; 3195 root = rotateLeft(root, xp); 3196 xpr = (xp = x.parent) == null ? null : xp.right; 3197 } 3198 if (xpr == null) 3199 x = xp; 3200 else { 3201 TreeNode<K,V> sl = xpr.left, sr = xpr.right; 3202 if ((sr == null || !sr.red) && 3203 (sl == null || !sl.red)) { 3204 xpr.red = true; 3205 x = xp; 3206 } 3207 else { 3208 if (sr == null || !sr.red) { 3209 if (sl != null) 3210 sl.red = false; 3211 xpr.red = true; 3212 root = rotateRight(root, xpr); 3213 xpr = (xp = x.parent) == null ? 3214 null : xp.right; 3215 } 3216 if (xpr != null) { 3217 xpr.red = (xp == null) ? false : xp.red; 3218 if ((sr = xpr.right) != null) 3219 sr.red = false; 3220 } 3221 if (xp != null) { 3222 xp.red = false; 3223 root = rotateLeft(root, xp); 3224 } 3225 x = root; 3226 } 3227 } 3228 } 3229 else { // symmetric 3230 if (xpl != null && xpl.red) { 3231 xpl.red = false; 3232 xp.red = true; 3233 root = rotateRight(root, xp); 3234 xpl = (xp = x.parent) == null ? null : xp.left; 3235 } 3236 if (xpl == null) 3237 x = xp; 3238 else { 3239 TreeNode<K,V> sl = xpl.left, sr = xpl.right; 3240 if ((sl == null || !sl.red) && 3241 (sr == null || !sr.red)) { 3242 xpl.red = true; 3243 x = xp; 3244 } 3245 else { 3246 if (sl == null || !sl.red) { 3247 if (sr != null) 3248 sr.red = false; 3249 xpl.red = true; 3250 root = rotateLeft(root, xpl); 3251 xpl = (xp = x.parent) == null ? 3252 null : xp.left; 3253 } 3254 if (xpl != null) { 3255 xpl.red = (xp == null) ? false : xp.red; 3256 if ((sl = xpl.left) != null) 3257 sl.red = false; 3258 } 3259 if (xp != null) { 3260 xp.red = false; 3261 root = rotateRight(root, xp); 3262 } 3263 x = root; 3264 } 3265 } 3266 } 3267 } 3268 } 3269 3270 /** 3271 * Checks invariants recursively for the tree of Nodes rooted at t. 3272 */ checkInvariants(TreeNode<K,V> t)3273 static <K,V> boolean checkInvariants(TreeNode<K,V> t) { 3274 TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right, 3275 tb = t.prev, tn = (TreeNode<K,V>)t.next; 3276 if (tb != null && tb.next != t) 3277 return false; 3278 if (tn != null && tn.prev != t) 3279 return false; 3280 if (tp != null && t != tp.left && t != tp.right) 3281 return false; 3282 if (tl != null && (tl.parent != t || tl.hash > t.hash)) 3283 return false; 3284 if (tr != null && (tr.parent != t || tr.hash < t.hash)) 3285 return false; 3286 if (t.red && tl != null && tl.red && tr != null && tr.red) 3287 return false; 3288 if (tl != null && !checkInvariants(tl)) 3289 return false; 3290 if (tr != null && !checkInvariants(tr)) 3291 return false; 3292 return true; 3293 } 3294 3295 private static final Unsafe U = Unsafe.getUnsafe(); 3296 private static final long LOCKSTATE 3297 = U.objectFieldOffset(TreeBin.class, "lockState"); 3298 } 3299 3300 /* ----------------Table Traversal -------------- */ 3301 3302 /** 3303 * Records the table, its length, and current traversal index for a 3304 * traverser that must process a region of a forwarded table before 3305 * proceeding with current table. 3306 */ 3307 static final class TableStack<K,V> { 3308 int length; 3309 int index; 3310 Node<K,V>[] tab; 3311 TableStack<K,V> next; 3312 } 3313 3314 /** 3315 * Encapsulates traversal for methods such as containsValue; also 3316 * serves as a base class for other iterators and spliterators. 3317 * 3318 * Method advance visits once each still-valid node that was 3319 * reachable upon iterator construction. It might miss some that 3320 * were added to a bin after the bin was visited, which is OK wrt 3321 * consistency guarantees. Maintaining this property in the face 3322 * of possible ongoing resizes requires a fair amount of 3323 * bookkeeping state that is difficult to optimize away amidst 3324 * volatile accesses. Even so, traversal maintains reasonable 3325 * throughput. 3326 * 3327 * Normally, iteration proceeds bin-by-bin traversing lists. 3328 * However, if the table has been resized, then all future steps 3329 * must traverse both the bin at the current index as well as at 3330 * (index + baseSize); and so on for further resizings. To 3331 * paranoically cope with potential sharing by users of iterators 3332 * across threads, iteration terminates if a bounds checks fails 3333 * for a table read. 3334 */ 3335 static class Traverser<K,V> { 3336 Node<K,V>[] tab; // current table; updated if resized 3337 Node<K,V> next; // the next entry to use 3338 TableStack<K,V> stack, spare; // to save/restore on ForwardingNodes 3339 int index; // index of bin to use next 3340 int baseIndex; // current index of initial table 3341 int baseLimit; // index bound for initial table 3342 final int baseSize; // initial table size 3343 Traverser(Node<K,V>[] tab, int size, int index, int limit)3344 Traverser(Node<K,V>[] tab, int size, int index, int limit) { 3345 this.tab = tab; 3346 this.baseSize = size; 3347 this.baseIndex = this.index = index; 3348 this.baseLimit = limit; 3349 this.next = null; 3350 } 3351 3352 /** 3353 * Advances if possible, returning next valid node, or null if none. 3354 */ advance()3355 final Node<K,V> advance() { 3356 Node<K,V> e; 3357 if ((e = next) != null) 3358 e = e.next; 3359 for (;;) { 3360 Node<K,V>[] t; int i, n; // must use locals in checks 3361 if (e != null) 3362 return next = e; 3363 if (baseIndex >= baseLimit || (t = tab) == null || 3364 (n = t.length) <= (i = index) || i < 0) 3365 return next = null; 3366 if ((e = tabAt(t, i)) != null && e.hash < 0) { 3367 if (e instanceof ForwardingNode) { 3368 tab = ((ForwardingNode<K,V>)e).nextTable; 3369 e = null; 3370 pushState(t, i, n); 3371 continue; 3372 } 3373 else if (e instanceof TreeBin) 3374 e = ((TreeBin<K,V>)e).first; 3375 else 3376 e = null; 3377 } 3378 if (stack != null) 3379 recoverState(n); 3380 else if ((index = i + baseSize) >= n) 3381 index = ++baseIndex; // visit upper slots if present 3382 } 3383 } 3384 3385 /** 3386 * Saves traversal state upon encountering a forwarding node. 3387 */ pushState(Node<K,V>[] t, int i, int n)3388 private void pushState(Node<K,V>[] t, int i, int n) { 3389 TableStack<K,V> s = spare; // reuse if possible 3390 if (s != null) 3391 spare = s.next; 3392 else 3393 s = new TableStack<K,V>(); 3394 s.tab = t; 3395 s.length = n; 3396 s.index = i; 3397 s.next = stack; 3398 stack = s; 3399 } 3400 3401 /** 3402 * Possibly pops traversal state. 3403 * 3404 * @param n length of current table 3405 */ recoverState(int n)3406 private void recoverState(int n) { 3407 TableStack<K,V> s; int len; 3408 while ((s = stack) != null && (index += (len = s.length)) >= n) { 3409 n = len; 3410 index = s.index; 3411 tab = s.tab; 3412 s.tab = null; 3413 TableStack<K,V> next = s.next; 3414 s.next = spare; // save for reuse 3415 stack = next; 3416 spare = s; 3417 } 3418 if (s == null && (index += baseSize) >= n) 3419 index = ++baseIndex; 3420 } 3421 } 3422 3423 /** 3424 * Base of key, value, and entry Iterators. Adds fields to 3425 * Traverser to support iterator.remove. 3426 */ 3427 static class BaseIterator<K,V> extends Traverser<K,V> { 3428 final ConcurrentHashMap<K,V> map; 3429 Node<K,V> lastReturned; BaseIterator(Node<K,V>[] tab, int size, int index, int limit, ConcurrentHashMap<K,V> map)3430 BaseIterator(Node<K,V>[] tab, int size, int index, int limit, 3431 ConcurrentHashMap<K,V> map) { 3432 super(tab, size, index, limit); 3433 this.map = map; 3434 advance(); 3435 } 3436 hasNext()3437 public final boolean hasNext() { return next != null; } hasMoreElements()3438 public final boolean hasMoreElements() { return next != null; } 3439 remove()3440 public final void remove() { 3441 Node<K,V> p; 3442 if ((p = lastReturned) == null) 3443 throw new IllegalStateException(); 3444 lastReturned = null; 3445 map.replaceNode(p.key, null, null); 3446 } 3447 } 3448 3449 static final class KeyIterator<K,V> extends BaseIterator<K,V> 3450 implements Iterator<K>, Enumeration<K> { KeyIterator(Node<K,V>[] tab, int size, int index, int limit, ConcurrentHashMap<K,V> map)3451 KeyIterator(Node<K,V>[] tab, int size, int index, int limit, 3452 ConcurrentHashMap<K,V> map) { 3453 super(tab, size, index, limit, map); 3454 } 3455 next()3456 public final K next() { 3457 Node<K,V> p; 3458 if ((p = next) == null) 3459 throw new NoSuchElementException(); 3460 K k = p.key; 3461 lastReturned = p; 3462 advance(); 3463 return k; 3464 } 3465 nextElement()3466 public final K nextElement() { return next(); } 3467 } 3468 3469 static final class ValueIterator<K,V> extends BaseIterator<K,V> 3470 implements Iterator<V>, Enumeration<V> { ValueIterator(Node<K,V>[] tab, int size, int index, int limit, ConcurrentHashMap<K,V> map)3471 ValueIterator(Node<K,V>[] tab, int size, int index, int limit, 3472 ConcurrentHashMap<K,V> map) { 3473 super(tab, size, index, limit, map); 3474 } 3475 next()3476 public final V next() { 3477 Node<K,V> p; 3478 if ((p = next) == null) 3479 throw new NoSuchElementException(); 3480 V v = p.val; 3481 lastReturned = p; 3482 advance(); 3483 return v; 3484 } 3485 nextElement()3486 public final V nextElement() { return next(); } 3487 } 3488 3489 static final class EntryIterator<K,V> extends BaseIterator<K,V> 3490 implements Iterator<Map.Entry<K,V>> { EntryIterator(Node<K,V>[] tab, int size, int index, int limit, ConcurrentHashMap<K,V> map)3491 EntryIterator(Node<K,V>[] tab, int size, int index, int limit, 3492 ConcurrentHashMap<K,V> map) { 3493 super(tab, size, index, limit, map); 3494 } 3495 next()3496 public final Map.Entry<K,V> next() { 3497 Node<K,V> p; 3498 if ((p = next) == null) 3499 throw new NoSuchElementException(); 3500 K k = p.key; 3501 V v = p.val; 3502 lastReturned = p; 3503 advance(); 3504 return new MapEntry<K,V>(k, v, map); 3505 } 3506 } 3507 3508 /** 3509 * Exported Entry for EntryIterator. 3510 */ 3511 static final class MapEntry<K,V> implements Map.Entry<K,V> { 3512 final K key; // non-null 3513 V val; // non-null 3514 final ConcurrentHashMap<K,V> map; MapEntry(K key, V val, ConcurrentHashMap<K,V> map)3515 MapEntry(K key, V val, ConcurrentHashMap<K,V> map) { 3516 this.key = key; 3517 this.val = val; 3518 this.map = map; 3519 } getKey()3520 public K getKey() { return key; } getValue()3521 public V getValue() { return val; } hashCode()3522 public int hashCode() { return key.hashCode() ^ val.hashCode(); } toString()3523 public String toString() { 3524 return Helpers.mapEntryToString(key, val); 3525 } 3526 equals(Object o)3527 public boolean equals(Object o) { 3528 Object k, v; Map.Entry<?,?> e; 3529 return ((o instanceof Map.Entry) && 3530 (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 3531 (v = e.getValue()) != null && 3532 (k == key || k.equals(key)) && 3533 (v == val || v.equals(val))); 3534 } 3535 3536 /** 3537 * Sets our entry's value and writes through to the map. The 3538 * value to return is somewhat arbitrary here. Since we do not 3539 * necessarily track asynchronous changes, the most recent 3540 * "previous" value could be different from what we return (or 3541 * could even have been removed, in which case the put will 3542 * re-establish). We do not and cannot guarantee more. 3543 */ setValue(V value)3544 public V setValue(V value) { 3545 if (value == null) throw new NullPointerException(); 3546 V v = val; 3547 val = value; 3548 map.put(key, value); 3549 return v; 3550 } 3551 } 3552 3553 static final class KeySpliterator<K,V> extends Traverser<K,V> 3554 implements Spliterator<K> { 3555 long est; // size estimate KeySpliterator(Node<K,V>[] tab, int size, int index, int limit, long est)3556 KeySpliterator(Node<K,V>[] tab, int size, int index, int limit, 3557 long est) { 3558 super(tab, size, index, limit); 3559 this.est = est; 3560 } 3561 trySplit()3562 public KeySpliterator<K,V> trySplit() { 3563 int i, f, h; 3564 return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null : 3565 new KeySpliterator<K,V>(tab, baseSize, baseLimit = h, 3566 f, est >>>= 1); 3567 } 3568 forEachRemaining(Consumer<? super K> action)3569 public void forEachRemaining(Consumer<? super K> action) { 3570 if (action == null) throw new NullPointerException(); 3571 for (Node<K,V> p; (p = advance()) != null;) 3572 action.accept(p.key); 3573 } 3574 tryAdvance(Consumer<? super K> action)3575 public boolean tryAdvance(Consumer<? super K> action) { 3576 if (action == null) throw new NullPointerException(); 3577 Node<K,V> p; 3578 if ((p = advance()) == null) 3579 return false; 3580 action.accept(p.key); 3581 return true; 3582 } 3583 estimateSize()3584 public long estimateSize() { return est; } 3585 characteristics()3586 public int characteristics() { 3587 return Spliterator.DISTINCT | Spliterator.CONCURRENT | 3588 Spliterator.NONNULL; 3589 } 3590 } 3591 3592 static final class ValueSpliterator<K,V> extends Traverser<K,V> 3593 implements Spliterator<V> { 3594 long est; // size estimate ValueSpliterator(Node<K,V>[] tab, int size, int index, int limit, long est)3595 ValueSpliterator(Node<K,V>[] tab, int size, int index, int limit, 3596 long est) { 3597 super(tab, size, index, limit); 3598 this.est = est; 3599 } 3600 trySplit()3601 public ValueSpliterator<K,V> trySplit() { 3602 int i, f, h; 3603 return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null : 3604 new ValueSpliterator<K,V>(tab, baseSize, baseLimit = h, 3605 f, est >>>= 1); 3606 } 3607 forEachRemaining(Consumer<? super V> action)3608 public void forEachRemaining(Consumer<? super V> action) { 3609 if (action == null) throw new NullPointerException(); 3610 for (Node<K,V> p; (p = advance()) != null;) 3611 action.accept(p.val); 3612 } 3613 tryAdvance(Consumer<? super V> action)3614 public boolean tryAdvance(Consumer<? super V> action) { 3615 if (action == null) throw new NullPointerException(); 3616 Node<K,V> p; 3617 if ((p = advance()) == null) 3618 return false; 3619 action.accept(p.val); 3620 return true; 3621 } 3622 estimateSize()3623 public long estimateSize() { return est; } 3624 characteristics()3625 public int characteristics() { 3626 return Spliterator.CONCURRENT | Spliterator.NONNULL; 3627 } 3628 } 3629 3630 static final class EntrySpliterator<K,V> extends Traverser<K,V> 3631 implements Spliterator<Map.Entry<K,V>> { 3632 final ConcurrentHashMap<K,V> map; // To export MapEntry 3633 long est; // size estimate EntrySpliterator(Node<K,V>[] tab, int size, int index, int limit, long est, ConcurrentHashMap<K,V> map)3634 EntrySpliterator(Node<K,V>[] tab, int size, int index, int limit, 3635 long est, ConcurrentHashMap<K,V> map) { 3636 super(tab, size, index, limit); 3637 this.map = map; 3638 this.est = est; 3639 } 3640 trySplit()3641 public EntrySpliterator<K,V> trySplit() { 3642 int i, f, h; 3643 return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null : 3644 new EntrySpliterator<K,V>(tab, baseSize, baseLimit = h, 3645 f, est >>>= 1, map); 3646 } 3647 forEachRemaining(Consumer<? super Map.Entry<K,V>> action)3648 public void forEachRemaining(Consumer<? super Map.Entry<K,V>> action) { 3649 if (action == null) throw new NullPointerException(); 3650 for (Node<K,V> p; (p = advance()) != null; ) 3651 action.accept(new MapEntry<K,V>(p.key, p.val, map)); 3652 } 3653 tryAdvance(Consumer<? super Map.Entry<K,V>> action)3654 public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) { 3655 if (action == null) throw new NullPointerException(); 3656 Node<K,V> p; 3657 if ((p = advance()) == null) 3658 return false; 3659 action.accept(new MapEntry<K,V>(p.key, p.val, map)); 3660 return true; 3661 } 3662 estimateSize()3663 public long estimateSize() { return est; } 3664 characteristics()3665 public int characteristics() { 3666 return Spliterator.DISTINCT | Spliterator.CONCURRENT | 3667 Spliterator.NONNULL; 3668 } 3669 } 3670 3671 // Parallel bulk operations 3672 3673 /** 3674 * Computes initial batch value for bulk tasks. The returned value 3675 * is approximately exp2 of the number of times (minus one) to 3676 * split task by two before executing leaf action. This value is 3677 * faster to compute and more convenient to use as a guide to 3678 * splitting than is the depth, since it is used while dividing by 3679 * two anyway. 3680 */ batchFor(long b)3681 final int batchFor(long b) { 3682 long n; 3683 if (b == Long.MAX_VALUE || (n = sumCount()) <= 1L || n < b) 3684 return 0; 3685 int sp = ForkJoinPool.getCommonPoolParallelism() << 2; // slack of 4 3686 return (b <= 0L || (n /= b) >= sp) ? sp : (int)n; 3687 } 3688 3689 /** 3690 * Performs the given action for each (key, value). 3691 * 3692 * @param parallelismThreshold the (estimated) number of elements 3693 * needed for this operation to be executed in parallel 3694 * @param action the action 3695 * @since 1.8 3696 */ forEach(long parallelismThreshold, BiConsumer<? super K,? super V> action)3697 public void forEach(long parallelismThreshold, 3698 BiConsumer<? super K,? super V> action) { 3699 if (action == null) throw new NullPointerException(); 3700 new ForEachMappingTask<K,V> 3701 (null, batchFor(parallelismThreshold), 0, 0, table, 3702 action).invoke(); 3703 } 3704 3705 /** 3706 * Performs the given action for each non-null transformation 3707 * of each (key, value). 3708 * 3709 * @param parallelismThreshold the (estimated) number of elements 3710 * needed for this operation to be executed in parallel 3711 * @param transformer a function returning the transformation 3712 * for an element, or null if there is no transformation (in 3713 * which case the action is not applied) 3714 * @param action the action 3715 * @param <U> the return type of the transformer 3716 * @since 1.8 3717 */ forEach(long parallelismThreshold, BiFunction<? super K, ? super V, ? extends U> transformer, Consumer<? super U> action)3718 public <U> void forEach(long parallelismThreshold, 3719 BiFunction<? super K, ? super V, ? extends U> transformer, 3720 Consumer<? super U> action) { 3721 if (transformer == null || action == null) 3722 throw new NullPointerException(); 3723 new ForEachTransformedMappingTask<K,V,U> 3724 (null, batchFor(parallelismThreshold), 0, 0, table, 3725 transformer, action).invoke(); 3726 } 3727 3728 /** 3729 * Returns a non-null result from applying the given search 3730 * function on each (key, value), or null if none. Upon 3731 * success, further element processing is suppressed and the 3732 * results of any other parallel invocations of the search 3733 * function are ignored. 3734 * 3735 * @param parallelismThreshold the (estimated) number of elements 3736 * needed for this operation to be executed in parallel 3737 * @param searchFunction a function returning a non-null 3738 * result on success, else null 3739 * @param <U> the return type of the search function 3740 * @return a non-null result from applying the given search 3741 * function on each (key, value), or null if none 3742 * @since 1.8 3743 */ search(long parallelismThreshold, BiFunction<? super K, ? super V, ? extends U> searchFunction)3744 public <U> U search(long parallelismThreshold, 3745 BiFunction<? super K, ? super V, ? extends U> searchFunction) { 3746 if (searchFunction == null) throw new NullPointerException(); 3747 return new SearchMappingsTask<K,V,U> 3748 (null, batchFor(parallelismThreshold), 0, 0, table, 3749 searchFunction, new AtomicReference<U>()).invoke(); 3750 } 3751 3752 /** 3753 * Returns the result of accumulating the given transformation 3754 * of all (key, value) pairs using the given reducer to 3755 * combine values, or null if none. 3756 * 3757 * @param parallelismThreshold the (estimated) number of elements 3758 * needed for this operation to be executed in parallel 3759 * @param transformer a function returning the transformation 3760 * for an element, or null if there is no transformation (in 3761 * which case it is not combined) 3762 * @param reducer a commutative associative combining function 3763 * @param <U> the return type of the transformer 3764 * @return the result of accumulating the given transformation 3765 * of all (key, value) pairs 3766 * @since 1.8 3767 */ reduce(long parallelismThreshold, BiFunction<? super K, ? super V, ? extends U> transformer, BiFunction<? super U, ? super U, ? extends U> reducer)3768 public <U> U reduce(long parallelismThreshold, 3769 BiFunction<? super K, ? super V, ? extends U> transformer, 3770 BiFunction<? super U, ? super U, ? extends U> reducer) { 3771 if (transformer == null || reducer == null) 3772 throw new NullPointerException(); 3773 return new MapReduceMappingsTask<K,V,U> 3774 (null, batchFor(parallelismThreshold), 0, 0, table, 3775 null, transformer, reducer).invoke(); 3776 } 3777 3778 /** 3779 * Returns the result of accumulating the given transformation 3780 * of all (key, value) pairs using the given reducer to 3781 * combine values, and the given basis as an identity value. 3782 * 3783 * @param parallelismThreshold the (estimated) number of elements 3784 * needed for this operation to be executed in parallel 3785 * @param transformer a function returning the transformation 3786 * for an element 3787 * @param basis the identity (initial default value) for the reduction 3788 * @param reducer a commutative associative combining function 3789 * @return the result of accumulating the given transformation 3790 * of all (key, value) pairs 3791 * @since 1.8 3792 */ reduceToDouble(long parallelismThreshold, ToDoubleBiFunction<? super K, ? super V> transformer, double basis, DoubleBinaryOperator reducer)3793 public double reduceToDouble(long parallelismThreshold, 3794 ToDoubleBiFunction<? super K, ? super V> transformer, 3795 double basis, 3796 DoubleBinaryOperator reducer) { 3797 if (transformer == null || reducer == null) 3798 throw new NullPointerException(); 3799 return new MapReduceMappingsToDoubleTask<K,V> 3800 (null, batchFor(parallelismThreshold), 0, 0, table, 3801 null, transformer, basis, reducer).invoke(); 3802 } 3803 3804 /** 3805 * Returns the result of accumulating the given transformation 3806 * of all (key, value) pairs using the given reducer to 3807 * combine values, and the given basis as an identity value. 3808 * 3809 * @param parallelismThreshold the (estimated) number of elements 3810 * needed for this operation to be executed in parallel 3811 * @param transformer a function returning the transformation 3812 * for an element 3813 * @param basis the identity (initial default value) for the reduction 3814 * @param reducer a commutative associative combining function 3815 * @return the result of accumulating the given transformation 3816 * of all (key, value) pairs 3817 * @since 1.8 3818 */ reduceToLong(long parallelismThreshold, ToLongBiFunction<? super K, ? super V> transformer, long basis, LongBinaryOperator reducer)3819 public long reduceToLong(long parallelismThreshold, 3820 ToLongBiFunction<? super K, ? super V> transformer, 3821 long basis, 3822 LongBinaryOperator reducer) { 3823 if (transformer == null || reducer == null) 3824 throw new NullPointerException(); 3825 return new MapReduceMappingsToLongTask<K,V> 3826 (null, batchFor(parallelismThreshold), 0, 0, table, 3827 null, transformer, basis, reducer).invoke(); 3828 } 3829 3830 /** 3831 * Returns the result of accumulating the given transformation 3832 * of all (key, value) pairs using the given reducer to 3833 * combine values, and the given basis as an identity value. 3834 * 3835 * @param parallelismThreshold the (estimated) number of elements 3836 * needed for this operation to be executed in parallel 3837 * @param transformer a function returning the transformation 3838 * for an element 3839 * @param basis the identity (initial default value) for the reduction 3840 * @param reducer a commutative associative combining function 3841 * @return the result of accumulating the given transformation 3842 * of all (key, value) pairs 3843 * @since 1.8 3844 */ reduceToInt(long parallelismThreshold, ToIntBiFunction<? super K, ? super V> transformer, int basis, IntBinaryOperator reducer)3845 public int reduceToInt(long parallelismThreshold, 3846 ToIntBiFunction<? super K, ? super V> transformer, 3847 int basis, 3848 IntBinaryOperator reducer) { 3849 if (transformer == null || reducer == null) 3850 throw new NullPointerException(); 3851 return new MapReduceMappingsToIntTask<K,V> 3852 (null, batchFor(parallelismThreshold), 0, 0, table, 3853 null, transformer, basis, reducer).invoke(); 3854 } 3855 3856 /** 3857 * Performs the given action for each key. 3858 * 3859 * @param parallelismThreshold the (estimated) number of elements 3860 * needed for this operation to be executed in parallel 3861 * @param action the action 3862 * @since 1.8 3863 */ forEachKey(long parallelismThreshold, Consumer<? super K> action)3864 public void forEachKey(long parallelismThreshold, 3865 Consumer<? super K> action) { 3866 if (action == null) throw new NullPointerException(); 3867 new ForEachKeyTask<K,V> 3868 (null, batchFor(parallelismThreshold), 0, 0, table, 3869 action).invoke(); 3870 } 3871 3872 /** 3873 * Performs the given action for each non-null transformation 3874 * of each key. 3875 * 3876 * @param parallelismThreshold the (estimated) number of elements 3877 * needed for this operation to be executed in parallel 3878 * @param transformer a function returning the transformation 3879 * for an element, or null if there is no transformation (in 3880 * which case the action is not applied) 3881 * @param action the action 3882 * @param <U> the return type of the transformer 3883 * @since 1.8 3884 */ forEachKey(long parallelismThreshold, Function<? super K, ? extends U> transformer, Consumer<? super U> action)3885 public <U> void forEachKey(long parallelismThreshold, 3886 Function<? super K, ? extends U> transformer, 3887 Consumer<? super U> action) { 3888 if (transformer == null || action == null) 3889 throw new NullPointerException(); 3890 new ForEachTransformedKeyTask<K,V,U> 3891 (null, batchFor(parallelismThreshold), 0, 0, table, 3892 transformer, action).invoke(); 3893 } 3894 3895 /** 3896 * Returns a non-null result from applying the given search 3897 * function on each key, or null if none. Upon success, 3898 * further element processing is suppressed and the results of 3899 * any other parallel invocations of the search function are 3900 * ignored. 3901 * 3902 * @param parallelismThreshold the (estimated) number of elements 3903 * needed for this operation to be executed in parallel 3904 * @param searchFunction a function returning a non-null 3905 * result on success, else null 3906 * @param <U> the return type of the search function 3907 * @return a non-null result from applying the given search 3908 * function on each key, or null if none 3909 * @since 1.8 3910 */ searchKeys(long parallelismThreshold, Function<? super K, ? extends U> searchFunction)3911 public <U> U searchKeys(long parallelismThreshold, 3912 Function<? super K, ? extends U> searchFunction) { 3913 if (searchFunction == null) throw new NullPointerException(); 3914 return new SearchKeysTask<K,V,U> 3915 (null, batchFor(parallelismThreshold), 0, 0, table, 3916 searchFunction, new AtomicReference<U>()).invoke(); 3917 } 3918 3919 /** 3920 * Returns the result of accumulating all keys using the given 3921 * reducer to combine values, or null if none. 3922 * 3923 * @param parallelismThreshold the (estimated) number of elements 3924 * needed for this operation to be executed in parallel 3925 * @param reducer a commutative associative combining function 3926 * @return the result of accumulating all keys using the given 3927 * reducer to combine values, or null if none 3928 * @since 1.8 3929 */ reduceKeys(long parallelismThreshold, BiFunction<? super K, ? super K, ? extends K> reducer)3930 public K reduceKeys(long parallelismThreshold, 3931 BiFunction<? super K, ? super K, ? extends K> reducer) { 3932 if (reducer == null) throw new NullPointerException(); 3933 return new ReduceKeysTask<K,V> 3934 (null, batchFor(parallelismThreshold), 0, 0, table, 3935 null, reducer).invoke(); 3936 } 3937 3938 /** 3939 * Returns the result of accumulating the given transformation 3940 * of all keys using the given reducer to combine values, or 3941 * null if none. 3942 * 3943 * @param parallelismThreshold the (estimated) number of elements 3944 * needed for this operation to be executed in parallel 3945 * @param transformer a function returning the transformation 3946 * for an element, or null if there is no transformation (in 3947 * which case it is not combined) 3948 * @param reducer a commutative associative combining function 3949 * @param <U> the return type of the transformer 3950 * @return the result of accumulating the given transformation 3951 * of all keys 3952 * @since 1.8 3953 */ reduceKeys(long parallelismThreshold, Function<? super K, ? extends U> transformer, BiFunction<? super U, ? super U, ? extends U> reducer)3954 public <U> U reduceKeys(long parallelismThreshold, 3955 Function<? super K, ? extends U> transformer, 3956 BiFunction<? super U, ? super U, ? extends U> reducer) { 3957 if (transformer == null || reducer == null) 3958 throw new NullPointerException(); 3959 return new MapReduceKeysTask<K,V,U> 3960 (null, batchFor(parallelismThreshold), 0, 0, table, 3961 null, transformer, reducer).invoke(); 3962 } 3963 3964 /** 3965 * Returns the result of accumulating the given transformation 3966 * of all keys using the given reducer to combine values, and 3967 * the given basis as an identity value. 3968 * 3969 * @param parallelismThreshold the (estimated) number of elements 3970 * needed for this operation to be executed in parallel 3971 * @param transformer a function returning the transformation 3972 * for an element 3973 * @param basis the identity (initial default value) for the reduction 3974 * @param reducer a commutative associative combining function 3975 * @return the result of accumulating the given transformation 3976 * of all keys 3977 * @since 1.8 3978 */ reduceKeysToDouble(long parallelismThreshold, ToDoubleFunction<? super K> transformer, double basis, DoubleBinaryOperator reducer)3979 public double reduceKeysToDouble(long parallelismThreshold, 3980 ToDoubleFunction<? super K> transformer, 3981 double basis, 3982 DoubleBinaryOperator reducer) { 3983 if (transformer == null || reducer == null) 3984 throw new NullPointerException(); 3985 return new MapReduceKeysToDoubleTask<K,V> 3986 (null, batchFor(parallelismThreshold), 0, 0, table, 3987 null, transformer, basis, reducer).invoke(); 3988 } 3989 3990 /** 3991 * Returns the result of accumulating the given transformation 3992 * of all keys using the given reducer to combine values, and 3993 * the given basis as an identity value. 3994 * 3995 * @param parallelismThreshold the (estimated) number of elements 3996 * needed for this operation to be executed in parallel 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 keys 4003 * @since 1.8 4004 */ reduceKeysToLong(long parallelismThreshold, ToLongFunction<? super K> transformer, long basis, LongBinaryOperator reducer)4005 public long reduceKeysToLong(long parallelismThreshold, 4006 ToLongFunction<? super K> transformer, 4007 long basis, 4008 LongBinaryOperator reducer) { 4009 if (transformer == null || reducer == null) 4010 throw new NullPointerException(); 4011 return new MapReduceKeysToLongTask<K,V> 4012 (null, batchFor(parallelismThreshold), 0, 0, table, 4013 null, transformer, basis, reducer).invoke(); 4014 } 4015 4016 /** 4017 * Returns the result of accumulating the given transformation 4018 * of all keys using the given reducer to combine values, and 4019 * the given basis as an identity value. 4020 * 4021 * @param parallelismThreshold the (estimated) number of elements 4022 * needed for this operation to be executed in parallel 4023 * @param transformer a function returning the transformation 4024 * for an element 4025 * @param basis the identity (initial default value) for the reduction 4026 * @param reducer a commutative associative combining function 4027 * @return the result of accumulating the given transformation 4028 * of all keys 4029 * @since 1.8 4030 */ reduceKeysToInt(long parallelismThreshold, ToIntFunction<? super K> transformer, int basis, IntBinaryOperator reducer)4031 public int reduceKeysToInt(long parallelismThreshold, 4032 ToIntFunction<? super K> transformer, 4033 int basis, 4034 IntBinaryOperator reducer) { 4035 if (transformer == null || reducer == null) 4036 throw new NullPointerException(); 4037 return new MapReduceKeysToIntTask<K,V> 4038 (null, batchFor(parallelismThreshold), 0, 0, table, 4039 null, transformer, basis, reducer).invoke(); 4040 } 4041 4042 /** 4043 * Performs the given action for each value. 4044 * 4045 * @param parallelismThreshold the (estimated) number of elements 4046 * needed for this operation to be executed in parallel 4047 * @param action the action 4048 * @since 1.8 4049 */ forEachValue(long parallelismThreshold, Consumer<? super V> action)4050 public void forEachValue(long parallelismThreshold, 4051 Consumer<? super V> action) { 4052 if (action == null) 4053 throw new NullPointerException(); 4054 new ForEachValueTask<K,V> 4055 (null, batchFor(parallelismThreshold), 0, 0, table, 4056 action).invoke(); 4057 } 4058 4059 /** 4060 * Performs the given action for each non-null transformation 4061 * of each value. 4062 * 4063 * @param parallelismThreshold the (estimated) number of elements 4064 * needed for this operation to be executed in parallel 4065 * @param transformer a function returning the transformation 4066 * for an element, or null if there is no transformation (in 4067 * which case the action is not applied) 4068 * @param action the action 4069 * @param <U> the return type of the transformer 4070 * @since 1.8 4071 */ forEachValue(long parallelismThreshold, Function<? super V, ? extends U> transformer, Consumer<? super U> action)4072 public <U> void forEachValue(long parallelismThreshold, 4073 Function<? super V, ? extends U> transformer, 4074 Consumer<? super U> action) { 4075 if (transformer == null || action == null) 4076 throw new NullPointerException(); 4077 new ForEachTransformedValueTask<K,V,U> 4078 (null, batchFor(parallelismThreshold), 0, 0, table, 4079 transformer, action).invoke(); 4080 } 4081 4082 /** 4083 * Returns a non-null result from applying the given search 4084 * function on each value, or null if none. Upon success, 4085 * further element processing is suppressed and the results of 4086 * any other parallel invocations of the search function are 4087 * ignored. 4088 * 4089 * @param parallelismThreshold the (estimated) number of elements 4090 * needed for this operation to be executed in parallel 4091 * @param searchFunction a function returning a non-null 4092 * result on success, else null 4093 * @param <U> the return type of the search function 4094 * @return a non-null result from applying the given search 4095 * function on each value, or null if none 4096 * @since 1.8 4097 */ searchValues(long parallelismThreshold, Function<? super V, ? extends U> searchFunction)4098 public <U> U searchValues(long parallelismThreshold, 4099 Function<? super V, ? extends U> searchFunction) { 4100 if (searchFunction == null) throw new NullPointerException(); 4101 return new SearchValuesTask<K,V,U> 4102 (null, batchFor(parallelismThreshold), 0, 0, table, 4103 searchFunction, new AtomicReference<U>()).invoke(); 4104 } 4105 4106 /** 4107 * Returns the result of accumulating all values using the 4108 * given reducer to combine values, or null if none. 4109 * 4110 * @param parallelismThreshold the (estimated) number of elements 4111 * needed for this operation to be executed in parallel 4112 * @param reducer a commutative associative combining function 4113 * @return the result of accumulating all values 4114 * @since 1.8 4115 */ reduceValues(long parallelismThreshold, BiFunction<? super V, ? super V, ? extends V> reducer)4116 public V reduceValues(long parallelismThreshold, 4117 BiFunction<? super V, ? super V, ? extends V> reducer) { 4118 if (reducer == null) throw new NullPointerException(); 4119 return new ReduceValuesTask<K,V> 4120 (null, batchFor(parallelismThreshold), 0, 0, table, 4121 null, reducer).invoke(); 4122 } 4123 4124 /** 4125 * Returns the result of accumulating the given transformation 4126 * of all values using the given reducer to combine values, or 4127 * null if none. 4128 * 4129 * @param parallelismThreshold the (estimated) number of elements 4130 * needed for this operation to be executed in parallel 4131 * @param transformer a function returning the transformation 4132 * for an element, or null if there is no transformation (in 4133 * which case it is not combined) 4134 * @param reducer a commutative associative combining function 4135 * @param <U> the return type of the transformer 4136 * @return the result of accumulating the given transformation 4137 * of all values 4138 * @since 1.8 4139 */ reduceValues(long parallelismThreshold, Function<? super V, ? extends U> transformer, BiFunction<? super U, ? super U, ? extends U> reducer)4140 public <U> U reduceValues(long parallelismThreshold, 4141 Function<? super V, ? extends U> transformer, 4142 BiFunction<? super U, ? super U, ? extends U> reducer) { 4143 if (transformer == null || reducer == null) 4144 throw new NullPointerException(); 4145 return new MapReduceValuesTask<K,V,U> 4146 (null, batchFor(parallelismThreshold), 0, 0, table, 4147 null, transformer, reducer).invoke(); 4148 } 4149 4150 /** 4151 * Returns the result of accumulating the given transformation 4152 * of all values using the given reducer to combine values, 4153 * and the given basis as an identity value. 4154 * 4155 * @param parallelismThreshold the (estimated) number of elements 4156 * needed for this operation to be executed in parallel 4157 * @param transformer a function returning the transformation 4158 * for an element 4159 * @param basis the identity (initial default value) for the reduction 4160 * @param reducer a commutative associative combining function 4161 * @return the result of accumulating the given transformation 4162 * of all values 4163 * @since 1.8 4164 */ reduceValuesToDouble(long parallelismThreshold, ToDoubleFunction<? super V> transformer, double basis, DoubleBinaryOperator reducer)4165 public double reduceValuesToDouble(long parallelismThreshold, 4166 ToDoubleFunction<? super V> transformer, 4167 double basis, 4168 DoubleBinaryOperator reducer) { 4169 if (transformer == null || reducer == null) 4170 throw new NullPointerException(); 4171 return new MapReduceValuesToDoubleTask<K,V> 4172 (null, batchFor(parallelismThreshold), 0, 0, table, 4173 null, transformer, basis, reducer).invoke(); 4174 } 4175 4176 /** 4177 * Returns the result of accumulating the given transformation 4178 * of all values using the given reducer to combine values, 4179 * and the given basis as an identity value. 4180 * 4181 * @param parallelismThreshold the (estimated) number of elements 4182 * needed for this operation to be executed in parallel 4183 * @param transformer a function returning the transformation 4184 * for an element 4185 * @param basis the identity (initial default value) for the reduction 4186 * @param reducer a commutative associative combining function 4187 * @return the result of accumulating the given transformation 4188 * of all values 4189 * @since 1.8 4190 */ reduceValuesToLong(long parallelismThreshold, ToLongFunction<? super V> transformer, long basis, LongBinaryOperator reducer)4191 public long reduceValuesToLong(long parallelismThreshold, 4192 ToLongFunction<? super V> transformer, 4193 long basis, 4194 LongBinaryOperator reducer) { 4195 if (transformer == null || reducer == null) 4196 throw new NullPointerException(); 4197 return new MapReduceValuesToLongTask<K,V> 4198 (null, batchFor(parallelismThreshold), 0, 0, table, 4199 null, transformer, basis, reducer).invoke(); 4200 } 4201 4202 /** 4203 * Returns the result of accumulating the given transformation 4204 * of all values using the given reducer to combine values, 4205 * and the given basis as an identity value. 4206 * 4207 * @param parallelismThreshold the (estimated) number of elements 4208 * needed for this operation to be executed in parallel 4209 * @param transformer a function returning the transformation 4210 * for an element 4211 * @param basis the identity (initial default value) for the reduction 4212 * @param reducer a commutative associative combining function 4213 * @return the result of accumulating the given transformation 4214 * of all values 4215 * @since 1.8 4216 */ reduceValuesToInt(long parallelismThreshold, ToIntFunction<? super V> transformer, int basis, IntBinaryOperator reducer)4217 public int reduceValuesToInt(long parallelismThreshold, 4218 ToIntFunction<? super V> transformer, 4219 int basis, 4220 IntBinaryOperator reducer) { 4221 if (transformer == null || reducer == null) 4222 throw new NullPointerException(); 4223 return new MapReduceValuesToIntTask<K,V> 4224 (null, batchFor(parallelismThreshold), 0, 0, table, 4225 null, transformer, basis, reducer).invoke(); 4226 } 4227 4228 /** 4229 * Performs the given action for each entry. 4230 * 4231 * @param parallelismThreshold the (estimated) number of elements 4232 * needed for this operation to be executed in parallel 4233 * @param action the action 4234 * @since 1.8 4235 */ forEachEntry(long parallelismThreshold, Consumer<? super Map.Entry<K,V>> action)4236 public void forEachEntry(long parallelismThreshold, 4237 Consumer<? super Map.Entry<K,V>> action) { 4238 if (action == null) throw new NullPointerException(); 4239 new ForEachEntryTask<K,V>(null, batchFor(parallelismThreshold), 0, 0, table, 4240 action).invoke(); 4241 } 4242 4243 /** 4244 * Performs the given action for each non-null transformation 4245 * of each entry. 4246 * 4247 * @param parallelismThreshold the (estimated) number of elements 4248 * needed for this operation to be executed in parallel 4249 * @param transformer a function returning the transformation 4250 * for an element, or null if there is no transformation (in 4251 * which case the action is not applied) 4252 * @param action the action 4253 * @param <U> the return type of the transformer 4254 * @since 1.8 4255 */ forEachEntry(long parallelismThreshold, Function<Map.Entry<K,V>, ? extends U> transformer, Consumer<? super U> action)4256 public <U> void forEachEntry(long parallelismThreshold, 4257 Function<Map.Entry<K,V>, ? extends U> transformer, 4258 Consumer<? super U> action) { 4259 if (transformer == null || action == null) 4260 throw new NullPointerException(); 4261 new ForEachTransformedEntryTask<K,V,U> 4262 (null, batchFor(parallelismThreshold), 0, 0, table, 4263 transformer, action).invoke(); 4264 } 4265 4266 /** 4267 * Returns a non-null result from applying the given search 4268 * function on each entry, or null if none. Upon success, 4269 * further element processing is suppressed and the results of 4270 * any other parallel invocations of the search function are 4271 * ignored. 4272 * 4273 * @param parallelismThreshold the (estimated) number of elements 4274 * needed for this operation to be executed in parallel 4275 * @param searchFunction a function returning a non-null 4276 * result on success, else null 4277 * @param <U> the return type of the search function 4278 * @return a non-null result from applying the given search 4279 * function on each entry, or null if none 4280 * @since 1.8 4281 */ searchEntries(long parallelismThreshold, Function<Map.Entry<K,V>, ? extends U> searchFunction)4282 public <U> U searchEntries(long parallelismThreshold, 4283 Function<Map.Entry<K,V>, ? extends U> searchFunction) { 4284 if (searchFunction == null) throw new NullPointerException(); 4285 return new SearchEntriesTask<K,V,U> 4286 (null, batchFor(parallelismThreshold), 0, 0, table, 4287 searchFunction, new AtomicReference<U>()).invoke(); 4288 } 4289 4290 /** 4291 * Returns the result of accumulating all entries using the 4292 * given reducer to combine values, or null if none. 4293 * 4294 * @param parallelismThreshold the (estimated) number of elements 4295 * needed for this operation to be executed in parallel 4296 * @param reducer a commutative associative combining function 4297 * @return the result of accumulating all entries 4298 * @since 1.8 4299 */ reduceEntries(long parallelismThreshold, BiFunction<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer)4300 public Map.Entry<K,V> reduceEntries(long parallelismThreshold, 4301 BiFunction<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) { 4302 if (reducer == null) throw new NullPointerException(); 4303 return new ReduceEntriesTask<K,V> 4304 (null, batchFor(parallelismThreshold), 0, 0, table, 4305 null, reducer).invoke(); 4306 } 4307 4308 /** 4309 * Returns the result of accumulating the given transformation 4310 * of all entries using the given reducer to combine values, 4311 * or null if none. 4312 * 4313 * @param parallelismThreshold the (estimated) number of elements 4314 * needed for this operation to be executed in parallel 4315 * @param transformer a function returning the transformation 4316 * for an element, or null if there is no transformation (in 4317 * which case it is not combined) 4318 * @param reducer a commutative associative combining function 4319 * @param <U> the return type of the transformer 4320 * @return the result of accumulating the given transformation 4321 * of all entries 4322 * @since 1.8 4323 */ reduceEntries(long parallelismThreshold, Function<Map.Entry<K,V>, ? extends U> transformer, BiFunction<? super U, ? super U, ? extends U> reducer)4324 public <U> U reduceEntries(long parallelismThreshold, 4325 Function<Map.Entry<K,V>, ? extends U> transformer, 4326 BiFunction<? super U, ? super U, ? extends U> reducer) { 4327 if (transformer == null || reducer == null) 4328 throw new NullPointerException(); 4329 return new MapReduceEntriesTask<K,V,U> 4330 (null, batchFor(parallelismThreshold), 0, 0, table, 4331 null, transformer, reducer).invoke(); 4332 } 4333 4334 /** 4335 * Returns the result of accumulating the given transformation 4336 * of all entries using the given reducer to combine values, 4337 * and the given basis as an identity value. 4338 * 4339 * @param parallelismThreshold the (estimated) number of elements 4340 * needed for this operation to be executed in parallel 4341 * @param transformer a function returning the transformation 4342 * for an element 4343 * @param basis the identity (initial default value) for the reduction 4344 * @param reducer a commutative associative combining function 4345 * @return the result of accumulating the given transformation 4346 * of all entries 4347 * @since 1.8 4348 */ reduceEntriesToDouble(long parallelismThreshold, ToDoubleFunction<Map.Entry<K,V>> transformer, double basis, DoubleBinaryOperator reducer)4349 public double reduceEntriesToDouble(long parallelismThreshold, 4350 ToDoubleFunction<Map.Entry<K,V>> transformer, 4351 double basis, 4352 DoubleBinaryOperator reducer) { 4353 if (transformer == null || reducer == null) 4354 throw new NullPointerException(); 4355 return new MapReduceEntriesToDoubleTask<K,V> 4356 (null, batchFor(parallelismThreshold), 0, 0, table, 4357 null, transformer, basis, reducer).invoke(); 4358 } 4359 4360 /** 4361 * Returns the result of accumulating the given transformation 4362 * of all entries using the given reducer to combine values, 4363 * and the given basis as an identity value. 4364 * 4365 * @param parallelismThreshold the (estimated) number of elements 4366 * needed for this operation to be executed in parallel 4367 * @param transformer a function returning the transformation 4368 * for an element 4369 * @param basis the identity (initial default value) for the reduction 4370 * @param reducer a commutative associative combining function 4371 * @return the result of accumulating the given transformation 4372 * of all entries 4373 * @since 1.8 4374 */ reduceEntriesToLong(long parallelismThreshold, ToLongFunction<Map.Entry<K,V>> transformer, long basis, LongBinaryOperator reducer)4375 public long reduceEntriesToLong(long parallelismThreshold, 4376 ToLongFunction<Map.Entry<K,V>> transformer, 4377 long basis, 4378 LongBinaryOperator reducer) { 4379 if (transformer == null || reducer == null) 4380 throw new NullPointerException(); 4381 return new MapReduceEntriesToLongTask<K,V> 4382 (null, batchFor(parallelismThreshold), 0, 0, table, 4383 null, transformer, basis, reducer).invoke(); 4384 } 4385 4386 /** 4387 * Returns the result of accumulating the given transformation 4388 * of all entries using the given reducer to combine values, 4389 * and the given basis as an identity value. 4390 * 4391 * @param parallelismThreshold the (estimated) number of elements 4392 * needed for this operation to be executed in parallel 4393 * @param transformer a function returning the transformation 4394 * for an element 4395 * @param basis the identity (initial default value) for the reduction 4396 * @param reducer a commutative associative combining function 4397 * @return the result of accumulating the given transformation 4398 * of all entries 4399 * @since 1.8 4400 */ reduceEntriesToInt(long parallelismThreshold, ToIntFunction<Map.Entry<K,V>> transformer, int basis, IntBinaryOperator reducer)4401 public int reduceEntriesToInt(long parallelismThreshold, 4402 ToIntFunction<Map.Entry<K,V>> transformer, 4403 int basis, 4404 IntBinaryOperator reducer) { 4405 if (transformer == null || reducer == null) 4406 throw new NullPointerException(); 4407 return new MapReduceEntriesToIntTask<K,V> 4408 (null, batchFor(parallelismThreshold), 0, 0, table, 4409 null, transformer, basis, reducer).invoke(); 4410 } 4411 4412 4413 /* ----------------Views -------------- */ 4414 4415 /** 4416 * Base class for views. 4417 */ 4418 abstract static class CollectionView<K,V,E> 4419 implements Collection<E>, java.io.Serializable { 4420 private static final long serialVersionUID = 7249069246763182397L; 4421 final ConcurrentHashMap<K,V> map; CollectionView(ConcurrentHashMap<K,V> map)4422 CollectionView(ConcurrentHashMap<K,V> map) { this.map = map; } 4423 4424 /** 4425 * Returns the map backing this view. 4426 * 4427 * @return the map backing this view 4428 */ getMap()4429 public ConcurrentHashMap<K,V> getMap() { return map; } 4430 4431 /** 4432 * Removes all of the elements from this view, by removing all 4433 * the mappings from the map backing this view. 4434 */ clear()4435 public final void clear() { map.clear(); } size()4436 public final int size() { return map.size(); } isEmpty()4437 public final boolean isEmpty() { return map.isEmpty(); } 4438 4439 // implementations below rely on concrete classes supplying these 4440 // abstract methods 4441 /** 4442 * Returns an iterator over the elements in this collection. 4443 * 4444 * <p>The returned iterator is 4445 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 4446 * 4447 * @return an iterator over the elements in this collection 4448 */ iterator()4449 public abstract Iterator<E> iterator(); contains(Object o)4450 public abstract boolean contains(Object o); remove(Object o)4451 public abstract boolean remove(Object o); 4452 4453 private static final String OOME_MSG = "Required array size too large"; 4454 toArray()4455 public final Object[] toArray() { 4456 long sz = map.mappingCount(); 4457 if (sz > MAX_ARRAY_SIZE) 4458 throw new OutOfMemoryError(OOME_MSG); 4459 int n = (int)sz; 4460 Object[] r = new Object[n]; 4461 int i = 0; 4462 for (E e : this) { 4463 if (i == n) { 4464 if (n >= MAX_ARRAY_SIZE) 4465 throw new OutOfMemoryError(OOME_MSG); 4466 if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) 4467 n = MAX_ARRAY_SIZE; 4468 else 4469 n += (n >>> 1) + 1; 4470 r = Arrays.copyOf(r, n); 4471 } 4472 r[i++] = e; 4473 } 4474 return (i == n) ? r : Arrays.copyOf(r, i); 4475 } 4476 4477 @SuppressWarnings("unchecked") toArray(T[] a)4478 public final <T> T[] toArray(T[] a) { 4479 long sz = map.mappingCount(); 4480 if (sz > MAX_ARRAY_SIZE) 4481 throw new OutOfMemoryError(OOME_MSG); 4482 int m = (int)sz; 4483 T[] r = (a.length >= m) ? a : 4484 (T[])java.lang.reflect.Array 4485 .newInstance(a.getClass().getComponentType(), m); 4486 int n = r.length; 4487 int i = 0; 4488 for (E e : this) { 4489 if (i == n) { 4490 if (n >= MAX_ARRAY_SIZE) 4491 throw new OutOfMemoryError(OOME_MSG); 4492 if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) 4493 n = MAX_ARRAY_SIZE; 4494 else 4495 n += (n >>> 1) + 1; 4496 r = Arrays.copyOf(r, n); 4497 } 4498 r[i++] = (T)e; 4499 } 4500 if (a == r && i < n) { 4501 r[i] = null; // null-terminate 4502 return r; 4503 } 4504 return (i == n) ? r : Arrays.copyOf(r, i); 4505 } 4506 4507 /** 4508 * Returns a string representation of this collection. 4509 * The string representation consists of the string representations 4510 * of the collection's elements in the order they are returned by 4511 * its iterator, enclosed in square brackets ({@code "[]"}). 4512 * Adjacent elements are separated by the characters {@code ", "} 4513 * (comma and space). Elements are converted to strings as by 4514 * {@link String#valueOf(Object)}. 4515 * 4516 * @return a string representation of this collection 4517 */ toString()4518 public final String toString() { 4519 StringBuilder sb = new StringBuilder(); 4520 sb.append('['); 4521 Iterator<E> it = iterator(); 4522 if (it.hasNext()) { 4523 for (;;) { 4524 Object e = it.next(); 4525 sb.append(e == this ? "(this Collection)" : e); 4526 if (!it.hasNext()) 4527 break; 4528 sb.append(',').append(' '); 4529 } 4530 } 4531 return sb.append(']').toString(); 4532 } 4533 containsAll(Collection<?> c)4534 public final boolean containsAll(Collection<?> c) { 4535 if (c != this) { 4536 for (Object e : c) { 4537 if (e == null || !contains(e)) 4538 return false; 4539 } 4540 } 4541 return true; 4542 } 4543 removeAll(Collection<?> c)4544 public boolean removeAll(Collection<?> c) { 4545 if (c == null) throw new NullPointerException(); 4546 boolean modified = false; 4547 // Use (c instanceof Set) as a hint that lookup in c is as 4548 // efficient as this view 4549 Node<K,V>[] t; 4550 if ((t = map.table) == null) { 4551 return false; 4552 } else if (c instanceof Set<?> && c.size() > t.length) { 4553 for (Iterator<?> it = iterator(); it.hasNext(); ) { 4554 if (c.contains(it.next())) { 4555 it.remove(); 4556 modified = true; 4557 } 4558 } 4559 } else { 4560 for (Object e : c) 4561 modified |= remove(e); 4562 } 4563 return modified; 4564 } 4565 retainAll(Collection<?> c)4566 public final boolean retainAll(Collection<?> c) { 4567 if (c == null) throw new NullPointerException(); 4568 boolean modified = false; 4569 for (Iterator<E> it = iterator(); it.hasNext();) { 4570 if (!c.contains(it.next())) { 4571 it.remove(); 4572 modified = true; 4573 } 4574 } 4575 return modified; 4576 } 4577 4578 } 4579 4580 /** 4581 * A view of a ConcurrentHashMap as a {@link Set} of keys, in 4582 * which additions may optionally be enabled by mapping to a 4583 * common value. This class cannot be directly instantiated. 4584 * See {@link #keySet(Object) keySet(V)}, 4585 * {@link #newKeySet() newKeySet()}, 4586 * {@link #newKeySet(int) newKeySet(int)}. 4587 * 4588 * @since 1.8 4589 */ 4590 public static class KeySetView<K,V> extends CollectionView<K,V,K> 4591 implements Set<K>, java.io.Serializable { 4592 private static final long serialVersionUID = 7249069246763182397L; 4593 private final V value; KeySetView(ConcurrentHashMap<K,V> map, V value)4594 KeySetView(ConcurrentHashMap<K,V> map, V value) { // non-public 4595 super(map); 4596 this.value = value; 4597 } 4598 4599 /** 4600 * Returns the default mapped value for additions, 4601 * or {@code null} if additions are not supported. 4602 * 4603 * @return the default mapped value for additions, or {@code null} 4604 * if not supported 4605 */ getMappedValue()4606 public V getMappedValue() { return value; } 4607 4608 /** 4609 * {@inheritDoc} 4610 * @throws NullPointerException if the specified key is null 4611 */ contains(Object o)4612 public boolean contains(Object o) { return map.containsKey(o); } 4613 4614 /** 4615 * Removes the key from this map view, by removing the key (and its 4616 * corresponding value) from the backing map. This method does 4617 * nothing if the key is not in the map. 4618 * 4619 * @param o the key to be removed from the backing map 4620 * @return {@code true} if the backing map contained the specified key 4621 * @throws NullPointerException if the specified key is null 4622 */ remove(Object o)4623 public boolean remove(Object o) { return map.remove(o) != null; } 4624 4625 /** 4626 * @return an iterator over the keys of the backing map 4627 */ iterator()4628 public Iterator<K> iterator() { 4629 Node<K,V>[] t; 4630 ConcurrentHashMap<K,V> m = map; 4631 int f = (t = m.table) == null ? 0 : t.length; 4632 return new KeyIterator<K,V>(t, f, 0, f, m); 4633 } 4634 4635 /** 4636 * Adds the specified key to this set view by mapping the key to 4637 * the default mapped value in the backing map, if defined. 4638 * 4639 * @param e key to be added 4640 * @return {@code true} if this set changed as a result of the call 4641 * @throws NullPointerException if the specified key is null 4642 * @throws UnsupportedOperationException if no default mapped value 4643 * for additions was provided 4644 */ add(K e)4645 public boolean add(K e) { 4646 V v; 4647 if ((v = value) == null) 4648 throw new UnsupportedOperationException(); 4649 return map.putVal(e, v, true) == null; 4650 } 4651 4652 /** 4653 * Adds all of the elements in the specified collection to this set, 4654 * as if by calling {@link #add} on each one. 4655 * 4656 * @param c the elements to be inserted into this set 4657 * @return {@code true} if this set changed as a result of the call 4658 * @throws NullPointerException if the collection or any of its 4659 * elements are {@code null} 4660 * @throws UnsupportedOperationException if no default mapped value 4661 * for additions was provided 4662 */ addAll(Collection<? extends K> c)4663 public boolean addAll(Collection<? extends K> c) { 4664 boolean added = false; 4665 V v; 4666 if ((v = value) == null) 4667 throw new UnsupportedOperationException(); 4668 for (K e : c) { 4669 if (map.putVal(e, v, true) == null) 4670 added = true; 4671 } 4672 return added; 4673 } 4674 hashCode()4675 public int hashCode() { 4676 int h = 0; 4677 for (K e : this) 4678 h += e.hashCode(); 4679 return h; 4680 } 4681 equals(Object o)4682 public boolean equals(Object o) { 4683 Set<?> c; 4684 return ((o instanceof Set) && 4685 ((c = (Set<?>)o) == this || 4686 (containsAll(c) && c.containsAll(this)))); 4687 } 4688 spliterator()4689 public Spliterator<K> spliterator() { 4690 Node<K,V>[] t; 4691 ConcurrentHashMap<K,V> m = map; 4692 long n = m.sumCount(); 4693 int f = (t = m.table) == null ? 0 : t.length; 4694 return new KeySpliterator<K,V>(t, f, 0, f, n < 0L ? 0L : n); 4695 } 4696 forEach(Consumer<? super K> action)4697 public void forEach(Consumer<? super K> action) { 4698 if (action == null) throw new NullPointerException(); 4699 Node<K,V>[] t; 4700 if ((t = map.table) != null) { 4701 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 4702 for (Node<K,V> p; (p = it.advance()) != null; ) 4703 action.accept(p.key); 4704 } 4705 } 4706 } 4707 4708 /** 4709 * A view of a ConcurrentHashMap as a {@link Collection} of 4710 * values, in which additions are disabled. This class cannot be 4711 * directly instantiated. See {@link #values()}. 4712 */ 4713 static final class ValuesView<K,V> extends CollectionView<K,V,V> 4714 implements Collection<V>, java.io.Serializable { 4715 private static final long serialVersionUID = 2249069246763182397L; ValuesView(ConcurrentHashMap<K,V> map)4716 ValuesView(ConcurrentHashMap<K,V> map) { super(map); } contains(Object o)4717 public final boolean contains(Object o) { 4718 return map.containsValue(o); 4719 } 4720 remove(Object o)4721 public final boolean remove(Object o) { 4722 if (o != null) { 4723 for (Iterator<V> it = iterator(); it.hasNext();) { 4724 if (o.equals(it.next())) { 4725 it.remove(); 4726 return true; 4727 } 4728 } 4729 } 4730 return false; 4731 } 4732 iterator()4733 public final Iterator<V> iterator() { 4734 ConcurrentHashMap<K,V> m = map; 4735 Node<K,V>[] t; 4736 int f = (t = m.table) == null ? 0 : t.length; 4737 return new ValueIterator<K,V>(t, f, 0, f, m); 4738 } 4739 add(V e)4740 public final boolean add(V e) { 4741 throw new UnsupportedOperationException(); 4742 } addAll(Collection<? extends V> c)4743 public final boolean addAll(Collection<? extends V> c) { 4744 throw new UnsupportedOperationException(); 4745 } 4746 removeAll(Collection<?> c)4747 @Override public boolean removeAll(Collection<?> c) { 4748 if (c == null) throw new NullPointerException(); 4749 boolean modified = false; 4750 for (Iterator<V> it = iterator(); it.hasNext();) { 4751 if (c.contains(it.next())) { 4752 it.remove(); 4753 modified = true; 4754 } 4755 } 4756 return modified; 4757 } 4758 removeIf(Predicate<? super V> filter)4759 public boolean removeIf(Predicate<? super V> filter) { 4760 return map.removeValueIf(filter); 4761 } 4762 spliterator()4763 public Spliterator<V> spliterator() { 4764 Node<K,V>[] t; 4765 ConcurrentHashMap<K,V> m = map; 4766 long n = m.sumCount(); 4767 int f = (t = m.table) == null ? 0 : t.length; 4768 return new ValueSpliterator<K,V>(t, f, 0, f, n < 0L ? 0L : n); 4769 } 4770 forEach(Consumer<? super V> action)4771 public void forEach(Consumer<? super V> action) { 4772 if (action == null) throw new NullPointerException(); 4773 Node<K,V>[] t; 4774 if ((t = map.table) != null) { 4775 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 4776 for (Node<K,V> p; (p = it.advance()) != null; ) 4777 action.accept(p.val); 4778 } 4779 } 4780 } 4781 4782 /** 4783 * A view of a ConcurrentHashMap as a {@link Set} of (key, value) 4784 * entries. This class cannot be directly instantiated. See 4785 * {@link #entrySet()}. 4786 */ 4787 static final class EntrySetView<K,V> extends CollectionView<K,V,Map.Entry<K,V>> 4788 implements Set<Map.Entry<K,V>>, java.io.Serializable { 4789 private static final long serialVersionUID = 2249069246763182397L; EntrySetView(ConcurrentHashMap<K,V> map)4790 EntrySetView(ConcurrentHashMap<K,V> map) { super(map); } 4791 contains(Object o)4792 public boolean contains(Object o) { 4793 Object k, v, r; Map.Entry<?,?> e; 4794 return ((o instanceof Map.Entry) && 4795 (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 4796 (r = map.get(k)) != null && 4797 (v = e.getValue()) != null && 4798 (v == r || v.equals(r))); 4799 } 4800 remove(Object o)4801 public boolean remove(Object o) { 4802 Object k, v; Map.Entry<?,?> e; 4803 return ((o instanceof Map.Entry) && 4804 (k = (e = (Map.Entry<?,?>)o).getKey()) != null && 4805 (v = e.getValue()) != null && 4806 map.remove(k, v)); 4807 } 4808 4809 /** 4810 * @return an iterator over the entries of the backing map 4811 */ iterator()4812 public Iterator<Map.Entry<K,V>> iterator() { 4813 ConcurrentHashMap<K,V> m = map; 4814 Node<K,V>[] t; 4815 int f = (t = m.table) == null ? 0 : t.length; 4816 return new EntryIterator<K,V>(t, f, 0, f, m); 4817 } 4818 add(Entry<K,V> e)4819 public boolean add(Entry<K,V> e) { 4820 return map.putVal(e.getKey(), e.getValue(), false) == null; 4821 } 4822 addAll(Collection<? extends Entry<K,V>> c)4823 public boolean addAll(Collection<? extends Entry<K,V>> c) { 4824 boolean added = false; 4825 for (Entry<K,V> e : c) { 4826 if (add(e)) 4827 added = true; 4828 } 4829 return added; 4830 } 4831 removeIf(Predicate<? super Entry<K,V>> filter)4832 public boolean removeIf(Predicate<? super Entry<K,V>> filter) { 4833 return map.removeEntryIf(filter); 4834 } 4835 hashCode()4836 public final int hashCode() { 4837 int h = 0; 4838 Node<K,V>[] t; 4839 if ((t = map.table) != null) { 4840 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 4841 for (Node<K,V> p; (p = it.advance()) != null; ) { 4842 h += p.hashCode(); 4843 } 4844 } 4845 return h; 4846 } 4847 equals(Object o)4848 public final boolean equals(Object o) { 4849 Set<?> c; 4850 return ((o instanceof Set) && 4851 ((c = (Set<?>)o) == this || 4852 (containsAll(c) && c.containsAll(this)))); 4853 } 4854 spliterator()4855 public Spliterator<Map.Entry<K,V>> spliterator() { 4856 Node<K,V>[] t; 4857 ConcurrentHashMap<K,V> m = map; 4858 long n = m.sumCount(); 4859 int f = (t = m.table) == null ? 0 : t.length; 4860 return new EntrySpliterator<K,V>(t, f, 0, f, n < 0L ? 0L : n, m); 4861 } 4862 forEach(Consumer<? super Map.Entry<K,V>> action)4863 public void forEach(Consumer<? super Map.Entry<K,V>> action) { 4864 if (action == null) throw new NullPointerException(); 4865 Node<K,V>[] t; 4866 if ((t = map.table) != null) { 4867 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length); 4868 for (Node<K,V> p; (p = it.advance()) != null; ) 4869 action.accept(new MapEntry<K,V>(p.key, p.val, map)); 4870 } 4871 } 4872 4873 } 4874 4875 // ------------------------------------------------------- 4876 4877 /** 4878 * Base class for bulk tasks. Repeats some fields and code from 4879 * class Traverser, because we need to subclass CountedCompleter. 4880 */ 4881 @SuppressWarnings("serial") 4882 abstract static class BulkTask<K,V,R> extends CountedCompleter<R> { 4883 Node<K,V>[] tab; // same as Traverser 4884 Node<K,V> next; 4885 TableStack<K,V> stack, spare; 4886 int index; 4887 int baseIndex; 4888 int baseLimit; 4889 final int baseSize; 4890 int batch; // split control 4891 BulkTask(BulkTask<K,V,?> par, int b, int i, int f, Node<K,V>[] t)4892 BulkTask(BulkTask<K,V,?> par, int b, int i, int f, Node<K,V>[] t) { 4893 super(par); 4894 this.batch = b; 4895 this.index = this.baseIndex = i; 4896 if ((this.tab = t) == null) 4897 this.baseSize = this.baseLimit = 0; 4898 else if (par == null) 4899 this.baseSize = this.baseLimit = t.length; 4900 else { 4901 this.baseLimit = f; 4902 this.baseSize = par.baseSize; 4903 } 4904 } 4905 4906 /** 4907 * Same as Traverser version. 4908 */ advance()4909 final Node<K,V> advance() { 4910 Node<K,V> e; 4911 if ((e = next) != null) 4912 e = e.next; 4913 for (;;) { 4914 Node<K,V>[] t; int i, n; 4915 if (e != null) 4916 return next = e; 4917 if (baseIndex >= baseLimit || (t = tab) == null || 4918 (n = t.length) <= (i = index) || i < 0) 4919 return next = null; 4920 if ((e = tabAt(t, i)) != null && e.hash < 0) { 4921 if (e instanceof ForwardingNode) { 4922 tab = ((ForwardingNode<K,V>)e).nextTable; 4923 e = null; 4924 pushState(t, i, n); 4925 continue; 4926 } 4927 else if (e instanceof TreeBin) 4928 e = ((TreeBin<K,V>)e).first; 4929 else 4930 e = null; 4931 } 4932 if (stack != null) 4933 recoverState(n); 4934 else if ((index = i + baseSize) >= n) 4935 index = ++baseIndex; 4936 } 4937 } 4938 pushState(Node<K,V>[] t, int i, int n)4939 private void pushState(Node<K,V>[] t, int i, int n) { 4940 TableStack<K,V> s = spare; 4941 if (s != null) 4942 spare = s.next; 4943 else 4944 s = new TableStack<K,V>(); 4945 s.tab = t; 4946 s.length = n; 4947 s.index = i; 4948 s.next = stack; 4949 stack = s; 4950 } 4951 recoverState(int n)4952 private void recoverState(int n) { 4953 TableStack<K,V> s; int len; 4954 while ((s = stack) != null && (index += (len = s.length)) >= n) { 4955 n = len; 4956 index = s.index; 4957 tab = s.tab; 4958 s.tab = null; 4959 TableStack<K,V> next = s.next; 4960 s.next = spare; // save for reuse 4961 stack = next; 4962 spare = s; 4963 } 4964 if (s == null && (index += baseSize) >= n) 4965 index = ++baseIndex; 4966 } 4967 } 4968 4969 /* 4970 * Task classes. Coded in a regular but ugly format/style to 4971 * simplify checks that each variant differs in the right way from 4972 * others. The null screenings exist because compilers cannot tell 4973 * that we've already null-checked task arguments, so we force 4974 * simplest hoisted bypass to help avoid convoluted traps. 4975 */ 4976 @SuppressWarnings("serial") 4977 static final class ForEachKeyTask<K,V> 4978 extends BulkTask<K,V,Void> { 4979 final Consumer<? super K> action; ForEachKeyTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, Consumer<? super K> action)4980 ForEachKeyTask 4981 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 4982 Consumer<? super K> action) { 4983 super(p, b, i, f, t); 4984 this.action = action; 4985 } compute()4986 public final void compute() { 4987 final Consumer<? super K> action; 4988 if ((action = this.action) != null) { 4989 for (int i = baseIndex, f, h; batch > 0 && 4990 (h = ((f = baseLimit) + i) >>> 1) > i;) { 4991 addToPendingCount(1); 4992 new ForEachKeyTask<K,V> 4993 (this, batch >>>= 1, baseLimit = h, f, tab, 4994 action).fork(); 4995 } 4996 for (Node<K,V> p; (p = advance()) != null;) 4997 action.accept(p.key); 4998 propagateCompletion(); 4999 } 5000 } 5001 } 5002 5003 @SuppressWarnings("serial") 5004 static final class ForEachValueTask<K,V> 5005 extends BulkTask<K,V,Void> { 5006 final Consumer<? super V> action; ForEachValueTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, Consumer<? super V> action)5007 ForEachValueTask 5008 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5009 Consumer<? super V> action) { 5010 super(p, b, i, f, t); 5011 this.action = action; 5012 } compute()5013 public final void compute() { 5014 final Consumer<? super V> action; 5015 if ((action = this.action) != null) { 5016 for (int i = baseIndex, f, h; batch > 0 && 5017 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5018 addToPendingCount(1); 5019 new ForEachValueTask<K,V> 5020 (this, batch >>>= 1, baseLimit = h, f, tab, 5021 action).fork(); 5022 } 5023 for (Node<K,V> p; (p = advance()) != null;) 5024 action.accept(p.val); 5025 propagateCompletion(); 5026 } 5027 } 5028 } 5029 5030 @SuppressWarnings("serial") 5031 static final class ForEachEntryTask<K,V> 5032 extends BulkTask<K,V,Void> { 5033 final Consumer<? super Entry<K,V>> action; ForEachEntryTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, Consumer<? super Entry<K,V>> action)5034 ForEachEntryTask 5035 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5036 Consumer<? super Entry<K,V>> action) { 5037 super(p, b, i, f, t); 5038 this.action = action; 5039 } compute()5040 public final void compute() { 5041 final Consumer<? super Entry<K,V>> action; 5042 if ((action = this.action) != null) { 5043 for (int i = baseIndex, f, h; batch > 0 && 5044 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5045 addToPendingCount(1); 5046 new ForEachEntryTask<K,V> 5047 (this, batch >>>= 1, baseLimit = h, f, tab, 5048 action).fork(); 5049 } 5050 for (Node<K,V> p; (p = advance()) != null; ) 5051 action.accept(p); 5052 propagateCompletion(); 5053 } 5054 } 5055 } 5056 5057 @SuppressWarnings("serial") 5058 static final class ForEachMappingTask<K,V> 5059 extends BulkTask<K,V,Void> { 5060 final BiConsumer<? super K, ? super V> action; ForEachMappingTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, BiConsumer<? super K,? super V> action)5061 ForEachMappingTask 5062 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5063 BiConsumer<? super K,? super V> action) { 5064 super(p, b, i, f, t); 5065 this.action = action; 5066 } compute()5067 public final void compute() { 5068 final BiConsumer<? super K, ? super V> action; 5069 if ((action = this.action) != null) { 5070 for (int i = baseIndex, f, h; batch > 0 && 5071 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5072 addToPendingCount(1); 5073 new ForEachMappingTask<K,V> 5074 (this, batch >>>= 1, baseLimit = h, f, tab, 5075 action).fork(); 5076 } 5077 for (Node<K,V> p; (p = advance()) != null; ) 5078 action.accept(p.key, p.val); 5079 propagateCompletion(); 5080 } 5081 } 5082 } 5083 5084 @SuppressWarnings("serial") 5085 static final class ForEachTransformedKeyTask<K,V,U> 5086 extends BulkTask<K,V,Void> { 5087 final Function<? super K, ? extends U> transformer; 5088 final Consumer<? super U> action; ForEachTransformedKeyTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, Function<? super K, ? extends U> transformer, Consumer<? super U> action)5089 ForEachTransformedKeyTask 5090 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5091 Function<? super K, ? extends U> transformer, Consumer<? super U> action) { 5092 super(p, b, i, f, t); 5093 this.transformer = transformer; this.action = action; 5094 } compute()5095 public final void compute() { 5096 final Function<? super K, ? extends U> transformer; 5097 final Consumer<? super U> action; 5098 if ((transformer = this.transformer) != null && 5099 (action = this.action) != null) { 5100 for (int i = baseIndex, f, h; batch > 0 && 5101 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5102 addToPendingCount(1); 5103 new ForEachTransformedKeyTask<K,V,U> 5104 (this, batch >>>= 1, baseLimit = h, f, tab, 5105 transformer, action).fork(); 5106 } 5107 for (Node<K,V> p; (p = advance()) != null; ) { 5108 U u; 5109 if ((u = transformer.apply(p.key)) != null) 5110 action.accept(u); 5111 } 5112 propagateCompletion(); 5113 } 5114 } 5115 } 5116 5117 @SuppressWarnings("serial") 5118 static final class ForEachTransformedValueTask<K,V,U> 5119 extends BulkTask<K,V,Void> { 5120 final Function<? super V, ? extends U> transformer; 5121 final Consumer<? super U> action; ForEachTransformedValueTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, Function<? super V, ? extends U> transformer, Consumer<? super U> action)5122 ForEachTransformedValueTask 5123 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5124 Function<? super V, ? extends U> transformer, Consumer<? super U> action) { 5125 super(p, b, i, f, t); 5126 this.transformer = transformer; this.action = action; 5127 } compute()5128 public final void compute() { 5129 final Function<? super V, ? extends U> transformer; 5130 final Consumer<? super U> action; 5131 if ((transformer = this.transformer) != null && 5132 (action = this.action) != null) { 5133 for (int i = baseIndex, f, h; batch > 0 && 5134 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5135 addToPendingCount(1); 5136 new ForEachTransformedValueTask<K,V,U> 5137 (this, batch >>>= 1, baseLimit = h, f, tab, 5138 transformer, action).fork(); 5139 } 5140 for (Node<K,V> p; (p = advance()) != null; ) { 5141 U u; 5142 if ((u = transformer.apply(p.val)) != null) 5143 action.accept(u); 5144 } 5145 propagateCompletion(); 5146 } 5147 } 5148 } 5149 5150 @SuppressWarnings("serial") 5151 static final class ForEachTransformedEntryTask<K,V,U> 5152 extends BulkTask<K,V,Void> { 5153 final Function<Map.Entry<K,V>, ? extends U> transformer; 5154 final Consumer<? super U> action; ForEachTransformedEntryTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, Function<Map.Entry<K,V>, ? extends U> transformer, Consumer<? super U> action)5155 ForEachTransformedEntryTask 5156 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5157 Function<Map.Entry<K,V>, ? extends U> transformer, Consumer<? super U> action) { 5158 super(p, b, i, f, t); 5159 this.transformer = transformer; this.action = action; 5160 } compute()5161 public final void compute() { 5162 final Function<Map.Entry<K,V>, ? extends U> transformer; 5163 final Consumer<? super U> action; 5164 if ((transformer = this.transformer) != null && 5165 (action = this.action) != null) { 5166 for (int i = baseIndex, f, h; batch > 0 && 5167 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5168 addToPendingCount(1); 5169 new ForEachTransformedEntryTask<K,V,U> 5170 (this, batch >>>= 1, baseLimit = h, f, tab, 5171 transformer, action).fork(); 5172 } 5173 for (Node<K,V> p; (p = advance()) != null; ) { 5174 U u; 5175 if ((u = transformer.apply(p)) != null) 5176 action.accept(u); 5177 } 5178 propagateCompletion(); 5179 } 5180 } 5181 } 5182 5183 @SuppressWarnings("serial") 5184 static final class ForEachTransformedMappingTask<K,V,U> 5185 extends BulkTask<K,V,Void> { 5186 final BiFunction<? super K, ? super V, ? extends U> transformer; 5187 final Consumer<? super U> action; ForEachTransformedMappingTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, BiFunction<? super K, ? super V, ? extends U> transformer, Consumer<? super U> action)5188 ForEachTransformedMappingTask 5189 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5190 BiFunction<? super K, ? super V, ? extends U> transformer, 5191 Consumer<? super U> action) { 5192 super(p, b, i, f, t); 5193 this.transformer = transformer; this.action = action; 5194 } compute()5195 public final void compute() { 5196 final BiFunction<? super K, ? super V, ? extends U> transformer; 5197 final Consumer<? super U> action; 5198 if ((transformer = this.transformer) != null && 5199 (action = this.action) != null) { 5200 for (int i = baseIndex, f, h; batch > 0 && 5201 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5202 addToPendingCount(1); 5203 new ForEachTransformedMappingTask<K,V,U> 5204 (this, batch >>>= 1, baseLimit = h, f, tab, 5205 transformer, action).fork(); 5206 } 5207 for (Node<K,V> p; (p = advance()) != null; ) { 5208 U u; 5209 if ((u = transformer.apply(p.key, p.val)) != null) 5210 action.accept(u); 5211 } 5212 propagateCompletion(); 5213 } 5214 } 5215 } 5216 5217 @SuppressWarnings("serial") 5218 static final class SearchKeysTask<K,V,U> 5219 extends BulkTask<K,V,U> { 5220 final Function<? super K, ? extends U> searchFunction; 5221 final AtomicReference<U> result; SearchKeysTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, Function<? super K, ? extends U> searchFunction, AtomicReference<U> result)5222 SearchKeysTask 5223 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5224 Function<? super K, ? extends U> searchFunction, 5225 AtomicReference<U> result) { 5226 super(p, b, i, f, t); 5227 this.searchFunction = searchFunction; this.result = result; 5228 } getRawResult()5229 public final U getRawResult() { return result.get(); } compute()5230 public final void compute() { 5231 final Function<? super K, ? extends U> searchFunction; 5232 final AtomicReference<U> result; 5233 if ((searchFunction = this.searchFunction) != null && 5234 (result = this.result) != null) { 5235 for (int i = baseIndex, f, h; batch > 0 && 5236 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5237 if (result.get() != null) 5238 return; 5239 addToPendingCount(1); 5240 new SearchKeysTask<K,V,U> 5241 (this, batch >>>= 1, baseLimit = h, f, tab, 5242 searchFunction, result).fork(); 5243 } 5244 while (result.get() == null) { 5245 U u; 5246 Node<K,V> p; 5247 if ((p = advance()) == null) { 5248 propagateCompletion(); 5249 break; 5250 } 5251 if ((u = searchFunction.apply(p.key)) != null) { 5252 if (result.compareAndSet(null, u)) 5253 quietlyCompleteRoot(); 5254 break; 5255 } 5256 } 5257 } 5258 } 5259 } 5260 5261 @SuppressWarnings("serial") 5262 static final class SearchValuesTask<K,V,U> 5263 extends BulkTask<K,V,U> { 5264 final Function<? super V, ? extends U> searchFunction; 5265 final AtomicReference<U> result; SearchValuesTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, Function<? super V, ? extends U> searchFunction, AtomicReference<U> result)5266 SearchValuesTask 5267 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5268 Function<? super V, ? extends U> searchFunction, 5269 AtomicReference<U> result) { 5270 super(p, b, i, f, t); 5271 this.searchFunction = searchFunction; this.result = result; 5272 } getRawResult()5273 public final U getRawResult() { return result.get(); } compute()5274 public final void compute() { 5275 final Function<? super V, ? extends U> searchFunction; 5276 final AtomicReference<U> result; 5277 if ((searchFunction = this.searchFunction) != null && 5278 (result = this.result) != null) { 5279 for (int i = baseIndex, f, h; batch > 0 && 5280 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5281 if (result.get() != null) 5282 return; 5283 addToPendingCount(1); 5284 new SearchValuesTask<K,V,U> 5285 (this, batch >>>= 1, baseLimit = h, f, tab, 5286 searchFunction, result).fork(); 5287 } 5288 while (result.get() == null) { 5289 U u; 5290 Node<K,V> p; 5291 if ((p = advance()) == null) { 5292 propagateCompletion(); 5293 break; 5294 } 5295 if ((u = searchFunction.apply(p.val)) != null) { 5296 if (result.compareAndSet(null, u)) 5297 quietlyCompleteRoot(); 5298 break; 5299 } 5300 } 5301 } 5302 } 5303 } 5304 5305 @SuppressWarnings("serial") 5306 static final class SearchEntriesTask<K,V,U> 5307 extends BulkTask<K,V,U> { 5308 final Function<Entry<K,V>, ? extends U> searchFunction; 5309 final AtomicReference<U> result; SearchEntriesTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, Function<Entry<K,V>, ? extends U> searchFunction, AtomicReference<U> result)5310 SearchEntriesTask 5311 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5312 Function<Entry<K,V>, ? extends U> searchFunction, 5313 AtomicReference<U> result) { 5314 super(p, b, i, f, t); 5315 this.searchFunction = searchFunction; this.result = result; 5316 } getRawResult()5317 public final U getRawResult() { return result.get(); } compute()5318 public final void compute() { 5319 final Function<Entry<K,V>, ? extends U> searchFunction; 5320 final AtomicReference<U> result; 5321 if ((searchFunction = this.searchFunction) != null && 5322 (result = this.result) != null) { 5323 for (int i = baseIndex, f, h; batch > 0 && 5324 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5325 if (result.get() != null) 5326 return; 5327 addToPendingCount(1); 5328 new SearchEntriesTask<K,V,U> 5329 (this, batch >>>= 1, baseLimit = h, f, tab, 5330 searchFunction, result).fork(); 5331 } 5332 while (result.get() == null) { 5333 U u; 5334 Node<K,V> p; 5335 if ((p = advance()) == null) { 5336 propagateCompletion(); 5337 break; 5338 } 5339 if ((u = searchFunction.apply(p)) != null) { 5340 if (result.compareAndSet(null, u)) 5341 quietlyCompleteRoot(); 5342 return; 5343 } 5344 } 5345 } 5346 } 5347 } 5348 5349 @SuppressWarnings("serial") 5350 static final class SearchMappingsTask<K,V,U> 5351 extends BulkTask<K,V,U> { 5352 final BiFunction<? super K, ? super V, ? extends U> searchFunction; 5353 final AtomicReference<U> result; SearchMappingsTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, BiFunction<? super K, ? super V, ? extends U> searchFunction, AtomicReference<U> result)5354 SearchMappingsTask 5355 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5356 BiFunction<? super K, ? super V, ? extends U> searchFunction, 5357 AtomicReference<U> result) { 5358 super(p, b, i, f, t); 5359 this.searchFunction = searchFunction; this.result = result; 5360 } getRawResult()5361 public final U getRawResult() { return result.get(); } compute()5362 public final void compute() { 5363 final BiFunction<? super K, ? super V, ? extends U> searchFunction; 5364 final AtomicReference<U> result; 5365 if ((searchFunction = this.searchFunction) != null && 5366 (result = this.result) != null) { 5367 for (int i = baseIndex, f, h; batch > 0 && 5368 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5369 if (result.get() != null) 5370 return; 5371 addToPendingCount(1); 5372 new SearchMappingsTask<K,V,U> 5373 (this, batch >>>= 1, baseLimit = h, f, tab, 5374 searchFunction, result).fork(); 5375 } 5376 while (result.get() == null) { 5377 U u; 5378 Node<K,V> p; 5379 if ((p = advance()) == null) { 5380 propagateCompletion(); 5381 break; 5382 } 5383 if ((u = searchFunction.apply(p.key, p.val)) != null) { 5384 if (result.compareAndSet(null, u)) 5385 quietlyCompleteRoot(); 5386 break; 5387 } 5388 } 5389 } 5390 } 5391 } 5392 5393 @SuppressWarnings("serial") 5394 static final class ReduceKeysTask<K,V> 5395 extends BulkTask<K,V,K> { 5396 final BiFunction<? super K, ? super K, ? extends K> reducer; 5397 K result; 5398 ReduceKeysTask<K,V> rights, nextRight; ReduceKeysTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, ReduceKeysTask<K,V> nextRight, BiFunction<? super K, ? super K, ? extends K> reducer)5399 ReduceKeysTask 5400 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5401 ReduceKeysTask<K,V> nextRight, 5402 BiFunction<? super K, ? super K, ? extends K> reducer) { 5403 super(p, b, i, f, t); this.nextRight = nextRight; 5404 this.reducer = reducer; 5405 } getRawResult()5406 public final K getRawResult() { return result; } compute()5407 public final void compute() { 5408 final BiFunction<? super K, ? super K, ? extends K> reducer; 5409 if ((reducer = this.reducer) != null) { 5410 for (int i = baseIndex, f, h; batch > 0 && 5411 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5412 addToPendingCount(1); 5413 (rights = new ReduceKeysTask<K,V> 5414 (this, batch >>>= 1, baseLimit = h, f, tab, 5415 rights, reducer)).fork(); 5416 } 5417 K r = null; 5418 for (Node<K,V> p; (p = advance()) != null; ) { 5419 K u = p.key; 5420 r = (r == null) ? u : u == null ? r : reducer.apply(r, u); 5421 } 5422 result = r; 5423 CountedCompleter<?> c; 5424 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5425 @SuppressWarnings("unchecked") 5426 ReduceKeysTask<K,V> 5427 t = (ReduceKeysTask<K,V>)c, 5428 s = t.rights; 5429 while (s != null) { 5430 K tr, sr; 5431 if ((sr = s.result) != null) 5432 t.result = (((tr = t.result) == null) ? sr : 5433 reducer.apply(tr, sr)); 5434 s = t.rights = s.nextRight; 5435 } 5436 } 5437 } 5438 } 5439 } 5440 5441 @SuppressWarnings("serial") 5442 static final class ReduceValuesTask<K,V> 5443 extends BulkTask<K,V,V> { 5444 final BiFunction<? super V, ? super V, ? extends V> reducer; 5445 V result; 5446 ReduceValuesTask<K,V> rights, nextRight; ReduceValuesTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, ReduceValuesTask<K,V> nextRight, BiFunction<? super V, ? super V, ? extends V> reducer)5447 ReduceValuesTask 5448 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5449 ReduceValuesTask<K,V> nextRight, 5450 BiFunction<? super V, ? super V, ? extends V> reducer) { 5451 super(p, b, i, f, t); this.nextRight = nextRight; 5452 this.reducer = reducer; 5453 } getRawResult()5454 public final V getRawResult() { return result; } compute()5455 public final void compute() { 5456 final BiFunction<? super V, ? super V, ? extends V> reducer; 5457 if ((reducer = this.reducer) != null) { 5458 for (int i = baseIndex, f, h; batch > 0 && 5459 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5460 addToPendingCount(1); 5461 (rights = new ReduceValuesTask<K,V> 5462 (this, batch >>>= 1, baseLimit = h, f, tab, 5463 rights, reducer)).fork(); 5464 } 5465 V r = null; 5466 for (Node<K,V> p; (p = advance()) != null; ) { 5467 V v = p.val; 5468 r = (r == null) ? v : reducer.apply(r, v); 5469 } 5470 result = r; 5471 CountedCompleter<?> c; 5472 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5473 @SuppressWarnings("unchecked") 5474 ReduceValuesTask<K,V> 5475 t = (ReduceValuesTask<K,V>)c, 5476 s = t.rights; 5477 while (s != null) { 5478 V tr, sr; 5479 if ((sr = s.result) != null) 5480 t.result = (((tr = t.result) == null) ? sr : 5481 reducer.apply(tr, sr)); 5482 s = t.rights = s.nextRight; 5483 } 5484 } 5485 } 5486 } 5487 } 5488 5489 @SuppressWarnings("serial") 5490 static final class ReduceEntriesTask<K,V> 5491 extends BulkTask<K,V,Map.Entry<K,V>> { 5492 final BiFunction<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer; 5493 Map.Entry<K,V> result; 5494 ReduceEntriesTask<K,V> rights, nextRight; ReduceEntriesTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, ReduceEntriesTask<K,V> nextRight, BiFunction<Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer)5495 ReduceEntriesTask 5496 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5497 ReduceEntriesTask<K,V> nextRight, 5498 BiFunction<Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) { 5499 super(p, b, i, f, t); this.nextRight = nextRight; 5500 this.reducer = reducer; 5501 } getRawResult()5502 public final Map.Entry<K,V> getRawResult() { return result; } compute()5503 public final void compute() { 5504 final BiFunction<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer; 5505 if ((reducer = this.reducer) != null) { 5506 for (int i = baseIndex, f, h; batch > 0 && 5507 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5508 addToPendingCount(1); 5509 (rights = new ReduceEntriesTask<K,V> 5510 (this, batch >>>= 1, baseLimit = h, f, tab, 5511 rights, reducer)).fork(); 5512 } 5513 Map.Entry<K,V> r = null; 5514 for (Node<K,V> p; (p = advance()) != null; ) 5515 r = (r == null) ? p : reducer.apply(r, p); 5516 result = r; 5517 CountedCompleter<?> c; 5518 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5519 @SuppressWarnings("unchecked") 5520 ReduceEntriesTask<K,V> 5521 t = (ReduceEntriesTask<K,V>)c, 5522 s = t.rights; 5523 while (s != null) { 5524 Map.Entry<K,V> tr, sr; 5525 if ((sr = s.result) != null) 5526 t.result = (((tr = t.result) == null) ? sr : 5527 reducer.apply(tr, sr)); 5528 s = t.rights = s.nextRight; 5529 } 5530 } 5531 } 5532 } 5533 } 5534 5535 @SuppressWarnings("serial") 5536 static final class MapReduceKeysTask<K,V,U> 5537 extends BulkTask<K,V,U> { 5538 final Function<? super K, ? extends U> transformer; 5539 final BiFunction<? super U, ? super U, ? extends U> reducer; 5540 U result; 5541 MapReduceKeysTask<K,V,U> rights, nextRight; MapReduceKeysTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceKeysTask<K,V,U> nextRight, Function<? super K, ? extends U> transformer, BiFunction<? super U, ? super U, ? extends U> reducer)5542 MapReduceKeysTask 5543 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5544 MapReduceKeysTask<K,V,U> nextRight, 5545 Function<? super K, ? extends U> transformer, 5546 BiFunction<? super U, ? super U, ? extends U> reducer) { 5547 super(p, b, i, f, t); this.nextRight = nextRight; 5548 this.transformer = transformer; 5549 this.reducer = reducer; 5550 } getRawResult()5551 public final U getRawResult() { return result; } compute()5552 public final void compute() { 5553 final Function<? super K, ? extends U> transformer; 5554 final BiFunction<? super U, ? super U, ? extends U> reducer; 5555 if ((transformer = this.transformer) != null && 5556 (reducer = this.reducer) != null) { 5557 for (int i = baseIndex, f, h; batch > 0 && 5558 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5559 addToPendingCount(1); 5560 (rights = new MapReduceKeysTask<K,V,U> 5561 (this, batch >>>= 1, baseLimit = h, f, tab, 5562 rights, transformer, reducer)).fork(); 5563 } 5564 U r = null; 5565 for (Node<K,V> p; (p = advance()) != null; ) { 5566 U u; 5567 if ((u = transformer.apply(p.key)) != null) 5568 r = (r == null) ? u : reducer.apply(r, u); 5569 } 5570 result = r; 5571 CountedCompleter<?> c; 5572 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5573 @SuppressWarnings("unchecked") 5574 MapReduceKeysTask<K,V,U> 5575 t = (MapReduceKeysTask<K,V,U>)c, 5576 s = t.rights; 5577 while (s != null) { 5578 U tr, sr; 5579 if ((sr = s.result) != null) 5580 t.result = (((tr = t.result) == null) ? sr : 5581 reducer.apply(tr, sr)); 5582 s = t.rights = s.nextRight; 5583 } 5584 } 5585 } 5586 } 5587 } 5588 5589 @SuppressWarnings("serial") 5590 static final class MapReduceValuesTask<K,V,U> 5591 extends BulkTask<K,V,U> { 5592 final Function<? super V, ? extends U> transformer; 5593 final BiFunction<? super U, ? super U, ? extends U> reducer; 5594 U result; 5595 MapReduceValuesTask<K,V,U> rights, nextRight; MapReduceValuesTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceValuesTask<K,V,U> nextRight, Function<? super V, ? extends U> transformer, BiFunction<? super U, ? super U, ? extends U> reducer)5596 MapReduceValuesTask 5597 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5598 MapReduceValuesTask<K,V,U> nextRight, 5599 Function<? super V, ? extends U> transformer, 5600 BiFunction<? super U, ? super U, ? extends U> reducer) { 5601 super(p, b, i, f, t); this.nextRight = nextRight; 5602 this.transformer = transformer; 5603 this.reducer = reducer; 5604 } getRawResult()5605 public final U getRawResult() { return result; } compute()5606 public final void compute() { 5607 final Function<? super V, ? extends U> transformer; 5608 final BiFunction<? super U, ? super U, ? extends U> reducer; 5609 if ((transformer = this.transformer) != null && 5610 (reducer = this.reducer) != null) { 5611 for (int i = baseIndex, f, h; batch > 0 && 5612 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5613 addToPendingCount(1); 5614 (rights = new MapReduceValuesTask<K,V,U> 5615 (this, batch >>>= 1, baseLimit = h, f, tab, 5616 rights, transformer, reducer)).fork(); 5617 } 5618 U r = null; 5619 for (Node<K,V> p; (p = advance()) != null; ) { 5620 U u; 5621 if ((u = transformer.apply(p.val)) != null) 5622 r = (r == null) ? u : reducer.apply(r, u); 5623 } 5624 result = r; 5625 CountedCompleter<?> c; 5626 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5627 @SuppressWarnings("unchecked") 5628 MapReduceValuesTask<K,V,U> 5629 t = (MapReduceValuesTask<K,V,U>)c, 5630 s = t.rights; 5631 while (s != null) { 5632 U tr, sr; 5633 if ((sr = s.result) != null) 5634 t.result = (((tr = t.result) == null) ? sr : 5635 reducer.apply(tr, sr)); 5636 s = t.rights = s.nextRight; 5637 } 5638 } 5639 } 5640 } 5641 } 5642 5643 @SuppressWarnings("serial") 5644 static final class MapReduceEntriesTask<K,V,U> 5645 extends BulkTask<K,V,U> { 5646 final Function<Map.Entry<K,V>, ? extends U> transformer; 5647 final BiFunction<? super U, ? super U, ? extends U> reducer; 5648 U result; 5649 MapReduceEntriesTask<K,V,U> rights, nextRight; MapReduceEntriesTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceEntriesTask<K,V,U> nextRight, Function<Map.Entry<K,V>, ? extends U> transformer, BiFunction<? super U, ? super U, ? extends U> reducer)5650 MapReduceEntriesTask 5651 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5652 MapReduceEntriesTask<K,V,U> nextRight, 5653 Function<Map.Entry<K,V>, ? extends U> transformer, 5654 BiFunction<? super U, ? super U, ? extends U> reducer) { 5655 super(p, b, i, f, t); this.nextRight = nextRight; 5656 this.transformer = transformer; 5657 this.reducer = reducer; 5658 } getRawResult()5659 public final U getRawResult() { return result; } compute()5660 public final void compute() { 5661 final Function<Map.Entry<K,V>, ? extends U> transformer; 5662 final BiFunction<? super U, ? super U, ? extends U> reducer; 5663 if ((transformer = this.transformer) != null && 5664 (reducer = this.reducer) != null) { 5665 for (int i = baseIndex, f, h; batch > 0 && 5666 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5667 addToPendingCount(1); 5668 (rights = new MapReduceEntriesTask<K,V,U> 5669 (this, batch >>>= 1, baseLimit = h, f, tab, 5670 rights, transformer, reducer)).fork(); 5671 } 5672 U r = null; 5673 for (Node<K,V> p; (p = advance()) != null; ) { 5674 U u; 5675 if ((u = transformer.apply(p)) != null) 5676 r = (r == null) ? u : reducer.apply(r, u); 5677 } 5678 result = r; 5679 CountedCompleter<?> c; 5680 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5681 @SuppressWarnings("unchecked") 5682 MapReduceEntriesTask<K,V,U> 5683 t = (MapReduceEntriesTask<K,V,U>)c, 5684 s = t.rights; 5685 while (s != null) { 5686 U tr, sr; 5687 if ((sr = s.result) != null) 5688 t.result = (((tr = t.result) == null) ? sr : 5689 reducer.apply(tr, sr)); 5690 s = t.rights = s.nextRight; 5691 } 5692 } 5693 } 5694 } 5695 } 5696 5697 @SuppressWarnings("serial") 5698 static final class MapReduceMappingsTask<K,V,U> 5699 extends BulkTask<K,V,U> { 5700 final BiFunction<? super K, ? super V, ? extends U> transformer; 5701 final BiFunction<? super U, ? super U, ? extends U> reducer; 5702 U result; 5703 MapReduceMappingsTask<K,V,U> rights, nextRight; MapReduceMappingsTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceMappingsTask<K,V,U> nextRight, BiFunction<? super K, ? super V, ? extends U> transformer, BiFunction<? super U, ? super U, ? extends U> reducer)5704 MapReduceMappingsTask 5705 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5706 MapReduceMappingsTask<K,V,U> nextRight, 5707 BiFunction<? super K, ? super V, ? extends U> transformer, 5708 BiFunction<? super U, ? super U, ? extends U> reducer) { 5709 super(p, b, i, f, t); this.nextRight = nextRight; 5710 this.transformer = transformer; 5711 this.reducer = reducer; 5712 } getRawResult()5713 public final U getRawResult() { return result; } compute()5714 public final void compute() { 5715 final BiFunction<? super K, ? super V, ? extends U> transformer; 5716 final BiFunction<? super U, ? super U, ? extends U> reducer; 5717 if ((transformer = this.transformer) != null && 5718 (reducer = this.reducer) != null) { 5719 for (int i = baseIndex, f, h; batch > 0 && 5720 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5721 addToPendingCount(1); 5722 (rights = new MapReduceMappingsTask<K,V,U> 5723 (this, batch >>>= 1, baseLimit = h, f, tab, 5724 rights, transformer, reducer)).fork(); 5725 } 5726 U r = null; 5727 for (Node<K,V> p; (p = advance()) != null; ) { 5728 U u; 5729 if ((u = transformer.apply(p.key, p.val)) != null) 5730 r = (r == null) ? u : reducer.apply(r, u); 5731 } 5732 result = r; 5733 CountedCompleter<?> c; 5734 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5735 @SuppressWarnings("unchecked") 5736 MapReduceMappingsTask<K,V,U> 5737 t = (MapReduceMappingsTask<K,V,U>)c, 5738 s = t.rights; 5739 while (s != null) { 5740 U tr, sr; 5741 if ((sr = s.result) != null) 5742 t.result = (((tr = t.result) == null) ? sr : 5743 reducer.apply(tr, sr)); 5744 s = t.rights = s.nextRight; 5745 } 5746 } 5747 } 5748 } 5749 } 5750 5751 @SuppressWarnings("serial") 5752 static final class MapReduceKeysToDoubleTask<K,V> 5753 extends BulkTask<K,V,Double> { 5754 final ToDoubleFunction<? super K> transformer; 5755 final DoubleBinaryOperator reducer; 5756 final double basis; 5757 double result; 5758 MapReduceKeysToDoubleTask<K,V> rights, nextRight; MapReduceKeysToDoubleTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceKeysToDoubleTask<K,V> nextRight, ToDoubleFunction<? super K> transformer, double basis, DoubleBinaryOperator reducer)5759 MapReduceKeysToDoubleTask 5760 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5761 MapReduceKeysToDoubleTask<K,V> nextRight, 5762 ToDoubleFunction<? super K> transformer, 5763 double basis, 5764 DoubleBinaryOperator reducer) { 5765 super(p, b, i, f, t); this.nextRight = nextRight; 5766 this.transformer = transformer; 5767 this.basis = basis; this.reducer = reducer; 5768 } getRawResult()5769 public final Double getRawResult() { return result; } compute()5770 public final void compute() { 5771 final ToDoubleFunction<? super K> transformer; 5772 final DoubleBinaryOperator reducer; 5773 if ((transformer = this.transformer) != null && 5774 (reducer = this.reducer) != null) { 5775 double r = this.basis; 5776 for (int i = baseIndex, f, h; batch > 0 && 5777 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5778 addToPendingCount(1); 5779 (rights = new MapReduceKeysToDoubleTask<K,V> 5780 (this, batch >>>= 1, baseLimit = h, f, tab, 5781 rights, transformer, r, reducer)).fork(); 5782 } 5783 for (Node<K,V> p; (p = advance()) != null; ) 5784 r = reducer.applyAsDouble(r, transformer.applyAsDouble(p.key)); 5785 result = r; 5786 CountedCompleter<?> c; 5787 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5788 @SuppressWarnings("unchecked") 5789 MapReduceKeysToDoubleTask<K,V> 5790 t = (MapReduceKeysToDoubleTask<K,V>)c, 5791 s = t.rights; 5792 while (s != null) { 5793 t.result = reducer.applyAsDouble(t.result, s.result); 5794 s = t.rights = s.nextRight; 5795 } 5796 } 5797 } 5798 } 5799 } 5800 5801 @SuppressWarnings("serial") 5802 static final class MapReduceValuesToDoubleTask<K,V> 5803 extends BulkTask<K,V,Double> { 5804 final ToDoubleFunction<? super V> transformer; 5805 final DoubleBinaryOperator reducer; 5806 final double basis; 5807 double result; 5808 MapReduceValuesToDoubleTask<K,V> rights, nextRight; MapReduceValuesToDoubleTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceValuesToDoubleTask<K,V> nextRight, ToDoubleFunction<? super V> transformer, double basis, DoubleBinaryOperator reducer)5809 MapReduceValuesToDoubleTask 5810 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5811 MapReduceValuesToDoubleTask<K,V> nextRight, 5812 ToDoubleFunction<? super V> transformer, 5813 double basis, 5814 DoubleBinaryOperator reducer) { 5815 super(p, b, i, f, t); this.nextRight = nextRight; 5816 this.transformer = transformer; 5817 this.basis = basis; this.reducer = reducer; 5818 } getRawResult()5819 public final Double getRawResult() { return result; } compute()5820 public final void compute() { 5821 final ToDoubleFunction<? super V> transformer; 5822 final DoubleBinaryOperator reducer; 5823 if ((transformer = this.transformer) != null && 5824 (reducer = this.reducer) != null) { 5825 double r = this.basis; 5826 for (int i = baseIndex, f, h; batch > 0 && 5827 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5828 addToPendingCount(1); 5829 (rights = new MapReduceValuesToDoubleTask<K,V> 5830 (this, batch >>>= 1, baseLimit = h, f, tab, 5831 rights, transformer, r, reducer)).fork(); 5832 } 5833 for (Node<K,V> p; (p = advance()) != null; ) 5834 r = reducer.applyAsDouble(r, transformer.applyAsDouble(p.val)); 5835 result = r; 5836 CountedCompleter<?> c; 5837 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5838 @SuppressWarnings("unchecked") 5839 MapReduceValuesToDoubleTask<K,V> 5840 t = (MapReduceValuesToDoubleTask<K,V>)c, 5841 s = t.rights; 5842 while (s != null) { 5843 t.result = reducer.applyAsDouble(t.result, s.result); 5844 s = t.rights = s.nextRight; 5845 } 5846 } 5847 } 5848 } 5849 } 5850 5851 @SuppressWarnings("serial") 5852 static final class MapReduceEntriesToDoubleTask<K,V> 5853 extends BulkTask<K,V,Double> { 5854 final ToDoubleFunction<Map.Entry<K,V>> transformer; 5855 final DoubleBinaryOperator reducer; 5856 final double basis; 5857 double result; 5858 MapReduceEntriesToDoubleTask<K,V> rights, nextRight; MapReduceEntriesToDoubleTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceEntriesToDoubleTask<K,V> nextRight, ToDoubleFunction<Map.Entry<K,V>> transformer, double basis, DoubleBinaryOperator reducer)5859 MapReduceEntriesToDoubleTask 5860 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5861 MapReduceEntriesToDoubleTask<K,V> nextRight, 5862 ToDoubleFunction<Map.Entry<K,V>> transformer, 5863 double basis, 5864 DoubleBinaryOperator reducer) { 5865 super(p, b, i, f, t); this.nextRight = nextRight; 5866 this.transformer = transformer; 5867 this.basis = basis; this.reducer = reducer; 5868 } getRawResult()5869 public final Double getRawResult() { return result; } compute()5870 public final void compute() { 5871 final ToDoubleFunction<Map.Entry<K,V>> transformer; 5872 final DoubleBinaryOperator reducer; 5873 if ((transformer = this.transformer) != null && 5874 (reducer = this.reducer) != null) { 5875 double r = this.basis; 5876 for (int i = baseIndex, f, h; batch > 0 && 5877 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5878 addToPendingCount(1); 5879 (rights = new MapReduceEntriesToDoubleTask<K,V> 5880 (this, batch >>>= 1, baseLimit = h, f, tab, 5881 rights, transformer, r, reducer)).fork(); 5882 } 5883 for (Node<K,V> p; (p = advance()) != null; ) 5884 r = reducer.applyAsDouble(r, transformer.applyAsDouble(p)); 5885 result = r; 5886 CountedCompleter<?> c; 5887 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5888 @SuppressWarnings("unchecked") 5889 MapReduceEntriesToDoubleTask<K,V> 5890 t = (MapReduceEntriesToDoubleTask<K,V>)c, 5891 s = t.rights; 5892 while (s != null) { 5893 t.result = reducer.applyAsDouble(t.result, s.result); 5894 s = t.rights = s.nextRight; 5895 } 5896 } 5897 } 5898 } 5899 } 5900 5901 @SuppressWarnings("serial") 5902 static final class MapReduceMappingsToDoubleTask<K,V> 5903 extends BulkTask<K,V,Double> { 5904 final ToDoubleBiFunction<? super K, ? super V> transformer; 5905 final DoubleBinaryOperator reducer; 5906 final double basis; 5907 double result; 5908 MapReduceMappingsToDoubleTask<K,V> rights, nextRight; MapReduceMappingsToDoubleTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceMappingsToDoubleTask<K,V> nextRight, ToDoubleBiFunction<? super K, ? super V> transformer, double basis, DoubleBinaryOperator reducer)5909 MapReduceMappingsToDoubleTask 5910 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5911 MapReduceMappingsToDoubleTask<K,V> nextRight, 5912 ToDoubleBiFunction<? super K, ? super V> transformer, 5913 double basis, 5914 DoubleBinaryOperator reducer) { 5915 super(p, b, i, f, t); this.nextRight = nextRight; 5916 this.transformer = transformer; 5917 this.basis = basis; this.reducer = reducer; 5918 } getRawResult()5919 public final Double getRawResult() { return result; } compute()5920 public final void compute() { 5921 final ToDoubleBiFunction<? super K, ? super V> transformer; 5922 final DoubleBinaryOperator reducer; 5923 if ((transformer = this.transformer) != null && 5924 (reducer = this.reducer) != null) { 5925 double r = this.basis; 5926 for (int i = baseIndex, f, h; batch > 0 && 5927 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5928 addToPendingCount(1); 5929 (rights = new MapReduceMappingsToDoubleTask<K,V> 5930 (this, batch >>>= 1, baseLimit = h, f, tab, 5931 rights, transformer, r, reducer)).fork(); 5932 } 5933 for (Node<K,V> p; (p = advance()) != null; ) 5934 r = reducer.applyAsDouble(r, transformer.applyAsDouble(p.key, p.val)); 5935 result = r; 5936 CountedCompleter<?> c; 5937 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5938 @SuppressWarnings("unchecked") 5939 MapReduceMappingsToDoubleTask<K,V> 5940 t = (MapReduceMappingsToDoubleTask<K,V>)c, 5941 s = t.rights; 5942 while (s != null) { 5943 t.result = reducer.applyAsDouble(t.result, s.result); 5944 s = t.rights = s.nextRight; 5945 } 5946 } 5947 } 5948 } 5949 } 5950 5951 @SuppressWarnings("serial") 5952 static final class MapReduceKeysToLongTask<K,V> 5953 extends BulkTask<K,V,Long> { 5954 final ToLongFunction<? super K> transformer; 5955 final LongBinaryOperator reducer; 5956 final long basis; 5957 long result; 5958 MapReduceKeysToLongTask<K,V> rights, nextRight; MapReduceKeysToLongTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceKeysToLongTask<K,V> nextRight, ToLongFunction<? super K> transformer, long basis, LongBinaryOperator reducer)5959 MapReduceKeysToLongTask 5960 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 5961 MapReduceKeysToLongTask<K,V> nextRight, 5962 ToLongFunction<? super K> transformer, 5963 long basis, 5964 LongBinaryOperator reducer) { 5965 super(p, b, i, f, t); this.nextRight = nextRight; 5966 this.transformer = transformer; 5967 this.basis = basis; this.reducer = reducer; 5968 } getRawResult()5969 public final Long getRawResult() { return result; } compute()5970 public final void compute() { 5971 final ToLongFunction<? super K> transformer; 5972 final LongBinaryOperator reducer; 5973 if ((transformer = this.transformer) != null && 5974 (reducer = this.reducer) != null) { 5975 long r = this.basis; 5976 for (int i = baseIndex, f, h; batch > 0 && 5977 (h = ((f = baseLimit) + i) >>> 1) > i;) { 5978 addToPendingCount(1); 5979 (rights = new MapReduceKeysToLongTask<K,V> 5980 (this, batch >>>= 1, baseLimit = h, f, tab, 5981 rights, transformer, r, reducer)).fork(); 5982 } 5983 for (Node<K,V> p; (p = advance()) != null; ) 5984 r = reducer.applyAsLong(r, transformer.applyAsLong(p.key)); 5985 result = r; 5986 CountedCompleter<?> c; 5987 for (c = firstComplete(); c != null; c = c.nextComplete()) { 5988 @SuppressWarnings("unchecked") 5989 MapReduceKeysToLongTask<K,V> 5990 t = (MapReduceKeysToLongTask<K,V>)c, 5991 s = t.rights; 5992 while (s != null) { 5993 t.result = reducer.applyAsLong(t.result, s.result); 5994 s = t.rights = s.nextRight; 5995 } 5996 } 5997 } 5998 } 5999 } 6000 6001 @SuppressWarnings("serial") 6002 static final class MapReduceValuesToLongTask<K,V> 6003 extends BulkTask<K,V,Long> { 6004 final ToLongFunction<? super V> transformer; 6005 final LongBinaryOperator reducer; 6006 final long basis; 6007 long result; 6008 MapReduceValuesToLongTask<K,V> rights, nextRight; MapReduceValuesToLongTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceValuesToLongTask<K,V> nextRight, ToLongFunction<? super V> transformer, long basis, LongBinaryOperator reducer)6009 MapReduceValuesToLongTask 6010 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 6011 MapReduceValuesToLongTask<K,V> nextRight, 6012 ToLongFunction<? super V> transformer, 6013 long basis, 6014 LongBinaryOperator reducer) { 6015 super(p, b, i, f, t); this.nextRight = nextRight; 6016 this.transformer = transformer; 6017 this.basis = basis; this.reducer = reducer; 6018 } getRawResult()6019 public final Long getRawResult() { return result; } compute()6020 public final void compute() { 6021 final ToLongFunction<? super V> transformer; 6022 final LongBinaryOperator reducer; 6023 if ((transformer = this.transformer) != null && 6024 (reducer = this.reducer) != null) { 6025 long r = this.basis; 6026 for (int i = baseIndex, f, h; batch > 0 && 6027 (h = ((f = baseLimit) + i) >>> 1) > i;) { 6028 addToPendingCount(1); 6029 (rights = new MapReduceValuesToLongTask<K,V> 6030 (this, batch >>>= 1, baseLimit = h, f, tab, 6031 rights, transformer, r, reducer)).fork(); 6032 } 6033 for (Node<K,V> p; (p = advance()) != null; ) 6034 r = reducer.applyAsLong(r, transformer.applyAsLong(p.val)); 6035 result = r; 6036 CountedCompleter<?> c; 6037 for (c = firstComplete(); c != null; c = c.nextComplete()) { 6038 @SuppressWarnings("unchecked") 6039 MapReduceValuesToLongTask<K,V> 6040 t = (MapReduceValuesToLongTask<K,V>)c, 6041 s = t.rights; 6042 while (s != null) { 6043 t.result = reducer.applyAsLong(t.result, s.result); 6044 s = t.rights = s.nextRight; 6045 } 6046 } 6047 } 6048 } 6049 } 6050 6051 @SuppressWarnings("serial") 6052 static final class MapReduceEntriesToLongTask<K,V> 6053 extends BulkTask<K,V,Long> { 6054 final ToLongFunction<Map.Entry<K,V>> transformer; 6055 final LongBinaryOperator reducer; 6056 final long basis; 6057 long result; 6058 MapReduceEntriesToLongTask<K,V> rights, nextRight; MapReduceEntriesToLongTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceEntriesToLongTask<K,V> nextRight, ToLongFunction<Map.Entry<K,V>> transformer, long basis, LongBinaryOperator reducer)6059 MapReduceEntriesToLongTask 6060 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 6061 MapReduceEntriesToLongTask<K,V> nextRight, 6062 ToLongFunction<Map.Entry<K,V>> transformer, 6063 long basis, 6064 LongBinaryOperator reducer) { 6065 super(p, b, i, f, t); this.nextRight = nextRight; 6066 this.transformer = transformer; 6067 this.basis = basis; this.reducer = reducer; 6068 } getRawResult()6069 public final Long getRawResult() { return result; } compute()6070 public final void compute() { 6071 final ToLongFunction<Map.Entry<K,V>> transformer; 6072 final LongBinaryOperator reducer; 6073 if ((transformer = this.transformer) != null && 6074 (reducer = this.reducer) != null) { 6075 long r = this.basis; 6076 for (int i = baseIndex, f, h; batch > 0 && 6077 (h = ((f = baseLimit) + i) >>> 1) > i;) { 6078 addToPendingCount(1); 6079 (rights = new MapReduceEntriesToLongTask<K,V> 6080 (this, batch >>>= 1, baseLimit = h, f, tab, 6081 rights, transformer, r, reducer)).fork(); 6082 } 6083 for (Node<K,V> p; (p = advance()) != null; ) 6084 r = reducer.applyAsLong(r, transformer.applyAsLong(p)); 6085 result = r; 6086 CountedCompleter<?> c; 6087 for (c = firstComplete(); c != null; c = c.nextComplete()) { 6088 @SuppressWarnings("unchecked") 6089 MapReduceEntriesToLongTask<K,V> 6090 t = (MapReduceEntriesToLongTask<K,V>)c, 6091 s = t.rights; 6092 while (s != null) { 6093 t.result = reducer.applyAsLong(t.result, s.result); 6094 s = t.rights = s.nextRight; 6095 } 6096 } 6097 } 6098 } 6099 } 6100 6101 @SuppressWarnings("serial") 6102 static final class MapReduceMappingsToLongTask<K,V> 6103 extends BulkTask<K,V,Long> { 6104 final ToLongBiFunction<? super K, ? super V> transformer; 6105 final LongBinaryOperator reducer; 6106 final long basis; 6107 long result; 6108 MapReduceMappingsToLongTask<K,V> rights, nextRight; MapReduceMappingsToLongTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceMappingsToLongTask<K,V> nextRight, ToLongBiFunction<? super K, ? super V> transformer, long basis, LongBinaryOperator reducer)6109 MapReduceMappingsToLongTask 6110 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 6111 MapReduceMappingsToLongTask<K,V> nextRight, 6112 ToLongBiFunction<? super K, ? super V> transformer, 6113 long basis, 6114 LongBinaryOperator reducer) { 6115 super(p, b, i, f, t); this.nextRight = nextRight; 6116 this.transformer = transformer; 6117 this.basis = basis; this.reducer = reducer; 6118 } getRawResult()6119 public final Long getRawResult() { return result; } compute()6120 public final void compute() { 6121 final ToLongBiFunction<? super K, ? super V> transformer; 6122 final LongBinaryOperator reducer; 6123 if ((transformer = this.transformer) != null && 6124 (reducer = this.reducer) != null) { 6125 long r = this.basis; 6126 for (int i = baseIndex, f, h; batch > 0 && 6127 (h = ((f = baseLimit) + i) >>> 1) > i;) { 6128 addToPendingCount(1); 6129 (rights = new MapReduceMappingsToLongTask<K,V> 6130 (this, batch >>>= 1, baseLimit = h, f, tab, 6131 rights, transformer, r, reducer)).fork(); 6132 } 6133 for (Node<K,V> p; (p = advance()) != null; ) 6134 r = reducer.applyAsLong(r, transformer.applyAsLong(p.key, p.val)); 6135 result = r; 6136 CountedCompleter<?> c; 6137 for (c = firstComplete(); c != null; c = c.nextComplete()) { 6138 @SuppressWarnings("unchecked") 6139 MapReduceMappingsToLongTask<K,V> 6140 t = (MapReduceMappingsToLongTask<K,V>)c, 6141 s = t.rights; 6142 while (s != null) { 6143 t.result = reducer.applyAsLong(t.result, s.result); 6144 s = t.rights = s.nextRight; 6145 } 6146 } 6147 } 6148 } 6149 } 6150 6151 @SuppressWarnings("serial") 6152 static final class MapReduceKeysToIntTask<K,V> 6153 extends BulkTask<K,V,Integer> { 6154 final ToIntFunction<? super K> transformer; 6155 final IntBinaryOperator reducer; 6156 final int basis; 6157 int result; 6158 MapReduceKeysToIntTask<K,V> rights, nextRight; MapReduceKeysToIntTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceKeysToIntTask<K,V> nextRight, ToIntFunction<? super K> transformer, int basis, IntBinaryOperator reducer)6159 MapReduceKeysToIntTask 6160 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 6161 MapReduceKeysToIntTask<K,V> nextRight, 6162 ToIntFunction<? super K> transformer, 6163 int basis, 6164 IntBinaryOperator reducer) { 6165 super(p, b, i, f, t); this.nextRight = nextRight; 6166 this.transformer = transformer; 6167 this.basis = basis; this.reducer = reducer; 6168 } getRawResult()6169 public final Integer getRawResult() { return result; } compute()6170 public final void compute() { 6171 final ToIntFunction<? super K> transformer; 6172 final IntBinaryOperator reducer; 6173 if ((transformer = this.transformer) != null && 6174 (reducer = this.reducer) != null) { 6175 int r = this.basis; 6176 for (int i = baseIndex, f, h; batch > 0 && 6177 (h = ((f = baseLimit) + i) >>> 1) > i;) { 6178 addToPendingCount(1); 6179 (rights = new MapReduceKeysToIntTask<K,V> 6180 (this, batch >>>= 1, baseLimit = h, f, tab, 6181 rights, transformer, r, reducer)).fork(); 6182 } 6183 for (Node<K,V> p; (p = advance()) != null; ) 6184 r = reducer.applyAsInt(r, transformer.applyAsInt(p.key)); 6185 result = r; 6186 CountedCompleter<?> c; 6187 for (c = firstComplete(); c != null; c = c.nextComplete()) { 6188 @SuppressWarnings("unchecked") 6189 MapReduceKeysToIntTask<K,V> 6190 t = (MapReduceKeysToIntTask<K,V>)c, 6191 s = t.rights; 6192 while (s != null) { 6193 t.result = reducer.applyAsInt(t.result, s.result); 6194 s = t.rights = s.nextRight; 6195 } 6196 } 6197 } 6198 } 6199 } 6200 6201 @SuppressWarnings("serial") 6202 static final class MapReduceValuesToIntTask<K,V> 6203 extends BulkTask<K,V,Integer> { 6204 final ToIntFunction<? super V> transformer; 6205 final IntBinaryOperator reducer; 6206 final int basis; 6207 int result; 6208 MapReduceValuesToIntTask<K,V> rights, nextRight; MapReduceValuesToIntTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceValuesToIntTask<K,V> nextRight, ToIntFunction<? super V> transformer, int basis, IntBinaryOperator reducer)6209 MapReduceValuesToIntTask 6210 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 6211 MapReduceValuesToIntTask<K,V> nextRight, 6212 ToIntFunction<? super V> transformer, 6213 int basis, 6214 IntBinaryOperator reducer) { 6215 super(p, b, i, f, t); this.nextRight = nextRight; 6216 this.transformer = transformer; 6217 this.basis = basis; this.reducer = reducer; 6218 } getRawResult()6219 public final Integer getRawResult() { return result; } compute()6220 public final void compute() { 6221 final ToIntFunction<? super V> transformer; 6222 final IntBinaryOperator reducer; 6223 if ((transformer = this.transformer) != null && 6224 (reducer = this.reducer) != null) { 6225 int r = this.basis; 6226 for (int i = baseIndex, f, h; batch > 0 && 6227 (h = ((f = baseLimit) + i) >>> 1) > i;) { 6228 addToPendingCount(1); 6229 (rights = new MapReduceValuesToIntTask<K,V> 6230 (this, batch >>>= 1, baseLimit = h, f, tab, 6231 rights, transformer, r, reducer)).fork(); 6232 } 6233 for (Node<K,V> p; (p = advance()) != null; ) 6234 r = reducer.applyAsInt(r, transformer.applyAsInt(p.val)); 6235 result = r; 6236 CountedCompleter<?> c; 6237 for (c = firstComplete(); c != null; c = c.nextComplete()) { 6238 @SuppressWarnings("unchecked") 6239 MapReduceValuesToIntTask<K,V> 6240 t = (MapReduceValuesToIntTask<K,V>)c, 6241 s = t.rights; 6242 while (s != null) { 6243 t.result = reducer.applyAsInt(t.result, s.result); 6244 s = t.rights = s.nextRight; 6245 } 6246 } 6247 } 6248 } 6249 } 6250 6251 @SuppressWarnings("serial") 6252 static final class MapReduceEntriesToIntTask<K,V> 6253 extends BulkTask<K,V,Integer> { 6254 final ToIntFunction<Map.Entry<K,V>> transformer; 6255 final IntBinaryOperator reducer; 6256 final int basis; 6257 int result; 6258 MapReduceEntriesToIntTask<K,V> rights, nextRight; MapReduceEntriesToIntTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceEntriesToIntTask<K,V> nextRight, ToIntFunction<Map.Entry<K,V>> transformer, int basis, IntBinaryOperator reducer)6259 MapReduceEntriesToIntTask 6260 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 6261 MapReduceEntriesToIntTask<K,V> nextRight, 6262 ToIntFunction<Map.Entry<K,V>> transformer, 6263 int basis, 6264 IntBinaryOperator reducer) { 6265 super(p, b, i, f, t); this.nextRight = nextRight; 6266 this.transformer = transformer; 6267 this.basis = basis; this.reducer = reducer; 6268 } getRawResult()6269 public final Integer getRawResult() { return result; } compute()6270 public final void compute() { 6271 final ToIntFunction<Map.Entry<K,V>> transformer; 6272 final IntBinaryOperator reducer; 6273 if ((transformer = this.transformer) != null && 6274 (reducer = this.reducer) != null) { 6275 int r = this.basis; 6276 for (int i = baseIndex, f, h; batch > 0 && 6277 (h = ((f = baseLimit) + i) >>> 1) > i;) { 6278 addToPendingCount(1); 6279 (rights = new MapReduceEntriesToIntTask<K,V> 6280 (this, batch >>>= 1, baseLimit = h, f, tab, 6281 rights, transformer, r, reducer)).fork(); 6282 } 6283 for (Node<K,V> p; (p = advance()) != null; ) 6284 r = reducer.applyAsInt(r, transformer.applyAsInt(p)); 6285 result = r; 6286 CountedCompleter<?> c; 6287 for (c = firstComplete(); c != null; c = c.nextComplete()) { 6288 @SuppressWarnings("unchecked") 6289 MapReduceEntriesToIntTask<K,V> 6290 t = (MapReduceEntriesToIntTask<K,V>)c, 6291 s = t.rights; 6292 while (s != null) { 6293 t.result = reducer.applyAsInt(t.result, s.result); 6294 s = t.rights = s.nextRight; 6295 } 6296 } 6297 } 6298 } 6299 } 6300 6301 @SuppressWarnings("serial") 6302 static final class MapReduceMappingsToIntTask<K,V> 6303 extends BulkTask<K,V,Integer> { 6304 final ToIntBiFunction<? super K, ? super V> transformer; 6305 final IntBinaryOperator reducer; 6306 final int basis; 6307 int result; 6308 MapReduceMappingsToIntTask<K,V> rights, nextRight; MapReduceMappingsToIntTask(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, MapReduceMappingsToIntTask<K,V> nextRight, ToIntBiFunction<? super K, ? super V> transformer, int basis, IntBinaryOperator reducer)6309 MapReduceMappingsToIntTask 6310 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t, 6311 MapReduceMappingsToIntTask<K,V> nextRight, 6312 ToIntBiFunction<? super K, ? super V> transformer, 6313 int basis, 6314 IntBinaryOperator reducer) { 6315 super(p, b, i, f, t); this.nextRight = nextRight; 6316 this.transformer = transformer; 6317 this.basis = basis; this.reducer = reducer; 6318 } getRawResult()6319 public final Integer getRawResult() { return result; } compute()6320 public final void compute() { 6321 final ToIntBiFunction<? super K, ? super V> transformer; 6322 final IntBinaryOperator reducer; 6323 if ((transformer = this.transformer) != null && 6324 (reducer = this.reducer) != null) { 6325 int r = this.basis; 6326 for (int i = baseIndex, f, h; batch > 0 && 6327 (h = ((f = baseLimit) + i) >>> 1) > i;) { 6328 addToPendingCount(1); 6329 (rights = new MapReduceMappingsToIntTask<K,V> 6330 (this, batch >>>= 1, baseLimit = h, f, tab, 6331 rights, transformer, r, reducer)).fork(); 6332 } 6333 for (Node<K,V> p; (p = advance()) != null; ) 6334 r = reducer.applyAsInt(r, transformer.applyAsInt(p.key, p.val)); 6335 result = r; 6336 CountedCompleter<?> c; 6337 for (c = firstComplete(); c != null; c = c.nextComplete()) { 6338 @SuppressWarnings("unchecked") 6339 MapReduceMappingsToIntTask<K,V> 6340 t = (MapReduceMappingsToIntTask<K,V>)c, 6341 s = t.rights; 6342 while (s != null) { 6343 t.result = reducer.applyAsInt(t.result, s.result); 6344 s = t.rights = s.nextRight; 6345 } 6346 } 6347 } 6348 } 6349 } 6350 6351 // Unsafe mechanics 6352 private static final Unsafe U = Unsafe.getUnsafe(); 6353 private static final long SIZECTL; 6354 private static final long TRANSFERINDEX; 6355 private static final long BASECOUNT; 6356 private static final long CELLSBUSY; 6357 private static final long CELLVALUE; 6358 private static final int ABASE; 6359 private static final int ASHIFT; 6360 6361 static { 6362 SIZECTL = U.objectFieldOffset 6363 (ConcurrentHashMap.class, "sizeCtl"); 6364 TRANSFERINDEX = U.objectFieldOffset 6365 (ConcurrentHashMap.class, "transferIndex"); 6366 BASECOUNT = U.objectFieldOffset 6367 (ConcurrentHashMap.class, "baseCount"); 6368 CELLSBUSY = U.objectFieldOffset 6369 (ConcurrentHashMap.class, "cellsBusy"); 6370 6371 CELLVALUE = U.objectFieldOffset 6372 (CounterCell.class, "value"); 6373 6374 ABASE = U.arrayBaseOffset(Node[].class); 6375 int scale = U.arrayIndexScale(Node[].class); 6376 if ((scale & (scale - 1)) != 0) 6377 throw new ExceptionInInitializerError("array index scale not a power of two"); 6378 ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); 6379 6380 // Reduce the risk of rare disastrous classloading in first call to 6381 // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773 6382 Class<?> ensureLoaded = LockSupport.class; 6383 6384 // Eager class load observed to help JIT during startup 6385 ensureLoaded = ReservationNode.class; 6386 } 6387 } 6388