ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListMap.java
Revision: 1.106
Committed: Wed Mar 13 12:39:02 2013 UTC (11 years, 3 months ago) by dl
Branch: MAIN
Changes since 1.105: +4 -37 lines
Log Message:
Synch with lambda Spliterator API

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 public 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
2640 static final class Values<E> extends AbstractCollection<E> {
2641 private final ConcurrentNavigableMap<?, E> m;
2642 Values(ConcurrentNavigableMap<?, E> map) {
2643 m = map;
2644 }
2645 @SuppressWarnings("unchecked")
2646 public Iterator<E> iterator() {
2647 if (m instanceof ConcurrentSkipListMap)
2648 return ((ConcurrentSkipListMap<?,E>)m).valueIterator();
2649 else
2650 return ((SubMap<?,E>)m).valueIterator();
2651 }
2652 public boolean isEmpty() {
2653 return m.isEmpty();
2654 }
2655 public int size() {
2656 return m.size();
2657 }
2658 public boolean contains(Object o) {
2659 return m.containsValue(o);
2660 }
2661 public void clear() {
2662 m.clear();
2663 }
2664 public Object[] toArray() { return toList(this).toArray(); }
2665 public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
2666 @SuppressWarnings("unchecked")
2667 public Spliterator<E> spliterator() {
2668 if (m instanceof ConcurrentSkipListMap)
2669 return ((ConcurrentSkipListMap<?,E>)m).valueSpliterator();
2670 else
2671 return (Spliterator<E>)((SubMap<?,E>)m).valueIterator();
2672 }
2673 }
2674
2675 static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> {
2676 private final ConcurrentNavigableMap<K1, V1> m;
2677 EntrySet(ConcurrentNavigableMap<K1, V1> map) {
2678 m = map;
2679 }
2680 @SuppressWarnings("unchecked")
2681 public Iterator<Map.Entry<K1,V1>> iterator() {
2682 if (m instanceof ConcurrentSkipListMap)
2683 return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator();
2684 else
2685 return ((SubMap<K1,V1>)m).entryIterator();
2686 }
2687
2688 public boolean contains(Object o) {
2689 if (!(o instanceof Map.Entry))
2690 return false;
2691 Map.Entry<?,?> e = (Map.Entry<?,?>)o;
2692 V1 v = m.get(e.getKey());
2693 return v != null && v.equals(e.getValue());
2694 }
2695 public boolean remove(Object o) {
2696 if (!(o instanceof Map.Entry))
2697 return false;
2698 Map.Entry<?,?> e = (Map.Entry<?,?>)o;
2699 return m.remove(e.getKey(),
2700 e.getValue());
2701 }
2702 public boolean isEmpty() {
2703 return m.isEmpty();
2704 }
2705 public int size() {
2706 return m.size();
2707 }
2708 public void clear() {
2709 m.clear();
2710 }
2711 public boolean equals(Object o) {
2712 if (o == this)
2713 return true;
2714 if (!(o instanceof Set))
2715 return false;
2716 Collection<?> c = (Collection<?>) o;
2717 try {
2718 return containsAll(c) && c.containsAll(this);
2719 } catch (ClassCastException unused) {
2720 return false;
2721 } catch (NullPointerException unused) {
2722 return false;
2723 }
2724 }
2725 public Object[] toArray() { return toList(this).toArray(); }
2726 public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
2727 @SuppressWarnings("unchecked")
2728 public Spliterator<Map.Entry<K1,V1>> spliterator() {
2729 if (m instanceof ConcurrentSkipListMap)
2730 return ((ConcurrentSkipListMap<K1,V1>)m).entrySpliterator();
2731 else
2732 return (Spliterator<Map.Entry<K1,V1>>)
2733 ((SubMap<K1,V1>)m).entryIterator();
2734 }
2735 }
2736
2737 /**
2738 * Submaps returned by {@link ConcurrentSkipListMap} submap operations
2739 * represent a subrange of mappings of their underlying
2740 * maps. Instances of this class support all methods of their
2741 * underlying maps, differing in that mappings outside their range are
2742 * ignored, and attempts to add mappings outside their ranges result
2743 * in {@link IllegalArgumentException}. Instances of this class are
2744 * constructed only using the {@code subMap}, {@code headMap}, and
2745 * {@code tailMap} methods of their underlying maps.
2746 *
2747 * @serial include
2748 */
2749 static final class SubMap<K,V> extends AbstractMap<K,V>
2750 implements ConcurrentNavigableMap<K,V>, Cloneable,
2751 java.io.Serializable {
2752 private static final long serialVersionUID = -7647078645895051609L;
2753
2754 /** Underlying map */
2755 private final ConcurrentSkipListMap<K,V> m;
2756 /** lower bound key, or null if from start */
2757 private final K lo;
2758 /** upper bound key, or null if to end */
2759 private final K hi;
2760 /** inclusion flag for lo */
2761 private final boolean loInclusive;
2762 /** inclusion flag for hi */
2763 private final boolean hiInclusive;
2764 /** direction */
2765 private final boolean isDescending;
2766
2767 // Lazily initialized view holders
2768 private transient KeySet<K> keySetView;
2769 private transient Set<Map.Entry<K,V>> entrySetView;
2770 private transient Collection<V> valuesView;
2771
2772 /**
2773 * Creates a new submap, initializing all fields.
2774 */
2775 SubMap(ConcurrentSkipListMap<K,V> map,
2776 K fromKey, boolean fromInclusive,
2777 K toKey, boolean toInclusive,
2778 boolean isDescending) {
2779 if (fromKey != null && toKey != null &&
2780 map.compare(fromKey, toKey) > 0)
2781 throw new IllegalArgumentException("inconsistent range");
2782 this.m = map;
2783 this.lo = fromKey;
2784 this.hi = toKey;
2785 this.loInclusive = fromInclusive;
2786 this.hiInclusive = toInclusive;
2787 this.isDescending = isDescending;
2788 }
2789
2790 /* ---------------- Utilities -------------- */
2791
2792 private boolean tooLow(K key) {
2793 if (lo != null) {
2794 int c = m.compare(key, lo);
2795 if (c < 0 || (c == 0 && !loInclusive))
2796 return true;
2797 }
2798 return false;
2799 }
2800
2801 private boolean tooHigh(K key) {
2802 if (hi != null) {
2803 int c = m.compare(key, hi);
2804 if (c > 0 || (c == 0 && !hiInclusive))
2805 return true;
2806 }
2807 return false;
2808 }
2809
2810 private boolean inBounds(K key) {
2811 return !tooLow(key) && !tooHigh(key);
2812 }
2813
2814 private void checkKeyBounds(K key) throws IllegalArgumentException {
2815 if (key == null)
2816 throw new NullPointerException();
2817 if (!inBounds(key))
2818 throw new IllegalArgumentException("key out of range");
2819 }
2820
2821 /**
2822 * Returns true if node key is less than upper bound of range.
2823 */
2824 private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) {
2825 if (n == null)
2826 return false;
2827 if (hi == null)
2828 return true;
2829 K k = n.key;
2830 if (k == null) // pass by markers and headers
2831 return true;
2832 int c = m.compare(k, hi);
2833 if (c > 0 || (c == 0 && !hiInclusive))
2834 return false;
2835 return true;
2836 }
2837
2838 /**
2839 * Returns lowest node. This node might not be in range, so
2840 * most usages need to check bounds.
2841 */
2842 private ConcurrentSkipListMap.Node<K,V> loNode() {
2843 if (lo == null)
2844 return m.findFirst();
2845 else if (loInclusive)
2846 return m.findNear(lo, GT|EQ);
2847 else
2848 return m.findNear(lo, GT);
2849 }
2850
2851 /**
2852 * Returns highest node. This node might not be in range, so
2853 * most usages need to check bounds.
2854 */
2855 private ConcurrentSkipListMap.Node<K,V> hiNode() {
2856 if (hi == null)
2857 return m.findLast();
2858 else if (hiInclusive)
2859 return m.findNear(hi, LT|EQ);
2860 else
2861 return m.findNear(hi, LT);
2862 }
2863
2864 /**
2865 * Returns lowest absolute key (ignoring directonality).
2866 */
2867 private K lowestKey() {
2868 ConcurrentSkipListMap.Node<K,V> n = loNode();
2869 if (isBeforeEnd(n))
2870 return n.key;
2871 else
2872 throw new NoSuchElementException();
2873 }
2874
2875 /**
2876 * Returns highest absolute key (ignoring directonality).
2877 */
2878 private K highestKey() {
2879 ConcurrentSkipListMap.Node<K,V> n = hiNode();
2880 if (n != null) {
2881 K last = n.key;
2882 if (inBounds(last))
2883 return last;
2884 }
2885 throw new NoSuchElementException();
2886 }
2887
2888 private Map.Entry<K,V> lowestEntry() {
2889 for (;;) {
2890 ConcurrentSkipListMap.Node<K,V> n = loNode();
2891 if (!isBeforeEnd(n))
2892 return null;
2893 Map.Entry<K,V> e = n.createSnapshot();
2894 if (e != null)
2895 return e;
2896 }
2897 }
2898
2899 private Map.Entry<K,V> highestEntry() {
2900 for (;;) {
2901 ConcurrentSkipListMap.Node<K,V> n = hiNode();
2902 if (n == null || !inBounds(n.key))
2903 return null;
2904 Map.Entry<K,V> e = n.createSnapshot();
2905 if (e != null)
2906 return e;
2907 }
2908 }
2909
2910 private Map.Entry<K,V> removeLowest() {
2911 for (;;) {
2912 Node<K,V> n = loNode();
2913 if (n == null)
2914 return null;
2915 K k = n.key;
2916 if (!inBounds(k))
2917 return null;
2918 V v = (m.comparator == null) ? m.doRemove(k, null) :
2919 m.doRemoveCmp(m.comparator, k, null);
2920 if (v != null)
2921 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
2922 }
2923 }
2924
2925 private Map.Entry<K,V> removeHighest() {
2926 for (;;) {
2927 Node<K,V> n = hiNode();
2928 if (n == null)
2929 return null;
2930 K k = n.key;
2931 if (!inBounds(k))
2932 return null;
2933 V v = (m.comparator == null) ? m.doRemove(k, null) :
2934 m.doRemoveCmp(m.comparator, k, null);
2935 if (v != null)
2936 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
2937 }
2938 }
2939
2940 /**
2941 * Submap version of ConcurrentSkipListMap.getNearEntry
2942 */
2943 private Map.Entry<K,V> getNearEntry(K key, int rel) {
2944 if (isDescending) { // adjust relation for direction
2945 if ((rel & LT) == 0)
2946 rel |= LT;
2947 else
2948 rel &= ~LT;
2949 }
2950 if (tooLow(key))
2951 return ((rel & LT) != 0) ? null : lowestEntry();
2952 if (tooHigh(key))
2953 return ((rel & LT) != 0) ? highestEntry() : null;
2954 for (;;) {
2955 Node<K,V> n = m.findNear(key, rel);
2956 if (n == null || !inBounds(n.key))
2957 return null;
2958 K k = n.key;
2959 V v = n.getValidValue();
2960 if (v != null)
2961 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
2962 }
2963 }
2964
2965 // Almost the same as getNearEntry, except for keys
2966 private K getNearKey(K key, int rel) {
2967 if (isDescending) { // adjust relation for direction
2968 if ((rel & LT) == 0)
2969 rel |= LT;
2970 else
2971 rel &= ~LT;
2972 }
2973 if (tooLow(key)) {
2974 if ((rel & LT) == 0) {
2975 ConcurrentSkipListMap.Node<K,V> n = loNode();
2976 if (isBeforeEnd(n))
2977 return n.key;
2978 }
2979 return null;
2980 }
2981 if (tooHigh(key)) {
2982 if ((rel & LT) != 0) {
2983 ConcurrentSkipListMap.Node<K,V> n = hiNode();
2984 if (n != null) {
2985 K last = n.key;
2986 if (inBounds(last))
2987 return last;
2988 }
2989 }
2990 return null;
2991 }
2992 for (;;) {
2993 Node<K,V> n = m.findNear(key, rel);
2994 if (n == null || !inBounds(n.key))
2995 return null;
2996 K k = n.key;
2997 V v = n.getValidValue();
2998 if (v != null)
2999 return k;
3000 }
3001 }
3002
3003 /* ---------------- Map API methods -------------- */
3004
3005 public boolean containsKey(Object key) {
3006 if (key == null) throw new NullPointerException();
3007 @SuppressWarnings("unchecked") K k = (K)key;
3008 return inBounds(k) && m.containsKey(k);
3009 }
3010
3011 public V get(Object key) {
3012 if (key == null) throw new NullPointerException();
3013 @SuppressWarnings("unchecked") K k = (K)key;
3014 return (!inBounds(k)) ? null : m.get(k);
3015 }
3016
3017 public V put(K key, V value) {
3018 checkKeyBounds(key);
3019 return m.put(key, value);
3020 }
3021
3022 public V remove(Object key) {
3023 @SuppressWarnings("unchecked") K k = (K)key;
3024 return (!inBounds(k)) ? null : m.remove(k);
3025 }
3026
3027 public int size() {
3028 long count = 0;
3029 for (ConcurrentSkipListMap.Node<K,V> n = loNode();
3030 isBeforeEnd(n);
3031 n = n.next) {
3032 if (n.getValidValue() != null)
3033 ++count;
3034 }
3035 return count >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)count;
3036 }
3037
3038 public boolean isEmpty() {
3039 return !isBeforeEnd(loNode());
3040 }
3041
3042 public boolean containsValue(Object value) {
3043 if (value == null)
3044 throw new NullPointerException();
3045 for (ConcurrentSkipListMap.Node<K,V> n = loNode();
3046 isBeforeEnd(n);
3047 n = n.next) {
3048 V v = n.getValidValue();
3049 if (v != null && value.equals(v))
3050 return true;
3051 }
3052 return false;
3053 }
3054
3055 public void clear() {
3056 for (ConcurrentSkipListMap.Node<K,V> n = loNode();
3057 isBeforeEnd(n);
3058 n = n.next) {
3059 if (n.getValidValue() != null)
3060 m.remove(n.key);
3061 }
3062 }
3063
3064 /* ---------------- ConcurrentMap API methods -------------- */
3065
3066 public V putIfAbsent(K key, V value) {
3067 checkKeyBounds(key);
3068 return m.putIfAbsent(key, value);
3069 }
3070
3071 public boolean remove(Object key, Object value) {
3072 @SuppressWarnings("unchecked") K k = (K)key;
3073 return inBounds(k) && m.remove(k, value);
3074 }
3075
3076 public boolean replace(K key, V oldValue, V newValue) {
3077 checkKeyBounds(key);
3078 return m.replace(key, oldValue, newValue);
3079 }
3080
3081 public V replace(K key, V value) {
3082 checkKeyBounds(key);
3083 return m.replace(key, value);
3084 }
3085
3086 /* ---------------- SortedMap API methods -------------- */
3087
3088 public Comparator<? super K> comparator() {
3089 Comparator<? super K> cmp = m.comparator();
3090 if (isDescending)
3091 return Collections.reverseOrder(cmp);
3092 else
3093 return cmp;
3094 }
3095
3096 /**
3097 * Utility to create submaps, where given bounds override
3098 * unbounded(null) ones and/or are checked against bounded ones.
3099 */
3100 private SubMap<K,V> newSubMap(K fromKey,
3101 boolean fromInclusive,
3102 K toKey,
3103 boolean toInclusive) {
3104 if (isDescending) { // flip senses
3105 K tk = fromKey;
3106 fromKey = toKey;
3107 toKey = tk;
3108 boolean ti = fromInclusive;
3109 fromInclusive = toInclusive;
3110 toInclusive = ti;
3111 }
3112 if (lo != null) {
3113 if (fromKey == null) {
3114 fromKey = lo;
3115 fromInclusive = loInclusive;
3116 }
3117 else {
3118 int c = m.compare(fromKey, lo);
3119 if (c < 0 || (c == 0 && !loInclusive && fromInclusive))
3120 throw new IllegalArgumentException("key out of range");
3121 }
3122 }
3123 if (hi != null) {
3124 if (toKey == null) {
3125 toKey = hi;
3126 toInclusive = hiInclusive;
3127 }
3128 else {
3129 int c = m.compare(toKey, hi);
3130 if (c > 0 || (c == 0 && !hiInclusive && toInclusive))
3131 throw new IllegalArgumentException("key out of range");
3132 }
3133 }
3134 return new SubMap<K,V>(m, fromKey, fromInclusive,
3135 toKey, toInclusive, isDescending);
3136 }
3137
3138 public SubMap<K,V> subMap(K fromKey,
3139 boolean fromInclusive,
3140 K toKey,
3141 boolean toInclusive) {
3142 if (fromKey == null || toKey == null)
3143 throw new NullPointerException();
3144 return newSubMap(fromKey, fromInclusive, toKey, toInclusive);
3145 }
3146
3147 public SubMap<K,V> headMap(K toKey,
3148 boolean inclusive) {
3149 if (toKey == null)
3150 throw new NullPointerException();
3151 return newSubMap(null, false, toKey, inclusive);
3152 }
3153
3154 public SubMap<K,V> tailMap(K fromKey,
3155 boolean inclusive) {
3156 if (fromKey == null)
3157 throw new NullPointerException();
3158 return newSubMap(fromKey, inclusive, null, false);
3159 }
3160
3161 public SubMap<K,V> subMap(K fromKey, K toKey) {
3162 return subMap(fromKey, true, toKey, false);
3163 }
3164
3165 public SubMap<K,V> headMap(K toKey) {
3166 return headMap(toKey, false);
3167 }
3168
3169 public SubMap<K,V> tailMap(K fromKey) {
3170 return tailMap(fromKey, true);
3171 }
3172
3173 public SubMap<K,V> descendingMap() {
3174 return new SubMap<K,V>(m, lo, loInclusive,
3175 hi, hiInclusive, !isDescending);
3176 }
3177
3178 /* ---------------- Relational methods -------------- */
3179
3180 public Map.Entry<K,V> ceilingEntry(K key) {
3181 return getNearEntry(key, GT|EQ);
3182 }
3183
3184 public K ceilingKey(K key) {
3185 return getNearKey(key, GT|EQ);
3186 }
3187
3188 public Map.Entry<K,V> lowerEntry(K key) {
3189 return getNearEntry(key, LT);
3190 }
3191
3192 public K lowerKey(K key) {
3193 return getNearKey(key, LT);
3194 }
3195
3196 public Map.Entry<K,V> floorEntry(K key) {
3197 return getNearEntry(key, LT|EQ);
3198 }
3199
3200 public K floorKey(K key) {
3201 return getNearKey(key, LT|EQ);
3202 }
3203
3204 public Map.Entry<K,V> higherEntry(K key) {
3205 return getNearEntry(key, GT);
3206 }
3207
3208 public K higherKey(K key) {
3209 return getNearKey(key, GT);
3210 }
3211
3212 public K firstKey() {
3213 return isDescending ? highestKey() : lowestKey();
3214 }
3215
3216 public K lastKey() {
3217 return isDescending ? lowestKey() : highestKey();
3218 }
3219
3220 public Map.Entry<K,V> firstEntry() {
3221 return isDescending ? highestEntry() : lowestEntry();
3222 }
3223
3224 public Map.Entry<K,V> lastEntry() {
3225 return isDescending ? lowestEntry() : highestEntry();
3226 }
3227
3228 public Map.Entry<K,V> pollFirstEntry() {
3229 return isDescending ? removeHighest() : removeLowest();
3230 }
3231
3232 public Map.Entry<K,V> pollLastEntry() {
3233 return isDescending ? removeLowest() : removeHighest();
3234 }
3235
3236 /* ---------------- Submap Views -------------- */
3237
3238 public NavigableSet<K> keySet() {
3239 KeySet<K> ks = keySetView;
3240 return (ks != null) ? ks : (keySetView = new KeySet<K>(this));
3241 }
3242
3243 public NavigableSet<K> navigableKeySet() {
3244 KeySet<K> ks = keySetView;
3245 return (ks != null) ? ks : (keySetView = new KeySet<K>(this));
3246 }
3247
3248 public Collection<V> values() {
3249 Collection<V> vs = valuesView;
3250 return (vs != null) ? vs : (valuesView = new Values<V>(this));
3251 }
3252
3253 public Set<Map.Entry<K,V>> entrySet() {
3254 Set<Map.Entry<K,V>> es = entrySetView;
3255 return (es != null) ? es : (entrySetView = new EntrySet<K,V>(this));
3256 }
3257
3258 public NavigableSet<K> descendingKeySet() {
3259 return descendingMap().navigableKeySet();
3260 }
3261
3262 Iterator<K> keyIterator() {
3263 return new SubMapKeyIterator();
3264 }
3265
3266 Iterator<V> valueIterator() {
3267 return new SubMapValueIterator();
3268 }
3269
3270 Iterator<Map.Entry<K,V>> entryIterator() {
3271 return new SubMapEntryIterator();
3272 }
3273
3274 /**
3275 * Variant of main Iter class to traverse through submaps.
3276 * Also serves as back-up Spliterator for views
3277 */
3278 abstract class SubMapIter<T> implements Iterator<T>, Spliterator<T> {
3279 /** the last node returned by next() */
3280 Node<K,V> lastReturned;
3281 /** the next node to return from next(); */
3282 Node<K,V> next;
3283 /** Cache of next value field to maintain weak consistency */
3284 V nextValue;
3285
3286 SubMapIter() {
3287 for (;;) {
3288 next = isDescending ? hiNode() : loNode();
3289 if (next == null)
3290 break;
3291 Object x = next.value;
3292 if (x != null && x != next) {
3293 @SuppressWarnings("unchecked") V vv = (V)x;
3294 if (! inBounds(next.key))
3295 next = null;
3296 else
3297 nextValue = vv;
3298 break;
3299 }
3300 }
3301 }
3302
3303 public final boolean hasNext() {
3304 return next != null;
3305 }
3306
3307 final void advance() {
3308 if (next == null)
3309 throw new NoSuchElementException();
3310 lastReturned = next;
3311 if (isDescending)
3312 descend();
3313 else
3314 ascend();
3315 }
3316
3317 private void ascend() {
3318 for (;;) {
3319 next = next.next;
3320 if (next == null)
3321 break;
3322 Object x = next.value;
3323 if (x != null && x != next) {
3324 @SuppressWarnings("unchecked") V vv = (V)x;
3325 if (tooHigh(next.key))
3326 next = null;
3327 else
3328 nextValue = vv;
3329 break;
3330 }
3331 }
3332 }
3333
3334 private void descend() {
3335 Comparator<? super K> cmp = m.comparator;
3336 for (;;) {
3337 next = (cmp == null) ? m.doFindNear(lastReturned.key, LT) :
3338 m.doFindNearCmp(cmp, lastReturned.key, LT);
3339 if (next == null)
3340 break;
3341 Object x = next.value;
3342 if (x != null && x != next) {
3343 @SuppressWarnings("unchecked") V vv = (V)x;
3344 if (tooLow(next.key))
3345 next = null;
3346 else
3347 nextValue = vv;
3348 break;
3349 }
3350 }
3351 }
3352
3353 public void remove() {
3354 Node<K,V> l = lastReturned;
3355 if (l == null)
3356 throw new IllegalStateException();
3357 m.remove(l.key);
3358 lastReturned = null;
3359 }
3360
3361 public boolean tryAdvance(Consumer<? super T> action) {
3362 if (hasNext()) {
3363 action.accept(next());
3364 return true;
3365 }
3366 return false;
3367 }
3368
3369 public void forEach(Consumer<? super T> action) {
3370 while (hasNext())
3371 action.accept(next());
3372 }
3373 }
3374
3375 final class SubMapValueIterator extends SubMapIter<V> {
3376 public V next() {
3377 V v = nextValue;
3378 advance();
3379 return v;
3380 }
3381 public int characteristics() {
3382 return 0;
3383 }
3384 }
3385
3386 final class SubMapKeyIterator extends SubMapIter<K> {
3387 public K next() {
3388 Node<K,V> n = next;
3389 advance();
3390 return n.key;
3391 }
3392 public int characteristics() {
3393 return Spliterator.DISTINCT | Spliterator.ORDERED |
3394 Spliterator.SORTED;
3395 }
3396 public final Comparator<? super K> getComparator() {
3397 return SubMap.this.comparator();
3398 }
3399 }
3400
3401 final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> {
3402 public Map.Entry<K,V> next() {
3403 Node<K,V> n = next;
3404 V v = nextValue;
3405 advance();
3406 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
3407 }
3408 public int characteristics() {
3409 return Spliterator.DISTINCT;
3410 }
3411 }
3412 }
3413
3414 /**
3415 * A view of a ConcurrentSkipListMap as a {@link Set} of keys, in
3416 * which additions may optionally be enabled by mapping to a
3417 * common value. This class cannot be directly instantiated. See
3418 * {@link #keySet()}, {@link #keySet(Object)}, {@link #newKeySet()},
3419 * {@link #newKeySet(Comparator)}.
3420 */
3421 public static class KeySetView<K,V> extends AbstractSet<K>
3422 implements NavigableSet<K>, java.io.Serializable {
3423
3424 /*
3425 * This class overlaps in functionality with the
3426 * relative-scoped KeySet class, but must be distinct and
3427 * unrelated. So we repeat most of the boring delegation code.
3428 */
3429
3430 private static final long serialVersionUID = 7249069246763182397L;
3431 private final ConcurrentSkipListMap<K,V> m;
3432 private final V value;
3433
3434 KeySetView(ConcurrentSkipListMap<K,V> map, V value) { // non-public
3435 this.m = map;
3436 this.value = value;
3437 }
3438
3439 /**
3440 * Returns the map backing this view.
3441 *
3442 * @return the map backing this view
3443 */
3444 public ConcurrentSkipListMap<K,V> getMap() { return m; }
3445
3446 /**
3447 * Returns the default mapped value for additions,
3448 * or {@code null} if additions are not supported.
3449 *
3450 * @return the default mapped value for additions, or {@code null}
3451 * if not supported.
3452 */
3453 public V getMappedValue() { return value; }
3454
3455 public boolean add(K e) {
3456 V v;
3457 if ((v = value) == null)
3458 throw new UnsupportedOperationException();
3459 if (e == null)
3460 throw new NullPointerException();
3461 return m.put(e, v) == null;
3462 }
3463
3464 public boolean addAll(Collection<? extends K> c) {
3465 boolean added = false;
3466 V v;
3467 if ((v = value) == null)
3468 throw new UnsupportedOperationException();
3469 for (K e : c) {
3470 if (e == null)
3471 throw new NullPointerException();
3472 if (m.put(e, v) == null)
3473 added = true;
3474 }
3475 return added;
3476 }
3477
3478 public int size() { return m.size(); }
3479 public boolean isEmpty() { return m.isEmpty(); }
3480 public boolean contains(Object o) { return m.containsKey(o); }
3481 public boolean remove(Object o) { return m.remove(o) != null; }
3482 public void clear() { m.clear(); }
3483 public K lower(K e) { return m.lowerKey(e); }
3484 public K floor(K e) { return m.floorKey(e); }
3485 public K ceiling(K e) { return m.ceilingKey(e); }
3486 public K higher(K e) { return m.higherKey(e); }
3487 public Comparator<? super K> comparator() { return m.comparator(); }
3488 public K first() { return m.firstKey(); }
3489 public K last() { return m.lastKey(); }
3490 public Iterator<K> iterator() { return m.keyIterator(); }
3491 public K pollFirst() {
3492 Map.Entry<K,?> e = m.pollFirstEntry();
3493 return (e == null) ? null : e.getKey();
3494 }
3495 public K pollLast() {
3496 Map.Entry<K,?> e = m.pollLastEntry();
3497 return (e == null) ? null : e.getKey();
3498 }
3499 public boolean equals(Object o) {
3500 if (o == this)
3501 return true;
3502 if (!(o instanceof Set))
3503 return false;
3504 Collection<?> c = (Collection<?>) o;
3505 try {
3506 return containsAll(c) && c.containsAll(this);
3507 } catch (ClassCastException unused) {
3508 return false;
3509 } catch (NullPointerException unused) {
3510 return false;
3511 }
3512 }
3513 public Object[] toArray() { return toList(this).toArray(); }
3514 public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
3515 public Iterator<K> descendingIterator() {
3516 return descendingSet().iterator();
3517 }
3518 public NavigableSet<K> subSet(K fromElement,
3519 boolean fromInclusive,
3520 K toElement,
3521 boolean toInclusive) {
3522 return new KeySet<K>(m.subMap(fromElement, fromInclusive,
3523 toElement, toInclusive));
3524 }
3525 public NavigableSet<K> headSet(K toElement, boolean inclusive) {
3526 return new KeySet<K>(m.headMap(toElement, inclusive));
3527 }
3528 public NavigableSet<K> tailSet(K fromElement, boolean inclusive) {
3529 return new KeySet<K>(m.tailMap(fromElement, inclusive));
3530 }
3531 public NavigableSet<K> subSet(K fromElement, K toElement) {
3532 return subSet(fromElement, true, toElement, false);
3533 }
3534 public NavigableSet<K> headSet(K toElement) {
3535 return headSet(toElement, false);
3536 }
3537 public NavigableSet<K> tailSet(K fromElement) {
3538 return tailSet(fromElement, true);
3539 }
3540 public NavigableSet<K> descendingSet() {
3541 return new KeySet<K>(m.descendingMap());
3542 }
3543
3544 public Spliterator<K> spliterator() {
3545 return m.keySpliterator();
3546 }
3547
3548 }
3549
3550 /**
3551 * Base class providing common structure for Spliterators.
3552 * (Although not all that much common functionality; as usual for
3553 * view classes, details annoyingly vary in key, value, and entry
3554 * subclasses in ways that are not worth abstracting out for
3555 * internal classes.)
3556 *
3557 * The basic split strategy is to recursively descend from top
3558 * level, row by row, descending to next row when either split
3559 * off, or the end of row is encountered. Control of the number of
3560 * splits relies on some statistical estimation: The expected
3561 * remaining number of elements of a skip list when advancing
3562 * either across or down decreases by about 25%. To make this
3563 * observation useful, we need to know initial size, which we
3564 * don't. But we can just use Integer.MAX_VALUE so that we
3565 * don't prematurely zero out while splitting.
3566 */
3567 static class CSLMSpliterator<K,V> {
3568 final Comparator<? super K> comparator;
3569 final K fence; // exclusive upper bound for keys, or null if to end
3570 Index<K,V> row; // the level to split out
3571 Node<K,V> current; // current traversal node; initialize at origin
3572 int est; // pseudo-size estimate
3573
3574 CSLMSpliterator(ConcurrentSkipListMap<K,V> m) {
3575 this.comparator = m.comparator;
3576 this.fence = null;
3577 for (;;) { // ensure h corresponds to origin p
3578 HeadIndex<K,V> h; Node<K,V> p;
3579 Node<K,V> b = (h = m.head).node;
3580 if ((p = b.next) == null || p.value != null) {
3581 this.est = ((p == null) ? 0 :
3582 (p.next == null) ? 1 : Integer.MAX_VALUE);
3583 this.current = p;
3584 this.row = h;
3585 break;
3586 }
3587 p.helpDelete(b, p.next);
3588 }
3589 }
3590
3591 CSLMSpliterator(Comparator<? super K> comparator, Index<K,V> row,
3592 Node<K,V> origin, K fence, int est) {
3593 this.comparator = comparator; this.row = row;
3594 this.current = origin; this.fence = fence; this.est = est;
3595 }
3596
3597 /** Return >= 0 if key is too large (out of bounds) */
3598 @SuppressWarnings("unchecked")
3599 final int compareBounds(K k) {
3600 Comparator<? super K> cmp; K f;
3601 if (k == null || (f = fence) == null)
3602 return -1;
3603 else if ((cmp = comparator) != null)
3604 return cmp.compare(k, f);
3605 else
3606 return ((Comparable<? super K>)k).compareTo(f);
3607 }
3608
3609 public final long estimateSize() { return (long)est; }
3610
3611 }
3612
3613 // factory methods
3614 final KeySpliterator<K,V> keySpliterator() {
3615 return new KeySpliterator<K,V>(this);
3616 }
3617
3618 final ValueSpliterator<K,V> valueSpliterator() {
3619 return new ValueSpliterator<K,V>(this);
3620 }
3621
3622 final EntrySpliterator<K,V> entrySpliterator() {
3623 return new EntrySpliterator<K,V>(this);
3624 }
3625
3626 static final class KeySpliterator<K,V> extends CSLMSpliterator<K,V>
3627 implements Spliterator<K> {
3628 KeySpliterator(ConcurrentSkipListMap<K,V> m) { super(m); }
3629 KeySpliterator(Comparator<? super K> comparator, Index<K,V> row,
3630 Node<K,V> origin, K fence, int est) {
3631 super(comparator, row, origin, fence, est);
3632 }
3633
3634 @SuppressWarnings("unchecked")
3635 public Spliterator<K> trySplit() {
3636 Node<K,V> e;
3637 Comparator<? super K> cmp = comparator;
3638 K f = fence;
3639 if ((e = current) != null) {
3640 for (Index<K,V> q = row; q != null; q = row = q.down) {
3641 Index<K,V> s; Node<K,V> n; K sk;
3642 est -= est >>> 2;
3643 if ((s = q.right) != null) {
3644 for (;;) {
3645 Node<K,V> b = s.node;
3646 if ((n = b.next) == null || n.value != null)
3647 break;
3648 n.helpDelete(b, n.next);
3649 }
3650 if (n != null && (sk = n.key) != null &&
3651 (f == null ||
3652 (cmp != null ? (cmp.compare(f, sk) > 0) :
3653 (((Comparable<? super K>)f).compareTo(sk) > 0)))) {
3654 current = n;
3655 Index<K,V> r = q.down;
3656 row = (s.right != null) ? s : s.down;
3657 return new KeySpliterator<K,V>(cmp, r, e, sk, est);
3658 }
3659 }
3660 }
3661 }
3662 return null;
3663 }
3664
3665 public void forEach(Consumer<? super K> action) {
3666 if (action == null) throw new NullPointerException();
3667 K f = fence;
3668 Comparator<? super K> cmp = comparator;
3669 @SuppressWarnings("unchecked")
3670 Comparable<? super K> cf = (f != null && cmp == null) ?
3671 (Comparable<? super K>)f : null;
3672 Node<K,V> e = current;
3673 current = null;
3674 for (; e != null; e = e.next) {
3675 K k; Object v;
3676 if ((k = e.key) != null &&
3677 (cf != null ? (cf.compareTo(k) <= 0) :
3678 (f != null && cmp.compare(f, k) <= 0)))
3679 break;
3680 if ((v = e.value) != null && v != e)
3681 action.accept(k);
3682 }
3683 }
3684
3685 public boolean tryAdvance(Consumer<? super K> action) {
3686 if (action == null) throw new NullPointerException();
3687 Node<K,V> e;
3688 for (e = current; e != null; e = e.next) {
3689 K k; Object v;
3690 if (compareBounds(k = e.key) >= 0) {
3691 e = null;
3692 break;
3693 }
3694 if ((v = e.value) != null && v != e) {
3695 current = e.next;
3696 action.accept(k);
3697 return true;
3698 }
3699 }
3700 current = e;
3701 return false;
3702 }
3703
3704 public int characteristics() {
3705 return Spliterator.DISTINCT | Spliterator.SORTED |
3706 Spliterator.ORDERED | Spliterator.CONCURRENT |
3707 Spliterator.NONNULL;
3708 }
3709
3710 public final Comparator<? super K> getComparator() {
3711 return comparator;
3712 }
3713 }
3714
3715 static final class ValueSpliterator<K,V> extends CSLMSpliterator<K,V>
3716 implements Spliterator<V> {
3717 ValueSpliterator(ConcurrentSkipListMap<K,V> m) { super(m); }
3718 ValueSpliterator(Comparator<? super K> comparator, Index<K,V> row,
3719 Node<K,V> origin, K fence, int est) {
3720 super(comparator, row, origin, fence, est);
3721 }
3722
3723 @SuppressWarnings("unchecked")
3724 public Spliterator<V> trySplit() {
3725 Node<K,V> e;
3726 Comparator<? super K> cmp = comparator;
3727 K f = fence;
3728 if ((e = current) != null) {
3729 for (Index<K,V> q = row; q != null; q = row = q.down) {
3730 Index<K,V> s; Node<K,V> n; K sk;
3731 est -= est >>> 2;
3732 if ((s = q.right) != null) {
3733 for (;;) {
3734 Node<K,V> b = s.node;
3735 if ((n = b.next) == null || n.value != null)
3736 break;
3737 n.helpDelete(b, n.next);
3738 }
3739 if (n != null && (sk = n.key) != null &&
3740 (f == null ||
3741 (cmp != null ? (cmp.compare(f, sk) > 0) :
3742 (((Comparable<? super K>)f).compareTo(sk) > 0)))) {
3743 current = n;
3744 Index<K,V> r = q.down;
3745 row = (s.right != null) ? s : s.down;
3746 return new ValueSpliterator<K,V>(cmp, r, e, sk, est);
3747 }
3748 }
3749 }
3750 }
3751 return null;
3752 }
3753
3754 public void forEach(Consumer<? super V> action) {
3755 if (action == null) throw new NullPointerException();
3756 K f = fence;
3757 Comparator<? super K> cmp = comparator;
3758 @SuppressWarnings("unchecked")
3759 Comparable<? super K> cf = (f != null && cmp == null) ?
3760 (Comparable<? super K>)f : null;
3761 Node<K,V> e = current;
3762 current = null;
3763 for (; e != null; e = e.next) {
3764 K k; Object v;
3765 if ((k = e.key) != null &&
3766 (cf != null ? (cf.compareTo(k) <= 0) :
3767 (f != null && cmp.compare(f, k) <= 0)))
3768 break;
3769 if ((v = e.value) != null && v != e) {
3770 @SuppressWarnings("unchecked") V vv = (V)v;
3771 action.accept(vv);
3772 }
3773 }
3774 }
3775
3776 public boolean tryAdvance(Consumer<? super V> action) {
3777 if (action == null) throw new NullPointerException();
3778 boolean advanced = false;
3779 Node<K,V> e;
3780 for (e = current; e != null; e = e.next) {
3781 K k; Object v;
3782 if (compareBounds(k = e.key) >= 0) {
3783 e = null;
3784 break;
3785 }
3786 if ((v = e.value) != null && v != e) {
3787 current = e.next;
3788 @SuppressWarnings("unchecked") V vv = (V)v;
3789 action.accept(vv);
3790 return true;
3791 }
3792 }
3793 current = e;
3794 return false;
3795 }
3796
3797 public int characteristics() {
3798 return Spliterator.CONCURRENT | Spliterator.NONNULL;
3799 }
3800 }
3801
3802 static final class EntrySpliterator<K,V> extends CSLMSpliterator<K,V>
3803 implements Spliterator<Map.Entry<K,V>> {
3804 EntrySpliterator(ConcurrentSkipListMap<K,V> m) { super(m); }
3805 EntrySpliterator(Comparator<? super K> comparator, Index<K,V> row,
3806 Node<K,V> origin, K fence, int est) {
3807 super(comparator, row, origin, fence, est);
3808 }
3809
3810 @SuppressWarnings("unchecked")
3811 public Spliterator<Map.Entry<K,V>> trySplit() {
3812 Node<K,V> e;
3813 Comparator<? super K> cmp = comparator;
3814 K f = fence;
3815 if ((e = current) != null) {
3816 for (Index<K,V> q = row; q != null; q = row = q.down) {
3817 Index<K,V> s; Node<K,V> n; K sk;
3818 est -= est >>> 2;
3819 if ((s = q.right) != null) {
3820 for (;;) {
3821 Node<K,V> b = s.node;
3822 if ((n = b.next) == null || n.value != null)
3823 break;
3824 n.helpDelete(b, n.next);
3825 }
3826 if (n != null && (sk = n.key) != null &&
3827 (f == null ||
3828 (cmp != null ?
3829 (cmp.compare(f, sk) > 0) :
3830 (((Comparable<? super K>)f).compareTo(sk) > 0)))) {
3831 current = n;
3832 Index<K,V> r = q.down;
3833 row = (s.right != null) ? s : s.down;
3834 return new EntrySpliterator<K,V>(cmp, r, e, sk, est);
3835 }
3836 }
3837 }
3838 }
3839 return null;
3840 }
3841
3842 public void forEach(Consumer<? super Map.Entry<K,V>> action) {
3843 if (action == null) throw new NullPointerException();
3844 K f = fence;
3845 Comparator<? super K> cmp = comparator;
3846 @SuppressWarnings("unchecked")
3847 Comparable<? super K> cf = (f != null && cmp == null) ?
3848 (Comparable<? super K>)f : null;
3849 Node<K,V> e = current;
3850 current = null;
3851 for (; e != null; e = e.next) {
3852 K k; Object v;
3853 if ((k = e.key) != null &&
3854 (cf != null ?
3855 (cf.compareTo(k) <= 0) :
3856 (f != null && cmp.compare(f, k) <= 0)))
3857 break;
3858 if ((v = e.value) != null && v != e) {
3859 @SuppressWarnings("unchecked") V vv = (V)v;
3860 action.accept
3861 (new AbstractMap.SimpleImmutableEntry<K,V>(k, vv));
3862 }
3863 }
3864 }
3865
3866 public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
3867 if (action == null) throw new NullPointerException();
3868 Node<K,V> e;
3869 for (e = current; e != null; e = e.next) {
3870 K k; Object v;
3871 if (compareBounds(k = e.key) >= 0) {
3872 e = null;
3873 break;
3874 }
3875 if ((v = e.value) != null && v != e) {
3876 current = e.next;
3877 @SuppressWarnings("unchecked") V vv = (V)v;
3878 action.accept
3879 (new AbstractMap.SimpleImmutableEntry<K,V>(k, vv));
3880 return true;
3881 }
3882 }
3883 current = e;
3884 return false;
3885 }
3886
3887 public int characteristics() {
3888 return Spliterator.DISTINCT | Spliterator.SORTED |
3889 Spliterator.ORDERED | Spliterator.CONCURRENT |
3890 Spliterator.NONNULL;
3891 }
3892 }
3893
3894 // Unsafe mechanics
3895 private static final sun.misc.Unsafe UNSAFE;
3896 private static final long headOffset;
3897 private static final long SECONDARY;
3898 static {
3899 try {
3900 UNSAFE = sun.misc.Unsafe.getUnsafe();
3901 Class<?> k = ConcurrentSkipListMap.class;
3902 headOffset = UNSAFE.objectFieldOffset
3903 (k.getDeclaredField("head"));
3904 Class<?> tk = Thread.class;
3905 SECONDARY = UNSAFE.objectFieldOffset
3906 (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
3907
3908 } catch (Exception e) {
3909 throw new Error(e);
3910 }
3911 }
3912 }