139 */
140 final void init() {
141 if (spliterator == null) {
142 spliterator = spliteratorSupplier.get();
143 spliteratorSupplier = null;
144 }
145 }
146
147 /**
148 * Get an element from the source, pushing it into the sink chain,
149 * setting up the buffer if needed
150 * @return whether there are elements to consume from the buffer
151 */
152 final boolean doAdvance() {
153 if (buffer == null) {
154 if (finished)
155 return false;
156
157 init();
158 initPartialTraversalState();
159 nextToConsume = 0;
160 bufferSink.begin(spliterator.getExactSizeIfKnown());
161 return fillBuffer();
162 }
163 else {
164 ++nextToConsume;
165 boolean hasNext = nextToConsume < buffer.count();
166 if (!hasNext) {
167 nextToConsume = 0;
168 buffer.clear();
169 hasNext = fillBuffer();
170 }
171 return hasNext;
172 }
173 }
174
175 /**
176 * Invokes the shape-specific constructor with the provided arguments
177 * and returns the result.
178 */
179 abstract AbstractWrappingSpliterator<P_IN, P_OUT, ?> wrap(Spliterator<P_IN> s);
180
181 /**
182 * Initializes buffer, sink chain, and pusher for a shape-specific
183 * implementation.
184 */
185 abstract void initPartialTraversalState();
186
187 @Override
188 public Spliterator<P_OUT> trySplit() {
189 if (isParallel && !finished) {
190 init();
191
192 Spliterator<P_IN> split = spliterator.trySplit();
193 return (split == null) ? null : wrap(split);
194 }
195 else
196 return null;
197 }
198
199 /**
200 * If the buffer is empty, push elements into the sink chain until
201 * the source is empty or cancellation is requested.
202 * @return whether there are elements to consume from the buffer
203 */
204 private boolean fillBuffer() {
205 while (buffer.count() == 0) {
206 if (bufferSink.cancellationRequested() || !pusher.getAsBoolean()) {
207 if (finished)
208 return false;
209 else {
210 bufferSink.end(); // might trigger more elements
211 finished = true;
212 }
213 }
274 boolean parallel) {
275 super(ph, supplier, parallel);
276 }
277
278 WrappingSpliterator(PipelineHelper<P_OUT> ph,
279 Spliterator<P_IN> spliterator,
280 boolean parallel) {
281 super(ph, spliterator, parallel);
282 }
283
284 @Override
285 WrappingSpliterator<P_IN, P_OUT> wrap(Spliterator<P_IN> s) {
286 return new WrappingSpliterator<>(ph, s, isParallel);
287 }
288
289 @Override
290 void initPartialTraversalState() {
291 SpinedBuffer<P_OUT> b = new SpinedBuffer<>();
292 buffer = b;
293 bufferSink = ph.wrapSink(b::accept);
294 pusher = () -> spliterator.tryAdvance(bufferSink);
295 }
296
297 @Override
298 public boolean tryAdvance(Consumer<? super P_OUT> consumer) {
299 Objects.requireNonNull(consumer);
300 boolean hasNext = doAdvance();
301 if (hasNext)
302 consumer.accept(buffer.get(nextToConsume));
303 return hasNext;
304 }
305
306 @Override
307 public void forEachRemaining(Consumer<? super P_OUT> consumer) {
308 if (buffer == null && !finished) {
309 Objects.requireNonNull(consumer);
310 init();
311
312 ph.wrapAndCopyInto((Sink<P_OUT>) consumer::accept, spliterator);
313 finished = true;
314 }
318 }
319 }
320
321 static final class IntWrappingSpliterator<P_IN>
322 extends AbstractWrappingSpliterator<P_IN, Integer, SpinedBuffer.OfInt>
323 implements Spliterator.OfInt {
324
325 IntWrappingSpliterator(PipelineHelper<Integer> ph,
326 Supplier<Spliterator<P_IN>> supplier,
327 boolean parallel) {
328 super(ph, supplier, parallel);
329 }
330
331 IntWrappingSpliterator(PipelineHelper<Integer> ph,
332 Spliterator<P_IN> spliterator,
333 boolean parallel) {
334 super(ph, spliterator, parallel);
335 }
336
337 @Override
338 AbstractWrappingSpliterator<P_IN, Integer, ?> wrap(Spliterator<P_IN> s) {
339 return new IntWrappingSpliterator<>(ph, s, isParallel);
340 }
341
342 @Override
343 void initPartialTraversalState() {
344 SpinedBuffer.OfInt b = new SpinedBuffer.OfInt();
345 buffer = b;
346 bufferSink = ph.wrapSink((Sink.OfInt) b::accept);
347 pusher = () -> spliterator.tryAdvance(bufferSink);
348 }
349
350 @Override
351 public Spliterator.OfInt trySplit() {
352 return (Spliterator.OfInt) super.trySplit();
353 }
354
355 @Override
356 public boolean tryAdvance(IntConsumer consumer) {
357 Objects.requireNonNull(consumer);
358 boolean hasNext = doAdvance();
359 if (hasNext)
360 consumer.accept(buffer.get(nextToConsume));
361 return hasNext;
362 }
363
364 @Override
365 public void forEachRemaining(IntConsumer consumer) {
366 if (buffer == null && !finished) {
367 Objects.requireNonNull(consumer);
376 }
377 }
378
379 static final class LongWrappingSpliterator<P_IN>
380 extends AbstractWrappingSpliterator<P_IN, Long, SpinedBuffer.OfLong>
381 implements Spliterator.OfLong {
382
383 LongWrappingSpliterator(PipelineHelper<Long> ph,
384 Supplier<Spliterator<P_IN>> supplier,
385 boolean parallel) {
386 super(ph, supplier, parallel);
387 }
388
389 LongWrappingSpliterator(PipelineHelper<Long> ph,
390 Spliterator<P_IN> spliterator,
391 boolean parallel) {
392 super(ph, spliterator, parallel);
393 }
394
395 @Override
396 AbstractWrappingSpliterator<P_IN, Long, ?> wrap(Spliterator<P_IN> s) {
397 return new LongWrappingSpliterator<>(ph, s, isParallel);
398 }
399
400 @Override
401 void initPartialTraversalState() {
402 SpinedBuffer.OfLong b = new SpinedBuffer.OfLong();
403 buffer = b;
404 bufferSink = ph.wrapSink((Sink.OfLong) b::accept);
405 pusher = () -> spliterator.tryAdvance(bufferSink);
406 }
407
408 @Override
409 public Spliterator.OfLong trySplit() {
410 return (Spliterator.OfLong) super.trySplit();
411 }
412
413 @Override
414 public boolean tryAdvance(LongConsumer consumer) {
415 Objects.requireNonNull(consumer);
416 boolean hasNext = doAdvance();
417 if (hasNext)
418 consumer.accept(buffer.get(nextToConsume));
419 return hasNext;
420 }
421
422 @Override
423 public void forEachRemaining(LongConsumer consumer) {
424 if (buffer == null && !finished) {
425 Objects.requireNonNull(consumer);
434 }
435 }
436
437 static final class DoubleWrappingSpliterator<P_IN>
438 extends AbstractWrappingSpliterator<P_IN, Double, SpinedBuffer.OfDouble>
439 implements Spliterator.OfDouble {
440
441 DoubleWrappingSpliterator(PipelineHelper<Double> ph,
442 Supplier<Spliterator<P_IN>> supplier,
443 boolean parallel) {
444 super(ph, supplier, parallel);
445 }
446
447 DoubleWrappingSpliterator(PipelineHelper<Double> ph,
448 Spliterator<P_IN> spliterator,
449 boolean parallel) {
450 super(ph, spliterator, parallel);
451 }
452
453 @Override
454 AbstractWrappingSpliterator<P_IN, Double, ?> wrap(Spliterator<P_IN> s) {
455 return new DoubleWrappingSpliterator<>(ph, s, isParallel);
456 }
457
458 @Override
459 void initPartialTraversalState() {
460 SpinedBuffer.OfDouble b = new SpinedBuffer.OfDouble();
461 buffer = b;
462 bufferSink = ph.wrapSink((Sink.OfDouble) b::accept);
463 pusher = () -> spliterator.tryAdvance(bufferSink);
464 }
465
466 @Override
467 public Spliterator.OfDouble trySplit() {
468 return (Spliterator.OfDouble) super.trySplit();
469 }
470
471 @Override
472 public boolean tryAdvance(DoubleConsumer consumer) {
473 Objects.requireNonNull(consumer);
474 boolean hasNext = doAdvance();
475 if (hasNext)
476 consumer.accept(buffer.get(nextToConsume));
477 return hasNext;
478 }
479
480 @Override
481 public void forEachRemaining(DoubleConsumer consumer) {
482 if (buffer == null && !finished) {
483 Objects.requireNonNull(consumer);
|
139 */
140 final void init() {
141 if (spliterator == null) {
142 spliterator = spliteratorSupplier.get();
143 spliteratorSupplier = null;
144 }
145 }
146
147 /**
148 * Get an element from the source, pushing it into the sink chain,
149 * setting up the buffer if needed
150 * @return whether there are elements to consume from the buffer
151 */
152 final boolean doAdvance() {
153 if (buffer == null) {
154 if (finished)
155 return false;
156
157 init();
158 initPartialTraversalState();
159 initPusher();
160 nextToConsume = 0;
161 bufferSink.begin(spliterator.getExactSizeIfKnown());
162 return fillBuffer();
163 }
164 else {
165 ++nextToConsume;
166 boolean hasNext = nextToConsume < buffer.count();
167 if (!hasNext) {
168 nextToConsume = 0;
169 buffer.clear();
170 hasNext = fillBuffer();
171 }
172 return hasNext;
173 }
174 }
175
176 /**
177 * Invokes the shape-specific constructor with the provided arguments
178 * and returns the result.
179 */
180 abstract AbstractWrappingSpliterator<P_IN, P_OUT, T_BUFFER> wrap(Spliterator<P_IN> s);
181
182 /**
183 * Initializes buffer, sink chain, and pusher for a shape-specific
184 * implementation.
185 */
186 abstract void initPartialTraversalState();
187
188 void initPusher() {
189 pusher = () -> spliterator.tryAdvance(bufferSink);
190 }
191
192 @Override
193 public Spliterator<P_OUT> trySplit() {
194 if (isParallel && !finished) {
195 init();
196
197 Spliterator<P_IN> split = spliterator.trySplit();
198 if (split == null)
199 return null;
200 AbstractWrappingSpliterator<P_IN, P_OUT, T_BUFFER> prefix = wrap(split);
201 if (buffer != null) {
202 prefix.buffer = buffer;
203 prefix.bufferSink = bufferSink;
204 prefix.nextToConsume = nextToConsume;
205 prefix.initPusher();
206 buffer = null;
207 }
208 return prefix;
209 }
210 else
211 return null;
212 }
213
214 /**
215 * If the buffer is empty, push elements into the sink chain until
216 * the source is empty or cancellation is requested.
217 * @return whether there are elements to consume from the buffer
218 */
219 private boolean fillBuffer() {
220 while (buffer.count() == 0) {
221 if (bufferSink.cancellationRequested() || !pusher.getAsBoolean()) {
222 if (finished)
223 return false;
224 else {
225 bufferSink.end(); // might trigger more elements
226 finished = true;
227 }
228 }
289 boolean parallel) {
290 super(ph, supplier, parallel);
291 }
292
293 WrappingSpliterator(PipelineHelper<P_OUT> ph,
294 Spliterator<P_IN> spliterator,
295 boolean parallel) {
296 super(ph, spliterator, parallel);
297 }
298
299 @Override
300 WrappingSpliterator<P_IN, P_OUT> wrap(Spliterator<P_IN> s) {
301 return new WrappingSpliterator<>(ph, s, isParallel);
302 }
303
304 @Override
305 void initPartialTraversalState() {
306 SpinedBuffer<P_OUT> b = new SpinedBuffer<>();
307 buffer = b;
308 bufferSink = ph.wrapSink(b::accept);
309 }
310
311 @Override
312 public boolean tryAdvance(Consumer<? super P_OUT> consumer) {
313 Objects.requireNonNull(consumer);
314 boolean hasNext = doAdvance();
315 if (hasNext)
316 consumer.accept(buffer.get(nextToConsume));
317 return hasNext;
318 }
319
320 @Override
321 public void forEachRemaining(Consumer<? super P_OUT> consumer) {
322 if (buffer == null && !finished) {
323 Objects.requireNonNull(consumer);
324 init();
325
326 ph.wrapAndCopyInto((Sink<P_OUT>) consumer::accept, spliterator);
327 finished = true;
328 }
332 }
333 }
334
335 static final class IntWrappingSpliterator<P_IN>
336 extends AbstractWrappingSpliterator<P_IN, Integer, SpinedBuffer.OfInt>
337 implements Spliterator.OfInt {
338
339 IntWrappingSpliterator(PipelineHelper<Integer> ph,
340 Supplier<Spliterator<P_IN>> supplier,
341 boolean parallel) {
342 super(ph, supplier, parallel);
343 }
344
345 IntWrappingSpliterator(PipelineHelper<Integer> ph,
346 Spliterator<P_IN> spliterator,
347 boolean parallel) {
348 super(ph, spliterator, parallel);
349 }
350
351 @Override
352 AbstractWrappingSpliterator<P_IN, Integer, SpinedBuffer.OfInt> wrap(Spliterator<P_IN> s) {
353 return new IntWrappingSpliterator<>(ph, s, isParallel);
354 }
355
356 @Override
357 void initPartialTraversalState() {
358 SpinedBuffer.OfInt b = new SpinedBuffer.OfInt();
359 buffer = b;
360 bufferSink = ph.wrapSink((Sink.OfInt) b::accept);
361 }
362
363 @Override
364 public Spliterator.OfInt trySplit() {
365 return (Spliterator.OfInt) super.trySplit();
366 }
367
368 @Override
369 public boolean tryAdvance(IntConsumer consumer) {
370 Objects.requireNonNull(consumer);
371 boolean hasNext = doAdvance();
372 if (hasNext)
373 consumer.accept(buffer.get(nextToConsume));
374 return hasNext;
375 }
376
377 @Override
378 public void forEachRemaining(IntConsumer consumer) {
379 if (buffer == null && !finished) {
380 Objects.requireNonNull(consumer);
389 }
390 }
391
392 static final class LongWrappingSpliterator<P_IN>
393 extends AbstractWrappingSpliterator<P_IN, Long, SpinedBuffer.OfLong>
394 implements Spliterator.OfLong {
395
396 LongWrappingSpliterator(PipelineHelper<Long> ph,
397 Supplier<Spliterator<P_IN>> supplier,
398 boolean parallel) {
399 super(ph, supplier, parallel);
400 }
401
402 LongWrappingSpliterator(PipelineHelper<Long> ph,
403 Spliterator<P_IN> spliterator,
404 boolean parallel) {
405 super(ph, spliterator, parallel);
406 }
407
408 @Override
409 AbstractWrappingSpliterator<P_IN, Long, SpinedBuffer.OfLong> wrap(Spliterator<P_IN> s) {
410 return new LongWrappingSpliterator<>(ph, s, isParallel);
411 }
412
413 @Override
414 void initPartialTraversalState() {
415 SpinedBuffer.OfLong b = new SpinedBuffer.OfLong();
416 buffer = b;
417 bufferSink = ph.wrapSink((Sink.OfLong) b::accept);
418 }
419
420 @Override
421 public Spliterator.OfLong trySplit() {
422 return (Spliterator.OfLong) super.trySplit();
423 }
424
425 @Override
426 public boolean tryAdvance(LongConsumer consumer) {
427 Objects.requireNonNull(consumer);
428 boolean hasNext = doAdvance();
429 if (hasNext)
430 consumer.accept(buffer.get(nextToConsume));
431 return hasNext;
432 }
433
434 @Override
435 public void forEachRemaining(LongConsumer consumer) {
436 if (buffer == null && !finished) {
437 Objects.requireNonNull(consumer);
446 }
447 }
448
449 static final class DoubleWrappingSpliterator<P_IN>
450 extends AbstractWrappingSpliterator<P_IN, Double, SpinedBuffer.OfDouble>
451 implements Spliterator.OfDouble {
452
453 DoubleWrappingSpliterator(PipelineHelper<Double> ph,
454 Supplier<Spliterator<P_IN>> supplier,
455 boolean parallel) {
456 super(ph, supplier, parallel);
457 }
458
459 DoubleWrappingSpliterator(PipelineHelper<Double> ph,
460 Spliterator<P_IN> spliterator,
461 boolean parallel) {
462 super(ph, spliterator, parallel);
463 }
464
465 @Override
466 AbstractWrappingSpliterator<P_IN, Double, SpinedBuffer.OfDouble> wrap(Spliterator<P_IN> s) {
467 return new DoubleWrappingSpliterator<>(ph, s, isParallel);
468 }
469
470 @Override
471 void initPartialTraversalState() {
472 SpinedBuffer.OfDouble b = new SpinedBuffer.OfDouble();
473 buffer = b;
474 bufferSink = ph.wrapSink((Sink.OfDouble) b::accept);
475 }
476
477 @Override
478 public Spliterator.OfDouble trySplit() {
479 return (Spliterator.OfDouble) super.trySplit();
480 }
481
482 @Override
483 public boolean tryAdvance(DoubleConsumer consumer) {
484 Objects.requireNonNull(consumer);
485 boolean hasNext = doAdvance();
486 if (hasNext)
487 consumer.accept(buffer.get(nextToConsume));
488 return hasNext;
489 }
490
491 @Override
492 public void forEachRemaining(DoubleConsumer consumer) {
493 if (buffer == null && !finished) {
494 Objects.requireNonNull(consumer);
|