ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166x/ConcurrentSkipListMap.java
Revision: 1.2
Committed: Mon Sep 6 17:01:54 2004 UTC (19 years, 8 months ago) by dl
Branch: MAIN
Changes since 1.1: +939 -32 lines
Log Message:
Add Navigable interfaces for concurrent skip list classes; adjust accordingly

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