ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListMap.java
Revision: 1.23
Committed: Sun May 22 10:55:55 2005 UTC (19 years ago) by dl
Branch: MAIN
Changes since 1.22: +2 -2 lines
Log Message:
Make remove(x, null) consistent with CHM

File Contents

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