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.lang.invoke.MethodHandles; 39 import java.lang.invoke.VarHandle; 40 import java.io.Serializable; 41 import java.util.AbstractCollection; 42 import java.util.AbstractMap; 43 import java.util.AbstractSet; 44 import java.util.ArrayList; 45 import java.util.Collection; 46 import java.util.Collections; 47 import java.util.Comparator; 48 import java.util.Iterator; 49 import java.util.List; 50 import java.util.Map; 51 import java.util.NavigableSet; 52 import java.util.NoSuchElementException; 53 import java.util.Set; 54 import java.util.SortedMap; 55 import java.util.Spliterator; 56 import java.util.function.BiConsumer; 57 import java.util.function.BiFunction; 58 import java.util.function.Consumer; 59 import java.util.function.Function; 60 import java.util.function.Predicate; 61 import java.util.concurrent.atomic.LongAdder; 62 63 /** 64 * A scalable concurrent {@link ConcurrentNavigableMap} implementation. 65 * The map is sorted according to the {@linkplain Comparable natural 66 * ordering} of its keys, or by a {@link Comparator} provided at map 67 * creation time, depending on which constructor is used. 68 * 69 * <p>This class implements a concurrent variant of <a 70 * href="http://en.wikipedia.org/wiki/Skip_list" target="_top">SkipLists</a> 71 * providing expected average <i>log(n)</i> time cost for the 72 * {@code containsKey}, {@code get}, {@code put} and 73 * {@code remove} operations and their variants. Insertion, removal, 74 * update, and access operations safely execute concurrently by 75 * multiple threads. 76 * 77 * <p>Iterators and spliterators are 78 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 79 * 80 * <p>Ascending key ordered views and their iterators are faster than 81 * descending ones. 82 * 83 * <p>All {@code Map.Entry} pairs returned by methods in this class 84 * and its views represent snapshots of mappings at the time they were 85 * produced. They do <em>not</em> support the {@code Entry.setValue} 86 * method. (Note however that it is possible to change mappings in the 87 * associated map using {@code put}, {@code putIfAbsent}, or 88 * {@code replace}, depending on exactly which effect you need.) 89 * 90 * <p>Beware that bulk operations {@code putAll}, {@code equals}, 91 * {@code toArray}, {@code containsValue}, and {@code clear} are 92 * <em>not</em> guaranteed to be performed atomically. For example, an 93 * iterator operating concurrently with a {@code putAll} operation 94 * might view only some of the added elements. 95 * 96 * <p>This class and its views and iterators implement all of the 97 * <em>optional</em> methods of the {@link Map} and {@link Iterator} 98 * interfaces. Like most other concurrent collections, this class does 99 * <em>not</em> permit the use of {@code null} keys or values because some 100 * null return values cannot be reliably distinguished from the absence of 101 * elements. 102 * 103 * <p>This class is a member of the 104 * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework"> 105 * Java Collections Framework</a>. 106 * 107 * @author Doug Lea 108 * @param <K> the type of keys maintained by this map 109 * @param <V> the type of mapped values 110 * @since 1.6 111 */ 112 public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> 113 implements ConcurrentNavigableMap<K,V>, Cloneable, Serializable { 114 /* 115 * This class implements a tree-like two-dimensionally linked skip 116 * list in which the index levels are represented in separate 117 * nodes from the base nodes holding data. There are two reasons 118 * for taking this approach instead of the usual array-based 119 * structure: 1) Array based implementations seem to encounter 120 * more complexity and overhead 2) We can use cheaper algorithms 121 * for the heavily-traversed index lists than can be used for the 122 * base lists. Here's a picture of some of the basics for a 123 * possible list with 2 levels of index: 124 * 125 * Head nodes Index nodes 126 * +-+ right +-+ +-+ 127 * |2|---------------->| |--------------------->| |->null 128 * +-+ +-+ +-+ 129 * | down | | 130 * v v v 131 * +-+ +-+ +-+ +-+ +-+ +-+ 132 * |1|----------->| |->| |------>| |----------->| |------>| |->null 133 * +-+ +-+ +-+ +-+ +-+ +-+ 134 * v | | | | | 135 * Nodes next v v v v v 136 * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ 137 * | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null 138 * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ 139 * 140 * The base lists use a variant of the HM linked ordered set 141 * algorithm. See Tim Harris, "A pragmatic implementation of 142 * non-blocking linked lists" 143 * http://www.cl.cam.ac.uk/~tlh20/publications.html and Maged 144 * Michael "High Performance Dynamic Lock-Free Hash Tables and 145 * List-Based Sets" 146 * http://www.research.ibm.com/people/m/michael/pubs.htm. The 147 * basic idea in these lists is to mark the "next" pointers of 148 * deleted nodes when deleting to avoid conflicts with concurrent 149 * insertions, and when traversing to keep track of triples 150 * (predecessor, node, successor) in order to detect when and how 151 * to unlink these deleted nodes. 152 * 153 * Rather than using mark-bits to mark list deletions (which can 154 * be slow and space-intensive using AtomicMarkedReference), nodes 155 * use direct CAS'able next pointers. On deletion, instead of 156 * marking a pointer, they splice in another node that can be 157 * thought of as standing for a marked pointer (see method 158 * unlinkNode). Using plain nodes acts roughly like "boxed" 159 * implementations of marked pointers, but uses new nodes only 160 * when nodes are deleted, not for every link. This requires less 161 * space and supports faster traversal. Even if marked references 162 * were better supported by JVMs, traversal using this technique 163 * might still be faster because any search need only read ahead 164 * one more node than otherwise required (to check for trailing 165 * marker) rather than unmasking mark bits or whatever on each 166 * read. 167 * 168 * This approach maintains the essential property needed in the HM 169 * algorithm of changing the next-pointer of a deleted node so 170 * that any other CAS of it will fail, but implements the idea by 171 * changing the pointer to point to a different node (with 172 * otherwise illegal null fields), not by marking it. While it 173 * would be possible to further squeeze space by defining marker 174 * nodes not to have key/value fields, it isn't worth the extra 175 * type-testing overhead. The deletion markers are rarely 176 * encountered during traversal, are easily detected via null 177 * checks that are needed anyway, and are normally quickly garbage 178 * collected. (Note that this technique would not work well in 179 * systems without garbage collection.) 180 * 181 * In addition to using deletion markers, the lists also use 182 * nullness of value fields to indicate deletion, in a style 183 * similar to typical lazy-deletion schemes. If a node's value is 184 * null, then it is considered logically deleted and ignored even 185 * though it is still reachable. 186 * 187 * Here's the sequence of events for a deletion of node n with 188 * predecessor b and successor f, initially: 189 * 190 * +------+ +------+ +------+ 191 * ... | b |------>| n |----->| f | ... 192 * +------+ +------+ +------+ 193 * 194 * 1. CAS n's value field from non-null to null. 195 * Traversals encountering a node with null value ignore it. 196 * However, ongoing insertions and deletions might still modify 197 * n's next pointer. 198 * 199 * 2. CAS n's next pointer to point to a new marker node. 200 * From this point on, no other nodes can be appended to n. 201 * which avoids deletion errors in CAS-based linked lists. 202 * 203 * +------+ +------+ +------+ +------+ 204 * ... | b |------>| n |----->|marker|------>| f | ... 205 * +------+ +------+ +------+ +------+ 206 * 207 * 3. CAS b's next pointer over both n and its marker. 208 * From this point on, no new traversals will encounter n, 209 * and it can eventually be GCed. 210 * +------+ +------+ 211 * ... | b |----------------------------------->| f | ... 212 * +------+ +------+ 213 * 214 * A failure at step 1 leads to simple retry due to a lost race 215 * with another operation. Steps 2-3 can fail because some other 216 * thread noticed during a traversal a node with null value and 217 * helped out by marking and/or unlinking. This helping-out 218 * ensures that no thread can become stuck waiting for progress of 219 * the deleting thread. 220 * 221 * Skip lists add indexing to this scheme, so that the base-level 222 * traversals start close to the locations being found, inserted 223 * or deleted -- usually base level traversals only traverse a few 224 * nodes. This doesn't change the basic algorithm except for the 225 * need to make sure base traversals start at predecessors (here, 226 * b) that are not (structurally) deleted, otherwise retrying 227 * after processing the deletion. 228 * 229 * Index levels are maintained using CAS to link and unlink 230 * successors ("right" fields). Races are allowed in index-list 231 * operations that can (rarely) fail to link in a new index node. 232 * (We can't do this of course for data nodes.) However, even 233 * when this happens, the index lists correctly guide search. 234 * This can impact performance, but since skip lists are 235 * probabilistic anyway, the net result is that under contention, 236 * the effective "p" value may be lower than its nominal value. 237 * 238 * Index insertion and deletion sometimes require a separate 239 * traversal pass occurring after the base-level action, to add or 240 * remove index nodes. This adds to single-threaded overhead, but 241 * improves contended multithreaded performance by narrowing 242 * interference windows, and allows deletion to ensure that all 243 * index nodes will be made unreachable upon return from a public 244 * remove operation, thus avoiding unwanted garbage retention. 245 * 246 * Indexing uses skip list parameters that maintain good search 247 * performance while using sparser-than-usual indices: The 248 * hardwired parameters k=1, p=0.5 (see method doPut) mean that 249 * about one-quarter of the nodes have indices. Of those that do, 250 * half have one level, a quarter have two, and so on (see Pugh's 251 * Skip List Cookbook, sec 3.4), up to a maximum of 62 levels 252 * (appropriate for up to 2^63 elements). The expected total 253 * space requirement for a map is slightly less than for the 254 * current implementation of java.util.TreeMap. 255 * 256 * Changing the level of the index (i.e, the height of the 257 * tree-like structure) also uses CAS. Creation of an index with 258 * height greater than the current level adds a level to the head 259 * index by CAS'ing on a new top-most head. To maintain good 260 * performance after a lot of removals, deletion methods 261 * heuristically try to reduce the height if the topmost levels 262 * appear to be empty. This may encounter races in which it is 263 * possible (but rare) to reduce and "lose" a level just as it is 264 * about to contain an index (that will then never be 265 * encountered). This does no structural harm, and in practice 266 * appears to be a better option than allowing unrestrained growth 267 * of levels. 268 * 269 * This class provides concurrent-reader-style memory consistency, 270 * ensuring that read-only methods report status and/or values no 271 * staler than those holding at method entry. This is done by 272 * performing all publication and structural updates using 273 * (volatile) CAS, placing an acquireFence in a few access 274 * methods, and ensuring that linked objects are transitively 275 * acquired via dependent reads (normally once) unless performing 276 * a volatile-mode CAS operation (that also acts as an acquire and 277 * release). This form of fence-hoisting is similar to RCU and 278 * related techniques (see McKenney's online book 279 * https://www.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html) 280 * It minimizes overhead that may otherwise occur when using so 281 * many volatile-mode reads. Using explicit acquireFences is 282 * logistically easier than targeting particular fields to be read 283 * in acquire mode: fences are just hoisted up as far as possible, 284 * to the entry points or loop headers of a few methods. A 285 * potential disadvantage is that these few remaining fences are 286 * not easily optimized away by compilers under exclusively 287 * single-thread use. It requires some care to avoid volatile 288 * mode reads of other fields. (Note that the memory semantics of 289 * a reference dependently read in plain mode exactly once are 290 * equivalent to those for atomic opaque mode.) Iterators and 291 * other traversals encounter each node and value exactly once. 292 * Other operations locate an element (or position to insert an 293 * element) via a sequence of dereferences. This search is broken 294 * into two parts. Method findPredecessor (and its specialized 295 * embeddings) searches index nodes only, returning a base-level 296 * predecessor of the key. Callers carry out the base-level 297 * search, restarting if encountering a marker preventing link 298 * modification. In some cases, it is possible to encounter a 299 * node multiple times while descending levels. For mutative 300 * operations, the reported value is validated using CAS (else 301 * retrying), preserving linearizability with respect to each 302 * other. Others may return any (non-null) value holding in the 303 * course of the method call. (Search-based methods also include 304 * some useless-looking explicit null checks designed to allow 305 * more fields to be nulled out upon removal, to reduce floating 306 * garbage, but which is not currently done, pending discovery of 307 * a way to do this with less impact on other operations.) 308 * 309 * To produce random values without interference across threads, 310 * we use within-JDK thread local random support (via the 311 * "secondary seed", to avoid interference with user-level 312 * ThreadLocalRandom.) 313 * 314 * For explanation of algorithms sharing at least a couple of 315 * features with this one, see Mikhail Fomitchev's thesis 316 * (http://www.cs.yorku.ca/~mikhail/), Keir Fraser's thesis 317 * (http://www.cl.cam.ac.uk/users/kaf24/), and Hakan Sundell's 318 * thesis (http://www.cs.chalmers.se/~phs/). 319 * 320 * Notation guide for local variables 321 * Node: b, n, f, p for predecessor, node, successor, aux 322 * Index: q, r, d for index node, right, down. 323 * Head: h 324 * Keys: k, key 325 * Values: v, value 326 * Comparisons: c 327 */ 328 329 private static final long serialVersionUID = -8627078645895051609L; 330 331 /** 332 * The comparator used to maintain order in this map, or null if 333 * using natural ordering. (Non-private to simplify access in 334 * nested classes.) 335 * @serial 336 */ 337 @SuppressWarnings("serial") // Conditionally serializable 338 final Comparator<? super K> comparator; 339 340 /** Lazily initialized topmost index of the skiplist. */ 341 private transient Index<K,V> head; 342 /** Lazily initialized element count */ 343 private transient LongAdder adder; 344 /** Lazily initialized key set */ 345 private transient KeySet<K,V> keySet; 346 /** Lazily initialized values collection */ 347 private transient Values<K,V> values; 348 /** Lazily initialized entry set */ 349 private transient EntrySet<K,V> entrySet; 350 /** Lazily initialized descending map */ 351 private transient SubMap<K,V> descendingMap; 352 353 /** 354 * Nodes hold keys and values, and are singly linked in sorted 355 * order, possibly with some intervening marker nodes. The list is 356 * headed by a header node accessible as head.node. Headers and 357 * marker nodes have null keys. The val field (but currently not 358 * the key field) is nulled out upon deletion. 359 */ 360 static final class Node<K,V> { 361 final K key; // currently, never detached 362 V val; 363 Node<K,V> next; Node(K key, V value, Node<K,V> next)364 Node(K key, V value, Node<K,V> next) { 365 this.key = key; 366 this.val = value; 367 this.next = next; 368 } 369 } 370 371 /** 372 * Index nodes represent the levels of the skip list. 373 */ 374 static final class Index<K,V> { 375 final Node<K,V> node; // currently, never detached 376 final Index<K,V> down; 377 Index<K,V> right; Index(Node<K,V> node, Index<K,V> down, Index<K,V> right)378 Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) { 379 this.node = node; 380 this.down = down; 381 this.right = right; 382 } 383 } 384 385 /* ---------------- Utilities -------------- */ 386 387 /** 388 * Compares using comparator or natural ordering if null. 389 * Called only by methods that have performed required type checks. 390 */ 391 @SuppressWarnings({"unchecked", "rawtypes"}) cpr(Comparator c, Object x, Object y)392 static int cpr(Comparator c, Object x, Object y) { 393 return (c != null) ? c.compare(x, y) : ((Comparable)x).compareTo(y); 394 } 395 396 /** 397 * Returns the header for base node list, or null if uninitialized 398 */ baseHead()399 final Node<K,V> baseHead() { 400 Index<K,V> h; 401 VarHandle.acquireFence(); 402 return ((h = head) == null) ? null : h.node; 403 } 404 405 /** 406 * Tries to unlink deleted node n from predecessor b (if both 407 * exist), by first splicing in a marker if not already present. 408 * Upon return, node n is sure to be unlinked from b, possibly 409 * via the actions of some other thread. 410 * 411 * @param b if nonnull, predecessor 412 * @param n if nonnull, node known to be deleted 413 */ unlinkNode(Node<K,V> b, Node<K,V> n)414 static <K,V> void unlinkNode(Node<K,V> b, Node<K,V> n) { 415 if (b != null && n != null) { 416 Node<K,V> f, p; 417 for (;;) { 418 if ((f = n.next) != null && f.key == null) { 419 p = f.next; // already marked 420 break; 421 } 422 else if (NEXT.compareAndSet(n, f, 423 new Node<K,V>(null, null, f))) { 424 p = f; // add marker 425 break; 426 } 427 } 428 NEXT.compareAndSet(b, n, p); 429 } 430 } 431 432 /** 433 * Adds to element count, initializing adder if necessary 434 * 435 * @param c count to add 436 */ addCount(long c)437 private void addCount(long c) { 438 LongAdder a; 439 do {} while ((a = adder) == null && 440 !ADDER.compareAndSet(this, null, a = new LongAdder())); 441 a.add(c); 442 } 443 444 /** 445 * Returns element count, initializing adder if necessary. 446 */ getAdderCount()447 final long getAdderCount() { 448 LongAdder a; long c; 449 do {} while ((a = adder) == null && 450 !ADDER.compareAndSet(this, null, a = new LongAdder())); 451 return ((c = a.sum()) <= 0L) ? 0L : c; // ignore transient negatives 452 } 453 454 /* ---------------- Traversal -------------- */ 455 456 /** 457 * Returns an index node with key strictly less than given key. 458 * Also unlinks indexes to deleted nodes found along the way. 459 * Callers rely on this side-effect of clearing indices to deleted 460 * nodes. 461 * 462 * @param key if nonnull the key 463 * @return a predecessor node of key, or null if uninitialized or null key 464 */ findPredecessor(Object key, Comparator<? super K> cmp)465 private Node<K,V> findPredecessor(Object key, Comparator<? super K> cmp) { 466 Index<K,V> q; 467 VarHandle.acquireFence(); 468 if ((q = head) == null || key == null) 469 return null; 470 else { 471 for (Index<K,V> r, d;;) { 472 while ((r = q.right) != null) { 473 Node<K,V> p; K k; 474 if ((p = r.node) == null || (k = p.key) == null || 475 p.val == null) // unlink index to deleted node 476 RIGHT.compareAndSet(q, r, r.right); 477 else if (cpr(cmp, key, k) > 0) 478 q = r; 479 else 480 break; 481 } 482 if ((d = q.down) != null) 483 q = d; 484 else 485 return q.node; 486 } 487 } 488 } 489 490 /** 491 * Returns node holding key or null if no such, clearing out any 492 * deleted nodes seen along the way. Repeatedly traverses at 493 * base-level looking for key starting at predecessor returned 494 * from findPredecessor, processing base-level deletions as 495 * encountered. Restarts occur, at traversal step encountering 496 * node n, if n's key field is null, indicating it is a marker, so 497 * its predecessor is deleted before continuing, which we help do 498 * by re-finding a valid predecessor. The traversal loops in 499 * doPut, doRemove, and findNear all include the same checks. 500 * 501 * @param key the key 502 * @return node holding key, or null if no such 503 */ findNode(Object key)504 private Node<K,V> findNode(Object key) { 505 if (key == null) 506 throw new NullPointerException(); // don't postpone errors 507 Comparator<? super K> cmp = comparator; 508 Node<K,V> b; 509 outer: while ((b = findPredecessor(key, cmp)) != null) { 510 for (;;) { 511 Node<K,V> n; K k; V v; int c; 512 if ((n = b.next) == null) 513 break outer; // empty 514 else if ((k = n.key) == null) 515 break; // b is deleted 516 else if ((v = n.val) == null) 517 unlinkNode(b, n); // n is deleted 518 else if ((c = cpr(cmp, key, k)) > 0) 519 b = n; 520 else if (c == 0) 521 return n; 522 else 523 break outer; 524 } 525 } 526 return null; 527 } 528 529 /** 530 * Gets value for key. Same idea as findNode, except skips over 531 * deletions and markers, and returns first encountered value to 532 * avoid possibly inconsistent rereads. 533 * 534 * @param key the key 535 * @return the value, or null if absent 536 */ doGet(Object key)537 private V doGet(Object key) { 538 Index<K,V> q; 539 VarHandle.acquireFence(); 540 if (key == null) 541 throw new NullPointerException(); 542 Comparator<? super K> cmp = comparator; 543 V result = null; 544 if ((q = head) != null) { 545 outer: for (Index<K,V> r, d;;) { 546 while ((r = q.right) != null) { 547 Node<K,V> p; K k; V v; int c; 548 if ((p = r.node) == null || (k = p.key) == null || 549 (v = p.val) == null) 550 RIGHT.compareAndSet(q, r, r.right); 551 else if ((c = cpr(cmp, key, k)) > 0) 552 q = r; 553 else if (c == 0) { 554 result = v; 555 break outer; 556 } 557 else 558 break; 559 } 560 if ((d = q.down) != null) 561 q = d; 562 else { 563 Node<K,V> b, n; 564 if ((b = q.node) != null) { 565 while ((n = b.next) != null) { 566 V v; int c; 567 K k = n.key; 568 if ((v = n.val) == null || k == null || 569 (c = cpr(cmp, key, k)) > 0) 570 b = n; 571 else { 572 if (c == 0) 573 result = v; 574 break; 575 } 576 } 577 } 578 break; 579 } 580 } 581 } 582 return result; 583 } 584 585 /* ---------------- Insertion -------------- */ 586 587 /** 588 * Main insertion method. Adds element if not present, or 589 * replaces value if present and onlyIfAbsent is false. 590 * 591 * @param key the key 592 * @param value the value that must be associated with key 593 * @param onlyIfAbsent if should not insert if already present 594 * @return the old value, or null if newly inserted 595 */ doPut(K key, V value, boolean onlyIfAbsent)596 private V doPut(K key, V value, boolean onlyIfAbsent) { 597 if (key == null) 598 throw new NullPointerException(); 599 Comparator<? super K> cmp = comparator; 600 for (;;) { 601 Index<K,V> h; Node<K,V> b; 602 VarHandle.acquireFence(); 603 int levels = 0; // number of levels descended 604 if ((h = head) == null) { // try to initialize 605 Node<K,V> base = new Node<K,V>(null, null, null); 606 h = new Index<K,V>(base, null, null); 607 b = (HEAD.compareAndSet(this, null, h)) ? base : null; 608 } 609 else { 610 for (Index<K,V> q = h, r, d;;) { // count while descending 611 while ((r = q.right) != null) { 612 Node<K,V> p; K k; 613 if ((p = r.node) == null || (k = p.key) == null || 614 p.val == null) 615 RIGHT.compareAndSet(q, r, r.right); 616 else if (cpr(cmp, key, k) > 0) 617 q = r; 618 else 619 break; 620 } 621 if ((d = q.down) != null) { 622 ++levels; 623 q = d; 624 } 625 else { 626 b = q.node; 627 break; 628 } 629 } 630 } 631 if (b != null) { 632 Node<K,V> z = null; // new node, if inserted 633 for (;;) { // find insertion point 634 Node<K,V> n, p; K k; V v; int c; 635 if ((n = b.next) == null) { 636 if (b.key == null) // if empty, type check key now 637 cpr(cmp, key, key); 638 c = -1; 639 } 640 else if ((k = n.key) == null) 641 break; // can't append; restart 642 else if ((v = n.val) == null) { 643 unlinkNode(b, n); 644 c = 1; 645 } 646 else if ((c = cpr(cmp, key, k)) > 0) 647 b = n; 648 else if (c == 0 && 649 (onlyIfAbsent || VAL.compareAndSet(n, v, value))) 650 return v; 651 652 if (c < 0 && 653 NEXT.compareAndSet(b, n, 654 p = new Node<K,V>(key, value, n))) { 655 z = p; 656 break; 657 } 658 } 659 660 if (z != null) { 661 int lr = ThreadLocalRandom.nextSecondarySeed(); 662 if ((lr & 0x3) == 0) { // add indices with 1/4 prob 663 int hr = ThreadLocalRandom.nextSecondarySeed(); 664 long rnd = ((long)hr << 32) | ((long)lr & 0xffffffffL); 665 int skips = levels; // levels to descend before add 666 Index<K,V> x = null; 667 for (;;) { // create at most 62 indices 668 x = new Index<K,V>(z, x, null); 669 if (rnd >= 0L || --skips < 0) 670 break; 671 else 672 rnd <<= 1; 673 } 674 if (addIndices(h, skips, x, cmp) && skips < 0 && 675 head == h) { // try to add new level 676 Index<K,V> hx = new Index<K,V>(z, x, null); 677 Index<K,V> nh = new Index<K,V>(h.node, h, hx); 678 HEAD.compareAndSet(this, h, nh); 679 } 680 if (z.val == null) // deleted while adding indices 681 findPredecessor(key, cmp); // clean 682 } 683 addCount(1L); 684 return null; 685 } 686 } 687 } 688 } 689 690 /** 691 * Add indices after an insertion. Descends iteratively to the 692 * highest level of insertion, then recursively, to chain index 693 * nodes to lower ones. Returns null on (staleness) failure, 694 * disabling higher-level insertions. Recursion depths are 695 * exponentially less probable. 696 * 697 * @param q starting index for current level 698 * @param skips levels to skip before inserting 699 * @param x index for this insertion 700 * @param cmp comparator 701 */ addIndices(Index<K,V> q, int skips, Index<K,V> x, Comparator<? super K> cmp)702 static <K,V> boolean addIndices(Index<K,V> q, int skips, Index<K,V> x, 703 Comparator<? super K> cmp) { 704 Node<K,V> z; K key; 705 if (x != null && (z = x.node) != null && (key = z.key) != null && 706 q != null) { // hoist checks 707 boolean retrying = false; 708 for (;;) { // find splice point 709 Index<K,V> r, d; int c; 710 if ((r = q.right) != null) { 711 Node<K,V> p; K k; 712 if ((p = r.node) == null || (k = p.key) == null || 713 p.val == null) { 714 RIGHT.compareAndSet(q, r, r.right); 715 c = 0; 716 } 717 else if ((c = cpr(cmp, key, k)) > 0) 718 q = r; 719 else if (c == 0) 720 break; // stale 721 } 722 else 723 c = -1; 724 725 if (c < 0) { 726 if ((d = q.down) != null && skips > 0) { 727 --skips; 728 q = d; 729 } 730 else if (d != null && !retrying && 731 !addIndices(d, 0, x.down, cmp)) 732 break; 733 else { 734 x.right = r; 735 if (RIGHT.compareAndSet(q, r, x)) 736 return true; 737 else 738 retrying = true; // re-find splice point 739 } 740 } 741 } 742 } 743 return false; 744 } 745 746 /* ---------------- Deletion -------------- */ 747 748 /** 749 * Main deletion method. Locates node, nulls value, appends a 750 * deletion marker, unlinks predecessor, removes associated index 751 * nodes, and possibly reduces head index level. 752 * 753 * @param key the key 754 * @param value if non-null, the value that must be 755 * associated with key 756 * @return the node, or null if not found 757 */ doRemove(Object key, Object value)758 final V doRemove(Object key, Object value) { 759 if (key == null) 760 throw new NullPointerException(); 761 Comparator<? super K> cmp = comparator; 762 V result = null; 763 Node<K,V> b; 764 outer: while ((b = findPredecessor(key, cmp)) != null && 765 result == null) { 766 for (;;) { 767 Node<K,V> n; K k; V v; int c; 768 if ((n = b.next) == null) 769 break outer; 770 else if ((k = n.key) == null) 771 break; 772 else if ((v = n.val) == null) 773 unlinkNode(b, n); 774 else if ((c = cpr(cmp, key, k)) > 0) 775 b = n; 776 else if (c < 0) 777 break outer; 778 else if (value != null && !value.equals(v)) 779 break outer; 780 else if (VAL.compareAndSet(n, v, null)) { 781 result = v; 782 unlinkNode(b, n); 783 break; // loop to clean up 784 } 785 } 786 } 787 if (result != null) { 788 tryReduceLevel(); 789 addCount(-1L); 790 } 791 return result; 792 } 793 794 /** 795 * Possibly reduce head level if it has no nodes. This method can 796 * (rarely) make mistakes, in which case levels can disappear even 797 * though they are about to contain index nodes. This impacts 798 * performance, not correctness. To minimize mistakes as well as 799 * to reduce hysteresis, the level is reduced by one only if the 800 * topmost three levels look empty. Also, if the removed level 801 * looks non-empty after CAS, we try to change it back quick 802 * before anyone notices our mistake! (This trick works pretty 803 * well because this method will practically never make mistakes 804 * unless current thread stalls immediately before first CAS, in 805 * which case it is very unlikely to stall again immediately 806 * afterwards, so will recover.) 807 * 808 * We put up with all this rather than just let levels grow 809 * because otherwise, even a small map that has undergone a large 810 * number of insertions and removals will have a lot of levels, 811 * slowing down access more than would an occasional unwanted 812 * reduction. 813 */ tryReduceLevel()814 private void tryReduceLevel() { 815 Index<K,V> h, d, e; 816 if ((h = head) != null && h.right == null && 817 (d = h.down) != null && d.right == null && 818 (e = d.down) != null && e.right == null && 819 HEAD.compareAndSet(this, h, d) && 820 h.right != null) // recheck 821 HEAD.compareAndSet(this, d, h); // try to backout 822 } 823 824 /* ---------------- Finding and removing first element -------------- */ 825 826 /** 827 * Gets first valid node, unlinking deleted nodes if encountered. 828 * @return first node or null if empty 829 */ findFirst()830 final Node<K,V> findFirst() { 831 Node<K,V> b, n; 832 if ((b = baseHead()) != null) { 833 while ((n = b.next) != null) { 834 if (n.val == null) 835 unlinkNode(b, n); 836 else 837 return n; 838 } 839 } 840 return null; 841 } 842 843 /** 844 * Entry snapshot version of findFirst 845 */ findFirstEntry()846 final AbstractMap.SimpleImmutableEntry<K,V> findFirstEntry() { 847 Node<K,V> b, n; V v; 848 if ((b = baseHead()) != null) { 849 while ((n = b.next) != null) { 850 if ((v = n.val) == null) 851 unlinkNode(b, n); 852 else 853 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); 854 } 855 } 856 return null; 857 } 858 859 /** 860 * Removes first entry; returns its snapshot. 861 * @return null if empty, else snapshot of first entry 862 */ doRemoveFirstEntry()863 private AbstractMap.SimpleImmutableEntry<K,V> doRemoveFirstEntry() { 864 Node<K,V> b, n; V v; 865 if ((b = baseHead()) != null) { 866 while ((n = b.next) != null) { 867 if ((v = n.val) == null || VAL.compareAndSet(n, v, null)) { 868 K k = n.key; 869 unlinkNode(b, n); 870 if (v != null) { 871 tryReduceLevel(); 872 findPredecessor(k, comparator); // clean index 873 addCount(-1L); 874 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); 875 } 876 } 877 } 878 } 879 return null; 880 } 881 882 /* ---------------- Finding and removing last element -------------- */ 883 884 /** 885 * Specialized version of find to get last valid node. 886 * @return last node or null if empty 887 */ findLast()888 final Node<K,V> findLast() { 889 outer: for (;;) { 890 Index<K,V> q; Node<K,V> b; 891 VarHandle.acquireFence(); 892 if ((q = head) == null) 893 break; 894 for (Index<K,V> r, d;;) { 895 while ((r = q.right) != null) { 896 Node<K,V> p; 897 if ((p = r.node) == null || p.val == null) 898 RIGHT.compareAndSet(q, r, r.right); 899 else 900 q = r; 901 } 902 if ((d = q.down) != null) 903 q = d; 904 else { 905 b = q.node; 906 break; 907 } 908 } 909 if (b != null) { 910 for (;;) { 911 Node<K,V> n; 912 if ((n = b.next) == null) { 913 if (b.key == null) // empty 914 break outer; 915 else 916 return b; 917 } 918 else if (n.key == null) 919 break; 920 else if (n.val == null) 921 unlinkNode(b, n); 922 else 923 b = n; 924 } 925 } 926 } 927 return null; 928 } 929 930 /** 931 * Entry version of findLast 932 * @return Entry for last node or null if empty 933 */ findLastEntry()934 final AbstractMap.SimpleImmutableEntry<K,V> findLastEntry() { 935 for (;;) { 936 Node<K,V> n; V v; 937 if ((n = findLast()) == null) 938 return null; 939 if ((v = n.val) != null) 940 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); 941 } 942 } 943 944 /** 945 * Removes last entry; returns its snapshot. 946 * Specialized variant of doRemove. 947 * @return null if empty, else snapshot of last entry 948 */ doRemoveLastEntry()949 private Map.Entry<K,V> doRemoveLastEntry() { 950 outer: for (;;) { 951 Index<K,V> q; Node<K,V> b; 952 VarHandle.acquireFence(); 953 if ((q = head) == null) 954 break; 955 for (;;) { 956 Index<K,V> d, r; Node<K,V> p; 957 while ((r = q.right) != null) { 958 if ((p = r.node) == null || p.val == null) 959 RIGHT.compareAndSet(q, r, r.right); 960 else if (p.next != null) 961 q = r; // continue only if a successor 962 else 963 break; 964 } 965 if ((d = q.down) != null) 966 q = d; 967 else { 968 b = q.node; 969 break; 970 } 971 } 972 if (b != null) { 973 for (;;) { 974 Node<K,V> n; K k; V v; 975 if ((n = b.next) == null) { 976 if (b.key == null) // empty 977 break outer; 978 else 979 break; // retry 980 } 981 else if ((k = n.key) == null) 982 break; 983 else if ((v = n.val) == null) 984 unlinkNode(b, n); 985 else if (n.next != null) 986 b = n; 987 else if (VAL.compareAndSet(n, v, null)) { 988 unlinkNode(b, n); 989 tryReduceLevel(); 990 findPredecessor(k, comparator); // clean index 991 addCount(-1L); 992 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); 993 } 994 } 995 } 996 } 997 return null; 998 } 999 1000 /* ---------------- Relational operations -------------- */ 1001 1002 // Control values OR'ed as arguments to findNear 1003 1004 private static final int EQ = 1; 1005 private static final int LT = 2; 1006 private static final int GT = 0; // Actually checked as !LT 1007 1008 /** 1009 * Utility for ceiling, floor, lower, higher methods. 1010 * @param key the key 1011 * @param rel the relation -- OR'ed combination of EQ, LT, GT 1012 * @return nearest node fitting relation, or null if no such 1013 */ findNear(K key, int rel, Comparator<? super K> cmp)1014 final Node<K,V> findNear(K key, int rel, Comparator<? super K> cmp) { 1015 if (key == null) 1016 throw new NullPointerException(); 1017 Node<K,V> result; 1018 outer: for (Node<K,V> b;;) { 1019 if ((b = findPredecessor(key, cmp)) == null) { 1020 result = null; 1021 break; // empty 1022 } 1023 for (;;) { 1024 Node<K,V> n; K k; int c; 1025 if ((n = b.next) == null) { 1026 result = ((rel & LT) != 0 && b.key != null) ? b : null; 1027 break outer; 1028 } 1029 else if ((k = n.key) == null) 1030 break; 1031 else if (n.val == null) 1032 unlinkNode(b, n); 1033 else if (((c = cpr(cmp, key, k)) == 0 && (rel & EQ) != 0) || 1034 (c < 0 && (rel & LT) == 0)) { 1035 result = n; 1036 break outer; 1037 } 1038 else if (c <= 0 && (rel & LT) != 0) { 1039 result = (b.key != null) ? b : null; 1040 break outer; 1041 } 1042 else 1043 b = n; 1044 } 1045 } 1046 return result; 1047 } 1048 1049 /** 1050 * Variant of findNear returning SimpleImmutableEntry 1051 * @param key the key 1052 * @param rel the relation -- OR'ed combination of EQ, LT, GT 1053 * @return Entry fitting relation, or null if no such 1054 */ findNearEntry(K key, int rel, Comparator<? super K> cmp)1055 final AbstractMap.SimpleImmutableEntry<K,V> findNearEntry(K key, int rel, 1056 Comparator<? super K> cmp) { 1057 for (;;) { 1058 Node<K,V> n; V v; 1059 if ((n = findNear(key, rel, cmp)) == null) 1060 return null; 1061 if ((v = n.val) != null) 1062 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); 1063 } 1064 } 1065 1066 /* ---------------- Constructors -------------- */ 1067 1068 /** 1069 * Constructs a new, empty map, sorted according to the 1070 * {@linkplain Comparable natural ordering} of the keys. 1071 */ ConcurrentSkipListMap()1072 public ConcurrentSkipListMap() { 1073 this.comparator = null; 1074 } 1075 1076 /** 1077 * Constructs a new, empty map, sorted according to the specified 1078 * comparator. 1079 * 1080 * @param comparator the comparator that will be used to order this map. 1081 * If {@code null}, the {@linkplain Comparable natural 1082 * ordering} of the keys will be used. 1083 */ ConcurrentSkipListMap(Comparator<? super K> comparator)1084 public ConcurrentSkipListMap(Comparator<? super K> comparator) { 1085 this.comparator = comparator; 1086 } 1087 1088 /** 1089 * Constructs a new map containing the same mappings as the given map, 1090 * sorted according to the {@linkplain Comparable natural ordering} of 1091 * the keys. 1092 * 1093 * @param m the map whose mappings are to be placed in this map 1094 * @throws ClassCastException if the keys in {@code m} are not 1095 * {@link Comparable}, or are not mutually comparable 1096 * @throws NullPointerException if the specified map or any of its keys 1097 * or values are null 1098 */ ConcurrentSkipListMap(Map<? extends K, ? extends V> m)1099 public ConcurrentSkipListMap(Map<? extends K, ? extends V> m) { 1100 this.comparator = null; 1101 putAll(m); 1102 } 1103 1104 /** 1105 * Constructs a new map containing the same mappings and using the 1106 * same ordering as the specified sorted map. 1107 * 1108 * @param m the sorted map whose mappings are to be placed in this 1109 * map, and whose comparator is to be used to sort this map 1110 * @throws NullPointerException if the specified sorted map or any of 1111 * its keys or values are null 1112 */ ConcurrentSkipListMap(SortedMap<K, ? extends V> m)1113 public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) { 1114 this.comparator = m.comparator(); 1115 buildFromSorted(m); // initializes transients 1116 } 1117 1118 /** 1119 * Returns a shallow copy of this {@code ConcurrentSkipListMap} 1120 * instance. (The keys and values themselves are not cloned.) 1121 * 1122 * @return a shallow copy of this map 1123 */ clone()1124 public ConcurrentSkipListMap<K,V> clone() { 1125 try { 1126 @SuppressWarnings("unchecked") 1127 ConcurrentSkipListMap<K,V> clone = 1128 (ConcurrentSkipListMap<K,V>) super.clone(); 1129 clone.keySet = null; 1130 clone.entrySet = null; 1131 clone.values = null; 1132 clone.descendingMap = null; 1133 clone.adder = null; 1134 clone.buildFromSorted(this); 1135 return clone; 1136 } catch (CloneNotSupportedException e) { 1137 throw new InternalError(); 1138 } 1139 } 1140 1141 /** 1142 * Streamlined bulk insertion to initialize from elements of 1143 * given sorted map. Call only from constructor or clone 1144 * method. 1145 */ buildFromSorted(SortedMap<K, ? extends V> map)1146 private void buildFromSorted(SortedMap<K, ? extends V> map) { 1147 if (map == null) 1148 throw new NullPointerException(); 1149 Iterator<? extends Map.Entry<? extends K, ? extends V>> it = 1150 map.entrySet().iterator(); 1151 1152 /* 1153 * Add equally spaced indices at log intervals, using the bits 1154 * of count during insertion. The maximum possible resulting 1155 * level is less than the number of bits in a long (64). The 1156 * preds array tracks the current rightmost node at each 1157 * level. 1158 */ 1159 @SuppressWarnings("unchecked") 1160 Index<K,V>[] preds = (Index<K,V>[])new Index<?,?>[64]; 1161 Node<K,V> bp = new Node<K,V>(null, null, null); 1162 Index<K,V> h = preds[0] = new Index<K,V>(bp, null, null); 1163 long count = 0; 1164 1165 while (it.hasNext()) { 1166 Map.Entry<? extends K, ? extends V> e = it.next(); 1167 K k = e.getKey(); 1168 V v = e.getValue(); 1169 if (k == null || v == null) 1170 throw new NullPointerException(); 1171 Node<K,V> z = new Node<K,V>(k, v, null); 1172 bp = bp.next = z; 1173 if ((++count & 3L) == 0L) { 1174 long m = count >>> 2; 1175 int i = 0; 1176 Index<K,V> idx = null, q; 1177 do { 1178 idx = new Index<K,V>(z, idx, null); 1179 if ((q = preds[i]) == null) 1180 preds[i] = h = new Index<K,V>(h.node, h, idx); 1181 else 1182 preds[i] = q.right = idx; 1183 } while (++i < preds.length && ((m >>>= 1) & 1L) != 0L); 1184 } 1185 } 1186 if (count != 0L) { 1187 VarHandle.releaseFence(); // emulate volatile stores 1188 addCount(count); 1189 head = h; 1190 VarHandle.fullFence(); 1191 } 1192 } 1193 1194 /* ---------------- Serialization -------------- */ 1195 1196 /** 1197 * Saves this map to a stream (that is, serializes it). 1198 * 1199 * @param s the stream 1200 * @throws java.io.IOException if an I/O error occurs 1201 * @serialData The key (Object) and value (Object) for each 1202 * key-value mapping represented by the map, followed by 1203 * {@code null}. The key-value mappings are emitted in key-order 1204 * (as determined by the Comparator, or by the keys' natural 1205 * ordering if no Comparator). 1206 */ writeObject(java.io.ObjectOutputStream s)1207 private void writeObject(java.io.ObjectOutputStream s) 1208 throws java.io.IOException { 1209 // Write out the Comparator and any hidden stuff 1210 s.defaultWriteObject(); 1211 1212 // Write out keys and values (alternating) 1213 Node<K,V> b, n; V v; 1214 if ((b = baseHead()) != null) { 1215 while ((n = b.next) != null) { 1216 if ((v = n.val) != null) { 1217 s.writeObject(n.key); 1218 s.writeObject(v); 1219 } 1220 b = n; 1221 } 1222 } 1223 s.writeObject(null); 1224 } 1225 1226 /** 1227 * Reconstitutes this map from a stream (that is, deserializes it). 1228 * @param s the stream 1229 * @throws ClassNotFoundException if the class of a serialized object 1230 * could not be found 1231 * @throws java.io.IOException if an I/O error occurs 1232 */ 1233 @SuppressWarnings("unchecked") readObject(final java.io.ObjectInputStream s)1234 private void readObject(final java.io.ObjectInputStream s) 1235 throws java.io.IOException, ClassNotFoundException { 1236 // Read in the Comparator and any hidden stuff 1237 s.defaultReadObject(); 1238 1239 // Same idea as buildFromSorted 1240 @SuppressWarnings("unchecked") 1241 Index<K,V>[] preds = (Index<K,V>[])new Index<?,?>[64]; 1242 Node<K,V> bp = new Node<K,V>(null, null, null); 1243 Index<K,V> h = preds[0] = new Index<K,V>(bp, null, null); 1244 Comparator<? super K> cmp = comparator; 1245 K prevKey = null; 1246 long count = 0; 1247 1248 for (;;) { 1249 K k = (K)s.readObject(); 1250 if (k == null) 1251 break; 1252 V v = (V)s.readObject(); 1253 if (v == null) 1254 throw new NullPointerException(); 1255 if (prevKey != null && cpr(cmp, prevKey, k) > 0) 1256 throw new IllegalStateException("out of order"); 1257 prevKey = k; 1258 Node<K,V> z = new Node<K,V>(k, v, null); 1259 bp = bp.next = z; 1260 if ((++count & 3L) == 0L) { 1261 long m = count >>> 2; 1262 int i = 0; 1263 Index<K,V> idx = null, q; 1264 do { 1265 idx = new Index<K,V>(z, idx, null); 1266 if ((q = preds[i]) == null) 1267 preds[i] = h = new Index<K,V>(h.node, h, idx); 1268 else 1269 preds[i] = q.right = idx; 1270 } while (++i < preds.length && ((m >>>= 1) & 1L) != 0L); 1271 } 1272 } 1273 if (count != 0L) { 1274 VarHandle.releaseFence(); 1275 addCount(count); 1276 head = h; 1277 VarHandle.fullFence(); 1278 } 1279 } 1280 1281 /* ------ Map API methods ------ */ 1282 1283 /** 1284 * Returns {@code true} if this map contains a mapping for the specified 1285 * key. 1286 * 1287 * @param key key whose presence in this map is to be tested 1288 * @return {@code true} if this map contains a mapping for the specified key 1289 * @throws ClassCastException if the specified key cannot be compared 1290 * with the keys currently in the map 1291 * @throws NullPointerException if the specified key is null 1292 */ containsKey(Object key)1293 public boolean containsKey(Object key) { 1294 return doGet(key) != null; 1295 } 1296 1297 /** 1298 * Returns the value to which the specified key is mapped, 1299 * or {@code null} if this map contains no mapping for the key. 1300 * 1301 * <p>More formally, if this map contains a mapping from a key 1302 * {@code k} to a value {@code v} such that {@code key} compares 1303 * equal to {@code k} according to the map's ordering, then this 1304 * method returns {@code v}; otherwise it returns {@code null}. 1305 * (There can be at most one such mapping.) 1306 * 1307 * @throws ClassCastException if the specified key cannot be compared 1308 * with the keys currently in the map 1309 * @throws NullPointerException if the specified key is null 1310 */ get(Object key)1311 public V get(Object key) { 1312 return doGet(key); 1313 } 1314 1315 /** 1316 * Returns the value to which the specified key is mapped, 1317 * or the given defaultValue if this map contains no mapping for the key. 1318 * 1319 * @param key the key 1320 * @param defaultValue the value to return if this map contains 1321 * no mapping for the given key 1322 * @return the mapping for the key, if present; else the defaultValue 1323 * @throws NullPointerException if the specified key is null 1324 * @since 1.8 1325 */ getOrDefault(Object key, V defaultValue)1326 public V getOrDefault(Object key, V defaultValue) { 1327 V v; 1328 return (v = doGet(key)) == null ? defaultValue : v; 1329 } 1330 1331 /** 1332 * Associates the specified value with the specified key in this map. 1333 * If the map previously contained a mapping for the key, the old 1334 * value is replaced. 1335 * 1336 * @param key key with which the specified value is to be associated 1337 * @param value value to be associated with the specified key 1338 * @return the previous value associated with the specified key, or 1339 * {@code null} if there was no mapping for the key 1340 * @throws ClassCastException if the specified key cannot be compared 1341 * with the keys currently in the map 1342 * @throws NullPointerException if the specified key or value is null 1343 */ put(K key, V value)1344 public V put(K key, V value) { 1345 if (value == null) 1346 throw new NullPointerException(); 1347 return doPut(key, value, false); 1348 } 1349 1350 /** 1351 * Removes the mapping for the specified key from this map if present. 1352 * 1353 * @param key key for which mapping should be removed 1354 * @return the previous value associated with the specified key, or 1355 * {@code null} if there was no mapping for the key 1356 * @throws ClassCastException if the specified key cannot be compared 1357 * with the keys currently in the map 1358 * @throws NullPointerException if the specified key is null 1359 */ remove(Object key)1360 public V remove(Object key) { 1361 return doRemove(key, null); 1362 } 1363 1364 /** 1365 * Returns {@code true} if this map maps one or more keys to the 1366 * specified value. This operation requires time linear in the 1367 * map size. Additionally, it is possible for the map to change 1368 * during execution of this method, in which case the returned 1369 * result may be inaccurate. 1370 * 1371 * @param value value whose presence in this map is to be tested 1372 * @return {@code true} if a mapping to {@code value} exists; 1373 * {@code false} otherwise 1374 * @throws NullPointerException if the specified value is null 1375 */ containsValue(Object value)1376 public boolean containsValue(Object value) { 1377 if (value == null) 1378 throw new NullPointerException(); 1379 Node<K,V> b, n; V v; 1380 if ((b = baseHead()) != null) { 1381 while ((n = b.next) != null) { 1382 if ((v = n.val) != null && value.equals(v)) 1383 return true; 1384 else 1385 b = n; 1386 } 1387 } 1388 return false; 1389 } 1390 1391 /** 1392 * {@inheritDoc} 1393 */ size()1394 public int size() { 1395 long c; 1396 return ((baseHead() == null) ? 0 : 1397 ((c = getAdderCount()) >= Integer.MAX_VALUE) ? 1398 Integer.MAX_VALUE : (int) c); 1399 } 1400 1401 /** 1402 * {@inheritDoc} 1403 */ isEmpty()1404 public boolean isEmpty() { 1405 return findFirst() == null; 1406 } 1407 1408 /** 1409 * Removes all of the mappings from this map. 1410 */ clear()1411 public void clear() { 1412 Index<K,V> h, r, d; Node<K,V> b; 1413 VarHandle.acquireFence(); 1414 while ((h = head) != null) { 1415 if ((r = h.right) != null) // remove indices 1416 RIGHT.compareAndSet(h, r, null); 1417 else if ((d = h.down) != null) // remove levels 1418 HEAD.compareAndSet(this, h, d); 1419 else { 1420 long count = 0L; 1421 if ((b = h.node) != null) { // remove nodes 1422 Node<K,V> n; V v; 1423 while ((n = b.next) != null) { 1424 if ((v = n.val) != null && 1425 VAL.compareAndSet(n, v, null)) { 1426 --count; 1427 v = null; 1428 } 1429 if (v == null) 1430 unlinkNode(b, n); 1431 } 1432 } 1433 if (count != 0L) 1434 addCount(count); 1435 else 1436 break; 1437 } 1438 } 1439 } 1440 1441 /** 1442 * If the specified key is not already associated with a value, 1443 * attempts to compute its value using the given mapping function 1444 * and enters it into this map unless {@code null}. The function 1445 * is <em>NOT</em> guaranteed to be applied once atomically only 1446 * if the value is not present. 1447 * 1448 * @param key key with which the specified value is to be associated 1449 * @param mappingFunction the function to compute a value 1450 * @return the current (existing or computed) value associated with 1451 * the specified key, or null if the computed value is null 1452 * @throws NullPointerException if the specified key is null 1453 * or the mappingFunction is null 1454 * @since 1.8 1455 */ computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)1456 public V computeIfAbsent(K key, 1457 Function<? super K, ? extends V> mappingFunction) { 1458 if (key == null || mappingFunction == null) 1459 throw new NullPointerException(); 1460 V v, p, r; 1461 if ((v = doGet(key)) == null && 1462 (r = mappingFunction.apply(key)) != null) 1463 v = (p = doPut(key, r, true)) == null ? r : p; 1464 return v; 1465 } 1466 1467 /** 1468 * If the value for the specified key is present, attempts to 1469 * compute a new mapping given the key and its current mapped 1470 * value. The function is <em>NOT</em> guaranteed to be applied 1471 * once atomically. 1472 * 1473 * @param key key with which a value may be associated 1474 * @param remappingFunction the function to compute a value 1475 * @return the new value associated with the specified key, or null if none 1476 * @throws NullPointerException if the specified key is null 1477 * or the remappingFunction is null 1478 * @since 1.8 1479 */ computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)1480 public V computeIfPresent(K key, 1481 BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 1482 if (key == null || remappingFunction == null) 1483 throw new NullPointerException(); 1484 Node<K,V> n; V v; 1485 while ((n = findNode(key)) != null) { 1486 if ((v = n.val) != null) { 1487 V r = remappingFunction.apply(key, v); 1488 if (r != null) { 1489 if (VAL.compareAndSet(n, v, r)) 1490 return r; 1491 } 1492 else if (doRemove(key, v) != null) 1493 break; 1494 } 1495 } 1496 return null; 1497 } 1498 1499 /** 1500 * Attempts to compute a mapping for the specified key and its 1501 * current mapped value (or {@code null} if there is no current 1502 * mapping). The function is <em>NOT</em> guaranteed to be applied 1503 * once atomically. 1504 * 1505 * @param key key with which the specified value is to be associated 1506 * @param remappingFunction the function to compute a value 1507 * @return the new value associated with the specified key, or null if none 1508 * @throws NullPointerException if the specified key is null 1509 * or the remappingFunction is null 1510 * @since 1.8 1511 */ compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)1512 public V compute(K key, 1513 BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 1514 if (key == null || remappingFunction == null) 1515 throw new NullPointerException(); 1516 for (;;) { 1517 Node<K,V> n; V v; V r; 1518 if ((n = findNode(key)) == null) { 1519 if ((r = remappingFunction.apply(key, null)) == null) 1520 break; 1521 if (doPut(key, r, true) == null) 1522 return r; 1523 } 1524 else if ((v = n.val) != null) { 1525 if ((r = remappingFunction.apply(key, v)) != null) { 1526 if (VAL.compareAndSet(n, v, r)) 1527 return r; 1528 } 1529 else if (doRemove(key, v) != null) 1530 break; 1531 } 1532 } 1533 return null; 1534 } 1535 1536 /** 1537 * If the specified key is not already associated with a value, 1538 * associates it with the given value. Otherwise, replaces the 1539 * value with the results of the given remapping function, or 1540 * removes if {@code null}. The function is <em>NOT</em> 1541 * guaranteed to be applied once atomically. 1542 * 1543 * @param key key with which the specified value is to be associated 1544 * @param value the value to use if absent 1545 * @param remappingFunction the function to recompute a value if present 1546 * @return the new value associated with the specified key, or null if none 1547 * @throws NullPointerException if the specified key or value is null 1548 * or the remappingFunction is null 1549 * @since 1.8 1550 */ merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)1551 public V merge(K key, V value, 1552 BiFunction<? super V, ? super V, ? extends V> remappingFunction) { 1553 if (key == null || value == null || remappingFunction == null) 1554 throw new NullPointerException(); 1555 for (;;) { 1556 Node<K,V> n; V v; V r; 1557 if ((n = findNode(key)) == null) { 1558 if (doPut(key, value, true) == null) 1559 return value; 1560 } 1561 else if ((v = n.val) != null) { 1562 if ((r = remappingFunction.apply(v, value)) != null) { 1563 if (VAL.compareAndSet(n, v, r)) 1564 return r; 1565 } 1566 else if (doRemove(key, v) != null) 1567 return null; 1568 } 1569 } 1570 } 1571 1572 /* ---------------- View methods -------------- */ 1573 1574 /* 1575 * Note: Lazy initialization works for views because view classes 1576 * are stateless/immutable so it doesn't matter wrt correctness if 1577 * more than one is created (which will only rarely happen). Even 1578 * so, the following idiom conservatively ensures that the method 1579 * returns the one it created if it does so, not one created by 1580 * another racing thread. 1581 */ 1582 1583 /** 1584 * Returns a {@link NavigableSet} view of the keys contained in this map. 1585 * 1586 * <p>The set's iterator returns the keys in ascending order. 1587 * The set's spliterator additionally reports {@link Spliterator#CONCURRENT}, 1588 * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and 1589 * {@link Spliterator#ORDERED}, with an encounter order that is ascending 1590 * key order. 1591 * 1592 * <p>The {@linkplain Spliterator#getComparator() spliterator's comparator} 1593 * is {@code null} if the {@linkplain #comparator() map's comparator} 1594 * is {@code null}. 1595 * Otherwise, the spliterator's comparator is the same as or imposes the 1596 * same total ordering as the map's comparator. 1597 * 1598 * <p>The set is backed by the map, so changes to the map are 1599 * reflected in the set, and vice-versa. The set supports element 1600 * removal, which removes the corresponding mapping from the map, 1601 * via the {@code Iterator.remove}, {@code Set.remove}, 1602 * {@code removeAll}, {@code retainAll}, and {@code clear} 1603 * operations. It does not support the {@code add} or {@code addAll} 1604 * operations. 1605 * 1606 * <p>The view's iterators and spliterators are 1607 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 1608 * 1609 * <p>This method is equivalent to method {@code navigableKeySet}. 1610 * 1611 * @return a navigable set view of the keys in this map 1612 */ keySet()1613 public NavigableSet<K> keySet() { 1614 KeySet<K,V> ks; 1615 if ((ks = keySet) != null) return ks; 1616 return keySet = new KeySet<>(this); 1617 } 1618 navigableKeySet()1619 public NavigableSet<K> navigableKeySet() { 1620 KeySet<K,V> ks; 1621 if ((ks = keySet) != null) return ks; 1622 return keySet = new KeySet<>(this); 1623 } 1624 1625 /** 1626 * Returns a {@link Collection} view of the values contained in this map. 1627 * <p>The collection's iterator returns the values in ascending order 1628 * of the corresponding keys. The collections's spliterator additionally 1629 * reports {@link Spliterator#CONCURRENT}, {@link Spliterator#NONNULL} and 1630 * {@link Spliterator#ORDERED}, with an encounter order that is ascending 1631 * order of the corresponding keys. 1632 * 1633 * <p>The collection is backed by the map, so changes to the map are 1634 * reflected in the collection, and vice-versa. The collection 1635 * supports element removal, which removes the corresponding 1636 * mapping from the map, via the {@code Iterator.remove}, 1637 * {@code Collection.remove}, {@code removeAll}, 1638 * {@code retainAll} and {@code clear} operations. It does not 1639 * support the {@code add} or {@code addAll} operations. 1640 * 1641 * <p>The view's iterators and spliterators are 1642 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 1643 */ values()1644 public Collection<V> values() { 1645 Values<K,V> vs; 1646 if ((vs = values) != null) return vs; 1647 return values = new Values<>(this); 1648 } 1649 1650 /** 1651 * Returns a {@link Set} view of the mappings contained in this map. 1652 * 1653 * <p>The set's iterator returns the entries in ascending key order. The 1654 * set's spliterator additionally reports {@link Spliterator#CONCURRENT}, 1655 * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and 1656 * {@link Spliterator#ORDERED}, with an encounter order that is ascending 1657 * key order. 1658 * 1659 * <p>The set is backed by the map, so changes to the map are 1660 * reflected in the set, and vice-versa. The set supports element 1661 * removal, which removes the corresponding mapping from the map, 1662 * via the {@code Iterator.remove}, {@code Set.remove}, 1663 * {@code removeAll}, {@code retainAll} and {@code clear} 1664 * operations. It does not support the {@code add} or 1665 * {@code addAll} operations. 1666 * 1667 * <p>The view's iterators and spliterators are 1668 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 1669 * 1670 * <p>The {@code Map.Entry} elements traversed by the {@code iterator} 1671 * or {@code spliterator} do <em>not</em> support the {@code setValue} 1672 * operation. 1673 * 1674 * @return a set view of the mappings contained in this map, 1675 * sorted in ascending key order 1676 */ entrySet()1677 public Set<Map.Entry<K,V>> entrySet() { 1678 EntrySet<K,V> es; 1679 if ((es = entrySet) != null) return es; 1680 return entrySet = new EntrySet<K,V>(this); 1681 } 1682 descendingMap()1683 public ConcurrentNavigableMap<K,V> descendingMap() { 1684 ConcurrentNavigableMap<K,V> dm; 1685 if ((dm = descendingMap) != null) return dm; 1686 return descendingMap = 1687 new SubMap<K,V>(this, null, false, null, false, true); 1688 } 1689 descendingKeySet()1690 public NavigableSet<K> descendingKeySet() { 1691 return descendingMap().navigableKeySet(); 1692 } 1693 1694 /* ---------------- AbstractMap Overrides -------------- */ 1695 1696 /** 1697 * Compares the specified object with this map for equality. 1698 * Returns {@code true} if the given object is also a map and the 1699 * two maps represent the same mappings. More formally, two maps 1700 * {@code m1} and {@code m2} represent the same mappings if 1701 * {@code m1.entrySet().equals(m2.entrySet())}. This 1702 * operation may return misleading results if either map is 1703 * concurrently modified during execution of this method. 1704 * 1705 * @param o object to be compared for equality with this map 1706 * @return {@code true} if the specified object is equal to this map 1707 */ equals(Object o)1708 public boolean equals(Object o) { 1709 if (o == this) 1710 return true; 1711 if (!(o instanceof Map)) 1712 return false; 1713 Map<?,?> m = (Map<?,?>) o; 1714 try { 1715 Comparator<? super K> cmp = comparator; 1716 // See JDK-8223553 for Iterator type wildcard rationale 1717 Iterator<? extends Map.Entry<?,?>> it = m.entrySet().iterator(); 1718 if (m instanceof SortedMap && 1719 ((SortedMap<?,?>)m).comparator() == cmp) { 1720 Node<K,V> b, n; 1721 if ((b = baseHead()) != null) { 1722 while ((n = b.next) != null) { 1723 K k; V v; 1724 if ((v = n.val) != null && (k = n.key) != null) { 1725 if (!it.hasNext()) 1726 return false; 1727 Map.Entry<?,?> e = it.next(); 1728 Object mk = e.getKey(); 1729 Object mv = e.getValue(); 1730 if (mk == null || mv == null) 1731 return false; 1732 try { 1733 if (cpr(cmp, k, mk) != 0) 1734 return false; 1735 } catch (ClassCastException cce) { 1736 return false; 1737 } 1738 if (!mv.equals(v)) 1739 return false; 1740 } 1741 b = n; 1742 } 1743 } 1744 return !it.hasNext(); 1745 } 1746 else { 1747 while (it.hasNext()) { 1748 V v; 1749 Map.Entry<?,?> e = it.next(); 1750 Object mk = e.getKey(); 1751 Object mv = e.getValue(); 1752 if (mk == null || mv == null || 1753 (v = get(mk)) == null || !v.equals(mv)) 1754 return false; 1755 } 1756 Node<K,V> b, n; 1757 if ((b = baseHead()) != null) { 1758 K k; V v; Object mv; 1759 while ((n = b.next) != null) { 1760 if ((v = n.val) != null && (k = n.key) != null && 1761 ((mv = m.get(k)) == null || !mv.equals(v))) 1762 return false; 1763 b = n; 1764 } 1765 } 1766 return true; 1767 } 1768 } catch (ClassCastException | NullPointerException unused) { 1769 return false; 1770 } 1771 } 1772 1773 /* ------ ConcurrentMap API methods ------ */ 1774 1775 /** 1776 * {@inheritDoc} 1777 * 1778 * @return the previous value associated with the specified key, 1779 * or {@code null} if there was no mapping for the key 1780 * @throws ClassCastException if the specified key cannot be compared 1781 * with the keys currently in the map 1782 * @throws NullPointerException if the specified key or value is null 1783 */ putIfAbsent(K key, V value)1784 public V putIfAbsent(K key, V value) { 1785 if (value == null) 1786 throw new NullPointerException(); 1787 return doPut(key, value, true); 1788 } 1789 1790 /** 1791 * {@inheritDoc} 1792 * 1793 * @throws ClassCastException if the specified key cannot be compared 1794 * with the keys currently in the map 1795 * @throws NullPointerException if the specified key is null 1796 */ remove(Object key, Object value)1797 public boolean remove(Object key, Object value) { 1798 if (key == null) 1799 throw new NullPointerException(); 1800 return value != null && doRemove(key, value) != null; 1801 } 1802 1803 /** 1804 * {@inheritDoc} 1805 * 1806 * @throws ClassCastException if the specified key cannot be compared 1807 * with the keys currently in the map 1808 * @throws NullPointerException if any of the arguments are null 1809 */ replace(K key, V oldValue, V newValue)1810 public boolean replace(K key, V oldValue, V newValue) { 1811 if (key == null || oldValue == null || newValue == null) 1812 throw new NullPointerException(); 1813 for (;;) { 1814 Node<K,V> n; V v; 1815 if ((n = findNode(key)) == null) 1816 return false; 1817 if ((v = n.val) != null) { 1818 if (!oldValue.equals(v)) 1819 return false; 1820 if (VAL.compareAndSet(n, v, newValue)) 1821 return true; 1822 } 1823 } 1824 } 1825 1826 /** 1827 * {@inheritDoc} 1828 * 1829 * @return the previous value associated with the specified key, 1830 * or {@code null} if there was no mapping for the key 1831 * @throws ClassCastException if the specified key cannot be compared 1832 * with the keys currently in the map 1833 * @throws NullPointerException if the specified key or value is null 1834 */ replace(K key, V value)1835 public V replace(K key, V value) { 1836 if (key == null || value == null) 1837 throw new NullPointerException(); 1838 for (;;) { 1839 Node<K,V> n; V v; 1840 if ((n = findNode(key)) == null) 1841 return null; 1842 if ((v = n.val) != null && VAL.compareAndSet(n, v, value)) 1843 return v; 1844 } 1845 } 1846 1847 /* ------ SortedMap API methods ------ */ 1848 comparator()1849 public Comparator<? super K> comparator() { 1850 return comparator; 1851 } 1852 1853 /** 1854 * @throws NoSuchElementException {@inheritDoc} 1855 */ firstKey()1856 public K firstKey() { 1857 Node<K,V> n = findFirst(); 1858 if (n == null) 1859 throw new NoSuchElementException(); 1860 return n.key; 1861 } 1862 1863 /** 1864 * @throws NoSuchElementException {@inheritDoc} 1865 */ lastKey()1866 public K lastKey() { 1867 Node<K,V> n = findLast(); 1868 if (n == null) 1869 throw new NoSuchElementException(); 1870 return n.key; 1871 } 1872 1873 /** 1874 * Throws {@code UnsupportedOperationException}. The encounter order induced by this 1875 * map's comparison method determines the position of mappings, so explicit positioning 1876 * is not supported. 1877 * 1878 * @throws UnsupportedOperationException always 1879 * @since 21 1880 */ putFirst(K k, V v)1881 public V putFirst(K k, V v) { 1882 throw new UnsupportedOperationException(); 1883 } 1884 1885 /** 1886 * Throws {@code UnsupportedOperationException}. The encounter order induced by this 1887 * map's comparison method determines the position of mappings, so explicit positioning 1888 * is not supported. 1889 * 1890 * @throws UnsupportedOperationException always 1891 * @since 21 1892 */ putLast(K k, V v)1893 public V putLast(K k, V v) { 1894 throw new UnsupportedOperationException(); 1895 } 1896 1897 /** 1898 * @throws ClassCastException {@inheritDoc} 1899 * @throws NullPointerException if {@code fromKey} or {@code toKey} is null 1900 * @throws IllegalArgumentException {@inheritDoc} 1901 */ subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)1902 public ConcurrentNavigableMap<K,V> subMap(K fromKey, 1903 boolean fromInclusive, 1904 K toKey, 1905 boolean toInclusive) { 1906 if (fromKey == null || toKey == null) 1907 throw new NullPointerException(); 1908 return new SubMap<K,V> 1909 (this, fromKey, fromInclusive, toKey, toInclusive, false); 1910 } 1911 1912 /** 1913 * @throws ClassCastException {@inheritDoc} 1914 * @throws NullPointerException if {@code toKey} is null 1915 * @throws IllegalArgumentException {@inheritDoc} 1916 */ headMap(K toKey, boolean inclusive)1917 public ConcurrentNavigableMap<K,V> headMap(K toKey, 1918 boolean inclusive) { 1919 if (toKey == null) 1920 throw new NullPointerException(); 1921 return new SubMap<K,V> 1922 (this, null, false, toKey, inclusive, false); 1923 } 1924 1925 /** 1926 * @throws ClassCastException {@inheritDoc} 1927 * @throws NullPointerException if {@code fromKey} is null 1928 * @throws IllegalArgumentException {@inheritDoc} 1929 */ tailMap(K fromKey, boolean inclusive)1930 public ConcurrentNavigableMap<K,V> tailMap(K fromKey, 1931 boolean inclusive) { 1932 if (fromKey == null) 1933 throw new NullPointerException(); 1934 return new SubMap<K,V> 1935 (this, fromKey, inclusive, null, false, false); 1936 } 1937 1938 /** 1939 * @throws ClassCastException {@inheritDoc} 1940 * @throws NullPointerException if {@code fromKey} or {@code toKey} is null 1941 * @throws IllegalArgumentException {@inheritDoc} 1942 */ subMap(K fromKey, K toKey)1943 public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) { 1944 return subMap(fromKey, true, toKey, false); 1945 } 1946 1947 /** 1948 * @throws ClassCastException {@inheritDoc} 1949 * @throws NullPointerException if {@code toKey} is null 1950 * @throws IllegalArgumentException {@inheritDoc} 1951 */ headMap(K toKey)1952 public ConcurrentNavigableMap<K,V> headMap(K toKey) { 1953 return headMap(toKey, false); 1954 } 1955 1956 /** 1957 * @throws ClassCastException {@inheritDoc} 1958 * @throws NullPointerException if {@code fromKey} is null 1959 * @throws IllegalArgumentException {@inheritDoc} 1960 */ tailMap(K fromKey)1961 public ConcurrentNavigableMap<K,V> tailMap(K fromKey) { 1962 return tailMap(fromKey, true); 1963 } 1964 1965 /* ---------------- Relational operations -------------- */ 1966 1967 /** 1968 * Returns a key-value mapping associated with the greatest key 1969 * strictly less than the given key, or {@code null} if there is 1970 * no such key. The returned entry does <em>not</em> support the 1971 * {@code Entry.setValue} method. 1972 * 1973 * @throws ClassCastException {@inheritDoc} 1974 * @throws NullPointerException if the specified key is null 1975 */ lowerEntry(K key)1976 public Map.Entry<K,V> lowerEntry(K key) { 1977 return findNearEntry(key, LT, comparator); 1978 } 1979 1980 /** 1981 * @throws ClassCastException {@inheritDoc} 1982 * @throws NullPointerException if the specified key is null 1983 */ lowerKey(K key)1984 public K lowerKey(K key) { 1985 Node<K,V> n = findNear(key, LT, comparator); 1986 return (n == null) ? null : n.key; 1987 } 1988 1989 /** 1990 * Returns a key-value mapping associated with the greatest key 1991 * less than or equal to the given key, or {@code null} if there 1992 * is no such key. The returned entry does <em>not</em> support 1993 * the {@code Entry.setValue} method. 1994 * 1995 * @param key the key 1996 * @throws ClassCastException {@inheritDoc} 1997 * @throws NullPointerException if the specified key is null 1998 */ floorEntry(K key)1999 public Map.Entry<K,V> floorEntry(K key) { 2000 return findNearEntry(key, LT|EQ, comparator); 2001 } 2002 2003 /** 2004 * @param key the key 2005 * @throws ClassCastException {@inheritDoc} 2006 * @throws NullPointerException if the specified key is null 2007 */ floorKey(K key)2008 public K floorKey(K key) { 2009 Node<K,V> n = findNear(key, LT|EQ, comparator); 2010 return (n == null) ? null : n.key; 2011 } 2012 2013 /** 2014 * Returns a key-value mapping associated with the least key 2015 * greater than or equal to the given key, or {@code null} if 2016 * there is no such entry. The returned entry does <em>not</em> 2017 * support the {@code Entry.setValue} method. 2018 * 2019 * @throws ClassCastException {@inheritDoc} 2020 * @throws NullPointerException if the specified key is null 2021 */ ceilingEntry(K key)2022 public Map.Entry<K,V> ceilingEntry(K key) { 2023 return findNearEntry(key, GT|EQ, comparator); 2024 } 2025 2026 /** 2027 * @throws ClassCastException {@inheritDoc} 2028 * @throws NullPointerException if the specified key is null 2029 */ ceilingKey(K key)2030 public K ceilingKey(K key) { 2031 Node<K,V> n = findNear(key, GT|EQ, comparator); 2032 return (n == null) ? null : n.key; 2033 } 2034 2035 /** 2036 * Returns a key-value mapping associated with the least key 2037 * strictly greater than the given key, or {@code null} if there 2038 * is no such key. The returned entry does <em>not</em> support 2039 * the {@code Entry.setValue} method. 2040 * 2041 * @param key the key 2042 * @throws ClassCastException {@inheritDoc} 2043 * @throws NullPointerException if the specified key is null 2044 */ higherEntry(K key)2045 public Map.Entry<K,V> higherEntry(K key) { 2046 return findNearEntry(key, GT, comparator); 2047 } 2048 2049 /** 2050 * @param key the key 2051 * @throws ClassCastException {@inheritDoc} 2052 * @throws NullPointerException if the specified key is null 2053 */ higherKey(K key)2054 public K higherKey(K key) { 2055 Node<K,V> n = findNear(key, GT, comparator); 2056 return (n == null) ? null : n.key; 2057 } 2058 2059 /** 2060 * Returns a key-value mapping associated with the least 2061 * key in this map, or {@code null} if the map is empty. 2062 * The returned entry does <em>not</em> support 2063 * the {@code Entry.setValue} method. 2064 */ firstEntry()2065 public Map.Entry<K,V> firstEntry() { 2066 return findFirstEntry(); 2067 } 2068 2069 /** 2070 * Returns a key-value mapping associated with the greatest 2071 * key in this map, or {@code null} if the map is empty. 2072 * The returned entry does <em>not</em> support 2073 * the {@code Entry.setValue} method. 2074 */ lastEntry()2075 public Map.Entry<K,V> lastEntry() { 2076 return findLastEntry(); 2077 } 2078 2079 /** 2080 * Removes and returns a key-value mapping associated with 2081 * the least key in this map, or {@code null} if the map is empty. 2082 * The returned entry does <em>not</em> support 2083 * the {@code Entry.setValue} method. 2084 */ pollFirstEntry()2085 public Map.Entry<K,V> pollFirstEntry() { 2086 return doRemoveFirstEntry(); 2087 } 2088 2089 /** 2090 * Removes and returns a key-value mapping associated with 2091 * the greatest key in this map, or {@code null} if the map is empty. 2092 * The returned entry does <em>not</em> support 2093 * the {@code Entry.setValue} method. 2094 */ pollLastEntry()2095 public Map.Entry<K,V> pollLastEntry() { 2096 return doRemoveLastEntry(); 2097 } 2098 2099 /* ---------------- Iterators -------------- */ 2100 2101 /** 2102 * Base of iterator classes 2103 */ 2104 abstract class Iter<T> implements Iterator<T> { 2105 /** the last node returned by next() */ 2106 Node<K,V> lastReturned; 2107 /** the next node to return from next(); */ 2108 Node<K,V> next; 2109 /** Cache of next value field to maintain weak consistency */ 2110 V nextValue; 2111 2112 /** Initializes ascending iterator for entire range. */ Iter()2113 Iter() { 2114 advance(baseHead()); 2115 } 2116 hasNext()2117 public final boolean hasNext() { 2118 return next != null; 2119 } 2120 2121 /** Advances next to higher entry. */ advance(Node<K,V> b)2122 final void advance(Node<K,V> b) { 2123 Node<K,V> n = null; 2124 V v = null; 2125 if ((lastReturned = b) != null) { 2126 while ((n = b.next) != null && (v = n.val) == null) 2127 b = n; 2128 } 2129 nextValue = v; 2130 next = n; 2131 } 2132 remove()2133 public final void remove() { 2134 Node<K,V> n; K k; 2135 if ((n = lastReturned) == null || (k = n.key) == null) 2136 throw new IllegalStateException(); 2137 // It would not be worth all of the overhead to directly 2138 // unlink from here. Using remove is fast enough. 2139 ConcurrentSkipListMap.this.remove(k); 2140 lastReturned = null; 2141 } 2142 } 2143 2144 final class ValueIterator extends Iter<V> { next()2145 public V next() { 2146 V v; 2147 if ((v = nextValue) == null) 2148 throw new NoSuchElementException(); 2149 advance(next); 2150 return v; 2151 } 2152 } 2153 2154 final class KeyIterator extends Iter<K> { next()2155 public K next() { 2156 Node<K,V> n; 2157 if ((n = next) == null) 2158 throw new NoSuchElementException(); 2159 K k = n.key; 2160 advance(n); 2161 return k; 2162 } 2163 } 2164 2165 final class EntryIterator extends Iter<Map.Entry<K,V>> { next()2166 public Map.Entry<K,V> next() { 2167 Node<K,V> n; 2168 if ((n = next) == null) 2169 throw new NoSuchElementException(); 2170 K k = n.key; 2171 V v = nextValue; 2172 advance(n); 2173 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); 2174 } 2175 } 2176 2177 /* ---------------- View Classes -------------- */ 2178 2179 /* 2180 * View classes are static, delegating to a ConcurrentNavigableMap 2181 * to allow use by SubMaps, which outweighs the ugliness of 2182 * needing type-tests for Iterator methods. 2183 */ 2184 toList(Collection<E> c)2185 static final <E> List<E> toList(Collection<E> c) { 2186 // Using size() here would be a pessimization. 2187 ArrayList<E> list = new ArrayList<E>(); 2188 for (E e : c) 2189 list.add(e); 2190 return list; 2191 } 2192 2193 static final class KeySet<K,V> 2194 extends AbstractSet<K> implements NavigableSet<K> { 2195 final ConcurrentNavigableMap<K,V> m; KeySet(ConcurrentNavigableMap<K,V> map)2196 KeySet(ConcurrentNavigableMap<K,V> map) { m = map; } size()2197 public int size() { return m.size(); } isEmpty()2198 public boolean isEmpty() { return m.isEmpty(); } contains(Object o)2199 public boolean contains(Object o) { return m.containsKey(o); } remove(Object o)2200 public boolean remove(Object o) { return m.remove(o) != null; } clear()2201 public void clear() { m.clear(); } lower(K e)2202 public K lower(K e) { return m.lowerKey(e); } floor(K e)2203 public K floor(K e) { return m.floorKey(e); } ceiling(K e)2204 public K ceiling(K e) { return m.ceilingKey(e); } higher(K e)2205 public K higher(K e) { return m.higherKey(e); } comparator()2206 public Comparator<? super K> comparator() { return m.comparator(); } first()2207 public K first() { return m.firstKey(); } last()2208 public K last() { return m.lastKey(); } pollFirst()2209 public K pollFirst() { 2210 Map.Entry<K,V> e = m.pollFirstEntry(); 2211 return (e == null) ? null : e.getKey(); 2212 } pollLast()2213 public K pollLast() { 2214 Map.Entry<K,V> e = m.pollLastEntry(); 2215 return (e == null) ? null : e.getKey(); 2216 } iterator()2217 public Iterator<K> iterator() { 2218 return (m instanceof ConcurrentSkipListMap) 2219 ? ((ConcurrentSkipListMap<K,V>)m).new KeyIterator() 2220 : ((SubMap<K,V>)m).new SubMapKeyIterator(); 2221 } equals(Object o)2222 public boolean equals(Object o) { 2223 if (o == this) 2224 return true; 2225 if (!(o instanceof Set)) 2226 return false; 2227 Collection<?> c = (Collection<?>) o; 2228 try { 2229 return containsAll(c) && c.containsAll(this); 2230 } catch (ClassCastException | NullPointerException unused) { 2231 return false; 2232 } 2233 } toArray()2234 public Object[] toArray() { return toList(this).toArray(); } toArray(T[] a)2235 public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } descendingIterator()2236 public Iterator<K> descendingIterator() { 2237 return descendingSet().iterator(); 2238 } subSet(K fromElement, boolean fromInclusive, K toElement, boolean toInclusive)2239 public NavigableSet<K> subSet(K fromElement, 2240 boolean fromInclusive, 2241 K toElement, 2242 boolean toInclusive) { 2243 return new KeySet<>(m.subMap(fromElement, fromInclusive, 2244 toElement, toInclusive)); 2245 } headSet(K toElement, boolean inclusive)2246 public NavigableSet<K> headSet(K toElement, boolean inclusive) { 2247 return new KeySet<>(m.headMap(toElement, inclusive)); 2248 } tailSet(K fromElement, boolean inclusive)2249 public NavigableSet<K> tailSet(K fromElement, boolean inclusive) { 2250 return new KeySet<>(m.tailMap(fromElement, inclusive)); 2251 } subSet(K fromElement, K toElement)2252 public NavigableSet<K> subSet(K fromElement, K toElement) { 2253 return subSet(fromElement, true, toElement, false); 2254 } headSet(K toElement)2255 public NavigableSet<K> headSet(K toElement) { 2256 return headSet(toElement, false); 2257 } tailSet(K fromElement)2258 public NavigableSet<K> tailSet(K fromElement) { 2259 return tailSet(fromElement, true); 2260 } descendingSet()2261 public NavigableSet<K> descendingSet() { 2262 return new KeySet<>(m.descendingMap()); 2263 } 2264 spliterator()2265 public Spliterator<K> spliterator() { 2266 return (m instanceof ConcurrentSkipListMap) 2267 ? ((ConcurrentSkipListMap<K,V>)m).keySpliterator() 2268 : ((SubMap<K,V>)m).new SubMapKeyIterator(); 2269 } 2270 } 2271 2272 static final class Values<K,V> extends AbstractCollection<V> { 2273 final ConcurrentNavigableMap<K,V> m; Values(ConcurrentNavigableMap<K,V> map)2274 Values(ConcurrentNavigableMap<K,V> map) { 2275 m = map; 2276 } iterator()2277 public Iterator<V> iterator() { 2278 return (m instanceof ConcurrentSkipListMap) 2279 ? ((ConcurrentSkipListMap<K,V>)m).new ValueIterator() 2280 : ((SubMap<K,V>)m).new SubMapValueIterator(); 2281 } size()2282 public int size() { return m.size(); } isEmpty()2283 public boolean isEmpty() { return m.isEmpty(); } contains(Object o)2284 public boolean contains(Object o) { return m.containsValue(o); } clear()2285 public void clear() { m.clear(); } toArray()2286 public Object[] toArray() { return toList(this).toArray(); } toArray(T[] a)2287 public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } 2288 spliterator()2289 public Spliterator<V> spliterator() { 2290 return (m instanceof ConcurrentSkipListMap) 2291 ? ((ConcurrentSkipListMap<K,V>)m).valueSpliterator() 2292 : ((SubMap<K,V>)m).new SubMapValueIterator(); 2293 } 2294 removeIf(Predicate<? super V> filter)2295 public boolean removeIf(Predicate<? super V> filter) { 2296 if (filter == null) throw new NullPointerException(); 2297 if (m instanceof ConcurrentSkipListMap) 2298 return ((ConcurrentSkipListMap<K,V>)m).removeValueIf(filter); 2299 // else use iterator 2300 Iterator<Map.Entry<K,V>> it = 2301 ((SubMap<K,V>)m).new SubMapEntryIterator(); 2302 boolean removed = false; 2303 while (it.hasNext()) { 2304 Map.Entry<K,V> e = it.next(); 2305 V v = e.getValue(); 2306 if (filter.test(v) && m.remove(e.getKey(), v)) 2307 removed = true; 2308 } 2309 return removed; 2310 } 2311 } 2312 2313 static final class EntrySet<K,V> extends AbstractSet<Map.Entry<K,V>> { 2314 final ConcurrentNavigableMap<K,V> m; EntrySet(ConcurrentNavigableMap<K,V> map)2315 EntrySet(ConcurrentNavigableMap<K,V> map) { 2316 m = map; 2317 } iterator()2318 public Iterator<Map.Entry<K,V>> iterator() { 2319 return (m instanceof ConcurrentSkipListMap) 2320 ? ((ConcurrentSkipListMap<K,V>)m).new EntryIterator() 2321 : ((SubMap<K,V>)m).new SubMapEntryIterator(); 2322 } 2323 contains(Object o)2324 public boolean contains(Object o) { 2325 if (!(o instanceof Map.Entry)) 2326 return false; 2327 Map.Entry<?,?> e = (Map.Entry<?,?>)o; 2328 V v = m.get(e.getKey()); 2329 return v != null && v.equals(e.getValue()); 2330 } remove(Object o)2331 public boolean remove(Object o) { 2332 if (!(o instanceof Map.Entry)) 2333 return false; 2334 Map.Entry<?,?> e = (Map.Entry<?,?>)o; 2335 return m.remove(e.getKey(), 2336 e.getValue()); 2337 } isEmpty()2338 public boolean isEmpty() { 2339 return m.isEmpty(); 2340 } size()2341 public int size() { 2342 return m.size(); 2343 } clear()2344 public void clear() { 2345 m.clear(); 2346 } equals(Object o)2347 public boolean equals(Object o) { 2348 if (o == this) 2349 return true; 2350 if (!(o instanceof Set)) 2351 return false; 2352 Collection<?> c = (Collection<?>) o; 2353 try { 2354 return containsAll(c) && c.containsAll(this); 2355 } catch (ClassCastException | NullPointerException unused) { 2356 return false; 2357 } 2358 } toArray()2359 public Object[] toArray() { return toList(this).toArray(); } toArray(T[] a)2360 public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } 2361 spliterator()2362 public Spliterator<Map.Entry<K,V>> spliterator() { 2363 return (m instanceof ConcurrentSkipListMap) 2364 ? ((ConcurrentSkipListMap<K,V>)m).entrySpliterator() 2365 : ((SubMap<K,V>)m).new SubMapEntryIterator(); 2366 } removeIf(Predicate<? super Entry<K,V>> filter)2367 public boolean removeIf(Predicate<? super Entry<K,V>> filter) { 2368 if (filter == null) throw new NullPointerException(); 2369 if (m instanceof ConcurrentSkipListMap) 2370 return ((ConcurrentSkipListMap<K,V>)m).removeEntryIf(filter); 2371 // else use iterator 2372 Iterator<Map.Entry<K,V>> it = 2373 ((SubMap<K,V>)m).new SubMapEntryIterator(); 2374 boolean removed = false; 2375 while (it.hasNext()) { 2376 Map.Entry<K,V> e = it.next(); 2377 if (filter.test(e) && m.remove(e.getKey(), e.getValue())) 2378 removed = true; 2379 } 2380 return removed; 2381 } 2382 } 2383 2384 /** 2385 * Submaps returned by {@link ConcurrentSkipListMap} submap operations 2386 * represent a subrange of mappings of their underlying maps. 2387 * Instances of this class support all methods of their underlying 2388 * maps, differing in that mappings outside their range are ignored, 2389 * and attempts to add mappings outside their ranges result in {@link 2390 * IllegalArgumentException}. Instances of this class are constructed 2391 * only using the {@code subMap}, {@code headMap}, and {@code tailMap} 2392 * methods of their underlying maps. 2393 * 2394 * @serial include 2395 */ 2396 static final class SubMap<K,V> extends AbstractMap<K,V> 2397 implements ConcurrentNavigableMap<K,V>, Serializable { 2398 private static final long serialVersionUID = -7647078645895051609L; 2399 2400 /** Underlying map */ 2401 final ConcurrentSkipListMap<K,V> m; 2402 /** lower bound key, or null if from start */ 2403 @SuppressWarnings("serial") // Conditionally serializable 2404 private final K lo; 2405 /** upper bound key, or null if to end */ 2406 @SuppressWarnings("serial") // Conditionally serializable 2407 private final K hi; 2408 /** inclusion flag for lo */ 2409 private final boolean loInclusive; 2410 /** inclusion flag for hi */ 2411 private final boolean hiInclusive; 2412 /** direction */ 2413 final boolean isDescending; 2414 2415 // Lazily initialized view holders 2416 private transient KeySet<K,V> keySetView; 2417 private transient Values<K,V> valuesView; 2418 private transient EntrySet<K,V> entrySetView; 2419 2420 /** 2421 * Creates a new submap, initializing all fields. 2422 */ SubMap(ConcurrentSkipListMap<K,V> map, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive, boolean isDescending)2423 SubMap(ConcurrentSkipListMap<K,V> map, 2424 K fromKey, boolean fromInclusive, 2425 K toKey, boolean toInclusive, 2426 boolean isDescending) { 2427 Comparator<? super K> cmp = map.comparator; 2428 if (fromKey != null && toKey != null && 2429 cpr(cmp, fromKey, toKey) > 0) 2430 throw new IllegalArgumentException("inconsistent range"); 2431 this.m = map; 2432 this.lo = fromKey; 2433 this.hi = toKey; 2434 this.loInclusive = fromInclusive; 2435 this.hiInclusive = toInclusive; 2436 this.isDescending = isDescending; 2437 } 2438 2439 /* ---------------- Utilities -------------- */ 2440 tooLow(Object key, Comparator<? super K> cmp)2441 boolean tooLow(Object key, Comparator<? super K> cmp) { 2442 int c; 2443 return (lo != null && ((c = cpr(cmp, key, lo)) < 0 || 2444 (c == 0 && !loInclusive))); 2445 } 2446 tooHigh(Object key, Comparator<? super K> cmp)2447 boolean tooHigh(Object key, Comparator<? super K> cmp) { 2448 int c; 2449 return (hi != null && ((c = cpr(cmp, key, hi)) > 0 || 2450 (c == 0 && !hiInclusive))); 2451 } 2452 inBounds(Object key, Comparator<? super K> cmp)2453 boolean inBounds(Object key, Comparator<? super K> cmp) { 2454 return !tooLow(key, cmp) && !tooHigh(key, cmp); 2455 } 2456 checkKeyBounds(K key, Comparator<? super K> cmp)2457 void checkKeyBounds(K key, Comparator<? super K> cmp) { 2458 if (key == null) 2459 throw new NullPointerException(); 2460 if (!inBounds(key, cmp)) 2461 throw new IllegalArgumentException("key out of range"); 2462 } 2463 2464 /** 2465 * Returns true if node key is less than upper bound of range. 2466 */ isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n, Comparator<? super K> cmp)2467 boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n, 2468 Comparator<? super K> cmp) { 2469 if (n == null) 2470 return false; 2471 if (hi == null) 2472 return true; 2473 K k = n.key; 2474 if (k == null) // pass by markers and headers 2475 return true; 2476 int c = cpr(cmp, k, hi); 2477 return c < 0 || (c == 0 && hiInclusive); 2478 } 2479 2480 /** 2481 * Returns lowest node. This node might not be in range, so 2482 * most usages need to check bounds. 2483 */ loNode(Comparator<? super K> cmp)2484 ConcurrentSkipListMap.Node<K,V> loNode(Comparator<? super K> cmp) { 2485 if (lo == null) 2486 return m.findFirst(); 2487 else if (loInclusive) 2488 return m.findNear(lo, GT|EQ, cmp); 2489 else 2490 return m.findNear(lo, GT, cmp); 2491 } 2492 2493 /** 2494 * Returns highest node. This node might not be in range, so 2495 * most usages need to check bounds. 2496 */ hiNode(Comparator<? super K> cmp)2497 ConcurrentSkipListMap.Node<K,V> hiNode(Comparator<? super K> cmp) { 2498 if (hi == null) 2499 return m.findLast(); 2500 else if (hiInclusive) 2501 return m.findNear(hi, LT|EQ, cmp); 2502 else 2503 return m.findNear(hi, LT, cmp); 2504 } 2505 2506 /** 2507 * Returns lowest absolute key (ignoring directionality). 2508 */ lowestKey()2509 K lowestKey() { 2510 Comparator<? super K> cmp = m.comparator; 2511 ConcurrentSkipListMap.Node<K,V> n = loNode(cmp); 2512 if (isBeforeEnd(n, cmp)) 2513 return n.key; 2514 else 2515 throw new NoSuchElementException(); 2516 } 2517 2518 /** 2519 * Returns highest absolute key (ignoring directionality). 2520 */ highestKey()2521 K highestKey() { 2522 Comparator<? super K> cmp = m.comparator; 2523 ConcurrentSkipListMap.Node<K,V> n = hiNode(cmp); 2524 if (n != null) { 2525 K last = n.key; 2526 if (inBounds(last, cmp)) 2527 return last; 2528 } 2529 throw new NoSuchElementException(); 2530 } 2531 lowestEntry()2532 Map.Entry<K,V> lowestEntry() { 2533 Comparator<? super K> cmp = m.comparator; 2534 for (;;) { 2535 ConcurrentSkipListMap.Node<K,V> n; V v; 2536 if ((n = loNode(cmp)) == null || !isBeforeEnd(n, cmp)) 2537 return null; 2538 else if ((v = n.val) != null) 2539 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); 2540 } 2541 } 2542 highestEntry()2543 Map.Entry<K,V> highestEntry() { 2544 Comparator<? super K> cmp = m.comparator; 2545 for (;;) { 2546 ConcurrentSkipListMap.Node<K,V> n; V v; 2547 if ((n = hiNode(cmp)) == null || !inBounds(n.key, cmp)) 2548 return null; 2549 else if ((v = n.val) != null) 2550 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); 2551 } 2552 } 2553 removeLowest()2554 Map.Entry<K,V> removeLowest() { 2555 Comparator<? super K> cmp = m.comparator; 2556 for (;;) { 2557 ConcurrentSkipListMap.Node<K,V> n; K k; V v; 2558 if ((n = loNode(cmp)) == null) 2559 return null; 2560 else if (!inBounds((k = n.key), cmp)) 2561 return null; 2562 else if ((v = m.doRemove(k, null)) != null) 2563 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); 2564 } 2565 } 2566 removeHighest()2567 Map.Entry<K,V> removeHighest() { 2568 Comparator<? super K> cmp = m.comparator; 2569 for (;;) { 2570 ConcurrentSkipListMap.Node<K,V> n; K k; V v; 2571 if ((n = hiNode(cmp)) == null) 2572 return null; 2573 else if (!inBounds((k = n.key), cmp)) 2574 return null; 2575 else if ((v = m.doRemove(k, null)) != null) 2576 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); 2577 } 2578 } 2579 2580 /** 2581 * Submap version of ConcurrentSkipListMap.findNearEntry. 2582 */ getNearEntry(K key, int rel)2583 Map.Entry<K,V> getNearEntry(K key, int rel) { 2584 Comparator<? super K> cmp = m.comparator; 2585 if (isDescending) { // adjust relation for direction 2586 if ((rel & LT) == 0) 2587 rel |= LT; 2588 else 2589 rel &= ~LT; 2590 } 2591 if (tooLow(key, cmp)) 2592 return ((rel & LT) != 0) ? null : lowestEntry(); 2593 if (tooHigh(key, cmp)) 2594 return ((rel & LT) != 0) ? highestEntry() : null; 2595 AbstractMap.SimpleImmutableEntry<K,V> e = 2596 m.findNearEntry(key, rel, cmp); 2597 if (e == null || !inBounds(e.getKey(), cmp)) 2598 return null; 2599 else 2600 return e; 2601 } 2602 2603 // Almost the same as getNearEntry, except for keys getNearKey(K key, int rel)2604 K getNearKey(K key, int rel) { 2605 Comparator<? super K> cmp = m.comparator; 2606 if (isDescending) { // adjust relation for direction 2607 if ((rel & LT) == 0) 2608 rel |= LT; 2609 else 2610 rel &= ~LT; 2611 } 2612 if (tooLow(key, cmp)) { 2613 if ((rel & LT) == 0) { 2614 ConcurrentSkipListMap.Node<K,V> n = loNode(cmp); 2615 if (isBeforeEnd(n, cmp)) 2616 return n.key; 2617 } 2618 return null; 2619 } 2620 if (tooHigh(key, cmp)) { 2621 if ((rel & LT) != 0) { 2622 ConcurrentSkipListMap.Node<K,V> n = hiNode(cmp); 2623 if (n != null) { 2624 K last = n.key; 2625 if (inBounds(last, cmp)) 2626 return last; 2627 } 2628 } 2629 return null; 2630 } 2631 for (;;) { 2632 Node<K,V> n = m.findNear(key, rel, cmp); 2633 if (n == null || !inBounds(n.key, cmp)) 2634 return null; 2635 if (n.val != null) 2636 return n.key; 2637 } 2638 } 2639 2640 /* ---------------- Map API methods -------------- */ 2641 containsKey(Object key)2642 public boolean containsKey(Object key) { 2643 if (key == null) throw new NullPointerException(); 2644 return inBounds(key, m.comparator) && m.containsKey(key); 2645 } 2646 get(Object key)2647 public V get(Object key) { 2648 if (key == null) throw new NullPointerException(); 2649 return (!inBounds(key, m.comparator)) ? null : m.get(key); 2650 } 2651 put(K key, V value)2652 public V put(K key, V value) { 2653 checkKeyBounds(key, m.comparator); 2654 return m.put(key, value); 2655 } 2656 remove(Object key)2657 public V remove(Object key) { 2658 return (!inBounds(key, m.comparator)) ? null : m.remove(key); 2659 } 2660 size()2661 public int size() { 2662 Comparator<? super K> cmp = m.comparator; 2663 long count = 0; 2664 for (ConcurrentSkipListMap.Node<K,V> n = loNode(cmp); 2665 isBeforeEnd(n, cmp); 2666 n = n.next) { 2667 if (n.val != null) 2668 ++count; 2669 } 2670 return count >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)count; 2671 } 2672 isEmpty()2673 public boolean isEmpty() { 2674 Comparator<? super K> cmp = m.comparator; 2675 return !isBeforeEnd(loNode(cmp), cmp); 2676 } 2677 containsValue(Object value)2678 public boolean containsValue(Object value) { 2679 if (value == null) 2680 throw new NullPointerException(); 2681 Comparator<? super K> cmp = m.comparator; 2682 for (ConcurrentSkipListMap.Node<K,V> n = loNode(cmp); 2683 isBeforeEnd(n, cmp); 2684 n = n.next) { 2685 V v = n.val; 2686 if (v != null && value.equals(v)) 2687 return true; 2688 } 2689 return false; 2690 } 2691 clear()2692 public void clear() { 2693 Comparator<? super K> cmp = m.comparator; 2694 for (ConcurrentSkipListMap.Node<K,V> n = loNode(cmp); 2695 isBeforeEnd(n, cmp); 2696 n = n.next) { 2697 if (n.val != null) 2698 m.remove(n.key); 2699 } 2700 } 2701 2702 /* ---------------- ConcurrentMap API methods -------------- */ 2703 putIfAbsent(K key, V value)2704 public V putIfAbsent(K key, V value) { 2705 checkKeyBounds(key, m.comparator); 2706 return m.putIfAbsent(key, value); 2707 } 2708 remove(Object key, Object value)2709 public boolean remove(Object key, Object value) { 2710 return inBounds(key, m.comparator) && m.remove(key, value); 2711 } 2712 replace(K key, V oldValue, V newValue)2713 public boolean replace(K key, V oldValue, V newValue) { 2714 checkKeyBounds(key, m.comparator); 2715 return m.replace(key, oldValue, newValue); 2716 } 2717 replace(K key, V value)2718 public V replace(K key, V value) { 2719 checkKeyBounds(key, m.comparator); 2720 return m.replace(key, value); 2721 } 2722 2723 /* ---------------- SortedMap API methods -------------- */ 2724 comparator()2725 public Comparator<? super K> comparator() { 2726 Comparator<? super K> cmp = m.comparator(); 2727 if (isDescending) 2728 return Collections.reverseOrder(cmp); 2729 else 2730 return cmp; 2731 } 2732 2733 /** 2734 * Utility to create submaps, where given bounds override 2735 * unbounded(null) ones and/or are checked against bounded ones. 2736 */ newSubMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)2737 SubMap<K,V> newSubMap(K fromKey, boolean fromInclusive, 2738 K toKey, boolean toInclusive) { 2739 Comparator<? super K> cmp = m.comparator; 2740 if (isDescending) { // flip senses 2741 K tk = fromKey; 2742 fromKey = toKey; 2743 toKey = tk; 2744 boolean ti = fromInclusive; 2745 fromInclusive = toInclusive; 2746 toInclusive = ti; 2747 } 2748 if (lo != null) { 2749 if (fromKey == null) { 2750 fromKey = lo; 2751 fromInclusive = loInclusive; 2752 } 2753 else { 2754 int c = cpr(cmp, fromKey, lo); 2755 if (c < 0 || (c == 0 && !loInclusive && fromInclusive)) 2756 throw new IllegalArgumentException("key out of range"); 2757 } 2758 } 2759 if (hi != null) { 2760 if (toKey == null) { 2761 toKey = hi; 2762 toInclusive = hiInclusive; 2763 } 2764 else { 2765 int c = cpr(cmp, toKey, hi); 2766 if (c > 0 || (c == 0 && !hiInclusive && toInclusive)) 2767 throw new IllegalArgumentException("key out of range"); 2768 } 2769 } 2770 return new SubMap<K,V>(m, fromKey, fromInclusive, 2771 toKey, toInclusive, isDescending); 2772 } 2773 subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)2774 public SubMap<K,V> subMap(K fromKey, boolean fromInclusive, 2775 K toKey, boolean toInclusive) { 2776 if (fromKey == null || toKey == null) 2777 throw new NullPointerException(); 2778 return newSubMap(fromKey, fromInclusive, toKey, toInclusive); 2779 } 2780 headMap(K toKey, boolean inclusive)2781 public SubMap<K,V> headMap(K toKey, boolean inclusive) { 2782 if (toKey == null) 2783 throw new NullPointerException(); 2784 return newSubMap(null, false, toKey, inclusive); 2785 } 2786 tailMap(K fromKey, boolean inclusive)2787 public SubMap<K,V> tailMap(K fromKey, boolean inclusive) { 2788 if (fromKey == null) 2789 throw new NullPointerException(); 2790 return newSubMap(fromKey, inclusive, null, false); 2791 } 2792 subMap(K fromKey, K toKey)2793 public SubMap<K,V> subMap(K fromKey, K toKey) { 2794 return subMap(fromKey, true, toKey, false); 2795 } 2796 headMap(K toKey)2797 public SubMap<K,V> headMap(K toKey) { 2798 return headMap(toKey, false); 2799 } 2800 tailMap(K fromKey)2801 public SubMap<K,V> tailMap(K fromKey) { 2802 return tailMap(fromKey, true); 2803 } 2804 descendingMap()2805 public SubMap<K,V> descendingMap() { 2806 return new SubMap<K,V>(m, lo, loInclusive, 2807 hi, hiInclusive, !isDescending); 2808 } 2809 2810 /* ---------------- Relational methods -------------- */ 2811 ceilingEntry(K key)2812 public Map.Entry<K,V> ceilingEntry(K key) { 2813 return getNearEntry(key, GT|EQ); 2814 } 2815 ceilingKey(K key)2816 public K ceilingKey(K key) { 2817 return getNearKey(key, GT|EQ); 2818 } 2819 lowerEntry(K key)2820 public Map.Entry<K,V> lowerEntry(K key) { 2821 return getNearEntry(key, LT); 2822 } 2823 lowerKey(K key)2824 public K lowerKey(K key) { 2825 return getNearKey(key, LT); 2826 } 2827 floorEntry(K key)2828 public Map.Entry<K,V> floorEntry(K key) { 2829 return getNearEntry(key, LT|EQ); 2830 } 2831 floorKey(K key)2832 public K floorKey(K key) { 2833 return getNearKey(key, LT|EQ); 2834 } 2835 higherEntry(K key)2836 public Map.Entry<K,V> higherEntry(K key) { 2837 return getNearEntry(key, GT); 2838 } 2839 higherKey(K key)2840 public K higherKey(K key) { 2841 return getNearKey(key, GT); 2842 } 2843 firstKey()2844 public K firstKey() { 2845 return isDescending ? highestKey() : lowestKey(); 2846 } 2847 lastKey()2848 public K lastKey() { 2849 return isDescending ? lowestKey() : highestKey(); 2850 } 2851 firstEntry()2852 public Map.Entry<K,V> firstEntry() { 2853 return isDescending ? highestEntry() : lowestEntry(); 2854 } 2855 lastEntry()2856 public Map.Entry<K,V> lastEntry() { 2857 return isDescending ? lowestEntry() : highestEntry(); 2858 } 2859 pollFirstEntry()2860 public Map.Entry<K,V> pollFirstEntry() { 2861 return isDescending ? removeHighest() : removeLowest(); 2862 } 2863 pollLastEntry()2864 public Map.Entry<K,V> pollLastEntry() { 2865 return isDescending ? removeLowest() : removeHighest(); 2866 } 2867 2868 /* ---------------- Submap Views -------------- */ 2869 keySet()2870 public NavigableSet<K> keySet() { 2871 KeySet<K,V> ks; 2872 if ((ks = keySetView) != null) return ks; 2873 return keySetView = new KeySet<>(this); 2874 } 2875 navigableKeySet()2876 public NavigableSet<K> navigableKeySet() { 2877 KeySet<K,V> ks; 2878 if ((ks = keySetView) != null) return ks; 2879 return keySetView = new KeySet<>(this); 2880 } 2881 values()2882 public Collection<V> values() { 2883 Values<K,V> vs; 2884 if ((vs = valuesView) != null) return vs; 2885 return valuesView = new Values<>(this); 2886 } 2887 entrySet()2888 public Set<Map.Entry<K,V>> entrySet() { 2889 EntrySet<K,V> es; 2890 if ((es = entrySetView) != null) return es; 2891 return entrySetView = new EntrySet<K,V>(this); 2892 } 2893 descendingKeySet()2894 public NavigableSet<K> descendingKeySet() { 2895 return descendingMap().navigableKeySet(); 2896 } 2897 2898 /** 2899 * Variant of main Iter class to traverse through submaps. 2900 * Also serves as back-up Spliterator for views. 2901 */ 2902 abstract class SubMapIter<T> implements Iterator<T>, Spliterator<T> { 2903 /** the last node returned by next() */ 2904 Node<K,V> lastReturned; 2905 /** the next node to return from next(); */ 2906 Node<K,V> next; 2907 /** Cache of next value field to maintain weak consistency */ 2908 V nextValue; 2909 SubMapIter()2910 SubMapIter() { 2911 VarHandle.acquireFence(); 2912 Comparator<? super K> cmp = m.comparator; 2913 for (;;) { 2914 next = isDescending ? hiNode(cmp) : loNode(cmp); 2915 if (next == null) 2916 break; 2917 V x = next.val; 2918 if (x != null) { 2919 if (! inBounds(next.key, cmp)) 2920 next = null; 2921 else 2922 nextValue = x; 2923 break; 2924 } 2925 } 2926 } 2927 hasNext()2928 public final boolean hasNext() { 2929 return next != null; 2930 } 2931 advance()2932 final void advance() { 2933 if (next == null) 2934 throw new NoSuchElementException(); 2935 lastReturned = next; 2936 if (isDescending) 2937 descend(); 2938 else 2939 ascend(); 2940 } 2941 ascend()2942 private void ascend() { 2943 Comparator<? super K> cmp = m.comparator; 2944 for (;;) { 2945 next = next.next; 2946 if (next == null) 2947 break; 2948 V x = next.val; 2949 if (x != null) { 2950 if (tooHigh(next.key, cmp)) 2951 next = null; 2952 else 2953 nextValue = x; 2954 break; 2955 } 2956 } 2957 } 2958 descend()2959 private void descend() { 2960 Comparator<? super K> cmp = m.comparator; 2961 for (;;) { 2962 next = m.findNear(lastReturned.key, LT, cmp); 2963 if (next == null) 2964 break; 2965 V x = next.val; 2966 if (x != null) { 2967 if (tooLow(next.key, cmp)) 2968 next = null; 2969 else 2970 nextValue = x; 2971 break; 2972 } 2973 } 2974 } 2975 remove()2976 public void remove() { 2977 Node<K,V> l = lastReturned; 2978 if (l == null) 2979 throw new IllegalStateException(); 2980 m.remove(l.key); 2981 lastReturned = null; 2982 } 2983 trySplit()2984 public Spliterator<T> trySplit() { 2985 return null; 2986 } 2987 tryAdvance(Consumer<? super T> action)2988 public boolean tryAdvance(Consumer<? super T> action) { 2989 if (hasNext()) { 2990 action.accept(next()); 2991 return true; 2992 } 2993 return false; 2994 } 2995 forEachRemaining(Consumer<? super T> action)2996 public void forEachRemaining(Consumer<? super T> action) { 2997 while (hasNext()) 2998 action.accept(next()); 2999 } 3000 estimateSize()3001 public long estimateSize() { 3002 return Long.MAX_VALUE; 3003 } 3004 3005 } 3006 3007 final class SubMapValueIterator extends SubMapIter<V> { next()3008 public V next() { 3009 V v = nextValue; 3010 advance(); 3011 return v; 3012 } characteristics()3013 public int characteristics() { 3014 return 0; 3015 } 3016 } 3017 3018 final class SubMapKeyIterator extends SubMapIter<K> { next()3019 public K next() { 3020 Node<K,V> n = next; 3021 advance(); 3022 return n.key; 3023 } characteristics()3024 public int characteristics() { 3025 return Spliterator.DISTINCT | Spliterator.ORDERED | 3026 Spliterator.SORTED; 3027 } getComparator()3028 public final Comparator<? super K> getComparator() { 3029 return SubMap.this.comparator(); 3030 } 3031 } 3032 3033 final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> { next()3034 public Map.Entry<K,V> next() { 3035 Node<K,V> n = next; 3036 V v = nextValue; 3037 advance(); 3038 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); 3039 } characteristics()3040 public int characteristics() { 3041 return Spliterator.DISTINCT; 3042 } 3043 } 3044 } 3045 3046 // default Map method overrides 3047 forEach(BiConsumer<? super K, ? super V> action)3048 public void forEach(BiConsumer<? super K, ? super V> action) { 3049 if (action == null) throw new NullPointerException(); 3050 Node<K,V> b, n; V v; 3051 if ((b = baseHead()) != null) { 3052 while ((n = b.next) != null) { 3053 if ((v = n.val) != null) 3054 action.accept(n.key, v); 3055 b = n; 3056 } 3057 } 3058 } 3059 replaceAll(BiFunction<? super K, ? super V, ? extends V> function)3060 public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { 3061 if (function == null) throw new NullPointerException(); 3062 Node<K,V> b, n; V v; 3063 if ((b = baseHead()) != null) { 3064 while ((n = b.next) != null) { 3065 while ((v = n.val) != null) { 3066 V r = function.apply(n.key, v); 3067 if (r == null) throw new NullPointerException(); 3068 if (VAL.compareAndSet(n, v, r)) 3069 break; 3070 } 3071 b = n; 3072 } 3073 } 3074 } 3075 3076 /** 3077 * Helper method for EntrySet.removeIf. 3078 */ removeEntryIf(Predicate<? super Entry<K,V>> function)3079 boolean removeEntryIf(Predicate<? super Entry<K,V>> function) { 3080 if (function == null) throw new NullPointerException(); 3081 boolean removed = false; 3082 Node<K,V> b, n; V v; 3083 if ((b = baseHead()) != null) { 3084 while ((n = b.next) != null) { 3085 if ((v = n.val) != null) { 3086 K k = n.key; 3087 Map.Entry<K,V> e = new AbstractMap.SimpleImmutableEntry<>(k, v); 3088 if (function.test(e) && remove(k, v)) 3089 removed = true; 3090 } 3091 b = n; 3092 } 3093 } 3094 return removed; 3095 } 3096 3097 /** 3098 * Helper method for Values.removeIf. 3099 */ removeValueIf(Predicate<? super V> function)3100 boolean removeValueIf(Predicate<? super V> function) { 3101 if (function == null) throw new NullPointerException(); 3102 boolean removed = false; 3103 Node<K,V> b, n; V v; 3104 if ((b = baseHead()) != null) { 3105 while ((n = b.next) != null) { 3106 if ((v = n.val) != null && function.test(v) && remove(n.key, v)) 3107 removed = true; 3108 b = n; 3109 } 3110 } 3111 return removed; 3112 } 3113 3114 /** 3115 * Base class providing common structure for Spliterators. 3116 * (Although not all that much common functionality; as usual for 3117 * view classes, details annoyingly vary in key, value, and entry 3118 * subclasses in ways that are not worth abstracting out for 3119 * internal classes.) 3120 * 3121 * The basic split strategy is to recursively descend from top 3122 * level, row by row, descending to next row when either split 3123 * off, or the end of row is encountered. Control of the number of 3124 * splits relies on some statistical estimation: The expected 3125 * remaining number of elements of a skip list when advancing 3126 * either across or down decreases by about 25%. 3127 */ 3128 abstract static class CSLMSpliterator<K,V> { 3129 final Comparator<? super K> comparator; 3130 final K fence; // exclusive upper bound for keys, or null if to end 3131 Index<K,V> row; // the level to split out 3132 Node<K,V> current; // current traversal node; initialize at origin 3133 long est; // size estimate CSLMSpliterator(Comparator<? super K> comparator, Index<K,V> row, Node<K,V> origin, K fence, long est)3134 CSLMSpliterator(Comparator<? super K> comparator, Index<K,V> row, 3135 Node<K,V> origin, K fence, long est) { 3136 this.comparator = comparator; this.row = row; 3137 this.current = origin; this.fence = fence; this.est = est; 3138 } 3139 estimateSize()3140 public final long estimateSize() { return est; } 3141 } 3142 3143 static final class KeySpliterator<K,V> extends CSLMSpliterator<K,V> 3144 implements Spliterator<K> { KeySpliterator(Comparator<? super K> comparator, Index<K,V> row, Node<K,V> origin, K fence, long est)3145 KeySpliterator(Comparator<? super K> comparator, Index<K,V> row, 3146 Node<K,V> origin, K fence, long est) { 3147 super(comparator, row, origin, fence, est); 3148 } 3149 trySplit()3150 public KeySpliterator<K,V> trySplit() { 3151 Node<K,V> e; K ek; 3152 Comparator<? super K> cmp = comparator; 3153 K f = fence; 3154 if ((e = current) != null && (ek = e.key) != null) { 3155 for (Index<K,V> q = row; q != null; q = row = q.down) { 3156 Index<K,V> s; Node<K,V> b, n; K sk; 3157 if ((s = q.right) != null && (b = s.node) != null && 3158 (n = b.next) != null && n.val != null && 3159 (sk = n.key) != null && cpr(cmp, sk, ek) > 0 && 3160 (f == null || cpr(cmp, sk, f) < 0)) { 3161 current = n; 3162 Index<K,V> r = q.down; 3163 row = (s.right != null) ? s : s.down; 3164 est -= est >>> 2; 3165 return new KeySpliterator<K,V>(cmp, r, e, sk, est); 3166 } 3167 } 3168 } 3169 return null; 3170 } 3171 forEachRemaining(Consumer<? super K> action)3172 public void forEachRemaining(Consumer<? super K> action) { 3173 if (action == null) throw new NullPointerException(); 3174 Comparator<? super K> cmp = comparator; 3175 K f = fence; 3176 Node<K,V> e = current; 3177 current = null; 3178 for (; e != null; e = e.next) { 3179 K k; 3180 if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) 3181 break; 3182 if (e.val != null) 3183 action.accept(k); 3184 } 3185 } 3186 tryAdvance(Consumer<? super K> action)3187 public boolean tryAdvance(Consumer<? super K> action) { 3188 if (action == null) throw new NullPointerException(); 3189 Comparator<? super K> cmp = comparator; 3190 K f = fence; 3191 Node<K,V> e = current; 3192 for (; e != null; e = e.next) { 3193 K k; 3194 if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) { 3195 e = null; 3196 break; 3197 } 3198 if (e.val != null) { 3199 current = e.next; 3200 action.accept(k); 3201 return true; 3202 } 3203 } 3204 current = e; 3205 return false; 3206 } 3207 characteristics()3208 public int characteristics() { 3209 return Spliterator.DISTINCT | Spliterator.SORTED | 3210 Spliterator.ORDERED | Spliterator.CONCURRENT | 3211 Spliterator.NONNULL; 3212 } 3213 getComparator()3214 public final Comparator<? super K> getComparator() { 3215 return comparator; 3216 } 3217 } 3218 // factory method for KeySpliterator keySpliterator()3219 final KeySpliterator<K,V> keySpliterator() { 3220 Index<K,V> h; Node<K,V> n; long est; 3221 VarHandle.acquireFence(); 3222 if ((h = head) == null) { 3223 n = null; 3224 est = 0L; 3225 } 3226 else { 3227 n = h.node; 3228 est = getAdderCount(); 3229 } 3230 return new KeySpliterator<K,V>(comparator, h, n, null, est); 3231 } 3232 3233 static final class ValueSpliterator<K,V> extends CSLMSpliterator<K,V> 3234 implements Spliterator<V> { ValueSpliterator(Comparator<? super K> comparator, Index<K,V> row, Node<K,V> origin, K fence, long est)3235 ValueSpliterator(Comparator<? super K> comparator, Index<K,V> row, 3236 Node<K,V> origin, K fence, long est) { 3237 super(comparator, row, origin, fence, est); 3238 } 3239 trySplit()3240 public ValueSpliterator<K,V> trySplit() { 3241 Node<K,V> e; K ek; 3242 Comparator<? super K> cmp = comparator; 3243 K f = fence; 3244 if ((e = current) != null && (ek = e.key) != null) { 3245 for (Index<K,V> q = row; q != null; q = row = q.down) { 3246 Index<K,V> s; Node<K,V> b, n; K sk; 3247 if ((s = q.right) != null && (b = s.node) != null && 3248 (n = b.next) != null && n.val != null && 3249 (sk = n.key) != null && cpr(cmp, sk, ek) > 0 && 3250 (f == null || cpr(cmp, sk, f) < 0)) { 3251 current = n; 3252 Index<K,V> r = q.down; 3253 row = (s.right != null) ? s : s.down; 3254 est -= est >>> 2; 3255 return new ValueSpliterator<K,V>(cmp, r, e, sk, est); 3256 } 3257 } 3258 } 3259 return null; 3260 } 3261 forEachRemaining(Consumer<? super V> action)3262 public void forEachRemaining(Consumer<? super V> action) { 3263 if (action == null) throw new NullPointerException(); 3264 Comparator<? super K> cmp = comparator; 3265 K f = fence; 3266 Node<K,V> e = current; 3267 current = null; 3268 for (; e != null; e = e.next) { 3269 K k; V v; 3270 if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) 3271 break; 3272 if ((v = e.val) != null) 3273 action.accept(v); 3274 } 3275 } 3276 tryAdvance(Consumer<? super V> action)3277 public boolean tryAdvance(Consumer<? super V> action) { 3278 if (action == null) throw new NullPointerException(); 3279 Comparator<? super K> cmp = comparator; 3280 K f = fence; 3281 Node<K,V> e = current; 3282 for (; e != null; e = e.next) { 3283 K k; V v; 3284 if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) { 3285 e = null; 3286 break; 3287 } 3288 if ((v = e.val) != null) { 3289 current = e.next; 3290 action.accept(v); 3291 return true; 3292 } 3293 } 3294 current = e; 3295 return false; 3296 } 3297 characteristics()3298 public int characteristics() { 3299 return Spliterator.CONCURRENT | Spliterator.ORDERED | 3300 Spliterator.NONNULL; 3301 } 3302 } 3303 3304 // Almost the same as keySpliterator() valueSpliterator()3305 final ValueSpliterator<K,V> valueSpliterator() { 3306 Index<K,V> h; Node<K,V> n; long est; 3307 VarHandle.acquireFence(); 3308 if ((h = head) == null) { 3309 n = null; 3310 est = 0L; 3311 } 3312 else { 3313 n = h.node; 3314 est = getAdderCount(); 3315 } 3316 return new ValueSpliterator<K,V>(comparator, h, n, null, est); 3317 } 3318 3319 static final class EntrySpliterator<K,V> extends CSLMSpliterator<K,V> 3320 implements Spliterator<Map.Entry<K,V>> { EntrySpliterator(Comparator<? super K> comparator, Index<K,V> row, Node<K,V> origin, K fence, long est)3321 EntrySpliterator(Comparator<? super K> comparator, Index<K,V> row, 3322 Node<K,V> origin, K fence, long est) { 3323 super(comparator, row, origin, fence, est); 3324 } 3325 trySplit()3326 public EntrySpliterator<K,V> trySplit() { 3327 Node<K,V> e; K ek; 3328 Comparator<? super K> cmp = comparator; 3329 K f = fence; 3330 if ((e = current) != null && (ek = e.key) != null) { 3331 for (Index<K,V> q = row; q != null; q = row = q.down) { 3332 Index<K,V> s; Node<K,V> b, n; K sk; 3333 if ((s = q.right) != null && (b = s.node) != null && 3334 (n = b.next) != null && n.val != null && 3335 (sk = n.key) != null && cpr(cmp, sk, ek) > 0 && 3336 (f == null || cpr(cmp, sk, f) < 0)) { 3337 current = n; 3338 Index<K,V> r = q.down; 3339 row = (s.right != null) ? s : s.down; 3340 est -= est >>> 2; 3341 return new EntrySpliterator<K,V>(cmp, r, e, sk, est); 3342 } 3343 } 3344 } 3345 return null; 3346 } 3347 forEachRemaining(Consumer<? super Map.Entry<K,V>> action)3348 public void forEachRemaining(Consumer<? super Map.Entry<K,V>> action) { 3349 if (action == null) throw new NullPointerException(); 3350 Comparator<? super K> cmp = comparator; 3351 K f = fence; 3352 Node<K,V> e = current; 3353 current = null; 3354 for (; e != null; e = e.next) { 3355 K k; V v; 3356 if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) 3357 break; 3358 if ((v = e.val) != null) { 3359 action.accept 3360 (new AbstractMap.SimpleImmutableEntry<K,V>(k, v)); 3361 } 3362 } 3363 } 3364 tryAdvance(Consumer<? super Map.Entry<K,V>> action)3365 public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) { 3366 if (action == null) throw new NullPointerException(); 3367 Comparator<? super K> cmp = comparator; 3368 K f = fence; 3369 Node<K,V> e = current; 3370 for (; e != null; e = e.next) { 3371 K k; V v; 3372 if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) { 3373 e = null; 3374 break; 3375 } 3376 if ((v = e.val) != null) { 3377 current = e.next; 3378 action.accept 3379 (new AbstractMap.SimpleImmutableEntry<K,V>(k, v)); 3380 return true; 3381 } 3382 } 3383 current = e; 3384 return false; 3385 } 3386 characteristics()3387 public int characteristics() { 3388 return Spliterator.DISTINCT | Spliterator.SORTED | 3389 Spliterator.ORDERED | Spliterator.CONCURRENT | 3390 Spliterator.NONNULL; 3391 } 3392 getComparator()3393 public final Comparator<Map.Entry<K,V>> getComparator() { 3394 // Adapt or create a key-based comparator 3395 if (comparator != null) { 3396 return Map.Entry.comparingByKey(comparator); 3397 } 3398 else { 3399 return (Comparator<Map.Entry<K,V>> & Serializable) (e1, e2) -> { 3400 @SuppressWarnings("unchecked") 3401 Comparable<? super K> k1 = (Comparable<? super K>) e1.getKey(); 3402 return k1.compareTo(e2.getKey()); 3403 }; 3404 } 3405 } 3406 } 3407 3408 // Almost the same as keySpliterator() entrySpliterator()3409 final EntrySpliterator<K,V> entrySpliterator() { 3410 Index<K,V> h; Node<K,V> n; long est; 3411 VarHandle.acquireFence(); 3412 if ((h = head) == null) { 3413 n = null; 3414 est = 0L; 3415 } 3416 else { 3417 n = h.node; 3418 est = getAdderCount(); 3419 } 3420 return new EntrySpliterator<K,V>(comparator, h, n, null, est); 3421 } 3422 3423 // VarHandle mechanics 3424 private static final VarHandle HEAD; 3425 private static final VarHandle ADDER; 3426 private static final VarHandle NEXT; 3427 private static final VarHandle VAL; 3428 private static final VarHandle RIGHT; 3429 static { 3430 try { 3431 MethodHandles.Lookup l = MethodHandles.lookup(); 3432 HEAD = l.findVarHandle(ConcurrentSkipListMap.class, "head", 3433 Index.class); 3434 ADDER = l.findVarHandle(ConcurrentSkipListMap.class, "adder", 3435 LongAdder.class); 3436 NEXT = l.findVarHandle(Node.class, "next", Node.class); 3437 VAL = l.findVarHandle(Node.class, "val", Object.class); 3438 RIGHT = l.findVarHandle(Index.class, "right", Index.class); 3439 } catch (ReflectiveOperationException e) { 3440 throw new ExceptionInInitializerError(e); 3441 } 3442 } 3443 } 3444