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.92 by jsr166, Wed Jan 16 01:59:47 2013 UTC vs.
Revision 1.93 by dl, Wed Jan 16 15:04:03 2013 UTC

# Line 15 | Line 15
15   */
16  
17   package java.util.concurrent;
18 < import java.util.*;
18 > import java.util.Arrays;
19 > import java.util.Collection;
20 > import java.util.List;
21 > import java.util.AbstractList;
22 > import java.util.Iterator;
23 > import java.util.ListIterator;
24 > import java.util.RandomAccess;
25 > import java.util.NoSuchElementException;
26 > import java.util.ConcurrentModificationException;
27 > import java.util.Spliterator;
28 > import java.util.stream.Stream;
29 > import java.util.stream.Streams;
30 > import java.util.function.Block;
31   import java.util.concurrent.locks.ReentrantLock;
32  
33   /**
# Line 970 | Line 982 | public class CopyOnWriteArrayList<E>
982          return new COWIterator<E>(elements, index);
983      }
984  
985 <    private static class COWIterator<E> implements ListIterator<E> {
985 >    public Stream<E> stream() {
986 >        int flags = Streams.STREAM_IS_ORDERED | Streams.STREAM_IS_SIZED;
987 >        Object[] a = getArray();
988 >        int n = a.length;
989 >        return Streams.stream
990 >            (() -> new COWSpliterator<E>(a, 0, n), flags);
991 >    }
992 >    public Stream<E> parallelStream() {
993 >        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);
998 >    }
999 >
1000 >    static final class COWIterator<E> implements ListIterator<E> {
1001          /** Snapshot of the array */
1002          private final Object[] snapshot;
1003          /** Index of element to be returned by subsequent call to next.  */
# Line 1241 | Line 1268 | public class CopyOnWriteArrayList<E>
1268              }
1269          }
1270  
1271 +        public Stream<E> stream() {
1272 +            int flags = Streams.STREAM_IS_ORDERED | Streams.STREAM_IS_SIZED;
1273 +            int lo = offset;
1274 +            int hi = offset + size;
1275 +            Object[] a = expectedArray;
1276 +            if (l.getArray() != a)
1277 +                throw new ConcurrentModificationException();
1278 +            if (lo < 0 || hi > a.length)
1279 +                throw new IndexOutOfBoundsException();
1280 +            return Streams.stream
1281 +                (() -> new COWSpliterator<E>(a, lo, hi), flags);
1282 +        }
1283 +
1284 +        public Stream<E> parallelStream() {
1285 +            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);
1295 +        }
1296 +
1297      }
1298  
1299  
# Line 1298 | Line 1351 | public class CopyOnWriteArrayList<E>
1351          }
1352      }
1353  
1354 +    /** Index-based split-by-two Spliterator */
1355 +    static final class COWSpliterator<E> implements Spliterator<E>, Iterator<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(Block<? 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(Block<? 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 +        // Iterator support
1399 +        public Iterator<E> iterator() { return this; }
1400 +        public void remove() { throw new UnsupportedOperationException(); }
1401 +        public boolean hasNext() { return index >= 0 && index < fence; }
1402 +
1403 +        public E next() {
1404 +            if (index < 0 || index >= fence)
1405 +                throw new NoSuchElementException();
1406 +            @SuppressWarnings("unchecked") E e = (E) array[index++];
1407 +            return e;
1408 +        }
1409 +    }
1410 +
1411 +
1412      // Support for resetting lock while deserializing
1413      private void resetLock() {
1414          UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines