ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk8/java/util/concurrent/ConcurrentSkipListSet.java
Revision: 1.2
Committed: Sat Mar 11 17:36:10 2017 UTC (7 years, 2 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +0 -1 lines
Log Message:
fix unused imports reported by errorprone [RemoveUnusedImports]

File Contents

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