ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListSet.java
Revision: 1.44
Committed: Wed Dec 31 09:37:20 2014 UTC (9 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.43: +0 -1 lines
Log Message:
remove unused/redundant imports

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4 jsr166 1.22 * http://creativecommons.org/publicdomain/zero/1.0/
5 dl 1.1 */
6    
7     package java.util.concurrent;
8 jsr166 1.43
9 dl 1.32 import java.util.AbstractSet;
10     import java.util.Collection;
11     import java.util.Collections;
12     import java.util.Comparator;
13     import java.util.Iterator;
14     import java.util.Map;
15     import java.util.NavigableMap;
16     import java.util.NavigableSet;
17     import java.util.Set;
18     import java.util.SortedSet;
19 dl 1.31 import java.util.Spliterator;
20 dl 1.1
21     /**
22     * A scalable concurrent {@link NavigableSet} implementation based on
23 jsr166 1.11 * a {@link ConcurrentSkipListMap}. The elements of the set are kept
24     * sorted according to their {@linkplain Comparable natural ordering},
25     * or by a {@link Comparator} provided at set creation time, depending
26     * on which constructor is used.
27 dl 1.1 *
28 jsr166 1.11 * <p>This implementation provides expected average <i>log(n)</i> time
29 jsr166 1.30 * cost for the {@code contains}, {@code add}, and {@code remove}
30 dl 1.1 * operations and their variants. Insertion, removal, and access
31 jsr166 1.11 * operations safely execute concurrently by multiple threads.
32 jsr166 1.42 *
33     * <p>Iterators and spliterators are
34     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
35     *
36     * <p>Ascending ordered views and their iterators are faster than
37     * descending ones.
38 dl 1.1 *
39 jsr166 1.30 * <p>Beware that, unlike in most collections, the {@code size}
40 dl 1.1 * method is <em>not</em> a constant-time operation. Because of the
41     * asynchronous nature of these sets, determining the current number
42 dl 1.23 * of elements requires a traversal of the elements, and so may report
43     * inaccurate results if this collection is modified during traversal.
44 jsr166 1.30 * Additionally, the bulk operations {@code addAll},
45     * {@code removeAll}, {@code retainAll}, {@code containsAll},
46     * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
47 dl 1.23 * to be performed atomically. For example, an iterator operating
48 jsr166 1.30 * concurrently with an {@code addAll} operation might view only some
49 dl 1.23 * of the added elements.
50 dl 1.1 *
51     * <p>This class and its iterators implement all of the
52     * <em>optional</em> methods of the {@link Set} and {@link Iterator}
53     * interfaces. Like most other concurrent collection implementations,
54 jsr166 1.30 * this class does not permit the use of {@code null} elements,
55     * because {@code null} arguments and return values cannot be reliably
56 dl 1.1 * distinguished from the absence of elements.
57     *
58 jsr166 1.10 * <p>This class is a member of the
59 jsr166 1.18 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
60 jsr166 1.10 * Java Collections Framework</a>.
61     *
62 dl 1.1 * @author Doug Lea
63     * @param <E> the type of elements maintained by this set
64 jsr166 1.9 * @since 1.6
65 dl 1.1 */
66     public class ConcurrentSkipListSet<E>
67     extends AbstractSet<E>
68     implements NavigableSet<E>, Cloneable, java.io.Serializable {
69    
70     private static final long serialVersionUID = -2479143111061671589L;
71    
72     /**
73     * The underlying map. Uses Boolean.TRUE as value for each
74 dl 1.15 * element. This field is declared final for the sake of thread
75 jsr166 1.34 * safety, which entails some ugliness in clone().
76 dl 1.1 */
77 dl 1.15 private final ConcurrentNavigableMap<E,Object> m;
78 dl 1.1
79     /**
80 jsr166 1.11 * Constructs a new, empty set that orders its elements according to
81     * their {@linkplain Comparable natural ordering}.
82 dl 1.1 */
83     public ConcurrentSkipListSet() {
84     m = new ConcurrentSkipListMap<E,Object>();
85     }
86    
87     /**
88 jsr166 1.11 * Constructs a new, empty set that orders its elements according to
89     * the specified comparator.
90 dl 1.1 *
91 jsr166 1.11 * @param comparator the comparator that will be used to order this set.
92 jsr166 1.30 * If {@code null}, the {@linkplain Comparable natural
93 jsr166 1.11 * ordering} of the elements will be used.
94 dl 1.1 */
95 jsr166 1.11 public ConcurrentSkipListSet(Comparator<? super E> comparator) {
96     m = new ConcurrentSkipListMap<E,Object>(comparator);
97 dl 1.1 }
98    
99     /**
100     * Constructs a new set containing the elements in the specified
101 jsr166 1.11 * collection, that orders its elements according to their
102     * {@linkplain Comparable natural ordering}.
103 dl 1.1 *
104 jsr166 1.11 * @param c The elements that will comprise the new set
105 jsr166 1.30 * @throws ClassCastException if the elements in {@code c} are
106 jsr166 1.11 * not {@link Comparable}, or are not mutually comparable
107     * @throws NullPointerException if the specified collection or any
108     * of its elements are null
109 dl 1.1 */
110     public ConcurrentSkipListSet(Collection<? extends E> c) {
111     m = new ConcurrentSkipListMap<E,Object>();
112     addAll(c);
113     }
114    
115     /**
116 jsr166 1.11 * Constructs a new set containing the same elements and using the
117     * same ordering as the specified sorted set.
118 dl 1.1 *
119 jsr166 1.11 * @param s sorted set whose elements will comprise the new set
120     * @throws NullPointerException if the specified sorted set or any
121     * of its elements are null
122 dl 1.1 */
123     public ConcurrentSkipListSet(SortedSet<E> s) {
124     m = new ConcurrentSkipListMap<E,Object>(s.comparator());
125     addAll(s);
126     }
127    
128     /**
129 dl 1.15 * For use by submaps
130     */
131     ConcurrentSkipListSet(ConcurrentNavigableMap<E,Object> m) {
132     this.m = m;
133     }
134    
135     /**
136 jsr166 1.30 * Returns a shallow copy of this {@code ConcurrentSkipListSet}
137 jsr166 1.11 * instance. (The elements themselves are not cloned.)
138 dl 1.1 *
139 jsr166 1.11 * @return a shallow copy of this set
140 dl 1.1 */
141 jsr166 1.7 public ConcurrentSkipListSet<E> clone() {
142 jsr166 1.19 try {
143 jsr166 1.28 @SuppressWarnings("unchecked")
144     ConcurrentSkipListSet<E> clone =
145     (ConcurrentSkipListSet<E>) super.clone();
146 jsr166 1.24 clone.setMap(new ConcurrentSkipListMap<E,Object>(m));
147 jsr166 1.28 return clone;
148 jsr166 1.19 } catch (CloneNotSupportedException e) {
149     throw new InternalError();
150     }
151 dl 1.1 }
152    
153     /* ---------------- Set operations -------------- */
154    
155     /**
156     * Returns the number of elements in this set. If this set
157 jsr166 1.30 * contains more than {@code Integer.MAX_VALUE} elements, it
158     * returns {@code Integer.MAX_VALUE}.
159 dl 1.1 *
160     * <p>Beware that, unlike in most collections, this method is
161     * <em>NOT</em> a constant-time operation. Because of the
162     * asynchronous nature of these sets, determining the current
163     * number of elements requires traversing them all to count them.
164     * Additionally, it is possible for the size to change during
165     * execution of this method, in which case the returned result
166     * will be inaccurate. Thus, this method is typically not very
167     * useful in concurrent applications.
168     *
169 jsr166 1.12 * @return the number of elements in this set
170 dl 1.1 */
171     public int size() {
172 jsr166 1.19 return m.size();
173 dl 1.1 }
174    
175     /**
176 jsr166 1.30 * Returns {@code true} if this set contains no elements.
177     * @return {@code true} if this set contains no elements
178 dl 1.1 */
179     public boolean isEmpty() {
180 jsr166 1.19 return m.isEmpty();
181 dl 1.1 }
182    
183     /**
184 jsr166 1.30 * Returns {@code true} if this set contains the specified element.
185     * More formally, returns {@code true} if and only if this set
186     * contains an element {@code e} such that {@code o.equals(e)}.
187 dl 1.1 *
188 jsr166 1.14 * @param o object to be checked for containment in this set
189 jsr166 1.30 * @return {@code true} if this set contains the specified element
190 jsr166 1.11 * @throws ClassCastException if the specified element cannot be
191 jsr166 1.14 * compared with the elements currently in this set
192 jsr166 1.11 * @throws NullPointerException if the specified element is null
193 dl 1.1 */
194     public boolean contains(Object o) {
195 jsr166 1.19 return m.containsKey(o);
196 dl 1.1 }
197    
198     /**
199     * Adds the specified element to this set if it is not already present.
200 jsr166 1.30 * More formally, adds the specified element {@code e} to this set if
201     * the set contains no element {@code e2} such that {@code e.equals(e2)}.
202 jsr166 1.14 * If this set already contains the element, the call leaves the set
203 jsr166 1.30 * unchanged and returns {@code false}.
204 dl 1.1 *
205 jsr166 1.11 * @param e element to be added to this set
206 jsr166 1.30 * @return {@code true} if this set did not already contain the
207 jsr166 1.11 * specified element
208 jsr166 1.30 * @throws ClassCastException if {@code e} cannot be compared
209 jsr166 1.14 * with the elements currently in this set
210 jsr166 1.11 * @throws NullPointerException if the specified element is null
211 dl 1.1 */
212 jsr166 1.5 public boolean add(E e) {
213 jsr166 1.19 return m.putIfAbsent(e, Boolean.TRUE) == null;
214 dl 1.1 }
215    
216     /**
217     * Removes the specified element from this set if it is present.
218 jsr166 1.30 * More formally, removes an element {@code e} such that
219     * {@code o.equals(e)}, if this set contains such an element.
220     * Returns {@code true} if this set contained the element (or
221 jsr166 1.14 * equivalently, if this set changed as a result of the call).
222     * (This set will not contain the element once the call returns.)
223 dl 1.1 *
224 jsr166 1.11 * @param o object to be removed from this set, if present
225 jsr166 1.30 * @return {@code true} if this set contained the specified element
226     * @throws ClassCastException if {@code o} cannot be compared
227 jsr166 1.14 * with the elements currently in this set
228 jsr166 1.11 * @throws NullPointerException if the specified element is null
229 dl 1.1 */
230     public boolean remove(Object o) {
231 jsr166 1.19 return m.remove(o, Boolean.TRUE);
232 dl 1.1 }
233    
234     /**
235     * Removes all of the elements from this set.
236     */
237     public void clear() {
238 jsr166 1.19 m.clear();
239 dl 1.1 }
240    
241     /**
242 jsr166 1.11 * Returns an iterator over the elements in this set in ascending order.
243 dl 1.1 *
244 jsr166 1.11 * @return an iterator over the elements in this set in ascending order
245 dl 1.1 */
246     public Iterator<E> iterator() {
247 dl 1.15 return m.navigableKeySet().iterator();
248 dl 1.1 }
249    
250     /**
251 jsr166 1.11 * Returns an iterator over the elements in this set in descending order.
252 dl 1.1 *
253 jsr166 1.11 * @return an iterator over the elements in this set in descending order
254 dl 1.1 */
255     public Iterator<E> descendingIterator() {
256 jsr166 1.19 return m.descendingKeySet().iterator();
257 dl 1.1 }
258    
259 dl 1.15
260 dl 1.1 /* ---------------- AbstractSet Overrides -------------- */
261    
262     /**
263     * Compares the specified object with this set for equality. Returns
264 jsr166 1.30 * {@code true} if the specified object is also a set, the two sets
265 dl 1.1 * have the same size, and every member of the specified set is
266     * contained in this set (or equivalently, every member of this set is
267     * contained in the specified set). This definition ensures that the
268     * equals method works properly across different implementations of the
269     * set interface.
270     *
271 jsr166 1.11 * @param o the object to be compared for equality with this set
272 jsr166 1.30 * @return {@code true} if the specified object is equal to this set
273 dl 1.1 */
274     public boolean equals(Object o) {
275     // Override AbstractSet version to avoid calling size()
276 jsr166 1.19 if (o == this)
277     return true;
278     if (!(o instanceof Set))
279     return false;
280     Collection<?> c = (Collection<?>) o;
281 dl 1.1 try {
282     return containsAll(c) && c.containsAll(this);
283 jsr166 1.29 } catch (ClassCastException unused) {
284 dl 1.1 return false;
285 jsr166 1.6 } catch (NullPointerException unused) {
286 dl 1.1 return false;
287     }
288     }
289 jsr166 1.8
290 dl 1.1 /**
291     * Removes from this set all of its elements that are contained in
292     * the specified collection. If the specified collection is also
293     * a set, this operation effectively modifies this set so that its
294     * value is the <i>asymmetric set difference</i> of the two sets.
295     *
296 jsr166 1.11 * @param c collection containing elements to be removed from this set
297 jsr166 1.30 * @return {@code true} if this set changed as a result of the call
298 dl 1.1 * @throws ClassCastException if the types of one or more elements in this
299 jsr166 1.11 * set are incompatible with the specified collection
300     * @throws NullPointerException if the specified collection or any
301     * of its elements are null
302 dl 1.1 */
303     public boolean removeAll(Collection<?> c) {
304     // Override AbstractSet version to avoid unnecessary call to size()
305     boolean modified = false;
306 jsr166 1.27 for (Object e : c)
307     if (remove(e))
308 dl 1.1 modified = true;
309     return modified;
310     }
311 jsr166 1.8
312 dl 1.1 /* ---------------- Relational operations -------------- */
313    
314     /**
315 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
316     * @throws NullPointerException if the specified element is null
317 dl 1.1 */
318 jsr166 1.11 public E lower(E e) {
319     return m.lowerKey(e);
320 dl 1.1 }
321    
322     /**
323 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
324     * @throws NullPointerException if the specified element is null
325 dl 1.1 */
326 jsr166 1.11 public E floor(E e) {
327     return m.floorKey(e);
328 dl 1.1 }
329    
330     /**
331 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
332     * @throws NullPointerException if the specified element is null
333 dl 1.1 */
334 jsr166 1.11 public E ceiling(E e) {
335     return m.ceilingKey(e);
336 dl 1.1 }
337    
338     /**
339 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
340     * @throws NullPointerException if the specified element is null
341 dl 1.1 */
342 jsr166 1.5 public E higher(E e) {
343     return m.higherKey(e);
344 dl 1.1 }
345    
346     public E pollFirst() {
347 dl 1.15 Map.Entry<E,Object> e = m.pollFirstEntry();
348 jsr166 1.20 return (e == null) ? null : e.getKey();
349 dl 1.1 }
350    
351     public E pollLast() {
352 dl 1.15 Map.Entry<E,Object> e = m.pollLastEntry();
353 jsr166 1.20 return (e == null) ? null : e.getKey();
354 dl 1.1 }
355    
356    
357     /* ---------------- SortedSet operations -------------- */
358    
359    
360     public Comparator<? super E> comparator() {
361     return m.comparator();
362     }
363    
364     /**
365 jsr166 1.37 * @throws java.util.NoSuchElementException {@inheritDoc}
366 dl 1.1 */
367     public E first() {
368     return m.firstKey();
369     }
370    
371     /**
372 jsr166 1.37 * @throws java.util.NoSuchElementException {@inheritDoc}
373 dl 1.1 */
374     public E last() {
375     return m.lastKey();
376     }
377    
378     /**
379 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
380 jsr166 1.17 * @throws NullPointerException if {@code fromElement} or
381     * {@code toElement} is null
382 jsr166 1.11 * @throws IllegalArgumentException {@inheritDoc}
383 dl 1.1 */
384 dl 1.16 public NavigableSet<E> subSet(E fromElement,
385     boolean fromInclusive,
386     E toElement,
387     boolean toInclusive) {
388 jsr166 1.19 return new ConcurrentSkipListSet<E>
389 dl 1.16 (m.subMap(fromElement, fromInclusive,
390     toElement, toInclusive));
391 dl 1.1 }
392    
393     /**
394 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
395 jsr166 1.17 * @throws NullPointerException if {@code toElement} is null
396 jsr166 1.11 * @throws IllegalArgumentException {@inheritDoc}
397 dl 1.1 */
398 dl 1.16 public NavigableSet<E> headSet(E toElement, boolean inclusive) {
399 jsr166 1.19 return new ConcurrentSkipListSet<E>(m.headMap(toElement, inclusive));
400 dl 1.1 }
401    
402     /**
403 jsr166 1.11 * @throws ClassCastException {@inheritDoc}
404 jsr166 1.17 * @throws NullPointerException if {@code fromElement} is null
405 jsr166 1.11 * @throws IllegalArgumentException {@inheritDoc}
406 dl 1.1 */
407 dl 1.16 public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
408 jsr166 1.19 return new ConcurrentSkipListSet<E>(m.tailMap(fromElement, inclusive));
409 dl 1.3 }
410    
411     /**
412 jsr166 1.17 * @throws ClassCastException {@inheritDoc}
413     * @throws NullPointerException if {@code fromElement} or
414     * {@code toElement} is null
415 jsr166 1.11 * @throws IllegalArgumentException {@inheritDoc}
416 dl 1.3 */
417 jsr166 1.18 public NavigableSet<E> subSet(E fromElement, E toElement) {
418 jsr166 1.19 return subSet(fromElement, true, toElement, false);
419 dl 1.3 }
420    
421     /**
422 jsr166 1.17 * @throws ClassCastException {@inheritDoc}
423     * @throws NullPointerException if {@code toElement} is null
424 jsr166 1.11 * @throws IllegalArgumentException {@inheritDoc}
425 dl 1.3 */
426 jsr166 1.18 public NavigableSet<E> headSet(E toElement) {
427 jsr166 1.19 return headSet(toElement, false);
428 dl 1.3 }
429    
430     /**
431 jsr166 1.17 * @throws ClassCastException {@inheritDoc}
432     * @throws NullPointerException if {@code fromElement} is null
433 jsr166 1.11 * @throws IllegalArgumentException {@inheritDoc}
434 dl 1.3 */
435 jsr166 1.18 public NavigableSet<E> tailSet(E fromElement) {
436 jsr166 1.19 return tailSet(fromElement, true);
437 dl 1.1 }
438    
439     /**
440 jsr166 1.18 * Returns a reverse order view of the elements contained in this set.
441     * The descending set is backed by this set, so changes to the set are
442     * reflected in the descending set, and vice-versa.
443     *
444     * <p>The returned set has an ordering equivalent to
445 jsr166 1.35 * {@link Collections#reverseOrder(Comparator) Collections.reverseOrder}{@code (comparator())}.
446 jsr166 1.18 * The expression {@code s.descendingSet().descendingSet()} returns a
447     * view of {@code s} essentially equivalent to {@code s}.
448     *
449     * @return a reverse order view of this set
450 dl 1.15 */
451     public NavigableSet<E> descendingSet() {
452 jsr166 1.24 return new ConcurrentSkipListSet<E>(m.descendingMap());
453 dl 1.15 }
454 dl 1.1
455 jsr166 1.40 /**
456     * Returns a {@link Spliterator} over the elements in this set.
457     *
458     * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
459     * {@link Spliterator#NONNULL}, {@link Spliterator#DISTINCT},
460 jsr166 1.41 * {@link Spliterator#SORTED} and {@link Spliterator#ORDERED}, with an
461 jsr166 1.40 * encounter order that is ascending order. Overriding implementations
462     * should document the reporting of additional characteristic values.
463     *
464     * <p>The spliterator's comparator (see
465     * {@link java.util.Spliterator#getComparator()}) is {@code null} if
466     * the set's comparator (see {@link #comparator()}) is {@code null}.
467     * Otherwise, the spliterator's comparator is the same as or imposes the
468     * same total ordering as the set's comparator.
469     *
470     * @return a {@code Spliterator} over the elements in this set
471     * @since 1.8
472     */
473 dl 1.32 @SuppressWarnings("unchecked")
474 dl 1.36 public Spliterator<E> spliterator() {
475 dl 1.31 if (m instanceof ConcurrentSkipListMap)
476 dl 1.32 return ((ConcurrentSkipListMap<E,?>)m).keySpliterator();
477 dl 1.31 else
478 dl 1.32 return (Spliterator<E>)((ConcurrentSkipListMap.SubMap<E,?>)m).keyIterator();
479 dl 1.31 }
480    
481 dl 1.15 // Support for resetting map in clone
482 dl 1.21 private void setMap(ConcurrentNavigableMap<E,Object> map) {
483     UNSAFE.putObjectVolatile(this, mapOffset, map);
484     }
485    
486     private static final sun.misc.Unsafe UNSAFE;
487 dl 1.15 private static final long mapOffset;
488     static {
489     try {
490 dl 1.21 UNSAFE = sun.misc.Unsafe.getUnsafe();
491 jsr166 1.24 Class<?> k = ConcurrentSkipListSet.class;
492 dl 1.21 mapOffset = UNSAFE.objectFieldOffset
493     (k.getDeclaredField("m"));
494     } catch (Exception e) {
495     throw new Error(e);
496     }
497 dl 1.15 }
498 jsr166 1.8 }