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