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 |
|
/** |
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. */ |
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 |
|
|
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()); |