908 |
|
|
909 |
|
/** A customized variant of Spliterators.IteratorSpliterator */ |
910 |
|
static final class LTQSpliterator<E> implements Spliterator<E> { |
911 |
< |
static final int MAX_BATCH = 1 << 20; // max batch array size; |
912 |
< |
static final int MAX_QUEUED = 1 << 12; // max task backlog |
911 |
> |
static final int MAX_BATCH = 1 << 25; // max batch array size; |
912 |
|
final LinkedTransferQueue<E> queue; |
913 |
|
Node current; // current node; null until initialized |
914 |
|
int batch; // batch size for splits |
917 |
|
this.queue = queue; |
918 |
|
} |
919 |
|
|
921 |
– |
/** |
922 |
– |
* Splits into arrays of arithmetically increasing batch sizes, |
923 |
– |
* giving up at MAX_BATCH. Treat the result as a |
924 |
– |
* CopyOnWriteArrayList array snapshot. This will only |
925 |
– |
* improve parallel performance if per-element forEach actions |
926 |
– |
* are more costly than transfering them into an array. If |
927 |
– |
* not, we limit slowdowns by eventually returning null split. |
928 |
– |
*/ |
920 |
|
public Spliterator<E> trySplit() { |
921 |
< |
Node p; int b; |
921 |
> |
Node p; |
922 |
|
final LinkedTransferQueue<E> q = this.queue; |
923 |
+ |
int b = batch; |
924 |
+ |
int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1; |
925 |
|
if (!exhausted && |
933 |
– |
((b = batch) < MAX_QUEUED || |
934 |
– |
ForkJoinTask.getQueuedTaskCount() < MAX_QUEUED) && |
926 |
|
((p = current) != null || (p = q.firstDataNode()) != null) && |
927 |
|
p.next != null) { |
937 |
– |
int n = batch = (b >= MAX_BATCH) ? MAX_BATCH : b + 1; |
928 |
|
Object[] a; |
929 |
|
try { |
930 |
|
a = new Object[n]; |
940 |
|
} while (p != null && i < n); |
941 |
|
if ((current = p) == null) |
942 |
|
exhausted = true; |
943 |
< |
return Spliterators.spliterator |
944 |
< |
(a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL | |
945 |
< |
Spliterator.CONCURRENT); |
943 |
> |
if (i > 0) { |
944 |
> |
batch = i; |
945 |
> |
return Spliterators.spliterator |
946 |
> |
(a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL | |
947 |
> |
Spliterator.CONCURRENT); |
948 |
> |
} |
949 |
|
} |
950 |
|
return null; |
951 |
|
} |