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