ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk8/java/util/concurrent/ConcurrentSkipListMap.java
Revision: 1.13
Committed: Thu Apr 25 20:05:40 2019 UTC (5 years ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.12: +1 -0 lines
Log Message:
8222930: ConcurrentSkipListMap.clone() shares size variable between original and clone

File Contents

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