ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListMap.java
Revision: 1.104
Committed: Mon Feb 25 17:59:40 2013 UTC (11 years, 3 months ago) by dl
Branch: MAIN
Changes since 1.103: +12 -16 lines
Log Message:
lambda syncs and improvements

File Contents

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