ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListMap.java
Revision: 1.105
Committed: Mon Feb 25 19:47:52 2013 UTC (11 years, 3 months ago) by jsr166
Branch: MAIN
Changes since 1.104: +1 -1 lines
Log Message:
whitespace

File Contents

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