ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListMap.java
Revision: 1.91
Committed: Wed Jan 23 18:40:30 2013 UTC (11 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.90: +2 -1 lines
Log Message:
Temporarily isolate from TLR updates

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