jdk/src/share/classes/java/util/stream/StreamSpliterators.java
changeset 18572 53b8b8c30086
parent 17182 b786c0de868c
child 19188 bbf287c5cd92
equal deleted inserted replaced
18571:8e3cb3c46ae8 18572:53b8b8c30086
    24  */
    24  */
    25 package java.util.stream;
    25 package java.util.stream;
    26 
    26 
    27 import java.util.Comparator;
    27 import java.util.Comparator;
    28 import java.util.Spliterator;
    28 import java.util.Spliterator;
       
    29 import java.util.concurrent.atomic.AtomicLong;
    29 import java.util.function.BooleanSupplier;
    30 import java.util.function.BooleanSupplier;
    30 import java.util.function.Consumer;
    31 import java.util.function.Consumer;
    31 import java.util.function.DoubleConsumer;
    32 import java.util.function.DoubleConsumer;
       
    33 import java.util.function.DoubleSupplier;
    32 import java.util.function.IntConsumer;
    34 import java.util.function.IntConsumer;
       
    35 import java.util.function.IntSupplier;
    33 import java.util.function.LongConsumer;
    36 import java.util.function.LongConsumer;
       
    37 import java.util.function.LongSupplier;
    34 import java.util.function.Supplier;
    38 import java.util.function.Supplier;
    35 
    39 
    36 /**
    40 /**
    37  * Spliterator implementations for wrapping and delegating spliterators, used
    41  * Spliterator implementations for wrapping and delegating spliterators, used
    38  * in the implementation of the {@link Stream#spliterator()} method.
    42  * in the implementation of the {@link Stream#spliterator()} method.
   210         }
   214         }
   211 
   215 
   212         @Override
   216         @Override
   213         public final long estimateSize() {
   217         public final long estimateSize() {
   214             init();
   218             init();
   215             return StreamOpFlag.SIZED.isKnown(ph.getStreamAndOpFlags())
   219             // Use the estimate of the wrapped spliterator
   216                    ? spliterator.estimateSize()
   220             // Note this may not be accurate if there are filter/flatMap
   217                    : Long.MAX_VALUE;
   221             // operations filtering or adding elements to the stream
       
   222             return spliterator.estimateSize();
   218         }
   223         }
   219 
   224 
   220         @Override
   225         @Override
   221         public final long getExactSizeIfKnown() {
   226         public final long getExactSizeIfKnown() {
   222             init();
   227             init();
   238             // with an exact size to an estimate for a sub-split, for example
   243             // with an exact size to an estimate for a sub-split, for example
   239             // with HashSet where the size is known at the top level spliterator
   244             // with HashSet where the size is known at the top level spliterator
   240             // but for sub-splits only an estimate is known
   245             // but for sub-splits only an estimate is known
   241             if ((c & Spliterator.SIZED) != 0) {
   246             if ((c & Spliterator.SIZED) != 0) {
   242                 c &= ~(Spliterator.SIZED | Spliterator.SUBSIZED);
   247                 c &= ~(Spliterator.SIZED | Spliterator.SUBSIZED);
   243                 c |= (spliterator.characteristics() & Spliterator.SIZED & Spliterator.SUBSIZED);
   248                 c |= (spliterator.characteristics() & (Spliterator.SIZED | Spliterator.SUBSIZED));
   244             }
   249             }
   245 
   250 
   246             return c;
   251             return c;
   247         }
   252         }
   248 
   253 
   302 
   307 
   303                 ph.wrapAndCopyInto((Sink<P_OUT>) consumer::accept, spliterator);
   308                 ph.wrapAndCopyInto((Sink<P_OUT>) consumer::accept, spliterator);
   304                 finished = true;
   309                 finished = true;
   305             }
   310             }
   306             else {
   311             else {
   307                 while (tryAdvance(consumer)) { }
   312                 do { } while (tryAdvance(consumer));
   308             }
   313             }
   309         }
   314         }
   310     }
   315     }
   311 
   316 
   312     static final class IntWrappingSpliterator<P_IN>
   317     static final class IntWrappingSpliterator<P_IN>
   358 
   363 
   359                 ph.wrapAndCopyInto((Sink.OfInt) consumer::accept, spliterator);
   364                 ph.wrapAndCopyInto((Sink.OfInt) consumer::accept, spliterator);
   360                 finished = true;
   365                 finished = true;
   361             }
   366             }
   362             else {
   367             else {
   363                 while (tryAdvance(consumer)) { }
   368                 do { } while (tryAdvance(consumer));
   364             }
   369             }
   365         }
   370         }
   366     }
   371     }
   367 
   372 
   368     static final class LongWrappingSpliterator<P_IN>
   373     static final class LongWrappingSpliterator<P_IN>
   414 
   419 
   415                 ph.wrapAndCopyInto((Sink.OfLong) consumer::accept, spliterator);
   420                 ph.wrapAndCopyInto((Sink.OfLong) consumer::accept, spliterator);
   416                 finished = true;
   421                 finished = true;
   417             }
   422             }
   418             else {
   423             else {
   419                 while (tryAdvance(consumer)) { }
   424                 do { } while (tryAdvance(consumer));
   420             }
   425             }
   421         }
   426         }
   422     }
   427     }
   423 
   428 
   424     static final class DoubleWrappingSpliterator<P_IN>
   429     static final class DoubleWrappingSpliterator<P_IN>
   470 
   475 
   471                 ph.wrapAndCopyInto((Sink.OfDouble) consumer::accept, spliterator);
   476                 ph.wrapAndCopyInto((Sink.OfDouble) consumer::accept, spliterator);
   472                 finished = true;
   477                 finished = true;
   473             }
   478             }
   474             else {
   479             else {
   475                 while (tryAdvance(consumer)) { }
   480                 do { } while (tryAdvance(consumer));
   476             }
   481             }
   477         }
   482         }
   478     }
   483     }
   479 
   484 
   480     /**
   485     /**
   481      * Spliterator implementation that delegates to an underlying spliterator,
   486      * Spliterator implementation that delegates to an underlying spliterator,
   482      * acquiring the spliterator from a {@code Supplier<Spliterator>} on the
   487      * acquiring the spliterator from a {@code Supplier<Spliterator>} on the
   483      * first call to any spliterator method.
   488      * first call to any spliterator method.
   484      * @param <T>
   489      * @param <T>
   485      */
   490      */
   486     static class DelegatingSpliterator<T> implements Spliterator<T> {
   491     static class DelegatingSpliterator<T, T_SPLITR extends Spliterator<T>>
   487         private final Supplier<Spliterator<T>> supplier;
   492             implements Spliterator<T> {
   488 
   493         private final Supplier<? extends T_SPLITR> supplier;
   489         private Spliterator<T> s;
   494 
   490 
   495         private T_SPLITR s;
   491         @SuppressWarnings("unchecked")
   496 
   492         DelegatingSpliterator(Supplier<? extends Spliterator<T>> supplier) {
   497         DelegatingSpliterator(Supplier<? extends T_SPLITR> supplier) {
   493             this.supplier = (Supplier<Spliterator<T>>) supplier;
   498             this.supplier = supplier;
   494         }
   499         }
   495 
   500 
   496         Spliterator<T> get() {
   501         T_SPLITR get() {
   497             if (s == null) {
   502             if (s == null) {
   498                 s = supplier.get();
   503                 s = supplier.get();
   499             }
   504             }
   500             return s;
   505             return s;
   501         }
   506         }
   502 
   507 
   503         @Override
   508         @Override
   504         public Spliterator<T> trySplit() {
   509         public T_SPLITR trySplit() {
   505             return get().trySplit();
   510             return (T_SPLITR) get().trySplit();
   506         }
   511         }
   507 
   512 
   508         @Override
   513         @Override
   509         public boolean tryAdvance(Consumer<? super T> consumer) {
   514         public boolean tryAdvance(Consumer<? super T> consumer) {
   510             return get().tryAdvance(consumer);
   515             return get().tryAdvance(consumer);
   538         @Override
   543         @Override
   539         public String toString() {
   544         public String toString() {
   540             return getClass().getName() + "[" + get() + "]";
   545             return getClass().getName() + "[" + get() + "]";
   541         }
   546         }
   542 
   547 
   543         static final class OfInt extends DelegatingSpliterator<Integer> implements Spliterator.OfInt {
   548         static class OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
   544             private Spliterator.OfInt s;
   549             extends DelegatingSpliterator<T, T_SPLITR>
       
   550             implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> {
       
   551             OfPrimitive(Supplier<? extends T_SPLITR> supplier) {
       
   552                 super(supplier);
       
   553             }
       
   554 
       
   555             @Override
       
   556             public boolean tryAdvance(T_CONS consumer) {
       
   557                 return get().tryAdvance(consumer);
       
   558             }
       
   559 
       
   560             @Override
       
   561             public void forEachRemaining(T_CONS consumer) {
       
   562                 get().forEachRemaining(consumer);
       
   563             }
       
   564         }
       
   565 
       
   566         static final class OfInt
       
   567                 extends OfPrimitive<Integer, IntConsumer, Spliterator.OfInt>
       
   568                 implements Spliterator.OfInt {
   545 
   569 
   546             OfInt(Supplier<Spliterator.OfInt> supplier) {
   570             OfInt(Supplier<Spliterator.OfInt> supplier) {
   547                 super(supplier);
   571                 super(supplier);
   548             }
   572             }
   549 
   573         }
   550             @Override
   574 
   551             Spliterator.OfInt get() {
   575         static final class OfLong
   552                 if (s == null) {
   576                 extends OfPrimitive<Long, LongConsumer, Spliterator.OfLong>
   553                     s = (Spliterator.OfInt) super.get();
   577                 implements Spliterator.OfLong {
   554                 }
       
   555                 return s;
       
   556             }
       
   557 
       
   558             @Override
       
   559             public Spliterator.OfInt trySplit() {
       
   560                 return get().trySplit();
       
   561             }
       
   562 
       
   563             @Override
       
   564             public boolean tryAdvance(IntConsumer consumer) {
       
   565                 return get().tryAdvance(consumer);
       
   566             }
       
   567 
       
   568             @Override
       
   569             public void forEachRemaining(IntConsumer consumer) {
       
   570                 get().forEachRemaining(consumer);
       
   571             }
       
   572         }
       
   573 
       
   574         static final class OfLong extends DelegatingSpliterator<Long> implements Spliterator.OfLong {
       
   575             private Spliterator.OfLong s;
       
   576 
   578 
   577             OfLong(Supplier<Spliterator.OfLong> supplier) {
   579             OfLong(Supplier<Spliterator.OfLong> supplier) {
   578                 super(supplier);
   580                 super(supplier);
   579             }
   581             }
   580 
   582         }
   581             @Override
   583 
   582             Spliterator.OfLong get() {
   584         static final class OfDouble
   583                 if (s == null) {
   585                 extends OfPrimitive<Double, DoubleConsumer, Spliterator.OfDouble>
   584                     s = (Spliterator.OfLong) super.get();
   586                 implements Spliterator.OfDouble {
   585                 }
       
   586                 return s;
       
   587             }
       
   588 
       
   589             @Override
       
   590             public Spliterator.OfLong trySplit() {
       
   591                 return get().trySplit();
       
   592             }
       
   593 
       
   594             @Override
       
   595             public boolean tryAdvance(LongConsumer consumer) {
       
   596                 return get().tryAdvance(consumer);
       
   597             }
       
   598 
       
   599             @Override
       
   600             public void forEachRemaining(LongConsumer consumer) {
       
   601                 get().forEachRemaining(consumer);
       
   602             }
       
   603         }
       
   604 
       
   605         static final class OfDouble extends DelegatingSpliterator<Double> implements Spliterator.OfDouble {
       
   606             private Spliterator.OfDouble s;
       
   607 
   587 
   608             OfDouble(Supplier<Spliterator.OfDouble> supplier) {
   588             OfDouble(Supplier<Spliterator.OfDouble> supplier) {
   609                 super(supplier);
   589                 super(supplier);
   610             }
   590             }
   611 
   591         }
   612             @Override
   592     }
   613             Spliterator.OfDouble get() {
   593 
   614                 if (s == null) {
   594     /**
   615                     s = (Spliterator.OfDouble) super.get();
   595      * A slice Spliterator from a source Spliterator that reports
   616                 }
   596      * {@code SUBSIZED}.
   617                 return s;
   597      *
       
   598      */
       
   599     static abstract class SliceSpliterator<T, T_SPLITR extends Spliterator<T>> {
       
   600         // The start index of the slice
       
   601         final long sliceOrigin;
       
   602         // One past the last index of the slice
       
   603         final long sliceFence;
       
   604 
       
   605         // The spliterator to slice
       
   606         T_SPLITR s;
       
   607         // current (absolute) index, modified on advance/split
       
   608         long index;
       
   609         // one past last (absolute) index or sliceFence, which ever is smaller
       
   610         long fence;
       
   611 
       
   612         SliceSpliterator(T_SPLITR s, long sliceOrigin, long sliceFence, long origin, long fence) {
       
   613             assert s.hasCharacteristics(Spliterator.SUBSIZED);
       
   614             this.s = s;
       
   615             this.sliceOrigin = sliceOrigin;
       
   616             this.sliceFence = sliceFence;
       
   617             this.index = origin;
       
   618             this.fence = fence;
       
   619         }
       
   620 
       
   621         protected abstract T_SPLITR makeSpliterator(T_SPLITR s, long sliceOrigin, long sliceFence, long origin, long fence);
       
   622 
       
   623         public T_SPLITR trySplit() {
       
   624             if (sliceOrigin >= fence)
       
   625                 return null;
       
   626 
       
   627             if (index >= fence)
       
   628                 return null;
       
   629 
       
   630             // Keep splitting until the left and right splits intersect with the slice
       
   631             // thereby ensuring the size estimate decreases.
       
   632             // This also avoids creating empty spliterators which can result in
       
   633             // existing and additionally created F/J tasks that perform
       
   634             // redundant work on no elements.
       
   635             while (true) {
       
   636                 T_SPLITR leftSplit = (T_SPLITR) s.trySplit();
       
   637                 if (leftSplit == null)
       
   638                     return null;
       
   639 
       
   640                 long leftSplitFenceUnbounded = index + leftSplit.estimateSize();
       
   641                 long leftSplitFence = Math.min(leftSplitFenceUnbounded, sliceFence);
       
   642                 if (sliceOrigin >= leftSplitFence) {
       
   643                     // The left split does not intersect with, and is to the left of, the slice
       
   644                     // The right split does intersect
       
   645                     // Discard the left split and split further with the right split
       
   646                     index = leftSplitFence;
       
   647                 }
       
   648                 else if (leftSplitFence >= sliceFence) {
       
   649                     // The right split does not intersect with, and is to the right of, the slice
       
   650                     // The left split does intersect
       
   651                     // Discard the right split and split further with the left split
       
   652                     s = leftSplit;
       
   653                     fence = leftSplitFence;
       
   654                 }
       
   655                 else if (index >= sliceOrigin && leftSplitFenceUnbounded <= sliceFence) {
       
   656                     // The left split is contained within the slice, return the underlying left split
       
   657                     // Right split is contained within or intersects with the slice
       
   658                     index = leftSplitFence;
       
   659                     return leftSplit;
       
   660                 } else {
       
   661                     // The left split intersects with the slice
       
   662                     // Right split is contained within or intersects with the slice
       
   663                     return makeSpliterator(leftSplit, sliceOrigin, sliceFence, index, index = leftSplitFence);
       
   664                 }
       
   665             }
       
   666         }
       
   667 
       
   668         public long estimateSize() {
       
   669             return (sliceOrigin < fence)
       
   670                    ? fence - Math.max(sliceOrigin, index) : 0;
       
   671         }
       
   672 
       
   673         public int characteristics() {
       
   674             return s.characteristics();
       
   675         }
       
   676 
       
   677         static final class OfRef<T>
       
   678                 extends SliceSpliterator<T, Spliterator<T>>
       
   679                 implements Spliterator<T> {
       
   680 
       
   681             OfRef(Spliterator<T> s, long sliceOrigin, long sliceFence) {
       
   682                 this(s, sliceOrigin, sliceFence, 0, Math.min(s.estimateSize(), sliceFence));
       
   683             }
       
   684 
       
   685             private OfRef(Spliterator<T> s,
       
   686                           long sliceOrigin, long sliceFence, long origin, long fence) {
       
   687                 super(s, sliceOrigin, sliceFence, origin, fence);
       
   688             }
       
   689 
       
   690             @Override
       
   691             protected Spliterator<T> makeSpliterator(Spliterator<T> s,
       
   692                                                      long sliceOrigin, long sliceFence,
       
   693                                                      long origin, long fence) {
       
   694                 return new OfRef<>(s, sliceOrigin, sliceFence, origin, fence);
       
   695             }
       
   696 
       
   697             @Override
       
   698             public boolean tryAdvance(Consumer<? super T> action) {
       
   699                 if (sliceOrigin >= fence)
       
   700                     return false;
       
   701 
       
   702                 while (sliceOrigin > index) {
       
   703                     s.tryAdvance(e -> {});
       
   704                     index++;
       
   705                 }
       
   706 
       
   707                 if (index >= fence)
       
   708                     return false;
       
   709 
       
   710                 index++;
       
   711                 return s.tryAdvance(action);
       
   712             }
       
   713 
       
   714             @Override
       
   715             public void forEachRemaining(Consumer<? super T> action) {
       
   716                 if (sliceOrigin >= fence)
       
   717                     return;
       
   718 
       
   719                 if (index >= fence)
       
   720                     return;
       
   721 
       
   722                 if (index >= sliceOrigin && (index + s.estimateSize()) <= sliceFence) {
       
   723                     // The spliterator is contained within the slice
       
   724                     s.forEachRemaining(action);
       
   725                     index = fence;
       
   726                 } else {
       
   727                     // The spliterator intersects with the slice
       
   728                     while (sliceOrigin > index) {
       
   729                         s.tryAdvance(e -> {});
       
   730                         index++;
       
   731                     }
       
   732                     // Traverse elements up to the fence
       
   733                     for (;index < fence; index++) {
       
   734                         s.tryAdvance(action);
       
   735                     }
       
   736                 }
       
   737             }
       
   738         }
       
   739 
       
   740         static abstract class OfPrimitive<T,
       
   741                 T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>,
       
   742                 T_CONS>
       
   743                 extends SliceSpliterator<T, T_SPLITR>
       
   744                 implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> {
       
   745 
       
   746             OfPrimitive(T_SPLITR s, long sliceOrigin, long sliceFence) {
       
   747                 this(s, sliceOrigin, sliceFence, 0, Math.min(s.estimateSize(), sliceFence));
       
   748             }
       
   749 
       
   750             private OfPrimitive(T_SPLITR s,
       
   751                                 long sliceOrigin, long sliceFence, long origin, long fence) {
       
   752                 super(s, sliceOrigin, sliceFence, origin, fence);
       
   753             }
       
   754 
       
   755             @Override
       
   756             public boolean tryAdvance(T_CONS action) {
       
   757                 if (sliceOrigin >= fence)
       
   758                     return false;
       
   759 
       
   760                 while (sliceOrigin > index) {
       
   761                     s.tryAdvance(emptyConsumer());
       
   762                     index++;
       
   763                 }
       
   764 
       
   765                 if (index >= fence)
       
   766                     return false;
       
   767 
       
   768                 index++;
       
   769                 return s.tryAdvance(action);
       
   770             }
       
   771 
       
   772             @Override
       
   773             public void forEachRemaining(T_CONS action) {
       
   774                 if (sliceOrigin >= fence)
       
   775                     return;
       
   776 
       
   777                 if (index >= fence)
       
   778                     return;
       
   779 
       
   780                 if (index >= sliceOrigin && (index + s.estimateSize()) <= sliceFence) {
       
   781                     // The spliterator is contained within the slice
       
   782                     s.forEachRemaining(action);
       
   783                     index = fence;
       
   784                 } else {
       
   785                     // The spliterator intersects with the slice
       
   786                     while (sliceOrigin > index) {
       
   787                         s.tryAdvance(emptyConsumer());
       
   788                         index++;
       
   789                     }
       
   790                     // Traverse elements up to the fence
       
   791                     for (;index < fence; index++) {
       
   792                         s.tryAdvance(action);
       
   793                     }
       
   794                 }
       
   795             }
       
   796 
       
   797             protected abstract T_CONS emptyConsumer();
       
   798         }
       
   799 
       
   800         static final class OfInt extends OfPrimitive<Integer, Spliterator.OfInt, IntConsumer>
       
   801                 implements Spliterator.OfInt {
       
   802             OfInt(Spliterator.OfInt s, long sliceOrigin, long sliceFence) {
       
   803                 super(s, sliceOrigin, sliceFence);
       
   804             }
       
   805 
       
   806             OfInt(Spliterator.OfInt s,
       
   807                   long sliceOrigin, long sliceFence, long origin, long fence) {
       
   808                 super(s, sliceOrigin, sliceFence, origin, fence);
       
   809             }
       
   810 
       
   811             @Override
       
   812             protected Spliterator.OfInt makeSpliterator(Spliterator.OfInt s,
       
   813                                                         long sliceOrigin, long sliceFence,
       
   814                                                         long origin, long fence) {
       
   815                 return new SliceSpliterator.OfInt(s, sliceOrigin, sliceFence, origin, fence);
       
   816             }
       
   817 
       
   818             @Override
       
   819             protected IntConsumer emptyConsumer() {
       
   820                 return e -> {};
       
   821             }
       
   822         }
       
   823 
       
   824         static final class OfLong extends OfPrimitive<Long, Spliterator.OfLong, LongConsumer>
       
   825                 implements Spliterator.OfLong {
       
   826             OfLong(Spliterator.OfLong s, long sliceOrigin, long sliceFence) {
       
   827                 super(s, sliceOrigin, sliceFence);
       
   828             }
       
   829 
       
   830             OfLong(Spliterator.OfLong s,
       
   831                    long sliceOrigin, long sliceFence, long origin, long fence) {
       
   832                 super(s, sliceOrigin, sliceFence, origin, fence);
       
   833             }
       
   834 
       
   835             @Override
       
   836             protected Spliterator.OfLong makeSpliterator(Spliterator.OfLong s,
       
   837                                                          long sliceOrigin, long sliceFence,
       
   838                                                          long origin, long fence) {
       
   839                 return new SliceSpliterator.OfLong(s, sliceOrigin, sliceFence, origin, fence);
       
   840             }
       
   841 
       
   842             @Override
       
   843             protected LongConsumer emptyConsumer() {
       
   844                 return e -> {};
       
   845             }
       
   846         }
       
   847 
       
   848         static final class OfDouble extends OfPrimitive<Double, Spliterator.OfDouble, DoubleConsumer>
       
   849                 implements Spliterator.OfDouble {
       
   850             OfDouble(Spliterator.OfDouble s, long sliceOrigin, long sliceFence) {
       
   851                 super(s, sliceOrigin, sliceFence);
       
   852             }
       
   853 
       
   854             OfDouble(Spliterator.OfDouble s,
       
   855                      long sliceOrigin, long sliceFence, long origin, long fence) {
       
   856                 super(s, sliceOrigin, sliceFence, origin, fence);
       
   857             }
       
   858 
       
   859             @Override
       
   860             protected Spliterator.OfDouble makeSpliterator(Spliterator.OfDouble s,
       
   861                                                            long sliceOrigin, long sliceFence,
       
   862                                                            long origin, long fence) {
       
   863                 return new SliceSpliterator.OfDouble(s, sliceOrigin, sliceFence, origin, fence);
       
   864             }
       
   865 
       
   866             @Override
       
   867             protected DoubleConsumer emptyConsumer() {
       
   868                 return e -> {};
       
   869             }
       
   870         }
       
   871     }
       
   872 
       
   873     /**
       
   874      * A slice Spliterator that does not preserve order, if any, of a source
       
   875      * Spliterator.
       
   876      *
       
   877      * Note: The source spliterator may report {@code ORDERED} since that
       
   878      * spliterator be the result of a previous pipeline stage that was
       
   879      * collected to a {@code Node}. It is the order of the pipeline stage
       
   880      * that governs whether the this slice spliterator is to be used or not.
       
   881      */
       
   882     static abstract class UnorderedSliceSpliterator<T, T_SPLITR extends Spliterator<T>> {
       
   883         static final int CHUNK_SIZE = 1 << 7;
       
   884 
       
   885         // The spliterator to slice
       
   886         protected final T_SPLITR s;
       
   887         protected final boolean unlimited;
       
   888         private final long skipThreshold;
       
   889         private final AtomicLong permits;
       
   890 
       
   891         UnorderedSliceSpliterator(T_SPLITR s, long skip, long limit) {
       
   892             this.s = s;
       
   893             this.unlimited = limit < 0;
       
   894             this.skipThreshold = limit >= 0 ? limit : 0;
       
   895             this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip);
       
   896         }
       
   897 
       
   898         UnorderedSliceSpliterator(T_SPLITR s, UnorderedSliceSpliterator parent) {
       
   899             this.s = s;
       
   900             this.unlimited = parent.unlimited;
       
   901             this.permits = parent.permits;
       
   902             this.skipThreshold = parent.skipThreshold;
       
   903         }
       
   904 
       
   905         /**
       
   906          * Acquire permission to skip or process elements.  The caller must
       
   907          * first acquire the elements, then consult this method for guidance
       
   908          * as to what to do with the data.
       
   909          *
       
   910          * <p>We use an {@code AtomicLong} to atomically maintain a counter,
       
   911          * which is initialized as skip+limit if we are limiting, or skip only
       
   912          * if we are not limiting.  The user should consult the method
       
   913          * {@code checkPermits()} before acquiring data elements.
       
   914          *
       
   915          * @param numElements the number of elements the caller has in hand
       
   916          * @return the number of elements that should be processed; any
       
   917          * remaining elements should be discarded.
       
   918          */
       
   919         protected final long acquirePermits(long numElements) {
       
   920             long remainingPermits;
       
   921             long grabbing;
       
   922             // permits never increase, and don't decrease below zero
       
   923             assert numElements > 0;
       
   924             do {
       
   925                 remainingPermits = permits.get();
       
   926                 if (remainingPermits == 0)
       
   927                     return unlimited ? numElements : 0;
       
   928                 grabbing = Math.min(remainingPermits, numElements);
       
   929             } while (grabbing > 0 &&
       
   930                      !permits.compareAndSet(remainingPermits, remainingPermits - grabbing));
       
   931 
       
   932             if (unlimited)
       
   933                 return Math.max(numElements - grabbing, 0);
       
   934             else if (remainingPermits > skipThreshold)
       
   935                 return Math.max(grabbing - (remainingPermits - skipThreshold), 0);
       
   936             else
       
   937                 return grabbing;
       
   938         }
       
   939 
       
   940         enum PermitStatus { NO_MORE, MAYBE_MORE, UNLIMITED }
       
   941 
       
   942         /** Call to check if permits might be available before acquiring data */
       
   943         protected final PermitStatus permitStatus() {
       
   944             if (permits.get() > 0)
       
   945                 return PermitStatus.MAYBE_MORE;
       
   946             else
       
   947                 return unlimited ?  PermitStatus.UNLIMITED : PermitStatus.NO_MORE;
       
   948         }
       
   949 
       
   950         public final T_SPLITR trySplit() {
       
   951             // Stop splitting when there are no more limit permits
       
   952             if (permits.get() == 0)
       
   953                 return null;
       
   954             T_SPLITR split = (T_SPLITR) s.trySplit();
       
   955             return split == null ? null : makeSpliterator(split);
       
   956         }
       
   957 
       
   958         protected abstract T_SPLITR makeSpliterator(T_SPLITR s);
       
   959 
       
   960         public final long estimateSize() {
       
   961             return s.estimateSize();
       
   962         }
       
   963 
       
   964         public final int characteristics() {
       
   965             return s.characteristics() &
       
   966                    ~(Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED);
       
   967         }
       
   968 
       
   969         static final class OfRef<T> extends UnorderedSliceSpliterator<T, Spliterator<T>>
       
   970                 implements Spliterator<T>, Consumer<T> {
       
   971             T tmpSlot;
       
   972 
       
   973             OfRef(Spliterator<T> s, long skip, long limit) {
       
   974                 super(s, skip, limit);
       
   975             }
       
   976 
       
   977             OfRef(Spliterator<T> s, OfRef parent) {
       
   978                 super(s, parent);
       
   979             }
       
   980 
       
   981             @Override
       
   982             public final void accept(T t) {
       
   983                 tmpSlot = t;
       
   984             }
       
   985 
       
   986             @Override
       
   987             public boolean tryAdvance(Consumer<? super T> action) {
       
   988                 while (permitStatus() != PermitStatus.NO_MORE) {
       
   989                     if (!s.tryAdvance(this))
       
   990                         return false;
       
   991                     else if (acquirePermits(1) == 1) {
       
   992                         action.accept(tmpSlot);
       
   993                         tmpSlot = null;
       
   994                         return true;
       
   995                     }
       
   996                 }
       
   997                 return false;
       
   998             }
       
   999 
       
  1000             @Override
       
  1001             public void forEachRemaining(Consumer<? super T> action) {
       
  1002                 ArrayBuffer.OfRef<T> sb = null;
       
  1003                 PermitStatus permitStatus;
       
  1004                 while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) {
       
  1005                     if (permitStatus == PermitStatus.MAYBE_MORE) {
       
  1006                         // Optimistically traverse elements up to a threshold of CHUNK_SIZE
       
  1007                         if (sb == null)
       
  1008                             sb = new ArrayBuffer.OfRef<>(CHUNK_SIZE);
       
  1009                         else
       
  1010                             sb.reset();
       
  1011                         long permitsRequested = 0;
       
  1012                         do { } while (s.tryAdvance(sb) && ++permitsRequested < CHUNK_SIZE);
       
  1013                         if (permitsRequested == 0)
       
  1014                             return;
       
  1015                         sb.forEach(action, acquirePermits(permitsRequested));
       
  1016                     }
       
  1017                     else {
       
  1018                         // Must be UNLIMITED; let 'er rip
       
  1019                         s.forEachRemaining(action);
       
  1020                         return;
       
  1021                     }
       
  1022                 }
       
  1023             }
       
  1024 
       
  1025             @Override
       
  1026             protected Spliterator<T> makeSpliterator(Spliterator<T> s) {
       
  1027                 return new UnorderedSliceSpliterator.OfRef<>(s, this);
       
  1028             }
       
  1029         }
       
  1030 
       
  1031         /**
       
  1032          * Concrete sub-types must also be an instance of type {@code T_CONS}.
       
  1033          *
       
  1034          * @param <T_BUFF> the type of the spined buffer. Must also be a type of
       
  1035          *        {@code T_CONS}.
       
  1036          */
       
  1037         static abstract class OfPrimitive<
       
  1038                 T,
       
  1039                 T_CONS,
       
  1040                 T_BUFF extends ArrayBuffer.OfPrimitive<T_CONS>,
       
  1041                 T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
       
  1042                 extends UnorderedSliceSpliterator<T, T_SPLITR>
       
  1043                 implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> {
       
  1044             OfPrimitive(T_SPLITR s, long skip, long limit) {
       
  1045                 super(s, skip, limit);
       
  1046             }
       
  1047 
       
  1048             OfPrimitive(T_SPLITR s, UnorderedSliceSpliterator.OfPrimitive parent) {
       
  1049                 super(s, parent);
       
  1050             }
       
  1051 
       
  1052             @Override
       
  1053             public boolean tryAdvance(T_CONS action) {
       
  1054                 while (permitStatus() != PermitStatus.NO_MORE) {
       
  1055                     if (!s.tryAdvance((T_CONS) this))
       
  1056                         return false;
       
  1057                     else if (acquirePermits(1) == 1) {
       
  1058                         acceptConsumed(action);
       
  1059                         return true;
       
  1060                     }
       
  1061                 }
       
  1062                 return false;
       
  1063             }
       
  1064 
       
  1065             protected abstract void acceptConsumed(T_CONS action);
       
  1066 
       
  1067             @Override
       
  1068             public void forEachRemaining(T_CONS action) {
       
  1069                 T_BUFF sb = null;
       
  1070                 PermitStatus permitStatus;
       
  1071                 while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) {
       
  1072                     if (permitStatus == PermitStatus.MAYBE_MORE) {
       
  1073                         // Optimistically traverse elements up to a threshold of CHUNK_SIZE
       
  1074                         if (sb == null)
       
  1075                             sb = bufferCreate(CHUNK_SIZE);
       
  1076                         else
       
  1077                             sb.reset();
       
  1078                         @SuppressWarnings("unchecked")
       
  1079                         T_CONS sbc = (T_CONS) sb;
       
  1080                         long permitsRequested = 0;
       
  1081                         do { } while (s.tryAdvance(sbc) && ++permitsRequested < CHUNK_SIZE);
       
  1082                         if (permitsRequested == 0)
       
  1083                             return;
       
  1084                         sb.forEach(action, acquirePermits(permitsRequested));
       
  1085                     }
       
  1086                     else {
       
  1087                         // Must be UNLIMITED; let 'er rip
       
  1088                         s.forEachRemaining(action);
       
  1089                         return;
       
  1090                     }
       
  1091                 }
       
  1092             }
       
  1093 
       
  1094             protected abstract T_BUFF bufferCreate(int initialCapacity);
       
  1095         }
       
  1096 
       
  1097         static final class OfInt
       
  1098                 extends OfPrimitive<Integer, IntConsumer, ArrayBuffer.OfInt, Spliterator.OfInt>
       
  1099                 implements Spliterator.OfInt, IntConsumer {
       
  1100 
       
  1101             int tmpValue;
       
  1102 
       
  1103             OfInt(Spliterator.OfInt s, long skip, long limit) {
       
  1104                 super(s, skip, limit);
       
  1105             }
       
  1106 
       
  1107             OfInt(Spliterator.OfInt s, UnorderedSliceSpliterator.OfInt parent) {
       
  1108                 super(s, parent);
       
  1109             }
       
  1110 
       
  1111             @Override
       
  1112             public void accept(int value) {
       
  1113                 tmpValue = value;
       
  1114             }
       
  1115 
       
  1116             @Override
       
  1117             protected void acceptConsumed(IntConsumer action) {
       
  1118                 action.accept(tmpValue);
       
  1119             }
       
  1120 
       
  1121             @Override
       
  1122             protected ArrayBuffer.OfInt bufferCreate(int initialCapacity) {
       
  1123                 return new ArrayBuffer.OfInt(initialCapacity);
       
  1124             }
       
  1125 
       
  1126             @Override
       
  1127             protected Spliterator.OfInt makeSpliterator(Spliterator.OfInt s) {
       
  1128                 return new UnorderedSliceSpliterator.OfInt(s, this);
       
  1129             }
       
  1130         }
       
  1131 
       
  1132         static final class OfLong
       
  1133                 extends OfPrimitive<Long, LongConsumer, ArrayBuffer.OfLong, Spliterator.OfLong>
       
  1134                 implements Spliterator.OfLong, LongConsumer {
       
  1135 
       
  1136             long tmpValue;
       
  1137 
       
  1138             OfLong(Spliterator.OfLong s, long skip, long limit) {
       
  1139                 super(s, skip, limit);
       
  1140             }
       
  1141 
       
  1142             OfLong(Spliterator.OfLong s, UnorderedSliceSpliterator.OfLong parent) {
       
  1143                 super(s, parent);
       
  1144             }
       
  1145 
       
  1146             @Override
       
  1147             public void accept(long value) {
       
  1148                 tmpValue = value;
       
  1149             }
       
  1150 
       
  1151             @Override
       
  1152             protected void acceptConsumed(LongConsumer action) {
       
  1153                 action.accept(tmpValue);
       
  1154             }
       
  1155 
       
  1156             @Override
       
  1157             protected ArrayBuffer.OfLong bufferCreate(int initialCapacity) {
       
  1158                 return new ArrayBuffer.OfLong(initialCapacity);
       
  1159             }
       
  1160 
       
  1161             @Override
       
  1162             protected Spliterator.OfLong makeSpliterator(Spliterator.OfLong s) {
       
  1163                 return new UnorderedSliceSpliterator.OfLong(s, this);
       
  1164             }
       
  1165         }
       
  1166 
       
  1167         static final class OfDouble
       
  1168                 extends OfPrimitive<Double, DoubleConsumer, ArrayBuffer.OfDouble, Spliterator.OfDouble>
       
  1169                 implements Spliterator.OfDouble, DoubleConsumer {
       
  1170 
       
  1171             double tmpValue;
       
  1172 
       
  1173             OfDouble(Spliterator.OfDouble s, long skip, long limit) {
       
  1174                 super(s, skip, limit);
       
  1175             }
       
  1176 
       
  1177             OfDouble(Spliterator.OfDouble s, UnorderedSliceSpliterator.OfDouble parent) {
       
  1178                 super(s, parent);
       
  1179             }
       
  1180 
       
  1181             @Override
       
  1182             public void accept(double value) {
       
  1183                 tmpValue = value;
       
  1184             }
       
  1185 
       
  1186             @Override
       
  1187             protected void acceptConsumed(DoubleConsumer action) {
       
  1188                 action.accept(tmpValue);
       
  1189             }
       
  1190 
       
  1191             @Override
       
  1192             protected ArrayBuffer.OfDouble bufferCreate(int initialCapacity) {
       
  1193                 return new ArrayBuffer.OfDouble(initialCapacity);
       
  1194             }
       
  1195 
       
  1196             @Override
       
  1197             protected Spliterator.OfDouble makeSpliterator(Spliterator.OfDouble s) {
       
  1198                 return new UnorderedSliceSpliterator.OfDouble(s, this);
       
  1199             }
       
  1200         }
       
  1201     }
       
  1202 
       
  1203     /**
       
  1204      * A Spliterator that infinitely supplies elements in no particular order.
       
  1205      *
       
  1206      * <p>Splitting divides the estimated size in two and stops when the
       
  1207      * estimate size is 0.
       
  1208      *
       
  1209      * <p>The {@code forEachRemaining} method if invoked will never terminate.
       
  1210      * The {@coe tryAdvance} method always returns true.
       
  1211      *
       
  1212      */
       
  1213     static abstract class InfiniteSupplyingSpliterator<T> implements Spliterator<T> {
       
  1214         long estimate;
       
  1215 
       
  1216         protected InfiniteSupplyingSpliterator(long estimate) {
       
  1217             this.estimate = estimate;
       
  1218         }
       
  1219 
       
  1220         @Override
       
  1221         public long estimateSize() {
       
  1222             return estimate;
       
  1223         }
       
  1224 
       
  1225         @Override
       
  1226         public int characteristics() {
       
  1227             return IMMUTABLE;
       
  1228         }
       
  1229 
       
  1230         static final class OfRef<T> extends InfiniteSupplyingSpliterator<T> {
       
  1231             final Supplier<T> s;
       
  1232 
       
  1233             OfRef(long size, Supplier<T> s) {
       
  1234                 super(size);
       
  1235                 this.s = s;
       
  1236             }
       
  1237 
       
  1238             @Override
       
  1239             public boolean tryAdvance(Consumer<? super T> action) {
       
  1240                 action.accept(s.get());
       
  1241                 return true;
       
  1242             }
       
  1243 
       
  1244             @Override
       
  1245             public Spliterator<T> trySplit() {
       
  1246                 if (estimate == 0)
       
  1247                     return null;
       
  1248                 return new InfiniteSupplyingSpliterator.OfRef<>(estimate >>>= 1, s);
       
  1249             }
       
  1250         }
       
  1251 
       
  1252         static final class OfInt extends InfiniteSupplyingSpliterator<Integer>
       
  1253                 implements Spliterator.OfInt {
       
  1254             final IntSupplier s;
       
  1255 
       
  1256             OfInt(long size, IntSupplier s) {
       
  1257                 super(size);
       
  1258                 this.s = s;
       
  1259             }
       
  1260 
       
  1261             @Override
       
  1262             public boolean tryAdvance(IntConsumer action) {
       
  1263                 action.accept(s.getAsInt());
       
  1264                 return true;
       
  1265             }
       
  1266 
       
  1267             @Override
       
  1268             public Spliterator.OfInt trySplit() {
       
  1269                 if (estimate == 0)
       
  1270                     return null;
       
  1271                 return new InfiniteSupplyingSpliterator.OfInt(estimate = estimate >>> 1, s);
       
  1272             }
       
  1273         }
       
  1274 
       
  1275         static final class OfLong extends InfiniteSupplyingSpliterator<Long>
       
  1276                 implements Spliterator.OfLong {
       
  1277             final LongSupplier s;
       
  1278 
       
  1279             OfLong(long size, LongSupplier s) {
       
  1280                 super(size);
       
  1281                 this.s = s;
       
  1282             }
       
  1283 
       
  1284             @Override
       
  1285             public boolean tryAdvance(LongConsumer action) {
       
  1286                 action.accept(s.getAsLong());
       
  1287                 return true;
       
  1288             }
       
  1289 
       
  1290             @Override
       
  1291             public Spliterator.OfLong trySplit() {
       
  1292                 if (estimate == 0)
       
  1293                     return null;
       
  1294                 return new InfiniteSupplyingSpliterator.OfLong(estimate = estimate >>> 1, s);
       
  1295             }
       
  1296         }
       
  1297 
       
  1298         static final class OfDouble extends InfiniteSupplyingSpliterator<Double>
       
  1299                 implements Spliterator.OfDouble {
       
  1300             final DoubleSupplier s;
       
  1301 
       
  1302             OfDouble(long size, DoubleSupplier s) {
       
  1303                 super(size);
       
  1304                 this.s = s;
       
  1305             }
       
  1306 
       
  1307             @Override
       
  1308             public boolean tryAdvance(DoubleConsumer action) {
       
  1309                 action.accept(s.getAsDouble());
       
  1310                 return true;
   618             }
  1311             }
   619 
  1312 
   620             @Override
  1313             @Override
   621             public Spliterator.OfDouble trySplit() {
  1314             public Spliterator.OfDouble trySplit() {
   622                 return get().trySplit();
  1315                 if (estimate == 0)
   623             }
  1316                     return null;
   624 
  1317                 return new InfiniteSupplyingSpliterator.OfDouble(estimate = estimate >>> 1, s);
   625             @Override
  1318             }
   626             public boolean tryAdvance(DoubleConsumer consumer) {
  1319         }
   627                 return get().tryAdvance(consumer);
  1320     }
   628             }
  1321 
   629 
  1322     // @@@ Consolidate with Node.Builder
   630             @Override
  1323     static abstract class ArrayBuffer {
   631             public void forEachRemaining(DoubleConsumer consumer) {
  1324         int index;
   632                 get().forEachRemaining(consumer);
  1325 
       
  1326         void reset() {
       
  1327             index = 0;
       
  1328         }
       
  1329 
       
  1330         static final class OfRef<T> extends ArrayBuffer implements Consumer<T> {
       
  1331             final Object[] array;
       
  1332 
       
  1333             OfRef(int size) {
       
  1334                 this.array = new Object[size];
       
  1335             }
       
  1336 
       
  1337             @Override
       
  1338             public void accept(T t) {
       
  1339                 array[index++] = t;
       
  1340             }
       
  1341 
       
  1342             public void forEach(Consumer<? super T> action, long fence) {
       
  1343                 for (int i = 0; i < fence; i++) {
       
  1344                     @SuppressWarnings("unchecked")
       
  1345                     T t = (T) array[i];
       
  1346                     action.accept(t);
       
  1347                 }
       
  1348             }
       
  1349         }
       
  1350 
       
  1351         static abstract class OfPrimitive<T_CONS> extends ArrayBuffer {
       
  1352             int index;
       
  1353 
       
  1354             @Override
       
  1355             void reset() {
       
  1356                 index = 0;
       
  1357             }
       
  1358 
       
  1359             abstract void forEach(T_CONS action, long fence);
       
  1360         }
       
  1361 
       
  1362         static final class OfInt extends OfPrimitive<IntConsumer>
       
  1363                 implements IntConsumer {
       
  1364             final int[] array;
       
  1365 
       
  1366             OfInt(int size) {
       
  1367                 this.array = new int[size];
       
  1368             }
       
  1369 
       
  1370             @Override
       
  1371             public void accept(int t) {
       
  1372                 array[index++] = t;
       
  1373             }
       
  1374 
       
  1375             @Override
       
  1376             public void forEach(IntConsumer action, long fence) {
       
  1377                 for (int i = 0; i < fence; i++) {
       
  1378                     action.accept(array[i]);
       
  1379                 }
       
  1380             }
       
  1381         }
       
  1382 
       
  1383         static final class OfLong extends OfPrimitive<LongConsumer>
       
  1384                 implements LongConsumer {
       
  1385             final long[] array;
       
  1386 
       
  1387             OfLong(int size) {
       
  1388                 this.array = new long[size];
       
  1389             }
       
  1390 
       
  1391             @Override
       
  1392             public void accept(long t) {
       
  1393                 array[index++] = t;
       
  1394             }
       
  1395 
       
  1396             @Override
       
  1397             public void forEach(LongConsumer action, long fence) {
       
  1398                 for (int i = 0; i < fence; i++) {
       
  1399                     action.accept(array[i]);
       
  1400                 }
       
  1401             }
       
  1402         }
       
  1403 
       
  1404         static final class OfDouble extends OfPrimitive<DoubleConsumer>
       
  1405                 implements DoubleConsumer {
       
  1406             final double[] array;
       
  1407 
       
  1408             OfDouble(int size) {
       
  1409                 this.array = new double[size];
       
  1410             }
       
  1411 
       
  1412             @Override
       
  1413             public void accept(double t) {
       
  1414                 array[index++] = t;
       
  1415             }
       
  1416 
       
  1417             @Override
       
  1418             void forEach(DoubleConsumer action, long fence) {
       
  1419                 for (int i = 0; i < fence; i++) {
       
  1420                     action.accept(array[i]);
       
  1421                 }
   633             }
  1422             }
   634         }
  1423         }
   635     }
  1424     }
   636 }
  1425 }