1128 |
|
Node<E> nextNode(Node<E> n) { return n.prev; } |
1129 |
|
} |
1130 |
|
|
1131 |
+ |
/** A customized variant of Spliterators.IteratorSpliterator */ |
1132 |
|
static final class LBDSpliterator<E> implements Spliterator<E> { |
1133 |
< |
// Similar idea to ConcurrentLinkedQueue spliterator |
1134 |
< |
static final int MAX_BATCH = 1 << 11; // saturate batch size |
1133 |
> |
static final int MAX_BATCH = 1 << 20; // max batch array size; |
1134 |
> |
static final int MAX_QUEUED = 1 << 12; // max task backlog |
1135 |
|
final LinkedBlockingDeque<E> queue; |
1136 |
|
Node<E> current; // current node; null until initialized |
1137 |
|
int batch; // batch size for splits |
1145 |
|
public long estimateSize() { return est; } |
1146 |
|
|
1147 |
|
public Spliterator<E> trySplit() { |
1148 |
< |
int n; |
1148 |
> |
int b; |
1149 |
|
final LinkedBlockingDeque<E> q = this.queue; |
1150 |
|
final ReentrantLock lock = q.lock; |
1151 |
< |
if (!exhausted && (n = batch + 1) > 0 && n <= MAX_BATCH) { |
1152 |
< |
Object[] a = new Object[batch = n]; |
1151 |
> |
if (!exhausted && |
1152 |
> |
((b = batch) < MAX_QUEUED || |
1153 |
> |
java.util.concurrent.ForkJoinTask.getQueuedTaskCount() < MAX_QUEUED)) { |
1154 |
> |
int n = batch = (b >= MAX_BATCH)? MAX_BATCH : b + 1; |
1155 |
> |
Object[] a; |
1156 |
> |
try { |
1157 |
> |
a = new Object[n]; |
1158 |
> |
} catch (OutOfMemoryError oome) { |
1159 |
> |
return null; |
1160 |
> |
} |
1161 |
|
int i = 0; |
1162 |
|
Node<E> p = current; |
1163 |
|
lock.lock(); |
1175 |
|
est = 0L; |
1176 |
|
exhausted = true; |
1177 |
|
} |
1178 |
< |
else if ((est -= i) <= 0L) |
1179 |
< |
est = 1L; |
1178 |
> |
else if ((est -= i) < 0L) |
1179 |
> |
est = 0L; |
1180 |
|
return Spliterators.spliterator |
1181 |
|
(a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL | |
1182 |
|
Spliterator.CONCURRENT); |
1231 |
|
} finally { |
1232 |
|
lock.unlock(); |
1233 |
|
} |
1234 |
+ |
if (current == null) |
1235 |
+ |
exhausted = true; |
1236 |
|
if (e != null) { |
1237 |
|
action.accept(e); |
1238 |
|
return true; |
1239 |
|
} |
1229 |
– |
exhausted = true; |
1240 |
|
} |
1241 |
|
return false; |
1242 |
|
} |