OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [external/] [jsr166/] [java/] [util/] [concurrent/] [CopyOnWriteArraySet.java] - Blame information for rev 768

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 768 jeremybenn
/*
2
 * Written by Doug Lea with assistance from members of JCP JSR-166
3
 * Expert Group and released to the public domain. Use, modify, and
4
 * redistribute this code in any way without acknowledgement.
5
 */
6
 
7
package java.util.concurrent;
8
import java.util.*;
9
 
10
/**
11
 * A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList}
12
 * for all of its operations.  Thus, it shares the same basic properties:
13
 * <ul>
14
 *  <li>It is best suited for applications in which set sizes generally
15
 *       stay small, read-only operations
16
 *       vastly outnumber mutative operations, and you need
17
 *       to prevent interference among threads during traversal.
18
 *  <li>It is thread-safe.
19
 *  <li>Mutative operations (<tt>add</tt>, <tt>set</tt>, <tt>remove</tt>, etc.)
20
 *      are expensive since they usually entail copying the entire underlying
21
 *      array.
22
 *  <li>Iterators do not support the mutative <tt>remove</tt> operation.
23
 *  <li>Traversal via iterators is fast and cannot encounter
24
 *      interference from other threads. Iterators rely on
25
 *      unchanging snapshots of the array at the time the iterators were
26
 *      constructed.
27
 * </ul>
28
 *
29
 * <p> <b>Sample Usage.</b> The following code sketch uses a
30
 * copy-on-write set to maintain a set of Handler objects that
31
 * perform some action upon state updates.
32
 *
33
 * <pre>
34
 * class Handler { void handle(); ... }
35
 *
36
 * class X {
37
 *    private final CopyOnWriteArraySet&lt;Handler&gt; handlers
38
 *       = new CopyOnWriteArraySet&lt;Handler&gt;();
39
 *    public void addHandler(Handler h) { handlers.add(h); }
40
 *
41
 *    private long internalState;
42
 *    private synchronized void changeState() { internalState = ...; }
43
 *
44
 *    public void update() {
45
 *       changeState();
46
 *       for (Handler handler : handlers)
47
 *          handler.handle();
48
 *    }
49
 * }
50
 * </pre>
51
 *
52
 * <p>This class is a member of the
53
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
54
 * Java Collections Framework</a>.
55
 *
56
 * @see CopyOnWriteArrayList
57
 * @since 1.5
58
 * @author Doug Lea
59
 * @param <E> the type of elements held in this collection
60
 */
61
public class CopyOnWriteArraySet<E> extends AbstractSet<E>
62
        implements java.io.Serializable {
63
    private static final long serialVersionUID = 5457747651344034263L;
64
 
65
    private final CopyOnWriteArrayList<E> al;
66
 
67
    /**
68
     * Creates an empty set.
69
     */
70
    public CopyOnWriteArraySet() {
71
        al = new CopyOnWriteArrayList<E>();
72
    }
73
 
74
    /**
75
     * Creates a set containing all of the elements of the specified
76
     * collection.
77
     *
78
     * @param c the collection of elements to initially contain
79
     * @throws NullPointerException if the specified collection is null
80
     */
81
    public CopyOnWriteArraySet(Collection<? extends E> c) {
82
        al = new CopyOnWriteArrayList<E>();
83
        al.addAllAbsent(c);
84
    }
85
 
86
    /**
87
     * Returns the number of elements in this set.
88
     *
89
     * @return the number of elements in this set
90
     */
91
    public int size() {
92
        return al.size();
93
    }
94
 
95
    /**
96
     * Returns <tt>true</tt> if this set contains no elements.
97
     *
98
     * @return <tt>true</tt> if this set contains no elements
99
     */
100
    public boolean isEmpty() {
101
        return al.isEmpty();
102
    }
103
 
104
    /**
105
     * Returns <tt>true</tt> if this set contains the specified element.
106
     * More formally, returns <tt>true</tt> if and only if this set
107
     * contains an element <tt>e</tt> such that
108
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
109
     *
110
     * @param o element whose presence in this set is to be tested
111
     * @return <tt>true</tt> if this set contains the specified element
112
     */
113
    public boolean contains(Object o) {
114
        return al.contains(o);
115
    }
116
 
117
    /**
118
     * Returns an array containing all of the elements in this set.
119
     * If this set makes any guarantees as to what order its elements
120
     * are returned by its iterator, this method must return the
121
     * elements in the same order.
122
     *
123
     * <p>The returned array will be "safe" in that no references to it
124
     * are maintained by this set.  (In other words, this method must
125
     * allocate a new array even if this set is backed by an array).
126
     * The caller is thus free to modify the returned array.
127
     *
128
     * <p>This method acts as bridge between array-based and collection-based
129
     * APIs.
130
     *
131
     * @return an array containing all the elements in this set
132
     */
133
    public Object[] toArray() {
134
        return al.toArray();
135
    }
136
 
137
    /**
138
     * Returns an array containing all of the elements in this set; the
139
     * runtime type of the returned array is that of the specified array.
140
     * If the set fits in the specified array, it is returned therein.
141
     * Otherwise, a new array is allocated with the runtime type of the
142
     * specified array and the size of this set.
143
     *
144
     * <p>If this set fits in the specified array with room to spare
145
     * (i.e., the array has more elements than this set), the element in
146
     * the array immediately following the end of the set is set to
147
     * <tt>null</tt>.  (This is useful in determining the length of this
148
     * set <i>only</i> if the caller knows that this set does not contain
149
     * any null elements.)
150
     *
151
     * <p>If this set makes any guarantees as to what order its elements
152
     * are returned by its iterator, this method must return the elements
153
     * in the same order.
154
     *
155
     * <p>Like the {@link #toArray()} method, this method acts as bridge between
156
     * array-based and collection-based APIs.  Further, this method allows
157
     * precise control over the runtime type of the output array, and may,
158
     * under certain circumstances, be used to save allocation costs.
159
     *
160
     * <p>Suppose <tt>x</tt> is a set known to contain only strings.
161
     * The following code can be used to dump the set into a newly allocated
162
     * array of <tt>String</tt>:
163
     *
164
     * <pre>
165
     *     String[] y = x.toArray(new String[0]);</pre>
166
     *
167
     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
168
     * <tt>toArray()</tt>.
169
     *
170
     * @param a the array into which the elements of this set are to be
171
     *        stored, if it is big enough; otherwise, a new array of the same
172
     *        runtime type is allocated for this purpose.
173
     * @return an array containing all the elements in this set
174
     * @throws ArrayStoreException if the runtime type of the specified array
175
     *         is not a supertype of the runtime type of every element in this
176
     *         set
177
     * @throws NullPointerException if the specified array is null
178
     */
179
    public <T> T[] toArray(T[] a) {
180
        return al.toArray(a);
181
    }
182
 
183
    /**
184
     * Removes all of the elements from this set.
185
     * The set will be empty after this call returns.
186
     */
187
    public void clear() {
188
        al.clear();
189
    }
190
 
191
    /**
192
     * Removes the specified element from this set if it is present.
193
     * More formally, removes an element <tt>e</tt> such that
194
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>,
195
     * if this set contains such an element.  Returns <tt>true</tt> if
196
     * this set contained the element (or equivalently, if this set
197
     * changed as a result of the call).  (This set will not contain the
198
     * element once the call returns.)
199
     *
200
     * @param o object to be removed from this set, if present
201
     * @return <tt>true</tt> if this set contained the specified element
202
     */
203
    public boolean remove(Object o) {
204
        return al.remove(o);
205
    }
206
 
207
    /**
208
     * Adds the specified element to this set if it is not already present.
209
     * More formally, adds the specified element <tt>e</tt> to this set if
210
     * the set contains no element <tt>e2</tt> such that
211
     * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
212
     * If this set already contains the element, the call leaves the set
213
     * unchanged and returns <tt>false</tt>.
214
     *
215
     * @param e element to be added to this set
216
     * @return <tt>true</tt> if this set did not already contain the specified
217
     *         element
218
     */
219
    public boolean add(E e) {
220
        return al.addIfAbsent(e);
221
    }
222
 
223
    /**
224
     * Returns <tt>true</tt> if this set contains all of the elements of the
225
     * specified collection.  If the specified collection is also a set, this
226
     * method returns <tt>true</tt> if it is a <i>subset</i> of this set.
227
     *
228
     * @param  c collection to be checked for containment in this set
229
     * @return <tt>true</tt> if this set contains all of the elements of the
230
     *         specified collection
231
     * @throws NullPointerException if the specified collection is null
232
     * @see #contains(Object)
233
     */
234
    public boolean containsAll(Collection<?> c) {
235
        return al.containsAll(c);
236
    }
237
 
238
    /**
239
     * Adds all of the elements in the specified collection to this set if
240
     * they're not already present.  If the specified collection is also a
241
     * set, the <tt>addAll</tt> operation effectively modifies this set so
242
     * that its value is the <i>union</i> of the two sets.  The behavior of
243
     * this operation is undefined if the specified collection is modified
244
     * while the operation is in progress.
245
     *
246
     * @param  c collection containing elements to be added to this set
247
     * @return <tt>true</tt> if this set changed as a result of the call
248
     * @throws NullPointerException if the specified collection is null
249
     * @see #add(Object)
250
     */
251
    public boolean addAll(Collection<? extends E> c) {
252
        return al.addAllAbsent(c) > 0;
253
    }
254
 
255
    /**
256
     * Removes from this set all of its elements that are contained in the
257
     * specified collection.  If the specified collection is also a set,
258
     * this operation effectively modifies this set so that its value is the
259
     * <i>asymmetric set difference</i> of the two sets.
260
     *
261
     * @param  c collection containing elements to be removed from this set
262
     * @return <tt>true</tt> if this set changed as a result of the call
263
     * @throws ClassCastException if the class of an element of this set
264
     *         is incompatible with the specified collection (optional)
265
     * @throws NullPointerException if this set contains a null element and the
266
     *         specified collection does not permit null elements (optional),
267
     *         or if the specified collection is null
268
     * @see #remove(Object)
269
     */
270
    public boolean removeAll(Collection<?> c) {
271
        return al.removeAll(c);
272
    }
273
 
274
    /**
275
     * Retains only the elements in this set that are contained in the
276
     * specified collection.  In other words, removes from this set all of
277
     * its elements that are not contained in the specified collection.  If
278
     * the specified collection is also a set, this operation effectively
279
     * modifies this set so that its value is the <i>intersection</i> of the
280
     * two sets.
281
     *
282
     * @param  c collection containing elements to be retained in this set
283
     * @return <tt>true</tt> if this set changed as a result of the call
284
     * @throws ClassCastException if the class of an element of this set
285
     *         is incompatible with the specified collection (optional)
286
     * @throws NullPointerException if this set contains a null element and the
287
     *         specified collection does not permit null elements (optional),
288
     *         or if the specified collection is null
289
     * @see #remove(Object)
290
     */
291
    public boolean retainAll(Collection<?> c) {
292
        return al.retainAll(c);
293
    }
294
 
295
    /**
296
     * Returns an iterator over the elements contained in this set
297
     * in the order in which these elements were added.
298
     *
299
     * <p>The returned iterator provides a snapshot of the state of the set
300
     * when the iterator was constructed. No synchronization is needed while
301
     * traversing the iterator. The iterator does <em>NOT</em> support the
302
     * <tt>remove</tt> method.
303
     *
304
     * @return an iterator over the elements in this set
305
     */
306
    public Iterator<E> iterator() {
307
        return al.iterator();
308
    }
309
 
310
    /**
311
     * Compares the specified object with this set for equality.
312
     * Returns {@code true} if the specified object is the same object
313
     * as this object, or if it is also a {@link Set} and the elements
314
     * returned by an {@linkplain List#iterator() iterator} over the
315
     * specified set are the same as the elements returned by an
316
     * iterator over this set.  More formally, the two iterators are
317
     * considered to return the same elements if they return the same
318
     * number of elements and for every element {@code e1} returned by
319
     * the iterator over the specified set, there is an element
320
     * {@code e2} returned by the iterator over this set such that
321
     * {@code (e1==null ? e2==null : e1.equals(e2))}.
322
     *
323
     * @param o object to be compared for equality with this set
324
     * @return {@code true} if the specified object is equal to this set
325
     */
326
    public boolean equals(Object o) {
327
        if (o == this)
328
            return true;
329
        if (!(o instanceof Set))
330
            return false;
331
        Set<?> set = (Set<?>)(o);
332
        Iterator<?> it = set.iterator();
333
 
334
        // Uses O(n^2) algorithm that is only appropriate
335
        // for small sets, which CopyOnWriteArraySets should be.
336
 
337
        //  Use a single snapshot of underlying array
338
        Object[] elements = al.getArray();
339
        int len = elements.length;
340
        // Mark matched elements to avoid re-checking
341
        boolean[] matched = new boolean[len];
342
        int k = 0;
343
        outer: while (it.hasNext()) {
344
            if (++k > len)
345
                return false;
346
            Object x = it.next();
347
            for (int i = 0; i < len; ++i) {
348
                if (!matched[i] && eq(x, elements[i])) {
349
                    matched[i] = true;
350
                    continue outer;
351
                }
352
            }
353
            return false;
354
        }
355
        return k == len;
356
    }
357
 
358
    /**
359
     * Test for equality, coping with nulls.
360
     */
361
    private static boolean eq(Object o1, Object o2) {
362
        return (o1 == null ? o2 == null : o1.equals(o2));
363
    }
364
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.