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 } |