ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListMap.java
Revision: 1.87
Committed: Wed Jan 16 22:10:06 2013 UTC (11 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.86: +7 -7 lines
Log Message:
punctuation

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