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

Comparing jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java (file contents):
Revision 1.97 by dl, Fri Feb 1 01:02:37 2013 UTC vs.
Revision 1.98 by dl, Sun Feb 17 23:36:34 2013 UTC

# Line 15 | Line 15
15   */
16  
17   package java.util.concurrent;
18 + import java.util.AbstractList;
19   import java.util.Arrays;
20   import java.util.Collection;
21 < import java.util.List;
22 < import java.util.AbstractList;
21 > import java.util.Collections;
22 > import java.util.ConcurrentModificationException;
23   import java.util.Iterator;
24 + import java.util.List;
25   import java.util.ListIterator;
24 import java.util.RandomAccess;
26   import java.util.NoSuchElementException;
27 < import java.util.ConcurrentModificationException;
27 > import java.util.RandomAccess;
28   import java.util.Spliterator;
29 + import java.util.concurrent.locks.ReentrantLock;
30 + import java.util.function.Consumer;
31   import java.util.stream.Stream;
32   import java.util.stream.Streams;
30 import java.util.function.Consumer;
31 import java.util.concurrent.locks.ReentrantLock;
33  
34   /**
35   * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
# Line 982 | Line 983 | public class CopyOnWriteArrayList<E>
983          return new COWIterator<E>(elements, index);
984      }
985  
986 +    Spliterator<E> spliterator() {
987 +        return Collections.arraySnapshotSpliterator
988 +            (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED);
989 +    }
990 +
991      public Stream<E> stream() {
992 <        int flags = Streams.STREAM_IS_ORDERED | Streams.STREAM_IS_SIZED;
993 <        Object[] a = getArray();
988 <        int n = a.length;
989 <        return Streams.stream
990 <            (() -> new COWSpliterator<E>(a, 0, n), flags);
992 >        return Streams.stream(spliterator());
993 >
994      }
995      public Stream<E> parallelStream() {
996 <        int flags = Streams.STREAM_IS_ORDERED | Streams.STREAM_IS_SIZED;
994 <        Object[] a = getArray();
995 <        int n = a.length;
996 <        return Streams.parallelStream
997 <            (() -> new COWSpliterator<E>(a, 0, n), flags);
996 >        return Streams.parallelStream(spliterator());
997      }
998  
999      static final class COWIterator<E> implements ListIterator<E> {
# Line 1268 | Line 1267 | public class CopyOnWriteArrayList<E>
1267              }
1268          }
1269  
1270 <        public Stream<E> stream() {
1272 <            int flags = Streams.STREAM_IS_ORDERED | Streams.STREAM_IS_SIZED;
1270 >        Spliterator<E> spliterator() {
1271              int lo = offset;
1272              int hi = offset + size;
1273              Object[] a = expectedArray;
# Line 1277 | Line 1275 | public class CopyOnWriteArrayList<E>
1275                  throw new ConcurrentModificationException();
1276              if (lo < 0 || hi > a.length)
1277                  throw new IndexOutOfBoundsException();
1278 <            return Streams.stream
1279 <                (() -> new COWSpliterator<E>(a, lo, hi), flags);
1278 >            return Collections.arraySnapshotSpliterator
1279 >                (a, lo, hi, Spliterator.IMMUTABLE | Spliterator.ORDERED);
1280          }
1281  
1282 <        public Stream<E> parallelStream() {
1283 <            int flags = Streams.STREAM_IS_ORDERED | Streams.STREAM_IS_SIZED;
1286 <            int lo = offset;
1287 <            int hi = offset + size;
1288 <            Object[] a = expectedArray;
1289 <            if (l.getArray() != a)
1290 <                throw new ConcurrentModificationException();
1291 <            if (lo < 0 || hi > a.length)
1292 <                throw new IndexOutOfBoundsException();
1293 <            return Streams.parallelStream
1294 <                (() -> new COWSpliterator<E>(a, lo, hi), flags);
1282 >        public Stream<E> stream() {
1283 >            return Streams.stream(spliterator());
1284          }
1285  
1286 +        public Stream<E> parallelStream() {
1287 +            return Streams.parallelStream(spliterator());
1288 +        }
1289      }
1290  
1299
1291      private static class COWSubListIterator<E> implements ListIterator<E> {
1292          private final ListIterator<E> it;
1293          private final int offset;
# Line 1351 | Line 1342 | public class CopyOnWriteArrayList<E>
1342          }
1343      }
1344  
1354    /** Index-based split-by-two Spliterator */
1355    static final class COWSpliterator<E> implements Spliterator<E> {
1356        private final Object[] array;
1357        private int index;        // current index, modified on advance/split
1358        private final int fence;  // one past last index
1359
1360        /** Create new spliterator covering the given array and range */
1361        COWSpliterator(Object[] array, int origin, int fence) {
1362            this.array = array; this.index = origin; this.fence = fence;
1363        }
1364
1365        public COWSpliterator<E> trySplit() {
1366            int lo = index, mid = (lo + fence) >>> 1;
1367            return (lo >= mid) ? null :
1368                new COWSpliterator<E>(array, lo, index = mid);
1369        }
1370
1371        public void forEach(Consumer<? super E> block) {
1372            Object[] a; int i, hi; // hoist accesses and checks from loop
1373            if (block == null)
1374                throw new NullPointerException();
1375            if ((a = array).length >= (hi = fence) &&
1376                (i = index) >= 0 && i < hi) {
1377                index = hi;
1378                do {
1379                    @SuppressWarnings("unchecked") E e = (E) a[i];
1380                    block.accept(e);
1381                } while (++i < hi);
1382            }
1383        }
1384
1385        public boolean tryAdvance(Consumer<? super E> block) {
1386            if (index >= 0 && index < fence) {
1387                @SuppressWarnings("unchecked") E e = (E) array[index++];
1388                block.accept(e);
1389                return true;
1390            }
1391            return false;
1392        }
1393
1394        public long estimateSize() { return (long)(fence - index); }
1395        public boolean hasExactSize() { return true; }
1396        public boolean hasExactSplits() { return true; }
1397    }
1398
1399
1345      // Support for resetting lock while deserializing
1346      private void resetLock() {
1347          UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines