ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CopyOnWriteArraySet.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/CopyOnWriteArraySet.java (file contents):
Revision 1.65 by jsr166, Tue May 19 06:32:59 2015 UTC vs.
Revision 1.66 by jsr166, Tue May 26 19:22:09 2015 UTC

# Line 244 | Line 244 | public class CopyOnWriteArraySet<E> exte
244       * @see #contains(Object)
245       */
246      public boolean containsAll(Collection<?> c) {
247 <        return al.containsAll(c);
247 >        return (c instanceof Set)
248 >            ? compareSets(al.getArray(), (Set<?>) c) >= 0
249 >            : al.containsAll(c);
250 >    }
251 >
252 >    /**
253 >     * Tells whether the objects in snapshot (regarded as a set) are a
254 >     * superset of the given set.
255 >     *
256 >     * @return -1 if snapshot is not a superset, 0 if the two sets
257 >     * contain precisely the same elements, and 1 if snapshot is a
258 >     * proper superset of the given set
259 >     */
260 >    private static int compareSets(Object[] snapshot, Set<?> set) {
261 >        // Uses O(n^2) algorithm, that is only appropriate for small
262 >        // sets, which CopyOnWriteArraySets should be.
263 >        //
264 >        // Optimize up to O(n) if the two sets share a long common prefix,
265 >        // as might happen if one set was created as a copy of the other set.
266 >
267 >        final int len = snapshot.length;
268 >        // Mark matched elements to avoid re-checking
269 >        final boolean[] matched = new boolean[len];
270 >
271 >        // j is the largest int with matched[i] true for { i | 0 <= i < j }
272 >        int j = 0;
273 >        outer: for (Object x : set) {
274 >            for (int i = j; i < len; i++) {
275 >                if (!matched[i] && Objects.equals(x, snapshot[i])) {
276 >                    matched[i] = true;
277 >                    if (i == j)
278 >                        do { j++; } while (j < len && matched[j]);
279 >                    continue outer;
280 >                }
281 >            }
282 >            return -1;
283 >        }
284 >        return (j == len) ? 0 : 1;
285      }
286  
287      /**
# Line 336 | Line 373 | public class CopyOnWriteArraySet<E> exte
373       * @return {@code true} if the specified object is equal to this set
374       */
375      public boolean equals(Object o) {
376 <        if (o == this)
377 <            return true;
378 <        if (!(o instanceof Set))
342 <            return false;
343 <        Set<?> set = (Set<?>)o;
344 <        Iterator<?> it = set.iterator();
345 <
346 <        // Uses O(n^2) algorithm that is only appropriate
347 <        // for small sets, which CopyOnWriteArraySets should be.
348 <
349 <        //  Use a single snapshot of underlying array
350 <        Object[] elements = al.getArray();
351 <        int len = elements.length;
352 <        // Mark matched elements to avoid re-checking
353 <        boolean[] matched = new boolean[len];
354 <        int k = 0;
355 <        outer: while (it.hasNext()) {
356 <            if (++k > len)
357 <                return false;
358 <            Object x = it.next();
359 <            for (int i = 0; i < len; ++i) {
360 <                if (!matched[i] && Objects.equals(x, elements[i])) {
361 <                    matched[i] = true;
362 <                    continue outer;
363 <                }
364 <            }
365 <            return false;
366 <        }
367 <        return k == len;
376 >        return (o == this)
377 >            || ((o instanceof Set)
378 >                && compareSets(al.getArray(), (Set<?>) o) == 0);
379      }
380  
381      public boolean removeIf(Predicate<? super E> filter) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines