1 /*
   2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.util.stream;
  26 
  27 import java.util.Comparator;
  28 import java.util.Objects;
  29 import java.util.Spliterator;
  30 import java.util.concurrent.ConcurrentHashMap;
  31 import java.util.concurrent.atomic.AtomicLong;
  32 import java.util.function.BooleanSupplier;
  33 import java.util.function.Consumer;
  34 import java.util.function.DoubleConsumer;
  35 import java.util.function.DoubleSupplier;
  36 import java.util.function.IntConsumer;
  37 import java.util.function.IntSupplier;
  38 import java.util.function.LongConsumer;
  39 import java.util.function.LongSupplier;
  40 import java.util.function.Supplier;
  41 
  42 /**
  43  * Spliterator implementations for wrapping and delegating spliterators, used
  44  * in the implementation of the {@link Stream#spliterator()} method.
  45  *
  46  * @since 1.8
  47  */
  48 class StreamSpliterators {
  49 
  50     /**
  51      * Abstract wrapping spliterator that binds to the spliterator of a
  52      * pipeline helper on first operation.
  53      *
  54      * <p>This spliterator is not late-binding and will bind to the source
  55      * spliterator when first operated on.
  56      *
  57      * <p>A wrapping spliterator produced from a sequential stream
  58      * cannot be split if there are stateful operations present.
  59      */
  60     private abstract static class AbstractWrappingSpliterator<P_IN, P_OUT,
  61                                                               T_BUFFER extends AbstractSpinedBuffer>
  62             implements Spliterator<P_OUT> {
  63 
  64         // @@@ Detect if stateful operations are present or not
  65         //     If not then can split otherwise cannot
  66 
  67         /**
  68          * True if this spliterator supports splitting
  69          */
  70         final boolean isParallel;
  71 
  72         final PipelineHelper<P_OUT> ph;
  73 
  74         /**
  75          * Supplier for the source spliterator.  Client provides either a
  76          * spliterator or a supplier.
  77          */
  78         private Supplier<Spliterator<P_IN>> spliteratorSupplier;
  79 
  80         /**
  81          * Source spliterator.  Either provided from client or obtained from
  82          * supplier.
  83          */
  84         Spliterator<P_IN> spliterator;
  85 
  86         /**
  87          * Sink chain for the downstream stages of the pipeline, ultimately
  88          * leading to the buffer. Used during partial traversal.
  89          */
  90         Sink<P_IN> bufferSink;
  91 
  92         /**
  93          * A function that advances one element of the spliterator, pushing
  94          * it to bufferSink.  Returns whether any elements were processed.
  95          * Used during partial traversal.
  96          */
  97         BooleanSupplier pusher;
  98 
  99         /** Next element to consume from the buffer, used during partial traversal */
 100         long nextToConsume;
 101 
 102         /** Buffer into which elements are pushed.  Used during partial traversal. */
 103         T_BUFFER buffer;
 104 
 105         /**
 106          * True if full traversal has occurred (with possible cancelation).
 107          * If doing a partial traversal, there may be still elements in buffer.
 108          */
 109         boolean finished;
 110 
 111         /**
 112          * Construct an AbstractWrappingSpliterator from a
 113          * {@code Supplier<Spliterator>}.
 114          */
 115         AbstractWrappingSpliterator(PipelineHelper<P_OUT> ph,
 116                                     Supplier<Spliterator<P_IN>> spliteratorSupplier,
 117                                     boolean parallel) {
 118             this.ph = ph;
 119             this.spliteratorSupplier = spliteratorSupplier;
 120             this.spliterator = null;
 121             this.isParallel = parallel;
 122         }
 123 
 124         /**
 125          * Construct an AbstractWrappingSpliterator from a
 126          * {@code Spliterator}.
 127          */
 128         AbstractWrappingSpliterator(PipelineHelper<P_OUT> ph,
 129                                     Spliterator<P_IN> spliterator,
 130                                     boolean parallel) {
 131             this.ph = ph;
 132             this.spliteratorSupplier = null;
 133             this.spliterator = spliterator;
 134             this.isParallel = parallel;
 135         }
 136 
 137         /**
 138          * Called before advancing to set up spliterator, if needed.
 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                 if (buffer != null && buffer.count() > 0) // partial traversal started
 193                     return null;
 194                 Spliterator<P_IN> split = spliterator.trySplit();
 195                 return (split == null) ? null : wrap(split);
 196             }
 197             else
 198                 return null;
 199         }
 200 
 201         /**
 202          * If the buffer is empty, push elements into the sink chain until
 203          * the source is empty or cancellation is requested.
 204          * @return whether there are elements to consume from the buffer
 205          */
 206         private boolean fillBuffer() {
 207             while (buffer.count() == 0) {
 208                 if (bufferSink.cancellationRequested() || !pusher.getAsBoolean()) {
 209                     if (finished)
 210                         return false;
 211                     else {
 212                         bufferSink.end(); // might trigger more elements
 213                         finished = true;
 214                     }
 215                 }
 216             }
 217             return true;
 218         }
 219 
 220         @Override
 221         public final long estimateSize() {
 222             init();
 223             // Use the estimate of the wrapped spliterator
 224             // Note this may not be accurate if there are filter/flatMap
 225             // operations filtering or adding elements to the stream
 226             return spliterator.estimateSize();
 227         }
 228 
 229         @Override
 230         public final long getExactSizeIfKnown() {
 231             init();
 232             return StreamOpFlag.SIZED.isKnown(ph.getStreamAndOpFlags())
 233                    ? spliterator.getExactSizeIfKnown()
 234                    : -1;
 235         }
 236 
 237         @Override
 238         public final int characteristics() {
 239             init();
 240 
 241             // Get the characteristics from the pipeline
 242             int c = StreamOpFlag.toCharacteristics(StreamOpFlag.toStreamFlags(ph.getStreamAndOpFlags()));
 243 
 244             // Mask off the size and uniform characteristics and replace with
 245             // those of the spliterator
 246             // Note that a non-uniform spliterator can change from something
 247             // with an exact size to an estimate for a sub-split, for example
 248             // with HashSet where the size is known at the top level spliterator
 249             // but for sub-splits only an estimate is known
 250             if ((c & Spliterator.SIZED) != 0) {
 251                 c &= ~(Spliterator.SIZED | Spliterator.SUBSIZED);
 252                 c |= (spliterator.characteristics() & (Spliterator.SIZED | Spliterator.SUBSIZED));
 253             }
 254 
 255             return c;
 256         }
 257 
 258         @Override
 259         public Comparator<? super P_OUT> getComparator() {
 260             if (!hasCharacteristics(SORTED))
 261                 throw new IllegalStateException();
 262             return null;
 263         }
 264 
 265         @Override
 266         public final String toString() {
 267             return String.format("%s[%s]", getClass().getName(), spliterator);
 268         }
 269     }
 270 
 271     static final class WrappingSpliterator<P_IN, P_OUT>
 272             extends AbstractWrappingSpliterator<P_IN, P_OUT, SpinedBuffer<P_OUT>> {
 273 
 274         WrappingSpliterator(PipelineHelper<P_OUT> ph,
 275                             Supplier<Spliterator<P_IN>> supplier,
 276                             boolean parallel) {
 277             super(ph, supplier, parallel);
 278         }
 279 
 280         WrappingSpliterator(PipelineHelper<P_OUT> ph,
 281                             Spliterator<P_IN> spliterator,
 282                             boolean parallel) {
 283             super(ph, spliterator, parallel);
 284         }
 285 
 286         @Override
 287         WrappingSpliterator<P_IN, P_OUT> wrap(Spliterator<P_IN> s) {
 288             return new WrappingSpliterator<>(ph, s, isParallel);
 289         }
 290 
 291         @Override
 292         void initPartialTraversalState() {
 293             SpinedBuffer<P_OUT> b = new SpinedBuffer<>();
 294             buffer = b;
 295             bufferSink = ph.wrapSink(b::accept);
 296             pusher = () -> spliterator.tryAdvance(bufferSink);
 297         }
 298 
 299         @Override
 300         public boolean tryAdvance(Consumer<? super P_OUT> consumer) {
 301             Objects.requireNonNull(consumer);
 302             boolean hasNext = doAdvance();
 303             if (hasNext)
 304                 consumer.accept(buffer.get(nextToConsume));
 305             return hasNext;
 306         }
 307 
 308         @Override
 309         public void forEachRemaining(Consumer<? super P_OUT> consumer) {
 310             if (buffer == null && !finished) {
 311                 Objects.requireNonNull(consumer);
 312                 init();
 313 
 314                 ph.wrapAndCopyInto((Sink<P_OUT>) consumer::accept, spliterator);
 315                 finished = true;
 316             }
 317             else {
 318                 do { } while (tryAdvance(consumer));
 319             }
 320         }
 321     }
 322 
 323     static final class IntWrappingSpliterator<P_IN>
 324             extends AbstractWrappingSpliterator<P_IN, Integer, SpinedBuffer.OfInt>
 325             implements Spliterator.OfInt {
 326 
 327         IntWrappingSpliterator(PipelineHelper<Integer> ph,
 328                                Supplier<Spliterator<P_IN>> supplier,
 329                                boolean parallel) {
 330             super(ph, supplier, parallel);
 331         }
 332 
 333         IntWrappingSpliterator(PipelineHelper<Integer> ph,
 334                                Spliterator<P_IN> spliterator,
 335                                boolean parallel) {
 336             super(ph, spliterator, parallel);
 337         }
 338 
 339         @Override
 340         AbstractWrappingSpliterator<P_IN, Integer, ?> wrap(Spliterator<P_IN> s) {
 341             return new IntWrappingSpliterator<>(ph, s, isParallel);
 342         }
 343 
 344         @Override
 345         void initPartialTraversalState() {
 346             SpinedBuffer.OfInt b = new SpinedBuffer.OfInt();
 347             buffer = b;
 348             bufferSink = ph.wrapSink((Sink.OfInt) b::accept);
 349             pusher = () -> spliterator.tryAdvance(bufferSink);
 350         }
 351 
 352         @Override
 353         public Spliterator.OfInt trySplit() {
 354             return (Spliterator.OfInt) super.trySplit();
 355         }
 356 
 357         @Override
 358         public boolean tryAdvance(IntConsumer consumer) {
 359             Objects.requireNonNull(consumer);
 360             boolean hasNext = doAdvance();
 361             if (hasNext)
 362                 consumer.accept(buffer.get(nextToConsume));
 363             return hasNext;
 364         }
 365 
 366         @Override
 367         public void forEachRemaining(IntConsumer consumer) {
 368             if (buffer == null && !finished) {
 369                 Objects.requireNonNull(consumer);
 370                 init();
 371 
 372                 ph.wrapAndCopyInto((Sink.OfInt) consumer::accept, spliterator);
 373                 finished = true;
 374             }
 375             else {
 376                 do { } while (tryAdvance(consumer));
 377             }
 378         }
 379     }
 380 
 381     static final class LongWrappingSpliterator<P_IN>
 382             extends AbstractWrappingSpliterator<P_IN, Long, SpinedBuffer.OfLong>
 383             implements Spliterator.OfLong {
 384 
 385         LongWrappingSpliterator(PipelineHelper<Long> ph,
 386                                 Supplier<Spliterator<P_IN>> supplier,
 387                                 boolean parallel) {
 388             super(ph, supplier, parallel);
 389         }
 390 
 391         LongWrappingSpliterator(PipelineHelper<Long> ph,
 392                                 Spliterator<P_IN> spliterator,
 393                                 boolean parallel) {
 394             super(ph, spliterator, parallel);
 395         }
 396 
 397         @Override
 398         AbstractWrappingSpliterator<P_IN, Long, ?> wrap(Spliterator<P_IN> s) {
 399             return new LongWrappingSpliterator<>(ph, s, isParallel);
 400         }
 401 
 402         @Override
 403         void initPartialTraversalState() {
 404             SpinedBuffer.OfLong b = new SpinedBuffer.OfLong();
 405             buffer = b;
 406             bufferSink = ph.wrapSink((Sink.OfLong) b::accept);
 407             pusher = () -> spliterator.tryAdvance(bufferSink);
 408         }
 409 
 410         @Override
 411         public Spliterator.OfLong trySplit() {
 412             return (Spliterator.OfLong) super.trySplit();
 413         }
 414 
 415         @Override
 416         public boolean tryAdvance(LongConsumer consumer) {
 417             Objects.requireNonNull(consumer);
 418             boolean hasNext = doAdvance();
 419             if (hasNext)
 420                 consumer.accept(buffer.get(nextToConsume));
 421             return hasNext;
 422         }
 423 
 424         @Override
 425         public void forEachRemaining(LongConsumer consumer) {
 426             if (buffer == null && !finished) {
 427                 Objects.requireNonNull(consumer);
 428                 init();
 429 
 430                 ph.wrapAndCopyInto((Sink.OfLong) consumer::accept, spliterator);
 431                 finished = true;
 432             }
 433             else {
 434                 do { } while (tryAdvance(consumer));
 435             }
 436         }
 437     }
 438 
 439     static final class DoubleWrappingSpliterator<P_IN>
 440             extends AbstractWrappingSpliterator<P_IN, Double, SpinedBuffer.OfDouble>
 441             implements Spliterator.OfDouble {
 442 
 443         DoubleWrappingSpliterator(PipelineHelper<Double> ph,
 444                                   Supplier<Spliterator<P_IN>> supplier,
 445                                   boolean parallel) {
 446             super(ph, supplier, parallel);
 447         }
 448 
 449         DoubleWrappingSpliterator(PipelineHelper<Double> ph,
 450                                   Spliterator<P_IN> spliterator,
 451                                   boolean parallel) {
 452             super(ph, spliterator, parallel);
 453         }
 454 
 455         @Override
 456         AbstractWrappingSpliterator<P_IN, Double, ?> wrap(Spliterator<P_IN> s) {
 457             return new DoubleWrappingSpliterator<>(ph, s, isParallel);
 458         }
 459 
 460         @Override
 461         void initPartialTraversalState() {
 462             SpinedBuffer.OfDouble b = new SpinedBuffer.OfDouble();
 463             buffer = b;
 464             bufferSink = ph.wrapSink((Sink.OfDouble) b::accept);
 465             pusher = () -> spliterator.tryAdvance(bufferSink);
 466         }
 467 
 468         @Override
 469         public Spliterator.OfDouble trySplit() {
 470             return (Spliterator.OfDouble) super.trySplit();
 471         }
 472 
 473         @Override
 474         public boolean tryAdvance(DoubleConsumer consumer) {
 475             Objects.requireNonNull(consumer);
 476             boolean hasNext = doAdvance();
 477             if (hasNext)
 478                 consumer.accept(buffer.get(nextToConsume));
 479             return hasNext;
 480         }
 481 
 482         @Override
 483         public void forEachRemaining(DoubleConsumer consumer) {
 484             if (buffer == null && !finished) {
 485                 Objects.requireNonNull(consumer);
 486                 init();
 487 
 488                 ph.wrapAndCopyInto((Sink.OfDouble) consumer::accept, spliterator);
 489                 finished = true;
 490             }
 491             else {
 492                 do { } while (tryAdvance(consumer));
 493             }
 494         }
 495     }
 496 
 497     /**
 498      * Spliterator implementation that delegates to an underlying spliterator,
 499      * acquiring the spliterator from a {@code Supplier<Spliterator>} on the
 500      * first call to any spliterator method.
 501      * @param <T>
 502      */
 503     static class DelegatingSpliterator<T, T_SPLITR extends Spliterator<T>>
 504             implements Spliterator<T> {
 505         private final Supplier<? extends T_SPLITR> supplier;
 506 
 507         private T_SPLITR s;
 508 
 509         DelegatingSpliterator(Supplier<? extends T_SPLITR> supplier) {
 510             this.supplier = supplier;
 511         }
 512 
 513         T_SPLITR get() {
 514             if (s == null) {
 515                 s = supplier.get();
 516             }
 517             return s;
 518         }
 519 
 520         @Override
 521         @SuppressWarnings("unchecked")
 522         public T_SPLITR trySplit() {
 523             return (T_SPLITR) get().trySplit();
 524         }
 525 
 526         @Override
 527         public boolean tryAdvance(Consumer<? super T> consumer) {
 528             return get().tryAdvance(consumer);
 529         }
 530 
 531         @Override
 532         public void forEachRemaining(Consumer<? super T> consumer) {
 533             get().forEachRemaining(consumer);
 534         }
 535 
 536         @Override
 537         public long estimateSize() {
 538             return get().estimateSize();
 539         }
 540 
 541         @Override
 542         public int characteristics() {
 543             return get().characteristics();
 544         }
 545 
 546         @Override
 547         public Comparator<? super T> getComparator() {
 548             return get().getComparator();
 549         }
 550 
 551         @Override
 552         public long getExactSizeIfKnown() {
 553             return get().getExactSizeIfKnown();
 554         }
 555 
 556         @Override
 557         public String toString() {
 558             return getClass().getName() + "[" + get() + "]";
 559         }
 560 
 561         static class OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
 562             extends DelegatingSpliterator<T, T_SPLITR>
 563             implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> {
 564             OfPrimitive(Supplier<? extends T_SPLITR> supplier) {
 565                 super(supplier);
 566             }
 567 
 568             @Override
 569             public boolean tryAdvance(T_CONS consumer) {
 570                 return get().tryAdvance(consumer);
 571             }
 572 
 573             @Override
 574             public void forEachRemaining(T_CONS consumer) {
 575                 get().forEachRemaining(consumer);
 576             }
 577         }
 578 
 579         static final class OfInt
 580                 extends OfPrimitive<Integer, IntConsumer, Spliterator.OfInt>
 581                 implements Spliterator.OfInt {
 582 
 583             OfInt(Supplier<Spliterator.OfInt> supplier) {
 584                 super(supplier);
 585             }
 586         }
 587 
 588         static final class OfLong
 589                 extends OfPrimitive<Long, LongConsumer, Spliterator.OfLong>
 590                 implements Spliterator.OfLong {
 591 
 592             OfLong(Supplier<Spliterator.OfLong> supplier) {
 593                 super(supplier);
 594             }
 595         }
 596 
 597         static final class OfDouble
 598                 extends OfPrimitive<Double, DoubleConsumer, Spliterator.OfDouble>
 599                 implements Spliterator.OfDouble {
 600 
 601             OfDouble(Supplier<Spliterator.OfDouble> supplier) {
 602                 super(supplier);
 603             }
 604         }
 605     }
 606 
 607     /**
 608      * A slice Spliterator from a source Spliterator that reports
 609      * {@code SUBSIZED}.
 610      *
 611      */
 612     abstract static class SliceSpliterator<T, T_SPLITR extends Spliterator<T>> {
 613         // The start index of the slice
 614         final long sliceOrigin;
 615         // One past the last index of the slice
 616         final long sliceFence;
 617 
 618         // The spliterator to slice
 619         T_SPLITR s;
 620         // current (absolute) index, modified on advance/split
 621         long index;
 622         // one past last (absolute) index or sliceFence, which ever is smaller
 623         long fence;
 624 
 625         SliceSpliterator(T_SPLITR s, long sliceOrigin, long sliceFence, long origin, long fence) {
 626             assert s.hasCharacteristics(Spliterator.SUBSIZED);
 627             this.s = s;
 628             this.sliceOrigin = sliceOrigin;
 629             this.sliceFence = sliceFence;
 630             this.index = origin;
 631             this.fence = fence;
 632         }
 633 
 634         protected abstract T_SPLITR makeSpliterator(T_SPLITR s, long sliceOrigin, long sliceFence, long origin, long fence);
 635 
 636         public T_SPLITR trySplit() {
 637             if (sliceOrigin >= fence)
 638                 return null;
 639 
 640             if (index >= fence)
 641                 return null;
 642 
 643             // Keep splitting until the left and right splits intersect with the slice
 644             // thereby ensuring the size estimate decreases.
 645             // This also avoids creating empty spliterators which can result in
 646             // existing and additionally created F/J tasks that perform
 647             // redundant work on no elements.
 648             while (true) {
 649                 @SuppressWarnings("unchecked")
 650                 T_SPLITR leftSplit = (T_SPLITR) s.trySplit();
 651                 if (leftSplit == null)
 652                     return null;
 653 
 654                 long leftSplitFenceUnbounded = index + leftSplit.estimateSize();
 655                 long leftSplitFence = Math.min(leftSplitFenceUnbounded, sliceFence);
 656                 if (sliceOrigin >= leftSplitFence) {
 657                     // The left split does not intersect with, and is to the left of, the slice
 658                     // The right split does intersect
 659                     // Discard the left split and split further with the right split
 660                     index = leftSplitFence;
 661                 }
 662                 else if (leftSplitFence >= sliceFence) {
 663                     // The right split does not intersect with, and is to the right of, the slice
 664                     // The left split does intersect
 665                     // Discard the right split and split further with the left split
 666                     s = leftSplit;
 667                     fence = leftSplitFence;
 668                 }
 669                 else if (index >= sliceOrigin && leftSplitFenceUnbounded <= sliceFence) {
 670                     // The left split is contained within the slice, return the underlying left split
 671                     // Right split is contained within or intersects with the slice
 672                     index = leftSplitFence;
 673                     return leftSplit;
 674                 } else {
 675                     // The left split intersects with the slice
 676                     // Right split is contained within or intersects with the slice
 677                     return makeSpliterator(leftSplit, sliceOrigin, sliceFence, index, index = leftSplitFence);
 678                 }
 679             }
 680         }
 681 
 682         public long estimateSize() {
 683             return (sliceOrigin < fence)
 684                    ? fence - Math.max(sliceOrigin, index) : 0;
 685         }
 686 
 687         public int characteristics() {
 688             return s.characteristics();
 689         }
 690 
 691         static final class OfRef<T>
 692                 extends SliceSpliterator<T, Spliterator<T>>
 693                 implements Spliterator<T> {
 694 
 695             OfRef(Spliterator<T> s, long sliceOrigin, long sliceFence) {
 696                 this(s, sliceOrigin, sliceFence, 0, Math.min(s.estimateSize(), sliceFence));
 697             }
 698 
 699             private OfRef(Spliterator<T> s,
 700                           long sliceOrigin, long sliceFence, long origin, long fence) {
 701                 super(s, sliceOrigin, sliceFence, origin, fence);
 702             }
 703 
 704             @Override
 705             protected Spliterator<T> makeSpliterator(Spliterator<T> s,
 706                                                      long sliceOrigin, long sliceFence,
 707                                                      long origin, long fence) {
 708                 return new OfRef<>(s, sliceOrigin, sliceFence, origin, fence);
 709             }
 710 
 711             @Override
 712             public boolean tryAdvance(Consumer<? super T> action) {
 713                 Objects.requireNonNull(action);
 714 
 715                 if (sliceOrigin >= fence)
 716                     return false;
 717 
 718                 while (sliceOrigin > index) {
 719                     s.tryAdvance(e -> {});
 720                     index++;
 721                 }
 722 
 723                 if (index >= fence)
 724                     return false;
 725 
 726                 index++;
 727                 return s.tryAdvance(action);
 728             }
 729 
 730             @Override
 731             public void forEachRemaining(Consumer<? super T> action) {
 732                 Objects.requireNonNull(action);
 733 
 734                 if (sliceOrigin >= fence)
 735                     return;
 736 
 737                 if (index >= fence)
 738                     return;
 739 
 740                 if (index >= sliceOrigin && (index + s.estimateSize()) <= sliceFence) {
 741                     // The spliterator is contained within the slice
 742                     s.forEachRemaining(action);
 743                     index = fence;
 744                 } else {
 745                     // The spliterator intersects with the slice
 746                     while (sliceOrigin > index) {
 747                         s.tryAdvance(e -> {});
 748                         index++;
 749                     }
 750                     // Traverse elements up to the fence
 751                     for (;index < fence; index++) {
 752                         s.tryAdvance(action);
 753                     }
 754                 }
 755             }
 756         }
 757 
 758         abstract static class OfPrimitive<T,
 759                 T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>,
 760                 T_CONS>
 761                 extends SliceSpliterator<T, T_SPLITR>
 762                 implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> {
 763 
 764             OfPrimitive(T_SPLITR s, long sliceOrigin, long sliceFence) {
 765                 this(s, sliceOrigin, sliceFence, 0, Math.min(s.estimateSize(), sliceFence));
 766             }
 767 
 768             private OfPrimitive(T_SPLITR s,
 769                                 long sliceOrigin, long sliceFence, long origin, long fence) {
 770                 super(s, sliceOrigin, sliceFence, origin, fence);
 771             }
 772 
 773             @Override
 774             public boolean tryAdvance(T_CONS action) {
 775                 Objects.requireNonNull(action);
 776 
 777                 if (sliceOrigin >= fence)
 778                     return false;
 779 
 780                 while (sliceOrigin > index) {
 781                     s.tryAdvance(emptyConsumer());
 782                     index++;
 783                 }
 784 
 785                 if (index >= fence)
 786                     return false;
 787 
 788                 index++;
 789                 return s.tryAdvance(action);
 790             }
 791 
 792             @Override
 793             public void forEachRemaining(T_CONS action) {
 794                 Objects.requireNonNull(action);
 795 
 796                 if (sliceOrigin >= fence)
 797                     return;
 798 
 799                 if (index >= fence)
 800                     return;
 801 
 802                 if (index >= sliceOrigin && (index + s.estimateSize()) <= sliceFence) {
 803                     // The spliterator is contained within the slice
 804                     s.forEachRemaining(action);
 805                     index = fence;
 806                 } else {
 807                     // The spliterator intersects with the slice
 808                     while (sliceOrigin > index) {
 809                         s.tryAdvance(emptyConsumer());
 810                         index++;
 811                     }
 812                     // Traverse elements up to the fence
 813                     for (;index < fence; index++) {
 814                         s.tryAdvance(action);
 815                     }
 816                 }
 817             }
 818 
 819             protected abstract T_CONS emptyConsumer();
 820         }
 821 
 822         static final class OfInt extends OfPrimitive<Integer, Spliterator.OfInt, IntConsumer>
 823                 implements Spliterator.OfInt {
 824             OfInt(Spliterator.OfInt s, long sliceOrigin, long sliceFence) {
 825                 super(s, sliceOrigin, sliceFence);
 826             }
 827 
 828             OfInt(Spliterator.OfInt s,
 829                   long sliceOrigin, long sliceFence, long origin, long fence) {
 830                 super(s, sliceOrigin, sliceFence, origin, fence);
 831             }
 832 
 833             @Override
 834             protected Spliterator.OfInt makeSpliterator(Spliterator.OfInt s,
 835                                                         long sliceOrigin, long sliceFence,
 836                                                         long origin, long fence) {
 837                 return new SliceSpliterator.OfInt(s, sliceOrigin, sliceFence, origin, fence);
 838             }
 839 
 840             @Override
 841             protected IntConsumer emptyConsumer() {
 842                 return e -> {};
 843             }
 844         }
 845 
 846         static final class OfLong extends OfPrimitive<Long, Spliterator.OfLong, LongConsumer>
 847                 implements Spliterator.OfLong {
 848             OfLong(Spliterator.OfLong s, long sliceOrigin, long sliceFence) {
 849                 super(s, sliceOrigin, sliceFence);
 850             }
 851 
 852             OfLong(Spliterator.OfLong s,
 853                    long sliceOrigin, long sliceFence, long origin, long fence) {
 854                 super(s, sliceOrigin, sliceFence, origin, fence);
 855             }
 856 
 857             @Override
 858             protected Spliterator.OfLong makeSpliterator(Spliterator.OfLong s,
 859                                                          long sliceOrigin, long sliceFence,
 860                                                          long origin, long fence) {
 861                 return new SliceSpliterator.OfLong(s, sliceOrigin, sliceFence, origin, fence);
 862             }
 863 
 864             @Override
 865             protected LongConsumer emptyConsumer() {
 866                 return e -> {};
 867             }
 868         }
 869 
 870         static final class OfDouble extends OfPrimitive<Double, Spliterator.OfDouble, DoubleConsumer>
 871                 implements Spliterator.OfDouble {
 872             OfDouble(Spliterator.OfDouble s, long sliceOrigin, long sliceFence) {
 873                 super(s, sliceOrigin, sliceFence);
 874             }
 875 
 876             OfDouble(Spliterator.OfDouble s,
 877                      long sliceOrigin, long sliceFence, long origin, long fence) {
 878                 super(s, sliceOrigin, sliceFence, origin, fence);
 879             }
 880 
 881             @Override
 882             protected Spliterator.OfDouble makeSpliterator(Spliterator.OfDouble s,
 883                                                            long sliceOrigin, long sliceFence,
 884                                                            long origin, long fence) {
 885                 return new SliceSpliterator.OfDouble(s, sliceOrigin, sliceFence, origin, fence);
 886             }
 887 
 888             @Override
 889             protected DoubleConsumer emptyConsumer() {
 890                 return e -> {};
 891             }
 892         }
 893     }
 894 
 895     /**
 896      * A slice Spliterator that does not preserve order, if any, of a source
 897      * Spliterator.
 898      *
 899      * Note: The source spliterator may report {@code ORDERED} since that
 900      * spliterator be the result of a previous pipeline stage that was
 901      * collected to a {@code Node}. It is the order of the pipeline stage
 902      * that governs whether the this slice spliterator is to be used or not.
 903      */
 904     abstract static class UnorderedSliceSpliterator<T, T_SPLITR extends Spliterator<T>> {
 905         static final int CHUNK_SIZE = 1 << 7;
 906 
 907         // The spliterator to slice
 908         protected final T_SPLITR s;
 909         protected final boolean unlimited;
 910         private final long skipThreshold;
 911         private final AtomicLong permits;
 912 
 913         UnorderedSliceSpliterator(T_SPLITR s, long skip, long limit) {
 914             this.s = s;
 915             this.unlimited = limit < 0;
 916             this.skipThreshold = limit >= 0 ? limit : 0;
 917             this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip);
 918         }
 919 
 920         UnorderedSliceSpliterator(T_SPLITR s,
 921                                   UnorderedSliceSpliterator<T, T_SPLITR> parent) {
 922             this.s = s;
 923             this.unlimited = parent.unlimited;
 924             this.permits = parent.permits;
 925             this.skipThreshold = parent.skipThreshold;
 926         }
 927 
 928         /**
 929          * Acquire permission to skip or process elements.  The caller must
 930          * first acquire the elements, then consult this method for guidance
 931          * as to what to do with the data.
 932          *
 933          * <p>We use an {@code AtomicLong} to atomically maintain a counter,
 934          * which is initialized as skip+limit if we are limiting, or skip only
 935          * if we are not limiting.  The user should consult the method
 936          * {@code checkPermits()} before acquiring data elements.
 937          *
 938          * @param numElements the number of elements the caller has in hand
 939          * @return the number of elements that should be processed; any
 940          * remaining elements should be discarded.
 941          */
 942         protected final long acquirePermits(long numElements) {
 943             long remainingPermits;
 944             long grabbing;
 945             // permits never increase, and don't decrease below zero
 946             assert numElements > 0;
 947             do {
 948                 remainingPermits = permits.get();
 949                 if (remainingPermits == 0)
 950                     return unlimited ? numElements : 0;
 951                 grabbing = Math.min(remainingPermits, numElements);
 952             } while (grabbing > 0 &&
 953                      !permits.compareAndSet(remainingPermits, remainingPermits - grabbing));
 954 
 955             if (unlimited)
 956                 return Math.max(numElements - grabbing, 0);
 957             else if (remainingPermits > skipThreshold)
 958                 return Math.max(grabbing - (remainingPermits - skipThreshold), 0);
 959             else
 960                 return grabbing;
 961         }
 962 
 963         enum PermitStatus { NO_MORE, MAYBE_MORE, UNLIMITED }
 964 
 965         /** Call to check if permits might be available before acquiring data */
 966         protected final PermitStatus permitStatus() {
 967             if (permits.get() > 0)
 968                 return PermitStatus.MAYBE_MORE;
 969             else
 970                 return unlimited ?  PermitStatus.UNLIMITED : PermitStatus.NO_MORE;
 971         }
 972 
 973         public final T_SPLITR trySplit() {
 974             // Stop splitting when there are no more limit permits
 975             if (permits.get() == 0)
 976                 return null;
 977             @SuppressWarnings("unchecked")
 978             T_SPLITR split = (T_SPLITR) s.trySplit();
 979             return split == null ? null : makeSpliterator(split);
 980         }
 981 
 982         protected abstract T_SPLITR makeSpliterator(T_SPLITR s);
 983 
 984         public final long estimateSize() {
 985             return s.estimateSize();
 986         }
 987 
 988         public final int characteristics() {
 989             return s.characteristics() &
 990                    ~(Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED);
 991         }
 992 
 993         static final class OfRef<T> extends UnorderedSliceSpliterator<T, Spliterator<T>>
 994                 implements Spliterator<T>, Consumer<T> {
 995             T tmpSlot;
 996 
 997             OfRef(Spliterator<T> s, long skip, long limit) {
 998                 super(s, skip, limit);
 999             }
1000 
1001             OfRef(Spliterator<T> s, OfRef<T> parent) {
1002                 super(s, parent);
1003             }
1004 
1005             @Override
1006             public final void accept(T t) {
1007                 tmpSlot = t;
1008             }
1009 
1010             @Override
1011             public boolean tryAdvance(Consumer<? super T> action) {
1012                 Objects.requireNonNull(action);
1013 
1014                 while (permitStatus() != PermitStatus.NO_MORE) {
1015                     if (!s.tryAdvance(this))
1016                         return false;
1017                     else if (acquirePermits(1) == 1) {
1018                         action.accept(tmpSlot);
1019                         tmpSlot = null;
1020                         return true;
1021                     }
1022                 }
1023                 return false;
1024             }
1025 
1026             @Override
1027             public void forEachRemaining(Consumer<? super T> action) {
1028                 Objects.requireNonNull(action);
1029 
1030                 ArrayBuffer.OfRef<T> sb = null;
1031                 PermitStatus permitStatus;
1032                 while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) {
1033                     if (permitStatus == PermitStatus.MAYBE_MORE) {
1034                         // Optimistically traverse elements up to a threshold of CHUNK_SIZE
1035                         if (sb == null)
1036                             sb = new ArrayBuffer.OfRef<>(CHUNK_SIZE);
1037                         else
1038                             sb.reset();
1039                         long permitsRequested = 0;
1040                         do { } while (s.tryAdvance(sb) && ++permitsRequested < CHUNK_SIZE);
1041                         if (permitsRequested == 0)
1042                             return;
1043                         sb.forEach(action, acquirePermits(permitsRequested));
1044                     }
1045                     else {
1046                         // Must be UNLIMITED; let 'er rip
1047                         s.forEachRemaining(action);
1048                         return;
1049                     }
1050                 }
1051             }
1052 
1053             @Override
1054             protected Spliterator<T> makeSpliterator(Spliterator<T> s) {
1055                 return new UnorderedSliceSpliterator.OfRef<>(s, this);
1056             }
1057         }
1058 
1059         /**
1060          * Concrete sub-types must also be an instance of type {@code T_CONS}.
1061          *
1062          * @param <T_BUFF> the type of the spined buffer. Must also be a type of
1063          *        {@code T_CONS}.
1064          */
1065         abstract static class OfPrimitive<
1066                 T,
1067                 T_CONS,
1068                 T_BUFF extends ArrayBuffer.OfPrimitive<T_CONS>,
1069                 T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
1070                 extends UnorderedSliceSpliterator<T, T_SPLITR>
1071                 implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> {
1072             OfPrimitive(T_SPLITR s, long skip, long limit) {
1073                 super(s, skip, limit);
1074             }
1075 
1076             OfPrimitive(T_SPLITR s, UnorderedSliceSpliterator.OfPrimitive<T, T_CONS, T_BUFF, T_SPLITR> parent) {
1077                 super(s, parent);
1078             }
1079 
1080             @Override
1081             public boolean tryAdvance(T_CONS action) {
1082                 Objects.requireNonNull(action);
1083                 @SuppressWarnings("unchecked")
1084                 T_CONS consumer = (T_CONS) this;
1085 
1086                 while (permitStatus() != PermitStatus.NO_MORE) {
1087                     if (!s.tryAdvance(consumer))
1088                         return false;
1089                     else if (acquirePermits(1) == 1) {
1090                         acceptConsumed(action);
1091                         return true;
1092                     }
1093                 }
1094                 return false;
1095             }
1096 
1097             protected abstract void acceptConsumed(T_CONS action);
1098 
1099             @Override
1100             public void forEachRemaining(T_CONS action) {
1101                 Objects.requireNonNull(action);
1102 
1103                 T_BUFF sb = null;
1104                 PermitStatus permitStatus;
1105                 while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) {
1106                     if (permitStatus == PermitStatus.MAYBE_MORE) {
1107                         // Optimistically traverse elements up to a threshold of CHUNK_SIZE
1108                         if (sb == null)
1109                             sb = bufferCreate(CHUNK_SIZE);
1110                         else
1111                             sb.reset();
1112                         @SuppressWarnings("unchecked")
1113                         T_CONS sbc = (T_CONS) sb;
1114                         long permitsRequested = 0;
1115                         do { } while (s.tryAdvance(sbc) && ++permitsRequested < CHUNK_SIZE);
1116                         if (permitsRequested == 0)
1117                             return;
1118                         sb.forEach(action, acquirePermits(permitsRequested));
1119                     }
1120                     else {
1121                         // Must be UNLIMITED; let 'er rip
1122                         s.forEachRemaining(action);
1123                         return;
1124                     }
1125                 }
1126             }
1127 
1128             protected abstract T_BUFF bufferCreate(int initialCapacity);
1129         }
1130 
1131         static final class OfInt
1132                 extends OfPrimitive<Integer, IntConsumer, ArrayBuffer.OfInt, Spliterator.OfInt>
1133                 implements Spliterator.OfInt, IntConsumer {
1134 
1135             int tmpValue;
1136 
1137             OfInt(Spliterator.OfInt s, long skip, long limit) {
1138                 super(s, skip, limit);
1139             }
1140 
1141             OfInt(Spliterator.OfInt s, UnorderedSliceSpliterator.OfInt parent) {
1142                 super(s, parent);
1143             }
1144 
1145             @Override
1146             public void accept(int value) {
1147                 tmpValue = value;
1148             }
1149 
1150             @Override
1151             protected void acceptConsumed(IntConsumer action) {
1152                 action.accept(tmpValue);
1153             }
1154 
1155             @Override
1156             protected ArrayBuffer.OfInt bufferCreate(int initialCapacity) {
1157                 return new ArrayBuffer.OfInt(initialCapacity);
1158             }
1159 
1160             @Override
1161             protected Spliterator.OfInt makeSpliterator(Spliterator.OfInt s) {
1162                 return new UnorderedSliceSpliterator.OfInt(s, this);
1163             }
1164         }
1165 
1166         static final class OfLong
1167                 extends OfPrimitive<Long, LongConsumer, ArrayBuffer.OfLong, Spliterator.OfLong>
1168                 implements Spliterator.OfLong, LongConsumer {
1169 
1170             long tmpValue;
1171 
1172             OfLong(Spliterator.OfLong s, long skip, long limit) {
1173                 super(s, skip, limit);
1174             }
1175 
1176             OfLong(Spliterator.OfLong s, UnorderedSliceSpliterator.OfLong parent) {
1177                 super(s, parent);
1178             }
1179 
1180             @Override
1181             public void accept(long value) {
1182                 tmpValue = value;
1183             }
1184 
1185             @Override
1186             protected void acceptConsumed(LongConsumer action) {
1187                 action.accept(tmpValue);
1188             }
1189 
1190             @Override
1191             protected ArrayBuffer.OfLong bufferCreate(int initialCapacity) {
1192                 return new ArrayBuffer.OfLong(initialCapacity);
1193             }
1194 
1195             @Override
1196             protected Spliterator.OfLong makeSpliterator(Spliterator.OfLong s) {
1197                 return new UnorderedSliceSpliterator.OfLong(s, this);
1198             }
1199         }
1200 
1201         static final class OfDouble
1202                 extends OfPrimitive<Double, DoubleConsumer, ArrayBuffer.OfDouble, Spliterator.OfDouble>
1203                 implements Spliterator.OfDouble, DoubleConsumer {
1204 
1205             double tmpValue;
1206 
1207             OfDouble(Spliterator.OfDouble s, long skip, long limit) {
1208                 super(s, skip, limit);
1209             }
1210 
1211             OfDouble(Spliterator.OfDouble s, UnorderedSliceSpliterator.OfDouble parent) {
1212                 super(s, parent);
1213             }
1214 
1215             @Override
1216             public void accept(double value) {
1217                 tmpValue = value;
1218             }
1219 
1220             @Override
1221             protected void acceptConsumed(DoubleConsumer action) {
1222                 action.accept(tmpValue);
1223             }
1224 
1225             @Override
1226             protected ArrayBuffer.OfDouble bufferCreate(int initialCapacity) {
1227                 return new ArrayBuffer.OfDouble(initialCapacity);
1228             }
1229 
1230             @Override
1231             protected Spliterator.OfDouble makeSpliterator(Spliterator.OfDouble s) {
1232                 return new UnorderedSliceSpliterator.OfDouble(s, this);
1233             }
1234         }
1235     }
1236 
1237     /**
1238      * A wrapping spliterator that only reports distinct elements of the
1239      * underlying spliterator. Does not preserve size and encounter order.
1240      */
1241     static final class DistinctSpliterator<T> implements Spliterator<T>, Consumer<T> {
1242 
1243         // The value to represent null in the ConcurrentHashMap
1244         private static final Object NULL_VALUE = new Object();
1245 
1246         // The underlying spliterator
1247         private final Spliterator<T> s;
1248 
1249         // ConcurrentHashMap holding distinct elements as keys
1250         private final ConcurrentHashMap<T, Boolean> seen;
1251 
1252         // Temporary element, only used with tryAdvance
1253         private T tmpSlot;
1254 
1255         DistinctSpliterator(Spliterator<T> s) {
1256             this(s, new ConcurrentHashMap<>());
1257         }
1258 
1259         private DistinctSpliterator(Spliterator<T> s, ConcurrentHashMap<T, Boolean> seen) {
1260             this.s = s;
1261             this.seen = seen;
1262         }
1263 
1264         @Override
1265         public void accept(T t) {
1266             this.tmpSlot = t;
1267         }
1268 
1269         @SuppressWarnings("unchecked")
1270         private T mapNull(T t) {
1271             return t != null ? t : (T) NULL_VALUE;
1272         }
1273 
1274         @Override
1275         public boolean tryAdvance(Consumer<? super T> action) {
1276             while (s.tryAdvance(this)) {
1277                 if (seen.putIfAbsent(mapNull(tmpSlot), Boolean.TRUE) == null) {
1278                     action.accept(tmpSlot);
1279                     tmpSlot = null;
1280                     return true;
1281                 }
1282             }
1283             return false;
1284         }
1285 
1286         @Override
1287         public void forEachRemaining(Consumer<? super T> action) {
1288             s.forEachRemaining(t -> {
1289                 if (seen.putIfAbsent(mapNull(t), Boolean.TRUE) == null) {
1290                     action.accept(t);
1291                 }
1292             });
1293         }
1294 
1295         @Override
1296         public Spliterator<T> trySplit() {
1297             Spliterator<T> split = s.trySplit();
1298             return (split != null) ? new DistinctSpliterator<>(split, seen) : null;
1299         }
1300 
1301         @Override
1302         public long estimateSize() {
1303             return s.estimateSize();
1304         }
1305 
1306         @Override
1307         public int characteristics() {
1308             return (s.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED |
1309                                             Spliterator.SORTED | Spliterator.ORDERED))
1310                    | Spliterator.DISTINCT;
1311         }
1312 
1313         @Override
1314         public Comparator<? super T> getComparator() {
1315             return s.getComparator();
1316         }
1317     }
1318 
1319     /**
1320      * A Spliterator that infinitely supplies elements in no particular order.
1321      *
1322      * <p>Splitting divides the estimated size in two and stops when the
1323      * estimate size is 0.
1324      *
1325      * <p>The {@code forEachRemaining} method if invoked will never terminate.
1326      * The {@code tryAdvance} method always returns true.
1327      *
1328      */
1329     abstract static class InfiniteSupplyingSpliterator<T> implements Spliterator<T> {
1330         long estimate;
1331 
1332         protected InfiniteSupplyingSpliterator(long estimate) {
1333             this.estimate = estimate;
1334         }
1335 
1336         @Override
1337         public long estimateSize() {
1338             return estimate;
1339         }
1340 
1341         @Override
1342         public int characteristics() {
1343             return IMMUTABLE;
1344         }
1345 
1346         static final class OfRef<T> extends InfiniteSupplyingSpliterator<T> {
1347             final Supplier<T> s;
1348 
1349             OfRef(long size, Supplier<T> s) {
1350                 super(size);
1351                 this.s = s;
1352             }
1353 
1354             @Override
1355             public boolean tryAdvance(Consumer<? super T> action) {
1356                 Objects.requireNonNull(action);
1357 
1358                 action.accept(s.get());
1359                 return true;
1360             }
1361 
1362             @Override
1363             public Spliterator<T> trySplit() {
1364                 if (estimate == 0)
1365                     return null;
1366                 return new InfiniteSupplyingSpliterator.OfRef<>(estimate >>>= 1, s);
1367             }
1368         }
1369 
1370         static final class OfInt extends InfiniteSupplyingSpliterator<Integer>
1371                 implements Spliterator.OfInt {
1372             final IntSupplier s;
1373 
1374             OfInt(long size, IntSupplier s) {
1375                 super(size);
1376                 this.s = s;
1377             }
1378 
1379             @Override
1380             public boolean tryAdvance(IntConsumer action) {
1381                 Objects.requireNonNull(action);
1382 
1383                 action.accept(s.getAsInt());
1384                 return true;
1385             }
1386 
1387             @Override
1388             public Spliterator.OfInt trySplit() {
1389                 if (estimate == 0)
1390                     return null;
1391                 return new InfiniteSupplyingSpliterator.OfInt(estimate = estimate >>> 1, s);
1392             }
1393         }
1394 
1395         static final class OfLong extends InfiniteSupplyingSpliterator<Long>
1396                 implements Spliterator.OfLong {
1397             final LongSupplier s;
1398 
1399             OfLong(long size, LongSupplier s) {
1400                 super(size);
1401                 this.s = s;
1402             }
1403 
1404             @Override
1405             public boolean tryAdvance(LongConsumer action) {
1406                 Objects.requireNonNull(action);
1407 
1408                 action.accept(s.getAsLong());
1409                 return true;
1410             }
1411 
1412             @Override
1413             public Spliterator.OfLong trySplit() {
1414                 if (estimate == 0)
1415                     return null;
1416                 return new InfiniteSupplyingSpliterator.OfLong(estimate = estimate >>> 1, s);
1417             }
1418         }
1419 
1420         static final class OfDouble extends InfiniteSupplyingSpliterator<Double>
1421                 implements Spliterator.OfDouble {
1422             final DoubleSupplier s;
1423 
1424             OfDouble(long size, DoubleSupplier s) {
1425                 super(size);
1426                 this.s = s;
1427             }
1428 
1429             @Override
1430             public boolean tryAdvance(DoubleConsumer action) {
1431                 Objects.requireNonNull(action);
1432 
1433                 action.accept(s.getAsDouble());
1434                 return true;
1435             }
1436 
1437             @Override
1438             public Spliterator.OfDouble trySplit() {
1439                 if (estimate == 0)
1440                     return null;
1441                 return new InfiniteSupplyingSpliterator.OfDouble(estimate = estimate >>> 1, s);
1442             }
1443         }
1444     }
1445 
1446     // @@@ Consolidate with Node.Builder
1447     abstract static class ArrayBuffer {
1448         int index;
1449 
1450         void reset() {
1451             index = 0;
1452         }
1453 
1454         static final class OfRef<T> extends ArrayBuffer implements Consumer<T> {
1455             final Object[] array;
1456 
1457             OfRef(int size) {
1458                 this.array = new Object[size];
1459             }
1460 
1461             @Override
1462             public void accept(T t) {
1463                 array[index++] = t;
1464             }
1465 
1466             public void forEach(Consumer<? super T> action, long fence) {
1467                 for (int i = 0; i < fence; i++) {
1468                     @SuppressWarnings("unchecked")
1469                     T t = (T) array[i];
1470                     action.accept(t);
1471                 }
1472             }
1473         }
1474 
1475         abstract static class OfPrimitive<T_CONS> extends ArrayBuffer {
1476             int index;
1477 
1478             @Override
1479             void reset() {
1480                 index = 0;
1481             }
1482 
1483             abstract void forEach(T_CONS action, long fence);
1484         }
1485 
1486         static final class OfInt extends OfPrimitive<IntConsumer>
1487                 implements IntConsumer {
1488             final int[] array;
1489 
1490             OfInt(int size) {
1491                 this.array = new int[size];
1492             }
1493 
1494             @Override
1495             public void accept(int t) {
1496                 array[index++] = t;
1497             }
1498 
1499             @Override
1500             public void forEach(IntConsumer action, long fence) {
1501                 for (int i = 0; i < fence; i++) {
1502                     action.accept(array[i]);
1503                 }
1504             }
1505         }
1506 
1507         static final class OfLong extends OfPrimitive<LongConsumer>
1508                 implements LongConsumer {
1509             final long[] array;
1510 
1511             OfLong(int size) {
1512                 this.array = new long[size];
1513             }
1514 
1515             @Override
1516             public void accept(long t) {
1517                 array[index++] = t;
1518             }
1519 
1520             @Override
1521             public void forEach(LongConsumer action, long fence) {
1522                 for (int i = 0; i < fence; i++) {
1523                     action.accept(array[i]);
1524                 }
1525             }
1526         }
1527 
1528         static final class OfDouble extends OfPrimitive<DoubleConsumer>
1529                 implements DoubleConsumer {
1530             final double[] array;
1531 
1532             OfDouble(int size) {
1533                 this.array = new double[size];
1534             }
1535 
1536             @Override
1537             public void accept(double t) {
1538                 array[index++] = t;
1539             }
1540 
1541             @Override
1542             void forEach(DoubleConsumer action, long fence) {
1543                 for (int i = 0; i < fence; i++) {
1544                     action.accept(array[i]);
1545                 }
1546             }
1547         }
1548     }
1549 }
1550