ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListMap.java
Revision: 1.89
Committed: Tue Jan 22 20:08:33 2013 UTC (11 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.88: +8 -6 lines
Log Message:
coding style

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 level = 0;
867 if ((x & 0x80000001) == 0) { // test highest and lowest bits
868 do { ++level; }
869 while (((x >>>= 1) & 1) != 0);
870 }
871 return level;
872 }
873
874 /**
875 * Creates and adds index nodes for the given node.
876 * @param z the node
877 * @param level the level of the index
878 */
879 private void insertIndex(Node<K,V> z, int level) {
880 HeadIndex<K,V> h = head;
881 int max = h.level;
882
883 if (level <= max) {
884 Index<K,V> idx = null;
885 for (int i = 1; i <= level; ++i)
886 idx = new Index<K,V>(z, idx, null);
887 addIndex(idx, h, level);
888
889 } else { // Add a new level
890 /*
891 * To reduce interference by other threads checking for
892 * empty levels in tryReduceLevel, new levels are added
893 * with initialized right pointers. Which in turn requires
894 * keeping levels in an array to access them while
895 * creating new head index nodes from the opposite
896 * direction.
897 */
898 level = max + 1;
899 Index<K,V>[] idxs = (Index<K,V>[])new Index<?,?>[level+1];
900 Index<K,V> idx = null;
901 for (int i = 1; i <= level; ++i)
902 idxs[i] = idx = new Index<K,V>(z, idx, null);
903
904 HeadIndex<K,V> oldh;
905 int k;
906 for (;;) {
907 oldh = head;
908 int oldLevel = oldh.level;
909 if (level <= oldLevel) { // lost race to add level
910 k = level;
911 break;
912 }
913 HeadIndex<K,V> newh = oldh;
914 Node<K,V> oldbase = oldh.node;
915 for (int j = oldLevel+1; j <= level; ++j)
916 newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j);
917 if (casHead(oldh, newh)) {
918 k = oldLevel;
919 break;
920 }
921 }
922 addIndex(idxs[k], oldh, k);
923 }
924 }
925
926 /**
927 * Adds given index nodes from given level down to 1.
928 * @param idx the topmost index node being inserted
929 * @param h the value of head to use to insert. This must be
930 * snapshotted by callers to provide correct insertion level.
931 * @param indexLevel the level of the index
932 */
933 @SuppressWarnings("unchecked")
934 private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) {
935 // Track next level to insert in case of retries
936 int insertionLevel = indexLevel;
937 K key = idx.node.key;
938 if (key == null) throw new NullPointerException();
939 Comparator<? super K> cmp = comparator;
940 // Similar to findPredecessor, but adding index nodes along
941 // path to key.
942 for (;;) {
943 int j = h.level;
944 Index<K,V> q = h;
945 Index<K,V> r = q.right;
946 Index<K,V> t = idx;
947 for (;;) {
948 if (r != null) {
949 Node<K,V> n = r.node;
950 // compare before deletion check avoids needing recheck
951 int c = (cmp == null) ?
952 ((Comparable<? super K>)key).compareTo(n.key) :
953 cmp.compare(key, n.key);
954 if (n.value == null) {
955 if (!q.unlink(r))
956 break;
957 r = q.right;
958 continue;
959 }
960 if (c > 0) {
961 q = r;
962 r = r.right;
963 continue;
964 }
965 }
966
967 if (j == insertionLevel) {
968 // Don't insert index if node already deleted
969 if (t.indexesDeletedNode()) {
970 if (cmp == null)
971 findNode((Comparable<? super K>)key); // cleans up
972 else
973 findNodeCmp(cmp, key);
974 return;
975 }
976 if (!q.link(r, t))
977 break; // restart
978 if (--insertionLevel == 0) {
979 // need final deletion check before return
980 if (t.indexesDeletedNode()) {
981 if (cmp == null)
982 findNode((Comparable<? super K>)key);
983 else
984 findNodeCmp(cmp, key);
985 }
986 return;
987 }
988 }
989
990 if (--j >= insertionLevel && j < indexLevel)
991 t = t.down;
992 q = q.down;
993 r = q.right;
994 }
995 }
996 }
997
998 /* ---------------- Deletion -------------- */
999
1000 /**
1001 * Main deletion method. Locates node, nulls value, appends a
1002 * deletion marker, unlinks predecessor, removes associated index
1003 * nodes, and possibly reduces head index level.
1004 *
1005 * Index nodes are cleared out simply by calling findPredecessor.
1006 * which unlinks indexes to deleted nodes found along path to key,
1007 * which will include the indexes to this node. This is done
1008 * unconditionally. We can't check beforehand whether there are
1009 * index nodes because it might be the case that some or all
1010 * indexes hadn't been inserted yet for this node during initial
1011 * search for it, and we'd like to ensure lack of garbage
1012 * retention, so must call to be sure.
1013 *
1014 * @param okey the key
1015 * @param value if non-null, the value that must be
1016 * associated with key
1017 * @return the node, or null if not found
1018 */
1019 final V doRemove(Object okey, Object value) {
1020 if (okey == null)
1021 throw new NullPointerException();
1022 @SuppressWarnings("unchecked") Comparable<? super K> key =
1023 (Comparable<? super K>)okey;
1024 for (;;) {
1025 Node<K,V> b = findPredecessor(key);
1026 Node<K,V> n = b.next;
1027 for (;;) {
1028 if (n == null)
1029 return null;
1030 Node<K,V> f = n.next;
1031 if (n != b.next) // inconsistent read
1032 break;
1033 Object v = n.value;
1034 if (v == null) { // n is deleted
1035 n.helpDelete(b, f);
1036 break;
1037 }
1038 if (v == n || b.value == null) // b is deleted
1039 break;
1040 int c = key.compareTo(n.key);
1041 if (c < 0)
1042 return null;
1043 if (c > 0) {
1044 b = n;
1045 n = f;
1046 continue;
1047 }
1048 if (value != null && !value.equals(v))
1049 return null;
1050 if (!n.casValue(v, null))
1051 break;
1052 if (!n.appendMarker(f) || !b.casNext(n, f))
1053 findNode(key); // Retry via findNode
1054 else {
1055 findPredecessor(key); // Clean index
1056 if (head.right == null)
1057 tryReduceLevel();
1058 }
1059 return (V)v;
1060 }
1061 }
1062 }
1063
1064 /**
1065 * Possibly reduce head level if it has no nodes. This method can
1066 * (rarely) make mistakes, in which case levels can disappear even
1067 * though they are about to contain index nodes. This impacts
1068 * performance, not correctness. To minimize mistakes as well as
1069 * to reduce hysteresis, the level is reduced by one only if the
1070 * topmost three levels look empty. Also, if the removed level
1071 * looks non-empty after CAS, we try to change it back quick
1072 * before anyone notices our mistake! (This trick works pretty
1073 * well because this method will practically never make mistakes
1074 * unless current thread stalls immediately before first CAS, in
1075 * which case it is very unlikely to stall again immediately
1076 * afterwards, so will recover.)
1077 *
1078 * We put up with all this rather than just let levels grow
1079 * because otherwise, even a small map that has undergone a large
1080 * number of insertions and removals will have a lot of levels,
1081 * slowing down access more than would an occasional unwanted
1082 * reduction.
1083 */
1084 private void tryReduceLevel() {
1085 HeadIndex<K,V> h = head;
1086 HeadIndex<K,V> d;
1087 HeadIndex<K,V> e;
1088 if (h.level > 3 &&
1089 (d = (HeadIndex<K,V>)h.down) != null &&
1090 (e = (HeadIndex<K,V>)d.down) != null &&
1091 e.right == null &&
1092 d.right == null &&
1093 h.right == null &&
1094 casHead(h, d) && // try to set
1095 h.right != null) // recheck
1096 casHead(d, h); // try to backout
1097 }
1098
1099 /* ---------------- Finding and removing first element -------------- */
1100
1101 /**
1102 * Specialized variant of findNode to get first valid node.
1103 * @return first node or null if empty
1104 */
1105 Node<K,V> findFirst() {
1106 for (;;) {
1107 Node<K,V> b = head.node;
1108 Node<K,V> n = b.next;
1109 if (n == null)
1110 return null;
1111 if (n.value != null)
1112 return n;
1113 n.helpDelete(b, n.next);
1114 }
1115 }
1116
1117 /**
1118 * Removes first entry; returns its snapshot.
1119 * @return null if empty, else snapshot of first entry
1120 */
1121 Map.Entry<K,V> doRemoveFirstEntry() {
1122 for (;;) {
1123 Node<K,V> b = head.node;
1124 Node<K,V> n = b.next;
1125 if (n == null)
1126 return null;
1127 Node<K,V> f = n.next;
1128 if (n != b.next)
1129 continue;
1130 Object v = n.value;
1131 if (v == null) {
1132 n.helpDelete(b, f);
1133 continue;
1134 }
1135 if (!n.casValue(v, null))
1136 continue;
1137 if (!n.appendMarker(f) || !b.casNext(n, f))
1138 findFirst(); // retry
1139 clearIndexToFirst();
1140 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, (V)v);
1141 }
1142 }
1143
1144 /**
1145 * Clears out index nodes associated with deleted first entry.
1146 */
1147 private void clearIndexToFirst() {
1148 for (;;) {
1149 Index<K,V> q = head;
1150 for (;;) {
1151 Index<K,V> r = q.right;
1152 if (r != null && r.indexesDeletedNode() && !q.unlink(r))
1153 break;
1154 if ((q = q.down) == null) {
1155 if (head.right == null)
1156 tryReduceLevel();
1157 return;
1158 }
1159 }
1160 }
1161 }
1162
1163 /**
1164 * Removes last entry; returns its snapshot.
1165 * Specialized variant of doRemove.
1166 * @return null if empty, else snapshot of last entry
1167 */
1168 Map.Entry<K,V> doRemoveLastEntry() {
1169 for (;;) {
1170 Node<K,V> b = findPredecessorOfLast();
1171 Node<K,V> n = b.next;
1172 if (n == null) {
1173 if (b.isBaseHeader()) // empty
1174 return null;
1175 else
1176 continue; // all b's successors are deleted; retry
1177 }
1178 for (;;) {
1179 Node<K,V> f = n.next;
1180 if (n != b.next) // inconsistent read
1181 break;
1182 Object v = n.value;
1183 if (v == null) { // n is deleted
1184 n.helpDelete(b, f);
1185 break;
1186 }
1187 if (v == n || b.value == null) // b is deleted
1188 break;
1189 if (f != null) {
1190 b = n;
1191 n = f;
1192 continue;
1193 }
1194 if (!n.casValue(v, null))
1195 break;
1196 K key = n.key;
1197 Comparator<? super K> cmp = comparator;
1198 if (!n.appendMarker(f) || !b.casNext(n, f)) {
1199 if (cmp == null) // Retry via findNode
1200 findNode((Comparable<? super K>)key);
1201 else
1202 findNodeCmp(cmp, key);
1203 }
1204 else { // Clean index
1205 if (cmp == null)
1206 findPredecessor((Comparable<? super K>)key);
1207 else
1208 findPredecessorCmp(cmp, key);
1209 if (head.right == null)
1210 tryReduceLevel();
1211 }
1212 return new AbstractMap.SimpleImmutableEntry<K,V>(key, (V)v);
1213 }
1214 }
1215 }
1216
1217 /* ---------------- Finding and removing last element -------------- */
1218
1219 /**
1220 * Specialized version of find to get last valid node.
1221 * @return last node or null if empty
1222 */
1223 Node<K,V> findLast() {
1224 /*
1225 * findPredecessor can't be used to traverse index level
1226 * because this doesn't use comparisons. So traversals of
1227 * both levels are folded together.
1228 */
1229 Index<K,V> q = head;
1230 for (;;) {
1231 Index<K,V> d, r;
1232 if ((r = q.right) != null) {
1233 if (r.indexesDeletedNode()) {
1234 q.unlink(r);
1235 q = head; // restart
1236 }
1237 else
1238 q = r;
1239 } else if ((d = q.down) != null) {
1240 q = d;
1241 } else {
1242 Node<K,V> b = q.node;
1243 Node<K,V> n = b.next;
1244 for (;;) {
1245 if (n == null)
1246 return b.isBaseHeader() ? null : b;
1247 Node<K,V> f = n.next; // inconsistent read
1248 if (n != b.next)
1249 break;
1250 Object v = n.value;
1251 if (v == null) { // n is deleted
1252 n.helpDelete(b, f);
1253 break;
1254 }
1255 if (v == n || b.value == null) // b is deleted
1256 break;
1257 b = n;
1258 n = f;
1259 }
1260 q = head; // restart
1261 }
1262 }
1263 }
1264
1265 /**
1266 * Specialized variant of findPredecessor to get predecessor of last
1267 * valid node. Needed when removing the last entry. It is possible
1268 * that all successors of returned node will have been deleted upon
1269 * return, in which case this method can be retried.
1270 * @return likely predecessor of last node
1271 */
1272 private Node<K,V> findPredecessorOfLast() {
1273 for (;;) {
1274 Index<K,V> q = head;
1275 for (;;) {
1276 Index<K,V> d, r;
1277 if ((r = q.right) != null) {
1278 if (r.indexesDeletedNode()) {
1279 q.unlink(r);
1280 break; // must restart
1281 }
1282 // proceed as far across as possible without overshooting
1283 if (r.node.next != null) {
1284 q = r;
1285 continue;
1286 }
1287 }
1288 if ((d = q.down) != null)
1289 q = d;
1290 else
1291 return q.node;
1292 }
1293 }
1294 }
1295
1296 /* ---------------- Relational operations -------------- */
1297
1298 // Control values OR'ed as arguments to findNear
1299
1300 private static final int EQ = 1;
1301 private static final int LT = 2;
1302 private static final int GT = 0; // Actually checked as !LT
1303
1304 /**
1305 * Utility for ceiling, floor, lower, higher methods.
1306 * @param kkey the key
1307 * @param rel the relation -- OR'ed combination of EQ, LT, GT
1308 * @return nearest node fitting relation, or null if no such
1309 */
1310 Node<K,V> doFindNear(K kkey, int rel) {
1311 @SuppressWarnings("unchecked") Comparable<? super K> key =
1312 (Comparable<? super K>)kkey;
1313 for (;;) {
1314 Node<K,V> b = findPredecessor(key);
1315 Node<K,V> n = b.next;
1316 for (;;) {
1317 if (n == null)
1318 return ((rel & LT) == 0 || b.isBaseHeader()) ? null : b;
1319 Node<K,V> f = n.next;
1320 if (n != b.next) // inconsistent read
1321 break;
1322 Object v = n.value;
1323 if (v == null) { // n is deleted
1324 n.helpDelete(b, f);
1325 break;
1326 }
1327 if (v == n || b.value == null) // b is deleted
1328 break;
1329 int c = key.compareTo(n.key);
1330 if ((c == 0 && (rel & EQ) != 0) ||
1331 (c < 0 && (rel & LT) == 0))
1332 return n;
1333 if ( c <= 0 && (rel & LT) != 0)
1334 return b.isBaseHeader() ? null : b;
1335 b = n;
1336 n = f;
1337 }
1338 }
1339 }
1340
1341 /* ---------------- cmp versions -------------- */
1342
1343 // Boringly almost the same as natural-Comparable ones
1344
1345 private Node<K,V> findPredecessorCmp(Comparator<? super K> cmp, Object okey) {
1346 if (cmp == null)
1347 throw new NullPointerException(); // don't postpone errors
1348 @SuppressWarnings("unchecked") K key = (K) okey;
1349 for (;;) {
1350 Index<K,V> q = head;
1351 Index<K,V> r = q.right;
1352 for (;;) {
1353 if (r != null) {
1354 Node<K,V> n = r.node;
1355 K k = n.key;
1356 if (n.value == null) {
1357 if (!q.unlink(r))
1358 break; // restart
1359 r = q.right; // reread r
1360 continue;
1361 }
1362 if (cmp.compare(key, k) > 0) {
1363 q = r;
1364 r = r.right;
1365 continue;
1366 }
1367 }
1368 Index<K,V> d = q.down;
1369 if (d != null) {
1370 q = d;
1371 r = d.right;
1372 } else
1373 return q.node;
1374 }
1375 }
1376 }
1377
1378 private Node<K,V> findNodeCmp(Comparator<? super K> cmp, Object okey) {
1379 if (cmp == null)
1380 throw new NullPointerException(); // don't postpone errors
1381 @SuppressWarnings("unchecked") K key = (K) okey;
1382 for (;;) {
1383 Node<K,V> b = findPredecessorCmp(cmp, key);
1384 Node<K,V> n = b.next;
1385 for (;;) {
1386 if (n == null)
1387 return null;
1388 Node<K,V> f = n.next;
1389 if (n != b.next) // inconsistent read
1390 break;
1391 Object v = n.value;
1392 if (v == null) { // n is deleted
1393 n.helpDelete(b, f);
1394 break;
1395 }
1396 if (v == n || b.value == null) // b is deleted
1397 break;
1398 int c = cmp.compare(key, n.key);
1399 if (c == 0)
1400 return n;
1401 if (c < 0)
1402 return null;
1403 b = n;
1404 n = f;
1405 }
1406 }
1407 }
1408
1409 private V doGetCmp(Comparator<? super K> cmp, Object okey) {
1410 if (cmp == null)
1411 throw new NullPointerException(); // don't postpone errors
1412 @SuppressWarnings("unchecked") K key = (K) okey;
1413 for (;;) {
1414 Node<K,V> b = findPredecessorCmp(cmp, key);
1415 Node<K,V> n = b.next;
1416 for (;;) {
1417 if (n == null)
1418 return null;
1419 Node<K,V> f = n.next;
1420 if (n != b.next) // inconsistent read
1421 break;
1422 Object v = n.value;
1423 if (v == null) { // n is deleted
1424 n.helpDelete(b, f);
1425 break;
1426 }
1427 if (v == n || b.value == null) // b is deleted
1428 break;
1429 int c = cmp.compare(key, n.key);
1430 if (c == 0)
1431 return (V)v;
1432 if (c < 0)
1433 return null;
1434 b = n;
1435 n = f;
1436 }
1437 }
1438 }
1439
1440 private V doPutCmp(Comparator<? super K> cmp, K key, V value, boolean onlyIfAbsent) {
1441 if (cmp == null)
1442 throw new NullPointerException(); // don't postpone errors
1443 for (;;) {
1444 Node<K,V> b = findPredecessorCmp(cmp, key);
1445 Node<K,V> n = b.next;
1446 for (;;) {
1447 if (n != null) {
1448 Node<K,V> f = n.next;
1449 if (n != b.next) // inconsistent read
1450 break;
1451 Object v = n.value;
1452 if (v == null) { // n is deleted
1453 n.helpDelete(b, f);
1454 break;
1455 }
1456 if (v == n || b.value == null) // b is deleted
1457 break;
1458 int c = cmp.compare(key, n.key);
1459 if (c > 0) {
1460 b = n;
1461 n = f;
1462 continue;
1463 }
1464 if (c == 0) {
1465 if (onlyIfAbsent || n.casValue(v, value))
1466 return (V)v;
1467 else
1468 break; // restart if lost race to replace value
1469 }
1470 // else c < 0; fall through
1471 }
1472
1473 Node<K,V> z = new Node<K,V>(key, value, n);
1474 if (!b.casNext(n, z))
1475 break; // restart if lost race to append to b
1476 int level = randomLevel();
1477 if (level > 0)
1478 insertIndex(z, level);
1479 return null;
1480 }
1481 }
1482 }
1483
1484 final V doRemoveCmp(Comparator<? super K> cmp, Object okey, Object value) {
1485 if (cmp == null)
1486 throw new NullPointerException(); // don't postpone errors
1487 @SuppressWarnings("unchecked") K key = (K) okey;
1488 for (;;) {
1489 Node<K,V> b = findPredecessorCmp(cmp, key);
1490 Node<K,V> n = b.next;
1491 for (;;) {
1492 if (n == null)
1493 return null;
1494 Node<K,V> f = n.next;
1495 if (n != b.next) // inconsistent read
1496 break;
1497 Object v = n.value;
1498 if (v == null) { // n is deleted
1499 n.helpDelete(b, f);
1500 break;
1501 }
1502 if (v == n || b.value == null) // b is deleted
1503 break;
1504 int c = cmp.compare(key, n.key);
1505 if (c < 0)
1506 return null;
1507 if (c > 0) {
1508 b = n;
1509 n = f;
1510 continue;
1511 }
1512 if (value != null && !value.equals(v))
1513 return null;
1514 if (!n.casValue(v, null))
1515 break;
1516 if (!n.appendMarker(f) || !b.casNext(n, f))
1517 findNodeCmp(cmp, key); // Retry via findNode
1518 else {
1519 findPredecessorCmp(cmp, key); // Clean index
1520 if (head.right == null)
1521 tryReduceLevel();
1522 }
1523 return (V)v;
1524 }
1525 }
1526 }
1527
1528 Node<K,V> doFindNearCmp(Comparator<? super K> cmp, K key, int rel) {
1529 if (cmp == null)
1530 throw new NullPointerException(); // don't postpone errors
1531 for (;;) {
1532 Node<K,V> b = findPredecessorCmp(cmp, key);
1533 Node<K,V> n = b.next;
1534 for (;;) {
1535 if (n == null)
1536 return ((rel & LT) == 0 || b.isBaseHeader()) ? null : b;
1537 Node<K,V> f = n.next;
1538 if (n != b.next) // inconsistent read
1539 break;
1540 Object v = n.value;
1541 if (v == null) { // n is deleted
1542 n.helpDelete(b, f);
1543 break;
1544 }
1545 if (v == n || b.value == null) // b is deleted
1546 break;
1547 int c = cmp.compare(key, n.key);
1548 if ((c == 0 && (rel & EQ) != 0) ||
1549 (c < 0 && (rel & LT) == 0))
1550 return n;
1551 if ( c <= 0 && (rel & LT) != 0)
1552 return b.isBaseHeader() ? null : b;
1553 b = n;
1554 n = f;
1555 }
1556 }
1557 }
1558
1559 /* ---------------- Relays to natural vs cmp methods -------------- */
1560
1561 Node<K,V> findNear(K key, int rel) {
1562 Comparator<? super K> cmp;
1563 return (cmp = comparator) == null ? doFindNear(key, rel) :
1564 doFindNearCmp(cmp, key, rel);
1565 }
1566
1567 /**
1568 * Returns SimpleImmutableEntry for results of findNear.
1569 * @param key the key
1570 * @param rel the relation -- OR'ed combination of EQ, LT, GT
1571 * @return Entry fitting relation, or null if no such
1572 */
1573 AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) {
1574 for (;;) {
1575 Node<K,V> n = findNear(key, rel);
1576 if (n == null)
1577 return null;
1578 AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
1579 if (e != null)
1580 return e;
1581 }
1582 }
1583
1584 /* ---------------- Constructors -------------- */
1585
1586 /**
1587 * Constructs a new, empty map, sorted according to the
1588 * {@linkplain Comparable natural ordering} of the keys.
1589 */
1590 public ConcurrentSkipListMap() {
1591 this.comparator = null;
1592 initialize();
1593 }
1594
1595 /**
1596 * Constructs a new, empty map, sorted according to the specified
1597 * comparator.
1598 *
1599 * @param comparator the comparator that will be used to order this map.
1600 * If {@code null}, the {@linkplain Comparable natural
1601 * ordering} of the keys will be used.
1602 */
1603 public ConcurrentSkipListMap(Comparator<? super K> comparator) {
1604 this.comparator = comparator;
1605 initialize();
1606 }
1607
1608 /**
1609 * Constructs a new map containing the same mappings as the given map,
1610 * sorted according to the {@linkplain Comparable natural ordering} of
1611 * the keys.
1612 *
1613 * @param m the map whose mappings are to be placed in this map
1614 * @throws ClassCastException if the keys in {@code m} are not
1615 * {@link Comparable}, or are not mutually comparable
1616 * @throws NullPointerException if the specified map or any of its keys
1617 * or values are null
1618 */
1619 public ConcurrentSkipListMap(Map<? extends K, ? extends V> m) {
1620 this.comparator = null;
1621 initialize();
1622 putAll(m);
1623 }
1624
1625 /**
1626 * Constructs a new map containing the same mappings and using the
1627 * same ordering as the specified sorted map.
1628 *
1629 * @param m the sorted map whose mappings are to be placed in this
1630 * map, and whose comparator is to be used to sort this map
1631 * @throws NullPointerException if the specified sorted map or any of
1632 * its keys or values are null
1633 */
1634 public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) {
1635 this.comparator = m.comparator();
1636 initialize();
1637 buildFromSorted(m);
1638 }
1639
1640 /**
1641 * Creates a new {@link Set} backed by a ConcurrentSkipListMap
1642 * from the given type to {@code Boolean.TRUE}.
1643 *
1644 * @return the new set
1645 */
1646 public static <K> KeySetView<K,Boolean> newKeySet() {
1647 return new KeySetView<K,Boolean>(new ConcurrentSkipListMap<K,Boolean>(),
1648 Boolean.TRUE);
1649 }
1650
1651 /**
1652 * Creates a new {@link Set} backed by a ConcurrentSkipListMap
1653 * from the given type to {@code Boolean.TRUE}, using the
1654 * given comparator.
1655 *
1656 * @param comparator the comparator that will be used to order this map.
1657 * If {@code null}, the {@linkplain Comparable natural
1658 * ordering} of the keys will be used.
1659 *
1660 * @return the new set
1661 */
1662 public static <K> KeySetView<K,Boolean> newKeySet(Comparator<? super K> comparator) {
1663 return new KeySetView<K,Boolean>
1664 (new ConcurrentSkipListMap<K,Boolean>(comparator), Boolean.TRUE);
1665 }
1666
1667 /**
1668 * Returns a shallow copy of this {@code ConcurrentSkipListMap}
1669 * instance. (The keys and values themselves are not cloned.)
1670 *
1671 * @return a shallow copy of this map
1672 */
1673 public ConcurrentSkipListMap<K,V> clone() {
1674 try {
1675 @SuppressWarnings("unchecked")
1676 ConcurrentSkipListMap<K,V> clone =
1677 (ConcurrentSkipListMap<K,V>) super.clone();
1678 clone.initialize();
1679 clone.buildFromSorted(this);
1680 return clone;
1681 } catch (CloneNotSupportedException e) {
1682 throw new InternalError();
1683 }
1684 }
1685
1686 /**
1687 * Streamlined bulk insertion to initialize from elements of
1688 * given sorted map. Call only from constructor or clone
1689 * method.
1690 */
1691 private void buildFromSorted(SortedMap<K, ? extends V> map) {
1692 if (map == null)
1693 throw new NullPointerException();
1694
1695 HeadIndex<K,V> h = head;
1696 Node<K,V> basepred = h.node;
1697
1698 // Track the current rightmost node at each level. Uses an
1699 // ArrayList to avoid committing to initial or maximum level.
1700 ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
1701
1702 // initialize
1703 for (int i = 0; i <= h.level; ++i)
1704 preds.add(null);
1705 Index<K,V> q = h;
1706 for (int i = h.level; i > 0; --i) {
1707 preds.set(i, q);
1708 q = q.down;
1709 }
1710
1711 Iterator<? extends Map.Entry<? extends K, ? extends V>> it =
1712 map.entrySet().iterator();
1713 while (it.hasNext()) {
1714 Map.Entry<? extends K, ? extends V> e = it.next();
1715 int j = randomLevel();
1716 if (j > h.level) j = h.level + 1;
1717 K k = e.getKey();
1718 V v = e.getValue();
1719 if (k == null || v == null)
1720 throw new NullPointerException();
1721 Node<K,V> z = new Node<K,V>(k, v, null);
1722 basepred.next = z;
1723 basepred = z;
1724 if (j > 0) {
1725 Index<K,V> idx = null;
1726 for (int i = 1; i <= j; ++i) {
1727 idx = new Index<K,V>(z, idx, null);
1728 if (i > h.level)
1729 h = new HeadIndex<K,V>(h.node, h, idx, i);
1730
1731 if (i < preds.size()) {
1732 preds.get(i).right = idx;
1733 preds.set(i, idx);
1734 } else
1735 preds.add(idx);
1736 }
1737 }
1738 }
1739 head = h;
1740 }
1741
1742 /* ---------------- Serialization -------------- */
1743
1744 /**
1745 * Saves this map to a stream (that is, serializes it).
1746 *
1747 * @serialData The key (Object) and value (Object) for each
1748 * key-value mapping represented by the map, followed by
1749 * {@code null}. The key-value mappings are emitted in key-order
1750 * (as determined by the Comparator, or by the keys' natural
1751 * ordering if no Comparator).
1752 */
1753 private void writeObject(java.io.ObjectOutputStream s)
1754 throws java.io.IOException {
1755 // Write out the Comparator and any hidden stuff
1756 s.defaultWriteObject();
1757
1758 // Write out keys and values (alternating)
1759 for (Node<K,V> n = findFirst(); n != null; n = n.next) {
1760 V v = n.getValidValue();
1761 if (v != null) {
1762 s.writeObject(n.key);
1763 s.writeObject(v);
1764 }
1765 }
1766 s.writeObject(null);
1767 }
1768
1769 /**
1770 * Reconstitutes this map from a stream (that is, deserializes it).
1771 */
1772 private void readObject(final java.io.ObjectInputStream s)
1773 throws java.io.IOException, ClassNotFoundException {
1774 // Read in the Comparator and any hidden stuff
1775 s.defaultReadObject();
1776 // Reset transients
1777 initialize();
1778
1779 /*
1780 * This is nearly identical to buildFromSorted, but is
1781 * distinct because readObject calls can't be nicely adapted
1782 * as the kind of iterator needed by buildFromSorted. (They
1783 * can be, but doing so requires type cheats and/or creation
1784 * of adaptor classes.) It is simpler to just adapt the code.
1785 */
1786
1787 HeadIndex<K,V> h = head;
1788 Node<K,V> basepred = h.node;
1789 ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
1790 for (int i = 0; i <= h.level; ++i)
1791 preds.add(null);
1792 Index<K,V> q = h;
1793 for (int i = h.level; i > 0; --i) {
1794 preds.set(i, q);
1795 q = q.down;
1796 }
1797
1798 for (;;) {
1799 Object k = s.readObject();
1800 if (k == null)
1801 break;
1802 Object v = s.readObject();
1803 if (v == null)
1804 throw new NullPointerException();
1805 K key = (K) k;
1806 V val = (V) v;
1807 int j = randomLevel();
1808 if (j > h.level) j = h.level + 1;
1809 Node<K,V> z = new Node<K,V>(key, val, null);
1810 basepred.next = z;
1811 basepred = z;
1812 if (j > 0) {
1813 Index<K,V> idx = null;
1814 for (int i = 1; i <= j; ++i) {
1815 idx = new Index<K,V>(z, idx, null);
1816 if (i > h.level)
1817 h = new HeadIndex<K,V>(h.node, h, idx, i);
1818
1819 if (i < preds.size()) {
1820 preds.get(i).right = idx;
1821 preds.set(i, idx);
1822 } else
1823 preds.add(idx);
1824 }
1825 }
1826 }
1827 head = h;
1828 }
1829
1830 /* ------ Map API methods ------ */
1831
1832 /**
1833 * Returns {@code true} if this map contains a mapping for the specified
1834 * key.
1835 *
1836 * @param key key whose presence in this map is to be tested
1837 * @return {@code true} if this map contains a mapping for the specified key
1838 * @throws ClassCastException if the specified key cannot be compared
1839 * with the keys currently in the map
1840 * @throws NullPointerException if the specified key is null
1841 */
1842 public boolean containsKey(Object key) {
1843 Comparator<? super K> cmp;
1844 Object v = ((cmp = comparator) == null ? doGet(key) :
1845 doGetCmp(cmp, key));
1846 return v != null;
1847 }
1848
1849 /**
1850 * Returns the value to which the specified key is mapped,
1851 * or {@code null} if this map contains no mapping for the key.
1852 *
1853 * <p>More formally, if this map contains a mapping from a key
1854 * {@code k} to a value {@code v} such that {@code key} compares
1855 * equal to {@code k} according to the map's ordering, then this
1856 * method returns {@code v}; otherwise it returns {@code null}.
1857 * (There can be at most one such mapping.)
1858 *
1859 * @throws ClassCastException if the specified key cannot be compared
1860 * with the keys currently in the map
1861 * @throws NullPointerException if the specified key is null
1862 */
1863 public V get(Object key) {
1864 Comparator<? super K> cmp;
1865 return ((cmp = comparator) == null) ? doGet(key) : doGetCmp(cmp, key);
1866 }
1867
1868 /**
1869 * Associates the specified value with the specified key in this map.
1870 * If the map previously contained a mapping for the key, the old
1871 * value is replaced.
1872 *
1873 * @param key key with which the specified value is to be associated
1874 * @param value value to be associated with the specified key
1875 * @return the previous value associated with the specified key, or
1876 * {@code null} if there was no mapping for the key
1877 * @throws ClassCastException if the specified key cannot be compared
1878 * with the keys currently in the map
1879 * @throws NullPointerException if the specified key or value is null
1880 */
1881 public V put(K key, V value) {
1882 Comparator<? super K> cmp;
1883 if (value == null)
1884 throw new NullPointerException();
1885 return ((cmp = comparator) == null) ?
1886 doPut(key, value, false) : doPutCmp(cmp, key, value, false);
1887 }
1888
1889 /**
1890 * Removes the mapping for the specified key from this map if present.
1891 *
1892 * @param key key for which mapping should be removed
1893 * @return the previous value associated with the specified key, or
1894 * {@code null} if there was no mapping for the key
1895 * @throws ClassCastException if the specified key cannot be compared
1896 * with the keys currently in the map
1897 * @throws NullPointerException if the specified key is null
1898 */
1899 public V remove(Object key) {
1900 Comparator<? super K> cmp;
1901 return ((cmp = comparator) == null) ? doRemove(key, null) :
1902 doRemoveCmp(cmp, key, null);
1903 }
1904
1905 /**
1906 * Returns {@code true} if this map maps one or more keys to the
1907 * specified value. This operation requires time linear in the
1908 * map size. Additionally, it is possible for the map to change
1909 * during execution of this method, in which case the returned
1910 * result may be inaccurate.
1911 *
1912 * @param value value whose presence in this map is to be tested
1913 * @return {@code true} if a mapping to {@code value} exists;
1914 * {@code false} otherwise
1915 * @throws NullPointerException if the specified value is null
1916 */
1917 public boolean containsValue(Object value) {
1918 if (value == null)
1919 throw new NullPointerException();
1920 for (Node<K,V> n = findFirst(); n != null; n = n.next) {
1921 V v = n.getValidValue();
1922 if (v != null && value.equals(v))
1923 return true;
1924 }
1925 return false;
1926 }
1927
1928 /**
1929 * Returns the number of key-value mappings in this map. If this map
1930 * contains more than {@code Integer.MAX_VALUE} elements, it
1931 * returns {@code Integer.MAX_VALUE}.
1932 *
1933 * <p>Beware that, unlike in most collections, this method is
1934 * <em>NOT</em> a constant-time operation. Because of the
1935 * asynchronous nature of these maps, determining the current
1936 * number of elements requires traversing them all to count them.
1937 * Additionally, it is possible for the size to change during
1938 * execution of this method, in which case the returned result
1939 * will be inaccurate. Thus, this method is typically not very
1940 * useful in concurrent applications.
1941 *
1942 * @return the number of elements in this map
1943 */
1944 public int size() {
1945 long count = 0;
1946 for (Node<K,V> n = findFirst(); n != null; n = n.next) {
1947 if (n.getValidValue() != null)
1948 ++count;
1949 }
1950 return (count >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count;
1951 }
1952
1953 /**
1954 * Returns {@code true} if this map contains no key-value mappings.
1955 * @return {@code true} if this map contains no key-value mappings
1956 */
1957 public boolean isEmpty() {
1958 return findFirst() == null;
1959 }
1960
1961 /**
1962 * Removes all of the mappings from this map.
1963 */
1964 public void clear() {
1965 initialize();
1966 }
1967
1968 /* ---------------- View methods -------------- */
1969
1970 /*
1971 * Note: Lazy initialization works for views because view classes
1972 * are stateless/immutable so it doesn't matter wrt correctness if
1973 * more than one is created (which will only rarely happen). Even
1974 * so, the following idiom conservatively ensures that the method
1975 * returns the one it created if it does so, not one created by
1976 * another racing thread.
1977 */
1978
1979 /**
1980 * Returns a {@link NavigableSet} view of the keys contained in this map.
1981 * The set's iterator returns the keys in ascending order.
1982 * The set is backed by the map, so changes to the map are
1983 * reflected in the set, and vice-versa. The set supports element
1984 * removal, which removes the corresponding mapping from the map,
1985 * via the {@code Iterator.remove}, {@code Set.remove},
1986 * {@code removeAll}, {@code retainAll}, and {@code clear}
1987 * operations. It does not support the {@code add} or {@code addAll}
1988 * operations.
1989 *
1990 * <p>The view's {@code iterator} is a "weakly consistent" iterator
1991 * that will never throw {@link ConcurrentModificationException},
1992 * and guarantees to traverse elements as they existed upon
1993 * construction of the iterator, and may (but is not guaranteed to)
1994 * reflect any modifications subsequent to construction.
1995 *
1996 * <p>This method is equivalent to method {@code navigableKeySet}.
1997 *
1998 * @return a navigable set view of the keys in this map
1999 */
2000 public NavigableSet<K> keySet() {
2001 KeySetView<K,V> ks = keySet;
2002 return (ks != null) ? ks : (keySet = new KeySetView<K,V>(this, null));
2003 }
2004
2005 public NavigableSet<K> navigableKeySet() {
2006 KeySetView<K,V> ks = keySet;
2007 return (ks != null) ? ks : (keySet = new KeySetView<K,V>(this, null));
2008 }
2009
2010 /**
2011 * Returns a {@link Set} view of the keys in this map, using the
2012 * given common mapped value for any additions (i.e., {@link
2013 * Collection#add} and {@link Collection#addAll}). This is of
2014 * course only appropriate if it is acceptable to use the same
2015 * value for all additions from this view.
2016 *
2017 * @param mappedValue the mapped value to use for any
2018 * additions.
2019 * @return the set view
2020 * @throws NullPointerException if the mappedValue is null
2021 */
2022 public KeySetView<K,V> keySet(V mappedValue) {
2023 if (mappedValue == null)
2024 throw new NullPointerException();
2025 return new KeySetView<K,V>(this, mappedValue);
2026 }
2027
2028 /**
2029 * Returns a {@link Collection} view of the values contained in this map.
2030 * The collection's iterator returns the values in ascending order
2031 * of the corresponding keys.
2032 * The collection is backed by the map, so changes to the map are
2033 * reflected in the collection, and vice-versa. The collection
2034 * supports element removal, which removes the corresponding
2035 * mapping from the map, via the {@code Iterator.remove},
2036 * {@code Collection.remove}, {@code removeAll},
2037 * {@code retainAll} and {@code clear} operations. It does not
2038 * support the {@code add} or {@code addAll} operations.
2039 *
2040 * <p>The view's {@code iterator} is a "weakly consistent" iterator
2041 * that will never throw {@link ConcurrentModificationException},
2042 * and guarantees to traverse elements as they existed upon
2043 * construction of the iterator, and may (but is not guaranteed to)
2044 * reflect any modifications subsequent to construction.
2045 */
2046 public Collection<V> values() {
2047 Values<V> vs = values;
2048 return (vs != null) ? vs : (values = new Values<V>(this));
2049 }
2050
2051 /**
2052 * Returns a {@link Set} view of the mappings contained in this map.
2053 * The set's iterator returns the entries in ascending key order.
2054 * The set is backed by the map, so changes to the map are
2055 * reflected in the set, and vice-versa. The set supports element
2056 * removal, which removes the corresponding mapping from the map,
2057 * via the {@code Iterator.remove}, {@code Set.remove},
2058 * {@code removeAll}, {@code retainAll} and {@code clear}
2059 * operations. It does not support the {@code add} or
2060 * {@code addAll} operations.
2061 *
2062 * <p>The view's {@code iterator} is a "weakly consistent" iterator
2063 * that will never throw {@link ConcurrentModificationException},
2064 * and guarantees to traverse elements as they existed upon
2065 * construction of the iterator, and may (but is not guaranteed to)
2066 * reflect any modifications subsequent to construction.
2067 *
2068 * <p>The {@code Map.Entry} elements returned by
2069 * {@code iterator.next()} do <em>not</em> support the
2070 * {@code setValue} operation.
2071 *
2072 * @return a set view of the mappings contained in this map,
2073 * sorted in ascending key order
2074 */
2075 public Set<Map.Entry<K,V>> entrySet() {
2076 EntrySet<K,V> es = entrySet;
2077 return (es != null) ? es : (entrySet = new EntrySet<K,V>(this));
2078 }
2079
2080 public ConcurrentNavigableMap<K,V> descendingMap() {
2081 ConcurrentNavigableMap<K,V> dm = descendingMap;
2082 return (dm != null) ? dm : (descendingMap = new SubMap<K,V>
2083 (this, null, false, null, false, true));
2084 }
2085
2086 public NavigableSet<K> descendingKeySet() {
2087 return descendingMap().navigableKeySet();
2088 }
2089
2090 /* ---------------- AbstractMap Overrides -------------- */
2091
2092 /**
2093 * Compares the specified object with this map for equality.
2094 * Returns {@code true} if the given object is also a map and the
2095 * two maps represent the same mappings. More formally, two maps
2096 * {@code m1} and {@code m2} represent the same mappings if
2097 * {@code m1.entrySet().equals(m2.entrySet())}. This
2098 * operation may return misleading results if either map is
2099 * concurrently modified during execution of this method.
2100 *
2101 * @param o object to be compared for equality with this map
2102 * @return {@code true} if the specified object is equal to this map
2103 */
2104 public boolean equals(Object o) {
2105 if (o == this)
2106 return true;
2107 if (!(o instanceof Map))
2108 return false;
2109 Map<?,?> m = (Map<?,?>) o;
2110 try {
2111 for (Map.Entry<K,V> e : this.entrySet())
2112 if (! e.getValue().equals(m.get(e.getKey())))
2113 return false;
2114 for (Map.Entry<?,?> e : m.entrySet()) {
2115 Object k = e.getKey();
2116 Object v = e.getValue();
2117 if (k == null || v == null || !v.equals(get(k)))
2118 return false;
2119 }
2120 return true;
2121 } catch (ClassCastException unused) {
2122 return false;
2123 } catch (NullPointerException unused) {
2124 return false;
2125 }
2126 }
2127
2128 /* ------ ConcurrentMap API methods ------ */
2129
2130 /**
2131 * {@inheritDoc}
2132 *
2133 * @return the previous value associated with the specified key,
2134 * or {@code null} if there was no mapping for the key
2135 * @throws ClassCastException if the specified key cannot be compared
2136 * with the keys currently in the map
2137 * @throws NullPointerException if the specified key or value is null
2138 */
2139 public V putIfAbsent(K key, V value) {
2140 Comparator<? super K> cmp;
2141 if (value == null)
2142 throw new NullPointerException();
2143 return ((cmp = comparator) == null) ?
2144 doPut(key, value, true) : doPutCmp(cmp, key, value, true);
2145 }
2146
2147 /**
2148 * {@inheritDoc}
2149 *
2150 * @throws ClassCastException if the specified key cannot be compared
2151 * with the keys currently in the map
2152 * @throws NullPointerException if the specified key is null
2153 */
2154 public boolean remove(Object key, Object value) {
2155 if (key == null)
2156 throw new NullPointerException();
2157 if (value == null)
2158 return false;
2159 Comparator<? super K> cmp;
2160 Object v = ((cmp = comparator) == null) ? doRemove(key, value) :
2161 doRemoveCmp(cmp, key, value);
2162 return v != null;
2163 }
2164
2165 /**
2166 * {@inheritDoc}
2167 *
2168 * @throws ClassCastException if the specified key cannot be compared
2169 * with the keys currently in the map
2170 * @throws NullPointerException if any of the arguments are null
2171 */
2172 public boolean replace(K key, V oldValue, V newValue) {
2173 if (oldValue == null || newValue == null)
2174 throw new NullPointerException();
2175 Comparator<? super K> cmp = comparator;
2176 for (;;) {
2177 Node<K,V> n = (cmp == null) ?
2178 findNode((Comparable<? super K>)key) :
2179 findNodeCmp(cmp, key);
2180 if (n == null)
2181 return false;
2182 Object v = n.value;
2183 if (v != null) {
2184 if (!oldValue.equals(v))
2185 return false;
2186 if (n.casValue(v, newValue))
2187 return true;
2188 }
2189 }
2190 }
2191
2192 /**
2193 * {@inheritDoc}
2194 *
2195 * @return the previous value associated with the specified key,
2196 * or {@code null} if there was no mapping for the key
2197 * @throws ClassCastException if the specified key cannot be compared
2198 * with the keys currently in the map
2199 * @throws NullPointerException if the specified key or value is null
2200 */
2201 public V replace(K key, V value) {
2202 if (value == null)
2203 throw new NullPointerException();
2204 Comparator<? super K> cmp = comparator;
2205 for (;;) {
2206 Node<K,V> n = (cmp == null) ?
2207 findNode((Comparable<? super K>)key) :
2208 findNodeCmp(cmp, key);
2209 if (n == null)
2210 return null;
2211 Object v = n.value;
2212 if (v != null && n.casValue(v, value))
2213 return (V)v;
2214 }
2215 }
2216
2217 /* ------ SortedMap API methods ------ */
2218
2219 public Comparator<? super K> comparator() {
2220 return comparator;
2221 }
2222
2223 /**
2224 * @throws NoSuchElementException {@inheritDoc}
2225 */
2226 public K firstKey() {
2227 Node<K,V> n = findFirst();
2228 if (n == null)
2229 throw new NoSuchElementException();
2230 return n.key;
2231 }
2232
2233 /**
2234 * @throws NoSuchElementException {@inheritDoc}
2235 */
2236 public K lastKey() {
2237 Node<K,V> n = findLast();
2238 if (n == null)
2239 throw new NoSuchElementException();
2240 return n.key;
2241 }
2242
2243 /**
2244 * @throws ClassCastException {@inheritDoc}
2245 * @throws NullPointerException if {@code fromKey} or {@code toKey} is null
2246 * @throws IllegalArgumentException {@inheritDoc}
2247 */
2248 public ConcurrentNavigableMap<K,V> subMap(K fromKey,
2249 boolean fromInclusive,
2250 K toKey,
2251 boolean toInclusive) {
2252 if (fromKey == null || toKey == null)
2253 throw new NullPointerException();
2254 return new SubMap<K,V>
2255 (this, fromKey, fromInclusive, toKey, toInclusive, false);
2256 }
2257
2258 /**
2259 * @throws ClassCastException {@inheritDoc}
2260 * @throws NullPointerException if {@code toKey} is null
2261 * @throws IllegalArgumentException {@inheritDoc}
2262 */
2263 public ConcurrentNavigableMap<K,V> headMap(K toKey,
2264 boolean inclusive) {
2265 if (toKey == null)
2266 throw new NullPointerException();
2267 return new SubMap<K,V>
2268 (this, null, false, toKey, inclusive, false);
2269 }
2270
2271 /**
2272 * @throws ClassCastException {@inheritDoc}
2273 * @throws NullPointerException if {@code fromKey} is null
2274 * @throws IllegalArgumentException {@inheritDoc}
2275 */
2276 public ConcurrentNavigableMap<K,V> tailMap(K fromKey,
2277 boolean inclusive) {
2278 if (fromKey == null)
2279 throw new NullPointerException();
2280 return new SubMap<K,V>
2281 (this, fromKey, inclusive, null, false, false);
2282 }
2283
2284 /**
2285 * @throws ClassCastException {@inheritDoc}
2286 * @throws NullPointerException if {@code fromKey} or {@code toKey} is null
2287 * @throws IllegalArgumentException {@inheritDoc}
2288 */
2289 public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) {
2290 return subMap(fromKey, true, toKey, false);
2291 }
2292
2293 /**
2294 * @throws ClassCastException {@inheritDoc}
2295 * @throws NullPointerException if {@code toKey} is null
2296 * @throws IllegalArgumentException {@inheritDoc}
2297 */
2298 public ConcurrentNavigableMap<K,V> headMap(K toKey) {
2299 return headMap(toKey, false);
2300 }
2301
2302 /**
2303 * @throws ClassCastException {@inheritDoc}
2304 * @throws NullPointerException if {@code fromKey} is null
2305 * @throws IllegalArgumentException {@inheritDoc}
2306 */
2307 public ConcurrentNavigableMap<K,V> tailMap(K fromKey) {
2308 return tailMap(fromKey, true);
2309 }
2310
2311 /* ---------------- Relational operations -------------- */
2312
2313 /**
2314 * Returns a key-value mapping associated with the greatest key
2315 * strictly less than the given key, or {@code null} if there is
2316 * no such key. The returned entry does <em>not</em> support the
2317 * {@code Entry.setValue} method.
2318 *
2319 * @throws ClassCastException {@inheritDoc}
2320 * @throws NullPointerException if the specified key is null
2321 */
2322 public Map.Entry<K,V> lowerEntry(K key) {
2323 return getNear(key, LT);
2324 }
2325
2326 /**
2327 * @throws ClassCastException {@inheritDoc}
2328 * @throws NullPointerException if the specified key is null
2329 */
2330 public K lowerKey(K key) {
2331 Comparator<? super K> cmp;
2332 Node<K,V> n = findNear(key, LT);
2333 return (n == null) ? null : n.key;
2334 }
2335
2336 /**
2337 * Returns a key-value mapping associated with the greatest key
2338 * less than or equal to the given key, or {@code null} if there
2339 * is no such key. The returned entry does <em>not</em> support
2340 * the {@code Entry.setValue} method.
2341 *
2342 * @param key the key
2343 * @throws ClassCastException {@inheritDoc}
2344 * @throws NullPointerException if the specified key is null
2345 */
2346 public Map.Entry<K,V> floorEntry(K key) {
2347 return getNear(key, LT|EQ);
2348 }
2349
2350 /**
2351 * @param key the key
2352 * @throws ClassCastException {@inheritDoc}
2353 * @throws NullPointerException if the specified key is null
2354 */
2355 public K floorKey(K key) {
2356 Node<K,V> n = findNear(key, LT|EQ);
2357 return (n == null) ? null : n.key;
2358 }
2359
2360 /**
2361 * Returns a key-value mapping associated with the least key
2362 * greater than or equal to the given key, or {@code null} if
2363 * there is no such entry. The returned entry does <em>not</em>
2364 * support the {@code Entry.setValue} method.
2365 *
2366 * @throws ClassCastException {@inheritDoc}
2367 * @throws NullPointerException if the specified key is null
2368 */
2369 public Map.Entry<K,V> ceilingEntry(K key) {
2370 return getNear(key, GT|EQ);
2371 }
2372
2373 /**
2374 * @throws ClassCastException {@inheritDoc}
2375 * @throws NullPointerException if the specified key is null
2376 */
2377 public K ceilingKey(K key) {
2378 Node<K,V> n = findNear(key, GT|EQ);
2379 return (n == null) ? null : n.key;
2380 }
2381
2382 /**
2383 * Returns a key-value mapping associated with the least key
2384 * strictly greater than the given key, or {@code null} if there
2385 * is no such key. The returned entry does <em>not</em> support
2386 * the {@code Entry.setValue} method.
2387 *
2388 * @param key the key
2389 * @throws ClassCastException {@inheritDoc}
2390 * @throws NullPointerException if the specified key is null
2391 */
2392 public Map.Entry<K,V> higherEntry(K key) {
2393 return getNear(key, GT);
2394 }
2395
2396 /**
2397 * @param key the key
2398 * @throws ClassCastException {@inheritDoc}
2399 * @throws NullPointerException if the specified key is null
2400 */
2401 public K higherKey(K key) {
2402 Node<K,V> n = findNear(key, GT);
2403 return (n == null) ? null : n.key;
2404 }
2405
2406 /**
2407 * Returns a key-value mapping associated with the least
2408 * key in this map, or {@code null} if the map is empty.
2409 * The returned entry does <em>not</em> support
2410 * the {@code Entry.setValue} method.
2411 */
2412 public Map.Entry<K,V> firstEntry() {
2413 for (;;) {
2414 Node<K,V> n = findFirst();
2415 if (n == null)
2416 return null;
2417 AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
2418 if (e != null)
2419 return e;
2420 }
2421 }
2422
2423 /**
2424 * Returns a key-value mapping associated with the greatest
2425 * key in this map, or {@code null} if the map is empty.
2426 * The returned entry does <em>not</em> support
2427 * the {@code Entry.setValue} method.
2428 */
2429 public Map.Entry<K,V> lastEntry() {
2430 for (;;) {
2431 Node<K,V> n = findLast();
2432 if (n == null)
2433 return null;
2434 AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
2435 if (e != null)
2436 return e;
2437 }
2438 }
2439
2440 /**
2441 * Removes and returns a key-value mapping associated with
2442 * the least key in this map, or {@code null} if the map is empty.
2443 * The returned entry does <em>not</em> support
2444 * the {@code Entry.setValue} method.
2445 */
2446 public Map.Entry<K,V> pollFirstEntry() {
2447 return doRemoveFirstEntry();
2448 }
2449
2450 /**
2451 * Removes and returns a key-value mapping associated with
2452 * the greatest key in this map, or {@code null} if the map is empty.
2453 * The returned entry does <em>not</em> support
2454 * the {@code Entry.setValue} method.
2455 */
2456 public Map.Entry<K,V> pollLastEntry() {
2457 return doRemoveLastEntry();
2458 }
2459
2460
2461 /* ---------------- Iterators -------------- */
2462
2463 /**
2464 * Base of iterator classes:
2465 */
2466 abstract class Iter<T> implements Iterator<T> {
2467 /** the last node returned by next() */
2468 Node<K,V> lastReturned;
2469 /** the next node to return from next(); */
2470 Node<K,V> next;
2471 /** Cache of next value field to maintain weak consistency */
2472 V nextValue;
2473
2474 /** Initializes ascending iterator for entire range. */
2475 Iter() {
2476 for (;;) {
2477 next = findFirst();
2478 if (next == null)
2479 break;
2480 Object x = next.value;
2481 if (x != null && x != next) {
2482 nextValue = (V) x;
2483 break;
2484 }
2485 }
2486 }
2487
2488 public final boolean hasNext() {
2489 return next != null;
2490 }
2491
2492 /** Advances next to higher entry. */
2493 final void advance() {
2494 if (next == null)
2495 throw new NoSuchElementException();
2496 lastReturned = next;
2497 for (;;) {
2498 next = next.next;
2499 if (next == null)
2500 break;
2501 Object x = next.value;
2502 if (x != null && x != next) {
2503 nextValue = (V) x;
2504 break;
2505 }
2506 }
2507 }
2508
2509 public void remove() {
2510 Node<K,V> l = lastReturned;
2511 if (l == null)
2512 throw new IllegalStateException();
2513 // It would not be worth all of the overhead to directly
2514 // unlink from here. Using remove is fast enough.
2515 ConcurrentSkipListMap.this.remove(l.key);
2516 lastReturned = null;
2517 }
2518
2519 }
2520
2521 final class ValueIterator extends Iter<V> {
2522 public V next() {
2523 V v = nextValue;
2524 advance();
2525 return v;
2526 }
2527 }
2528
2529 final class KeyIterator extends Iter<K> {
2530 public K next() {
2531 Node<K,V> n = next;
2532 advance();
2533 return n.key;
2534 }
2535 }
2536
2537 final class EntryIterator extends Iter<Map.Entry<K,V>> {
2538 public Map.Entry<K,V> next() {
2539 Node<K,V> n = next;
2540 V v = nextValue;
2541 advance();
2542 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
2543 }
2544 }
2545
2546 // Factory methods for iterators needed by ConcurrentSkipListSet etc
2547
2548 Iterator<K> keyIterator() {
2549 return new KeyIterator();
2550 }
2551
2552 Iterator<V> valueIterator() {
2553 return new ValueIterator();
2554 }
2555
2556 Iterator<Map.Entry<K,V>> entryIterator() {
2557 return new EntryIterator();
2558 }
2559
2560 /* ---------------- View Classes -------------- */
2561
2562 /*
2563 * View classes are static, delegating to a ConcurrentNavigableMap
2564 * to allow use by SubMaps, which outweighs the ugliness of
2565 * needing type-tests for Iterator methods.
2566 */
2567
2568 static final <E> List<E> toList(Collection<E> c) {
2569 // Using size() here would be a pessimization.
2570 List<E> list = new ArrayList<E>();
2571 for (E e : c)
2572 list.add(e);
2573 return list;
2574 }
2575
2576 static final class KeySet<E>
2577 extends AbstractSet<E> implements NavigableSet<E> {
2578 private final ConcurrentNavigableMap<E,?> m;
2579 KeySet(ConcurrentNavigableMap<E,?> map) { m = map; }
2580 public int size() { return m.size(); }
2581 public boolean isEmpty() { return m.isEmpty(); }
2582 public boolean contains(Object o) { return m.containsKey(o); }
2583 public boolean remove(Object o) { return m.remove(o) != null; }
2584 public void clear() { m.clear(); }
2585 public E lower(E e) { return m.lowerKey(e); }
2586 public E floor(E e) { return m.floorKey(e); }
2587 public E ceiling(E e) { return m.ceilingKey(e); }
2588 public E higher(E e) { return m.higherKey(e); }
2589 public Comparator<? super E> comparator() { return m.comparator(); }
2590 public E first() { return m.firstKey(); }
2591 public E last() { return m.lastKey(); }
2592 public E pollFirst() {
2593 Map.Entry<E,?> e = m.pollFirstEntry();
2594 return (e == null) ? null : e.getKey();
2595 }
2596 public E pollLast() {
2597 Map.Entry<E,?> e = m.pollLastEntry();
2598 return (e == null) ? null : e.getKey();
2599 }
2600 public Iterator<E> iterator() {
2601 if (m instanceof ConcurrentSkipListMap)
2602 return ((ConcurrentSkipListMap<E,Object>)m).keyIterator();
2603 else
2604 return ((ConcurrentSkipListMap.SubMap<E,Object>)m).keyIterator();
2605 }
2606 public boolean equals(Object o) {
2607 if (o == this)
2608 return true;
2609 if (!(o instanceof Set))
2610 return false;
2611 Collection<?> c = (Collection<?>) o;
2612 try {
2613 return containsAll(c) && c.containsAll(this);
2614 } catch (ClassCastException unused) {
2615 return false;
2616 } catch (NullPointerException unused) {
2617 return false;
2618 }
2619 }
2620 public Object[] toArray() { return toList(this).toArray(); }
2621 public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
2622 public Iterator<E> descendingIterator() {
2623 return descendingSet().iterator();
2624 }
2625 public NavigableSet<E> subSet(E fromElement,
2626 boolean fromInclusive,
2627 E toElement,
2628 boolean toInclusive) {
2629 return new KeySet<E>(m.subMap(fromElement, fromInclusive,
2630 toElement, toInclusive));
2631 }
2632 public NavigableSet<E> headSet(E toElement, boolean inclusive) {
2633 return new KeySet<E>(m.headMap(toElement, inclusive));
2634 }
2635 public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
2636 return new KeySet<E>(m.tailMap(fromElement, inclusive));
2637 }
2638 public NavigableSet<E> subSet(E fromElement, E toElement) {
2639 return subSet(fromElement, true, toElement, false);
2640 }
2641 public NavigableSet<E> headSet(E toElement) {
2642 return headSet(toElement, false);
2643 }
2644 public NavigableSet<E> tailSet(E fromElement) {
2645 return tailSet(fromElement, true);
2646 }
2647 public NavigableSet<E> descendingSet() {
2648 return new KeySet<E>(m.descendingMap());
2649 }
2650
2651 public Stream<E> stream() {
2652 int flags = Streams.STREAM_IS_DISTINCT |
2653 Streams.STREAM_IS_SORTED | Streams.STREAM_IS_ORDERED;
2654 if (m instanceof ConcurrentSkipListMap)
2655 return Streams.stream
2656 (() -> ((ConcurrentSkipListMap<E,?>)m).keySpliterator(),
2657 flags);
2658 else
2659 return Streams.stream
2660 (Streams.spliteratorUnknownSize(iterator()), flags);
2661 }
2662
2663 public Stream<E> parallelStream() {
2664 int flags = Streams.STREAM_IS_DISTINCT |
2665 Streams.STREAM_IS_SORTED | Streams.STREAM_IS_ORDERED;
2666 if (m instanceof ConcurrentSkipListMap)
2667 return Streams.parallelStream
2668 (() -> ((ConcurrentSkipListMap<E,?>)m).keySpliterator(),
2669 flags);
2670 else
2671 return Streams.parallelStream
2672 (Streams.spliteratorUnknownSize(iterator()), flags);
2673 }
2674 }
2675
2676 static final class Values<E> extends AbstractCollection<E> {
2677 private final ConcurrentNavigableMap<?, E> m;
2678 Values(ConcurrentNavigableMap<?, E> map) {
2679 m = map;
2680 }
2681 public Iterator<E> iterator() {
2682 if (m instanceof ConcurrentSkipListMap)
2683 return ((ConcurrentSkipListMap<?,E>)m).valueIterator();
2684 else
2685 return ((SubMap<?,E>)m).valueIterator();
2686 }
2687 public boolean isEmpty() {
2688 return m.isEmpty();
2689 }
2690 public int size() {
2691 return m.size();
2692 }
2693 public boolean contains(Object o) {
2694 return m.containsValue(o);
2695 }
2696 public void clear() {
2697 m.clear();
2698 }
2699 public Object[] toArray() { return toList(this).toArray(); }
2700 public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
2701
2702 public Stream<E> stream() {
2703 int flags = Streams.STREAM_IS_ORDERED;
2704 if (m instanceof ConcurrentSkipListMap)
2705 return Streams.stream
2706 (() -> ((ConcurrentSkipListMap<?,E>)m).valueSpliterator(),
2707 flags);
2708 else
2709 return Streams.stream
2710 (Streams.spliteratorUnknownSize(iterator()), flags);
2711 }
2712
2713 public Stream<E> parallelStream() {
2714 int flags = Streams.STREAM_IS_ORDERED;
2715 if (m instanceof ConcurrentSkipListMap)
2716 return Streams.parallelStream
2717 (() -> ((ConcurrentSkipListMap<?,E>)m).valueSpliterator(),
2718 flags);
2719 else
2720 return Streams.parallelStream
2721 (Streams.spliteratorUnknownSize(iterator()), flags);
2722 }
2723 }
2724
2725 static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> {
2726 private final ConcurrentNavigableMap<K1, V1> m;
2727 EntrySet(ConcurrentNavigableMap<K1, V1> map) {
2728 m = map;
2729 }
2730
2731 public Iterator<Map.Entry<K1,V1>> iterator() {
2732 if (m instanceof ConcurrentSkipListMap)
2733 return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator();
2734 else
2735 return ((SubMap<K1,V1>)m).entryIterator();
2736 }
2737
2738 public boolean contains(Object o) {
2739 if (!(o instanceof Map.Entry))
2740 return false;
2741 Map.Entry<?,?> e = (Map.Entry<?,?>)o;
2742 V1 v = m.get(e.getKey());
2743 return v != null && v.equals(e.getValue());
2744 }
2745 public boolean remove(Object o) {
2746 if (!(o instanceof Map.Entry))
2747 return false;
2748 Map.Entry<?,?> e = (Map.Entry<?,?>)o;
2749 return m.remove(e.getKey(),
2750 e.getValue());
2751 }
2752 public boolean isEmpty() {
2753 return m.isEmpty();
2754 }
2755 public int size() {
2756 return m.size();
2757 }
2758 public void clear() {
2759 m.clear();
2760 }
2761 public boolean equals(Object o) {
2762 if (o == this)
2763 return true;
2764 if (!(o instanceof Set))
2765 return false;
2766 Collection<?> c = (Collection<?>) o;
2767 try {
2768 return containsAll(c) && c.containsAll(this);
2769 } catch (ClassCastException unused) {
2770 return false;
2771 } catch (NullPointerException unused) {
2772 return false;
2773 }
2774 }
2775 public Object[] toArray() { return toList(this).toArray(); }
2776 public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
2777
2778 @Override public Stream<Map.Entry<K1,V1>> stream() {
2779 int flags = Streams.STREAM_IS_ORDERED | Streams.STREAM_IS_DISTINCT;
2780 if (m instanceof ConcurrentSkipListMap)
2781 return Streams.stream
2782 (() -> ((ConcurrentSkipListMap<K1,V1>)m).entrySpliterator(),
2783 flags);
2784 else
2785 return Streams.stream
2786 (Streams.spliteratorUnknownSize(iterator()), flags);
2787 }
2788
2789 public Stream<Map.Entry<K1,V1>> parallelStream() {
2790 int flags = Streams.STREAM_IS_ORDERED | Streams.STREAM_IS_DISTINCT;
2791 if (m instanceof ConcurrentSkipListMap)
2792 return Streams.parallelStream
2793 (() -> ((ConcurrentSkipListMap<K1,V1>)m).entrySpliterator(),
2794 flags);
2795 else
2796 return Streams.parallelStream
2797 (Streams.spliteratorUnknownSize(iterator()), flags);
2798 }
2799
2800 }
2801
2802 /**
2803 * Submaps returned by {@link ConcurrentSkipListMap} submap operations
2804 * represent a subrange of mappings of their underlying
2805 * maps. Instances of this class support all methods of their
2806 * underlying maps, differing in that mappings outside their range are
2807 * ignored, and attempts to add mappings outside their ranges result
2808 * in {@link IllegalArgumentException}. Instances of this class are
2809 * constructed only using the {@code subMap}, {@code headMap}, and
2810 * {@code tailMap} methods of their underlying maps.
2811 *
2812 * @serial include
2813 */
2814 static final class SubMap<K,V> extends AbstractMap<K,V>
2815 implements ConcurrentNavigableMap<K,V>, Cloneable,
2816 java.io.Serializable {
2817 private static final long serialVersionUID = -7647078645895051609L;
2818
2819 /** Underlying map */
2820 private final ConcurrentSkipListMap<K,V> m;
2821 /** lower bound key, or null if from start */
2822 private final K lo;
2823 /** upper bound key, or null if to end */
2824 private final K hi;
2825 /** inclusion flag for lo */
2826 private final boolean loInclusive;
2827 /** inclusion flag for hi */
2828 private final boolean hiInclusive;
2829 /** direction */
2830 private final boolean isDescending;
2831
2832 // Lazily initialized view holders
2833 private transient KeySet<K> keySetView;
2834 private transient Set<Map.Entry<K,V>> entrySetView;
2835 private transient Collection<V> valuesView;
2836
2837 /**
2838 * Creates a new submap, initializing all fields.
2839 */
2840 SubMap(ConcurrentSkipListMap<K,V> map,
2841 K fromKey, boolean fromInclusive,
2842 K toKey, boolean toInclusive,
2843 boolean isDescending) {
2844 if (fromKey != null && toKey != null &&
2845 map.compare(fromKey, toKey) > 0)
2846 throw new IllegalArgumentException("inconsistent range");
2847 this.m = map;
2848 this.lo = fromKey;
2849 this.hi = toKey;
2850 this.loInclusive = fromInclusive;
2851 this.hiInclusive = toInclusive;
2852 this.isDescending = isDescending;
2853 }
2854
2855 /* ---------------- Utilities -------------- */
2856
2857 private boolean tooLow(K key) {
2858 if (lo != null) {
2859 int c = m.compare(key, lo);
2860 if (c < 0 || (c == 0 && !loInclusive))
2861 return true;
2862 }
2863 return false;
2864 }
2865
2866 private boolean tooHigh(K key) {
2867 if (hi != null) {
2868 int c = m.compare(key, hi);
2869 if (c > 0 || (c == 0 && !hiInclusive))
2870 return true;
2871 }
2872 return false;
2873 }
2874
2875 private boolean inBounds(K key) {
2876 return !tooLow(key) && !tooHigh(key);
2877 }
2878
2879 private void checkKeyBounds(K key) throws IllegalArgumentException {
2880 if (key == null)
2881 throw new NullPointerException();
2882 if (!inBounds(key))
2883 throw new IllegalArgumentException("key out of range");
2884 }
2885
2886 /**
2887 * Returns true if node key is less than upper bound of range.
2888 */
2889 private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) {
2890 if (n == null)
2891 return false;
2892 if (hi == null)
2893 return true;
2894 K k = n.key;
2895 if (k == null) // pass by markers and headers
2896 return true;
2897 int c = m.compare(k, hi);
2898 if (c > 0 || (c == 0 && !hiInclusive))
2899 return false;
2900 return true;
2901 }
2902
2903 /**
2904 * Returns lowest node. This node might not be in range, so
2905 * most usages need to check bounds.
2906 */
2907 private ConcurrentSkipListMap.Node<K,V> loNode() {
2908 if (lo == null)
2909 return m.findFirst();
2910 else if (loInclusive)
2911 return m.findNear(lo, GT|EQ);
2912 else
2913 return m.findNear(lo, GT);
2914 }
2915
2916 /**
2917 * Returns highest node. This node might not be in range, so
2918 * most usages need to check bounds.
2919 */
2920 private ConcurrentSkipListMap.Node<K,V> hiNode() {
2921 if (hi == null)
2922 return m.findLast();
2923 else if (hiInclusive)
2924 return m.findNear(hi, LT|EQ);
2925 else
2926 return m.findNear(hi, LT);
2927 }
2928
2929 /**
2930 * Returns lowest absolute key (ignoring directonality).
2931 */
2932 private K lowestKey() {
2933 ConcurrentSkipListMap.Node<K,V> n = loNode();
2934 if (isBeforeEnd(n))
2935 return n.key;
2936 else
2937 throw new NoSuchElementException();
2938 }
2939
2940 /**
2941 * Returns highest absolute key (ignoring directonality).
2942 */
2943 private K highestKey() {
2944 ConcurrentSkipListMap.Node<K,V> n = hiNode();
2945 if (n != null) {
2946 K last = n.key;
2947 if (inBounds(last))
2948 return last;
2949 }
2950 throw new NoSuchElementException();
2951 }
2952
2953 private Map.Entry<K,V> lowestEntry() {
2954 for (;;) {
2955 ConcurrentSkipListMap.Node<K,V> n = loNode();
2956 if (!isBeforeEnd(n))
2957 return null;
2958 Map.Entry<K,V> e = n.createSnapshot();
2959 if (e != null)
2960 return e;
2961 }
2962 }
2963
2964 private Map.Entry<K,V> highestEntry() {
2965 for (;;) {
2966 ConcurrentSkipListMap.Node<K,V> n = hiNode();
2967 if (n == null || !inBounds(n.key))
2968 return null;
2969 Map.Entry<K,V> e = n.createSnapshot();
2970 if (e != null)
2971 return e;
2972 }
2973 }
2974
2975 private Map.Entry<K,V> removeLowest() {
2976 for (;;) {
2977 Node<K,V> n = loNode();
2978 if (n == null)
2979 return null;
2980 K k = n.key;
2981 if (!inBounds(k))
2982 return null;
2983 V v = (m.comparator == null) ? m.doRemove(k, null) :
2984 m.doRemoveCmp(m.comparator, k, null);
2985 if (v != null)
2986 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
2987 }
2988 }
2989
2990 private Map.Entry<K,V> removeHighest() {
2991 for (;;) {
2992 Node<K,V> n = hiNode();
2993 if (n == null)
2994 return null;
2995 K k = n.key;
2996 if (!inBounds(k))
2997 return null;
2998 V v = (m.comparator == null) ? m.doRemove(k, null) :
2999 m.doRemoveCmp(m.comparator, k, null);
3000 if (v != null)
3001 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
3002 }
3003 }
3004
3005 /**
3006 * Submap version of ConcurrentSkipListMap.getNearEntry
3007 */
3008 private Map.Entry<K,V> getNearEntry(K key, int rel) {
3009 if (isDescending) { // adjust relation for direction
3010 if ((rel & LT) == 0)
3011 rel |= LT;
3012 else
3013 rel &= ~LT;
3014 }
3015 if (tooLow(key))
3016 return ((rel & LT) != 0) ? null : lowestEntry();
3017 if (tooHigh(key))
3018 return ((rel & LT) != 0) ? highestEntry() : null;
3019 for (;;) {
3020 Node<K,V> n = m.findNear(key, rel);
3021 if (n == null || !inBounds(n.key))
3022 return null;
3023 K k = n.key;
3024 V v = n.getValidValue();
3025 if (v != null)
3026 return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
3027 }
3028 }
3029
3030 // Almost the same as getNearEntry, except for keys
3031 private K getNearKey(K key, int rel) {
3032 if (isDescending) { // adjust relation for direction
3033 if ((rel & LT) == 0)
3034 rel |= LT;
3035 else
3036 rel &= ~LT;
3037 }
3038 if (tooLow(key)) {
3039 if ((rel & LT) == 0) {
3040 ConcurrentSkipListMap.Node<K,V> n = loNode();
3041 if (isBeforeEnd(n))
3042 return n.key;
3043 }
3044 return null;
3045 }
3046 if (tooHigh(key)) {
3047 if ((rel & LT) != 0) {
3048 ConcurrentSkipListMap.Node<K,V> n = hiNode();
3049 if (n != null) {
3050 K last = n.key;
3051 if (inBounds(last))
3052 return last;
3053 }
3054 }
3055 return null;
3056 }
3057 for (;;) {
3058 Node<K,V> n = m.findNear(key, rel);
3059 if (n == null || !inBounds(n.key))
3060 return null;
3061 K k = n.key;
3062 V v = n.getValidValue();
3063 if (v != null)
3064 return k;
3065 }
3066 }
3067
3068 /* ---------------- Map API methods -------------- */
3069
3070 public boolean containsKey(Object key) {
3071 if (key == null) throw new NullPointerException();
3072 K k = (K)key;
3073 return inBounds(k) && m.containsKey(k);
3074 }
3075
3076 public V get(Object key) {
3077 if (key == null) throw new NullPointerException();
3078 K k = (K)key;
3079 return (!inBounds(k)) ? null : m.get(k);
3080 }
3081
3082 public V put(K key, V value) {
3083 checkKeyBounds(key);
3084 return m.put(key, value);
3085 }
3086
3087 public V remove(Object key) {
3088 K k = (K)key;
3089 return (!inBounds(k)) ? null : m.remove(k);
3090 }
3091
3092 public int size() {
3093 long count = 0;
3094 for (ConcurrentSkipListMap.Node<K,V> n = loNode();
3095 isBeforeEnd(n);
3096 n = n.next) {
3097 if (n.getValidValue() != null)
3098 ++count;
3099 }
3100 return count >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)count;
3101 }
3102
3103 public boolean isEmpty() {
3104 return !isBeforeEnd(loNode());
3105 }
3106
3107 public boolean containsValue(Object value) {
3108 if (value == null)
3109 throw new NullPointerException();
3110 for (ConcurrentSkipListMap.Node<K,V> n = loNode();
3111 isBeforeEnd(n);
3112 n = n.next) {
3113 V v = n.getValidValue();
3114 if (v != null && value.equals(v))
3115 return true;
3116 }
3117 return false;
3118 }
3119
3120 public void clear() {
3121 for (ConcurrentSkipListMap.Node<K,V> n = loNode();
3122 isBeforeEnd(n);
3123 n = n.next) {
3124 if (n.getValidValue() != null)
3125 m.remove(n.key);
3126 }
3127 }
3128
3129 /* ---------------- ConcurrentMap API methods -------------- */
3130
3131 public V putIfAbsent(K key, V value) {
3132 checkKeyBounds(key);
3133 return m.putIfAbsent(key, value);
3134 }
3135
3136 public boolean remove(Object key, Object value) {
3137 K k = (K)key;
3138 return inBounds(k) && m.remove(k, value);
3139 }
3140
3141 public boolean replace(K key, V oldValue, V newValue) {
3142 checkKeyBounds(key);
3143 return m.replace(key, oldValue, newValue);
3144 }
3145
3146 public V replace(K key, V value) {
3147 checkKeyBounds(key);
3148 return m.replace(key, value);
3149 }
3150
3151 /* ---------------- SortedMap API methods -------------- */
3152
3153 public Comparator<? super K> comparator() {
3154 Comparator<? super K> cmp = m.comparator();
3155 if (isDescending)
3156 return Collections.reverseOrder(cmp);
3157 else
3158 return cmp;
3159 }
3160
3161 /**
3162 * Utility to create submaps, where given bounds override
3163 * unbounded(null) ones and/or are checked against bounded ones.
3164 */
3165 private SubMap<K,V> newSubMap(K fromKey,
3166 boolean fromInclusive,
3167 K toKey,
3168 boolean toInclusive) {
3169 if (isDescending) { // flip senses
3170 K tk = fromKey;
3171 fromKey = toKey;
3172 toKey = tk;
3173 boolean ti = fromInclusive;
3174 fromInclusive = toInclusive;
3175 toInclusive = ti;
3176 }
3177 if (lo != null) {
3178 if (fromKey == null) {
3179 fromKey = lo;
3180 fromInclusive = loInclusive;
3181 }
3182 else {
3183 int c = m.compare(fromKey, lo);
3184 if (c < 0 || (c == 0 && !loInclusive && fromInclusive))
3185 throw new IllegalArgumentException("key out of range");
3186 }
3187 }
3188 if (hi != null) {
3189 if (toKey == null) {
3190 toKey = hi;
3191 toInclusive = hiInclusive;
3192 }
3193 else {
3194 int c = m.compare(toKey, hi);
3195 if (c > 0 || (c == 0 && !hiInclusive && toInclusive))
3196 throw new IllegalArgumentException("key out of range");
3197 }
3198 }
3199 return new SubMap<K,V>(m, fromKey, fromInclusive,
3200 toKey, toInclusive, isDescending);
3201 }
3202
3203 public SubMap<K,V> subMap(K fromKey,
3204 boolean fromInclusive,
3205 K toKey,
3206 boolean toInclusive) {
3207 if (fromKey == null || toKey == null)
3208 throw new NullPointerException();
3209 return newSubMap(fromKey, fromInclusive, toKey, toInclusive);
3210 }
3211
3212 public SubMap<K,V> headMap(K toKey,
3213 boolean inclusive) {
3214 if (toKey == null)
3215 throw new NullPointerException();
3216 return newSubMap(null, false, toKey, inclusive);
3217 }
3218
3219 public SubMap<K,V> tailMap(K fromKey,
3220 boolean inclusive) {
3221 if (fromKey == null)
3222 throw new NullPointerException();
3223 return newSubMap(fromKey, inclusive, null, false);
3224 }
3225
3226 public SubMap<K,V> subMap(K fromKey, K toKey) {
3227 return subMap(fromKey, true, toKey, false);
3228 }
3229
3230 public SubMap<K,V> headMap(K toKey) {
3231 return headMap(toKey, false);
3232 }
3233
3234 public SubMap<K,V> tailMap(K fromKey) {
3235 return tailMap(fromKey, true);
3236 }
3237
3238 public SubMap<K,V> descendingMap() {
3239 return new SubMap<K,V>(m, lo, loInclusive,
3240 hi, hiInclusive, !isDescending);
3241 }
3242
3243 /* ---------------- Relational methods -------------- */
3244
3245 public Map.Entry<K,V> ceilingEntry(K key) {
3246 return getNearEntry(key, GT|EQ);
3247 }
3248
3249 public K ceilingKey(K key) {
3250 return getNearKey(key, GT|EQ);
3251 }
3252
3253 public Map.Entry<K,V> lowerEntry(K key) {
3254 return getNearEntry(key, LT);
3255 }
3256
3257 public K lowerKey(K key) {
3258 return getNearKey(key, LT);
3259 }
3260
3261 public Map.Entry<K,V> floorEntry(K key) {
3262 return getNearEntry(key, LT|EQ);
3263 }
3264
3265 public K floorKey(K key) {
3266 return getNearKey(key, LT|EQ);
3267 }
3268
3269 public Map.Entry<K,V> higherEntry(K key) {
3270 return getNearEntry(key, GT);
3271 }
3272
3273 public K higherKey(K key) {
3274 return getNearKey(key, GT);
3275 }
3276
3277 public K firstKey() {
3278 return isDescending ? highestKey() : lowestKey();
3279 }
3280
3281 public K lastKey() {
3282 return isDescending ? lowestKey() : highestKey();
3283 }
3284
3285 public Map.Entry<K,V> firstEntry() {
3286 return isDescending ? highestEntry() : lowestEntry();
3287 }
3288
3289 public Map.Entry<K,V> lastEntry() {
3290 return isDescending ? lowestEntry() : highestEntry();
3291 }
3292
3293 public Map.Entry<K,V> pollFirstEntry() {
3294 return isDescending ? removeHighest() : removeLowest();
3295 }
3296
3297 public Map.Entry<K,V> pollLastEntry() {
3298 return isDescending ? removeLowest() : removeHighest();
3299 }
3300
3301 /* ---------------- Submap Views -------------- */
3302
3303 public NavigableSet<K> keySet() {
3304 KeySet<K> ks = keySetView;
3305 return (ks != null) ? ks : (keySetView = new KeySet<K>(this));
3306 }
3307
3308 public NavigableSet<K> navigableKeySet() {
3309 KeySet<K> ks = keySetView;
3310 return (ks != null) ? ks : (keySetView = new KeySet<K>(this));
3311 }
3312
3313 public Collection<V> values() {
3314 Collection<V> vs = valuesView;
3315 return (vs != null) ? vs : (valuesView = new Values<V>(this));
3316 }
3317
3318 public Set<Map.Entry<K,V>> entrySet() {
3319 Set<Map.Entry<K,V>> es = entrySetView;
3320 return (es != null) ? es : (entrySetView = new EntrySet<K,V>(this));
3321 }
3322
3323 public NavigableSet<K> descendingKeySet() {
3324 return descendingMap().navigableKeySet();
3325 }
3326
3327 Iterator<K> keyIterator() {
3328 return new SubMapKeyIterator();
3329 }
3330
3331 Iterator<V> valueIterator() {
3332 return new SubMapValueIterator();
3333 }
3334
3335 Iterator<Map.Entry<K,V>> entryIterator() {
3336 return new SubMapEntryIterator();
3337 }
3338
3339 /**
3340 * Variant of main Iter class to traverse through submaps.
3341 */
3342 abstract class SubMapIter<T> implements Iterator<T> {
3343 /** the last node returned by next() */
3344 Node<K,V> lastReturned;
3345 /** the next node to return from next(); */
3346 Node<K,V> next;
3347 /** Cache of next value field to maintain weak consistency */
3348 V nextValue;
3349
3350 SubMapIter() {
3351 for (;;) {
3352 next = isDescending ? hiNode() : loNode();
3353 if (next == null)
3354 break;
3355 Object x = next.value;
3356 if (x != null && x != next) {
3357 if (! inBounds(next.key))
3358 next = null;
3359 else
3360 nextValue = (V) x;
3361 break;
3362 }
3363 }
3364 }
3365
3366 public final boolean hasNext() {
3367 return next != null;
3368 }
3369
3370 final void advance() {
3371 if (next == null)
3372 throw new NoSuchElementException();
3373 lastReturned = next;
3374 if (isDescending)
3375 descend();
3376 else
3377 ascend();
3378 }
3379
3380 private void ascend() {
3381 for (;;) {
3382 next = next.next;
3383 if (next == null)
3384 break;
3385 Object x = next.value;
3386 if (x != null && x != next) {
3387 if (tooHigh(next.key))
3388 next = null;
3389 else
3390 nextValue = (V) x;
3391 break;
3392 }
3393 }
3394 }
3395
3396 private void descend() {
3397 Comparator<? super K> cmp = m.comparator;
3398 for (;;) {
3399 next = (cmp == null) ? m.doFindNear(lastReturned.key, LT) :
3400 m.doFindNearCmp(cmp, lastReturned.key, LT);
3401 if (next == null)
3402 break;
3403 Object x = next.value;
3404 if (x != null && x != next) {
3405 if (tooLow(next.key))
3406 next = null;
3407 else
3408 nextValue = (V) x;
3409 break;
3410 }
3411 }
3412 }
3413
3414 public void remove() {
3415 Node<K,V> l = lastReturned;
3416 if (l == null)
3417 throw new IllegalStateException();
3418 m.remove(l.key);
3419 lastReturned = null;
3420 }
3421
3422 }
3423
3424 final class SubMapValueIterator extends SubMapIter<V> {
3425 public V next() {
3426 V v = nextValue;
3427 advance();
3428 return v;
3429 }
3430 }
3431
3432 final class SubMapKeyIterator extends SubMapIter<K> {
3433 public K next() {
3434 Node<K,V> n = next;
3435 advance();
3436 return n.key;
3437 }
3438 }
3439
3440 final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> {
3441 public Map.Entry<K,V> next() {
3442 Node<K,V> n = next;
3443 V v = nextValue;
3444 advance();
3445 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
3446 }
3447 }
3448 }
3449
3450 /**
3451 * A view of a ConcurrentSkipListMap as a {@link Set} of keys, in
3452 * which additions may optionally be enabled by mapping to a
3453 * common value. This class cannot be directly instantiated. See
3454 * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
3455 * {@link #newKeySet(Comparator)}.
3456 */
3457 public static class KeySetView<K,V> extends AbstractSet<K>
3458 implements NavigableSet<K>, java.io.Serializable {
3459
3460 /*
3461 * This class overlaps in functionality with the
3462 * relative-scoped KeySet class, but must be distinct and
3463 * unrelated. So we repeat most of the boring delegation code.
3464 */
3465
3466 private static final long serialVersionUID = 7249069246763182397L;
3467 private final ConcurrentSkipListMap<K, V> m;
3468 private final V value;
3469
3470 KeySetView(ConcurrentSkipListMap<K, V> map, V value) { // non-public
3471 this.m = map;
3472 this.value = value;
3473 }
3474
3475 /**
3476 * Returns the map backing this view.
3477 *
3478 * @return the map backing this view
3479 */
3480 public ConcurrentSkipListMap<K,V> getMap() { return m; }
3481
3482 /**
3483 * Returns the default mapped value for additions,
3484 * or {@code null} if additions are not supported.
3485 *
3486 * @return the default mapped value for additions, or {@code null}
3487 * if not supported.
3488 */
3489 public V getMappedValue() { return value; }
3490
3491 public boolean add(K e) {
3492 V v;
3493 if ((v = value) == null)
3494 throw new UnsupportedOperationException();
3495 if (e == null)
3496 throw new NullPointerException();
3497 return m.put(e, v) == null;
3498 }
3499
3500 public boolean addAll(Collection<? extends K> c) {
3501 boolean added = false;
3502 V v;
3503 if ((v = value) == null)
3504 throw new UnsupportedOperationException();
3505 for (K e : c) {
3506 if (e == null)
3507 throw new NullPointerException();
3508 if (m.put(e, v) == null)
3509 added = true;
3510 }
3511 return added;
3512 }
3513
3514 public int size() { return m.size(); }
3515 public boolean isEmpty() { return m.isEmpty(); }
3516 public boolean contains(Object o) { return m.containsKey(o); }
3517 public boolean remove(Object o) { return m.remove(o) != null; }
3518 public void clear() { m.clear(); }
3519 public K lower(K e) { return m.lowerKey(e); }
3520 public K floor(K e) { return m.floorKey(e); }
3521 public K ceiling(K e) { return m.ceilingKey(e); }
3522 public K higher(K e) { return m.higherKey(e); }
3523 public Comparator<? super K> comparator() { return m.comparator(); }
3524 public K first() { return m.firstKey(); }
3525 public K last() { return m.lastKey(); }
3526 public Iterator<K> iterator() { return m.keyIterator(); }
3527 public K pollFirst() {
3528 Map.Entry<K,?> e = m.pollFirstEntry();
3529 return (e == null) ? null : e.getKey();
3530 }
3531 public K pollLast() {
3532 Map.Entry<K,?> e = m.pollLastEntry();
3533 return (e == null) ? null : e.getKey();
3534 }
3535 public boolean equals(Object o) {
3536 if (o == this)
3537 return true;
3538 if (!(o instanceof Set))
3539 return false;
3540 Collection<?> c = (Collection<?>) o;
3541 try {
3542 return containsAll(c) && c.containsAll(this);
3543 } catch (ClassCastException unused) {
3544 return false;
3545 } catch (NullPointerException unused) {
3546 return false;
3547 }
3548 }
3549 public Object[] toArray() { return toList(this).toArray(); }
3550 public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
3551 public Iterator<K> descendingIterator() {
3552 return descendingSet().iterator();
3553 }
3554 public NavigableSet<K> subSet(K fromElement,
3555 boolean fromInclusive,
3556 K toElement,
3557 boolean toInclusive) {
3558 return new KeySet<K>(m.subMap(fromElement, fromInclusive,
3559 toElement, toInclusive));
3560 }
3561 public NavigableSet<K> headSet(K toElement, boolean inclusive) {
3562 return new KeySet<K>(m.headMap(toElement, inclusive));
3563 }
3564 public NavigableSet<K> tailSet(K fromElement, boolean inclusive) {
3565 return new KeySet<K>(m.tailMap(fromElement, inclusive));
3566 }
3567 public NavigableSet<K> subSet(K fromElement, K toElement) {
3568 return subSet(fromElement, true, toElement, false);
3569 }
3570 public NavigableSet<K> headSet(K toElement) {
3571 return headSet(toElement, false);
3572 }
3573 public NavigableSet<K> tailSet(K fromElement) {
3574 return tailSet(fromElement, true);
3575 }
3576 public NavigableSet<K> descendingSet() {
3577 return new KeySet<K>(m.descendingMap());
3578 }
3579
3580 public Stream<K> stream() {
3581 int flags = Streams.STREAM_IS_DISTINCT |
3582 Streams.STREAM_IS_SORTED | Streams.STREAM_IS_ORDERED;
3583 return Streams.stream(() -> m.keySpliterator(), flags);
3584 }
3585
3586 public Stream<K> parallelStream() {
3587 int flags = Streams.STREAM_IS_DISTINCT |
3588 Streams.STREAM_IS_SORTED | Streams.STREAM_IS_ORDERED;
3589 return Streams.parallelStream(() -> m.keySpliterator(), flags);
3590 }
3591
3592 }
3593
3594 /**
3595 * Base class providing common structure for Spliterators.
3596 * (Although not all that much common functionality; as usual for
3597 * view classes, details annoyingly vary in key, value, and entry
3598 * subclasses in ways that are not worth abstracting out for
3599 * internal classes.)
3600 *
3601 * The basic split strategy is to recursively descend from top
3602 * level, row by row, descending to next row when either split
3603 * off, or the end of row is encountered. Control of the number of
3604 * splits relies on some statistical estimation: The expected
3605 * remaining number of elements of a skip list when advancing
3606 * either across or down decreases by about 25%. To make this
3607 * observation useful, we need to know initial size, which we
3608 * don't. But we use (1 << 2*levels) as a rough overestimate that
3609 * minimizes risk of prematurely zeroing out while splitting.
3610 */
3611 static class CSLMSpliterator<K,V> {
3612 final Comparator<? super K> comparator;
3613 final K fence; // exclusive upper bound for keys, or null if to end
3614 Index<K,V> row; // the level to split out
3615 Node<K,V> current; // current traversal node; initialize at origin
3616 int est; // pseudo-size estimate
3617
3618 CSLMSpliterator(Comparator<? super K> comparator, Index<K,V> row,
3619 Node<K,V> origin, K fence, int est) {
3620 this.comparator = comparator; this.row = row;
3621 this.current = origin; this.fence = fence; this.est = est;
3622 }
3623
3624 /** Return >= 0 if key is too large (out of bounds) */
3625 final int compareBounds(K k) {
3626 Comparator<? super K> cmp; K f;
3627 if (k == null || (f = fence) == null)
3628 return -1;
3629 else if ((cmp = comparator) != null)
3630 return cmp.compare(k, f);
3631 else
3632 return ((Comparable<? super K>)k).compareTo(f);
3633 }
3634
3635 public final long estimateSize() { return (long)est; }
3636 public final boolean hasExactSize() { return est == 0; }
3637 public final boolean hasExactSplits() { return false; }
3638 }
3639
3640 // factory methods
3641 final KeySpliterator<K,V> keySpliterator() {
3642 HeadIndex<K,V> h; Node<K,V> p; int d, n;
3643 for (;;) { // ensure h and n correspond to origin p
3644 Node<K,V> b = (h = head).node;
3645 if ((p = b.next) == null) {
3646 n = 0;
3647 break;
3648 }
3649 if (p.value != null) {
3650 n = (d = h.level << 1) >= 31 ? Integer.MAX_VALUE : 1 << d;
3651 break;
3652 }
3653 p.helpDelete(b, p.next);
3654 }
3655 return new KeySpliterator<K,V>(comparator, h, p, null, n);
3656 }
3657
3658 final ValueSpliterator<K,V> valueSpliterator() {
3659 HeadIndex<K,V> h; Node<K,V> p; int d, n;
3660 for (;;) { // same as key version
3661 Node<K,V> b = (h = head).node;
3662 if ((p = b.next) == null) {
3663 n = 0;
3664 break;
3665 }
3666 if (p.value != null) {
3667 n = (d = h.level << 1) >= 31 ? Integer.MAX_VALUE : 1 << d;
3668 break;
3669 }
3670 p.helpDelete(b, p.next);
3671 }
3672 return new ValueSpliterator<K,V>(comparator, h, p, null, n);
3673 }
3674
3675 final EntrySpliterator<K,V> entrySpliterator() {
3676 HeadIndex<K,V> h; Node<K,V> p; int d, n;
3677 for (;;) { // same as key version
3678 Node<K,V> b = (h = head).node;
3679 if ((p = b.next) == null) {
3680 n = 0;
3681 break;
3682 }
3683 if (p.value != null) {
3684 n = (d = h.level << 1) >= 31 ? Integer.MAX_VALUE : 1 << d;
3685 break;
3686 }
3687 p.helpDelete(b, p.next);
3688 }
3689 return new EntrySpliterator<K,V>(comparator, head, p, null, n);
3690 }
3691
3692 static final class KeySpliterator<K,V> extends CSLMSpliterator<K,V>
3693 implements Spliterator<K> {
3694 KeySpliterator(Comparator<? super K> comparator, Index<K,V> row,
3695 Node<K,V> origin, K fence, int est) {
3696 super(comparator, row, origin, fence, est);
3697 }
3698
3699 public KeySpliterator<K,V> trySplit() {
3700 Node<K,V> e;
3701 Comparator<? super K> cmp = comparator;
3702 K f = fence;
3703 if ((e = current) != null) {
3704 for (Index<K,V> q = row; q != null; q = row = q.down) {
3705 Index<K,V> s; Node<K,V> n; K sk;
3706 est -= est >>> 2;
3707 if ((s = q.right) != null) {
3708 for (;;) {
3709 Node<K,V> b = s.node;
3710 if ((n = b.next) == null || n.value != null)
3711 break;
3712 n.helpDelete(b, n.next);
3713 }
3714 if (n != null && (sk = n.key) != null &&
3715 (f == null ||
3716 (cmp != null ? (cmp.compare(f, sk) > 0) :
3717 (((Comparable<? super K>)f).compareTo(sk) > 0)))) {
3718 current = n;
3719 Index<K,V> r = q.down;
3720 row = (s.right != null) ? s : s.down;
3721 return new KeySpliterator<K,V>(cmp, r, e, sk, est);
3722 }
3723 }
3724 }
3725 }
3726 return null;
3727 }
3728
3729 public void forEach(Block<? super K> block) {
3730 if (block == null) throw new NullPointerException();
3731 K f = fence;
3732 Comparator<? super K> cmp = comparator;
3733 Comparable<? super K> cf = (f != null && cmp == null) ?
3734 (Comparable<? super K>)f : null;
3735 Node<K,V> e = current;
3736 current = null;
3737 for (; e != null; e = e.next) {
3738 K k; Object v;
3739 if ((k = e.key) != null &&
3740 (cf != null ? (cf.compareTo(k) <= 0) :
3741 (f != null && cmp.compare(f, k) <= 0)))
3742 break;
3743 if ((v = e.value) != null && v != e)
3744 block.accept(k);
3745 }
3746 }
3747
3748 public boolean tryAdvance(Block<? super K> block) {
3749 if (block == null) throw new NullPointerException();
3750 Node<K,V> e;
3751 for (e = current; e != null; e = e.next) {
3752 K k; Object v;
3753 if (compareBounds(k = e.key) >= 0) {
3754 e = null;
3755 break;
3756 }
3757 if ((v = e.value) != null && v != e) {
3758 current = e.next;
3759 block.accept(k);
3760 return true;
3761 }
3762 }
3763 current = e;
3764 return false;
3765 }
3766 }
3767
3768 static final class ValueSpliterator<K,V> extends CSLMSpliterator<K,V>
3769 implements Spliterator<V> {
3770 ValueSpliterator(Comparator<? super K> comparator, Index<K,V> row,
3771 Node<K,V> origin, K fence, int est) {
3772 super(comparator, row, origin, fence, est);
3773 }
3774
3775 public ValueSpliterator<K,V> trySplit() {
3776 Node<K,V> e;
3777 Comparator<? super K> cmp = comparator;
3778 K f = fence;
3779 if ((e = current) != null) {
3780 for (Index<K,V> q = row; q != null; q = row = q.down) {
3781 Index<K,V> s; Node<K,V> n; K sk;
3782 est -= est >>> 2;
3783 if ((s = q.right) != null) {
3784 for (;;) {
3785 Node<K,V> b = s.node;
3786 if ((n = b.next) == null || n.value != null)
3787 break;
3788 n.helpDelete(b, n.next);
3789 }
3790 if (n != null && (sk = n.key) != null &&
3791 (f == null ||
3792 (cmp != null ? (cmp.compare(f, sk) > 0) :
3793 (((Comparable<? super K>)f).compareTo(sk) > 0)))) {
3794 current = n;
3795 Index<K,V> r = q.down;
3796 row = (s.right != null) ? s : s.down;
3797 return new ValueSpliterator<K,V>(cmp, r, e, sk, est);
3798 }
3799 }
3800 }
3801 }
3802 return null;
3803 }
3804
3805 public void forEach(Block<? super V> block) {
3806 if (block == null) throw new NullPointerException();
3807 K f = fence;
3808 Comparator<? super K> cmp = comparator;
3809 Comparable<? super K> cf = (f != null && cmp == null) ?
3810 (Comparable<? super K>)f : null;
3811 Node<K,V> e = current;
3812 current = null;
3813 for (; e != null; e = e.next) {
3814 K k; Object v;
3815 if ((k = e.key) != null &&
3816 (cf != null ? (cf.compareTo(k) <= 0) :
3817 (f != null && cmp.compare(f, k) <= 0)))
3818 break;
3819 if ((v = e.value) != null && v != e)
3820 block.accept((V)v);
3821 }
3822 }
3823
3824 public boolean tryAdvance(Block<? super V> block) {
3825 if (block == null) throw new NullPointerException();
3826 boolean advanced = false;
3827 Node<K,V> e;
3828 for (e = current; e != null; e = e.next) {
3829 K k; Object v;
3830 if (compareBounds(k = e.key) >= 0) {
3831 e = null;
3832 break;
3833 }
3834 if ((v = e.value) != null && v != e) {
3835 current = e.next;
3836 block.accept((V)v);
3837 return true;
3838 }
3839 }
3840 current = e;
3841 return false;
3842 }
3843 }
3844
3845 static final class EntrySpliterator<K,V> extends CSLMSpliterator<K,V>
3846 implements Spliterator<Map.Entry<K,V>> {
3847 EntrySpliterator(Comparator<? super K> comparator, Index<K,V> row,
3848 Node<K,V> origin, K fence, int est) {
3849 super(comparator, row, origin, fence, est);
3850 }
3851
3852 public EntrySpliterator<K,V> trySplit() {
3853 Node<K,V> e;
3854 Comparator<? super K> cmp = comparator;
3855 K f = fence;
3856 if ((e = current) != null) {
3857 for (Index<K,V> q = row; q != null; q = row = q.down) {
3858 Index<K,V> s; Node<K,V> n; K sk;
3859 est -= est >>> 2;
3860 if ((s = q.right) != null) {
3861 for (;;) {
3862 Node<K,V> b = s.node;
3863 if ((n = b.next) == null || n.value != null)
3864 break;
3865 n.helpDelete(b, n.next);
3866 }
3867 if (n != null && (sk = n.key) != null &&
3868 (f == null ||
3869 (cmp != null ?
3870 (cmp.compare(f, sk) > 0) :
3871 (((Comparable<? super K>)f).compareTo(sk) > 0)))) {
3872 current = n;
3873 Index<K,V> r = q.down;
3874 row = (s.right != null) ? s : s.down;
3875 return new EntrySpliterator<K,V>(cmp, r, e, sk, est);
3876 }
3877 }
3878 }
3879 }
3880 return null;
3881 }
3882
3883 public void forEach(Block<? super Map.Entry<K,V>> block) {
3884 if (block == null) throw new NullPointerException();
3885 K f = fence;
3886 Comparator<? super K> cmp = comparator;
3887 Comparable<? super K> cf = (f != null && cmp == null) ?
3888 (Comparable<? super K>)f : null;
3889 Node<K,V> e = current;
3890 current = null;
3891 for (; e != null; e = e.next) {
3892 K k; Object v;
3893 if ((k = e.key) != null &&
3894 (cf != null ?
3895 (cf.compareTo(k) <= 0) :
3896 (f != null && cmp.compare(f, k) <= 0)))
3897 break;
3898 if ((v = e.value) != null && v != e)
3899 block.accept
3900 (new AbstractMap.SimpleImmutableEntry<K,V>(k, (V)v));
3901 }
3902 }
3903
3904 public boolean tryAdvance(Block<? super Map.Entry<K,V>> block) {
3905 if (block == null) throw new NullPointerException();
3906 Node<K,V> e;
3907 for (e = current; e != null; e = e.next) {
3908 K k; Object v;
3909 if (compareBounds(k = e.key) >= 0) {
3910 e = null;
3911 break;
3912 }
3913 if ((v = e.value) != null && v != e) {
3914 current = e.next;
3915 block.accept
3916 (new AbstractMap.SimpleImmutableEntry<K,V>(k, (V)v));
3917 return true;
3918 }
3919 }
3920 current = e;
3921 return false;
3922 }
3923 }
3924
3925 // Unsafe mechanics
3926 private static final sun.misc.Unsafe UNSAFE;
3927 private static final long headOffset;
3928 static {
3929 try {
3930 UNSAFE = sun.misc.Unsafe.getUnsafe();
3931 Class<?> k = ConcurrentSkipListMap.class;
3932 headOffset = UNSAFE.objectFieldOffset
3933 (k.getDeclaredField("head"));
3934 } catch (Exception e) {
3935 throw new Error(e);
3936 }
3937 }
3938 }