History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/util/concurrent/ConcurrentSkipListSet.java (1 of 18352 files). Show all

Unified · Split

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