| /* |
| * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| package java.util.stream; |
| |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.PrimitiveIterator; |
| import java.util.Spliterator; |
| import java.util.Spliterators; |
| import java.util.function.DoubleConsumer; |
| import java.util.function.Function; |
| import java.util.function.IntConsumer; |
| import java.util.function.LongConsumer; |
| import java.util.function.Supplier; |
| import java.util.function.ToIntFunction; |
| |
| /** Describes a test data set for use in stream tests */ |
| public interface TestData<T, S extends BaseStream<T, S>> |
| extends Iterable<T> { |
| |
| default int size() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| default Iterator<T> iterator() { |
| return Spliterators.iterator(spliterator()); |
| } |
| |
| Spliterator<T> spliterator(); |
| |
| default boolean isOrdered() { |
| return spliterator().hasCharacteristics(Spliterator.ORDERED); |
| } |
| |
| StreamShape getShape(); |
| |
| default <A extends Collection<? super T>> A into(A target) { |
| spliterator().forEachRemaining(target::add); |
| return target; |
| } |
| |
| S stream(); |
| |
| S parallelStream(); |
| |
| public interface OfRef<T> extends TestData<T, Stream<T>> { } |
| |
| public interface OfInt extends TestData<Integer, IntStream> { } |
| |
| public interface OfLong extends TestData<Long, LongStream> { } |
| |
| public interface OfDouble extends TestData<Double, DoubleStream> { } |
| |
| // @@@ Temporary garbage class to avoid triggering bugs with lambdas in static methods in interfaces |
| public static class Factory { |
| public static <T> OfRef<T> ofArray(String name, T[] array) { |
| return new AbstractTestData.RefTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(), |
| Arrays::spliterator, a -> a.length); |
| } |
| |
| public static <T> OfRef<T> ofCollection(String name, Collection<T> collection) { |
| return new AbstractTestData.RefTestData<>(name, collection, Collection::stream, Collection::parallelStream, |
| Collection::spliterator, Collection::size); |
| } |
| |
| public static <T> OfRef<T> ofSpinedBuffer(String name, SpinedBuffer<T> buffer) { |
| return new AbstractTestData.RefTestData<>(name, buffer, |
| b -> StreamSupport.stream(b.spliterator(), false), |
| b -> StreamSupport.stream(b.spliterator(), true), |
| SpinedBuffer::spliterator, |
| b -> (int) b.count()); |
| } |
| |
| public static <T> OfRef<T> ofSupplier(String name, Supplier<Stream<T>> supplier) { |
| return new AbstractTestData.RefTestData<>(name, supplier, |
| Supplier::get, |
| s -> s.get().parallel(), |
| s -> s.get().spliterator(), |
| s -> (int) s.get().spliterator().getExactSizeIfKnown()); |
| } |
| |
| public static <T> OfRef<T> ofRefNode(String name, Node<T> node) { |
| return new AbstractTestData.RefTestData<>(name, node, |
| n -> StreamSupport.stream(n::spliterator, Spliterator.SIZED | Spliterator.ORDERED, false), |
| n -> StreamSupport.stream(n::spliterator, Spliterator.SIZED | Spliterator.ORDERED, true), |
| Node::spliterator, |
| n -> (int) n.count()); |
| } |
| |
| // int factories |
| public static <T> OfInt ofArray(String name, int[] array) { |
| return new AbstractTestData.IntTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(), |
| Arrays::spliterator, a -> a.length); |
| } |
| |
| public static OfInt ofSpinedBuffer(String name, SpinedBuffer.OfInt buffer) { |
| return new AbstractTestData.IntTestData<>(name, buffer, |
| b -> StreamSupport.intStream(b.spliterator(), false), |
| b -> StreamSupport.intStream(b.spliterator(), true), |
| SpinedBuffer.OfInt::spliterator, |
| b -> (int) b.count()); |
| } |
| |
| public static OfInt ofIntSupplier(String name, Supplier<IntStream> supplier) { |
| return new AbstractTestData.IntTestData<>(name, supplier, |
| Supplier::get, |
| s -> s.get().parallel(), |
| s -> s.get().spliterator(), |
| s -> (int) s.get().spliterator().getExactSizeIfKnown()); |
| } |
| |
| public static OfInt ofNode(String name, Node.OfInt node) { |
| int characteristics = Spliterator.SIZED | Spliterator.ORDERED; |
| return new AbstractTestData.IntTestData<>(name, node, |
| n -> StreamSupport.intStream(n::spliterator, characteristics, false), |
| n -> StreamSupport.intStream(n::spliterator, characteristics, true), |
| Node.OfInt::spliterator, |
| n -> (int) n.count()); |
| } |
| |
| // long factories |
| public static <T> OfLong ofArray(String name, long[] array) { |
| return new AbstractTestData.LongTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(), |
| Arrays::spliterator, a -> a.length); |
| } |
| |
| public static OfLong ofSpinedBuffer(String name, SpinedBuffer.OfLong buffer) { |
| return new AbstractTestData.LongTestData<>(name, buffer, |
| b -> StreamSupport.longStream(b.spliterator(), false), |
| b -> StreamSupport.longStream(b.spliterator(), true), |
| SpinedBuffer.OfLong::spliterator, |
| b -> (int) b.count()); |
| } |
| |
| public static OfLong ofLongSupplier(String name, Supplier<LongStream> supplier) { |
| return new AbstractTestData.LongTestData<>(name, supplier, |
| Supplier::get, |
| s -> s.get().parallel(), |
| s -> s.get().spliterator(), |
| s -> (int) s.get().spliterator().getExactSizeIfKnown()); |
| } |
| |
| public static OfLong ofNode(String name, Node.OfLong node) { |
| int characteristics = Spliterator.SIZED | Spliterator.ORDERED; |
| return new AbstractTestData.LongTestData<>(name, node, |
| n -> StreamSupport.longStream(n::spliterator, characteristics, false), |
| n -> StreamSupport.longStream(n::spliterator, characteristics, true), |
| Node.OfLong::spliterator, |
| n -> (int) n.count()); |
| } |
| |
| // double factories |
| public static <T> OfDouble ofArray(String name, double[] array) { |
| return new AbstractTestData.DoubleTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(), |
| Arrays::spliterator, a -> a.length); |
| } |
| |
| public static OfDouble ofSpinedBuffer(String name, SpinedBuffer.OfDouble buffer) { |
| return new AbstractTestData.DoubleTestData<>(name, buffer, |
| b -> StreamSupport.doubleStream(b.spliterator(), false), |
| b -> StreamSupport.doubleStream(b.spliterator(), true), |
| SpinedBuffer.OfDouble::spliterator, |
| b -> (int) b.count()); |
| } |
| |
| public static OfDouble ofDoubleSupplier(String name, Supplier<DoubleStream> supplier) { |
| return new AbstractTestData.DoubleTestData<>(name, supplier, |
| Supplier::get, |
| s -> s.get().parallel(), |
| s -> s.get().spliterator(), |
| s -> (int) s.get().spliterator().getExactSizeIfKnown()); |
| } |
| |
| public static OfDouble ofNode(String name, Node.OfDouble node) { |
| int characteristics = Spliterator.SIZED | Spliterator.ORDERED; |
| return new AbstractTestData.DoubleTestData<>(name, node, |
| n -> StreamSupport.doubleStream(n::spliterator, characteristics, false), |
| n -> StreamSupport.doubleStream(n::spliterator, characteristics, true), |
| Node.OfDouble::spliterator, |
| n -> (int) n.count()); |
| } |
| } |
| |
| |
| abstract class AbstractTestData<T, S extends BaseStream<T, S>, |
| T_STATE, |
| T_SPLITR extends Spliterator<T>> |
| implements TestData<T, S> { |
| private final String name; |
| private final StreamShape shape; |
| protected final T_STATE state; |
| private final ToIntFunction<T_STATE> sizeFn; |
| private final Function<T_STATE, S> streamFn; |
| private final Function<T_STATE, S> parStreamFn; |
| private final Function<T_STATE, T_SPLITR> splitrFn; |
| |
| AbstractTestData(String name, |
| StreamShape shape, |
| T_STATE state, |
| Function<T_STATE, S> streamFn, |
| Function<T_STATE, S> parStreamFn, |
| Function<T_STATE, T_SPLITR> splitrFn, |
| ToIntFunction<T_STATE> sizeFn) { |
| this.name = name; |
| this.shape = shape; |
| this.state = state; |
| this.streamFn = streamFn; |
| this.parStreamFn = parStreamFn; |
| this.splitrFn = splitrFn; |
| this.sizeFn = sizeFn; |
| } |
| |
| @Override |
| public StreamShape getShape() { |
| return shape; |
| } |
| |
| @Override |
| public String toString() { |
| return getClass().getSimpleName() + "[" + name + "]"; |
| } |
| |
| @Override |
| public int size() { |
| return sizeFn.applyAsInt(state); |
| } |
| |
| @Override |
| public T_SPLITR spliterator() { |
| return splitrFn.apply(state); |
| } |
| |
| @Override |
| public S stream() { |
| return streamFn.apply(state); |
| } |
| |
| @Override |
| public S parallelStream() { |
| return parStreamFn.apply(state); |
| } |
| |
| public static class RefTestData<T, I> |
| extends AbstractTestData<T, Stream<T>, I, Spliterator<T>> |
| implements TestData.OfRef<T> { |
| |
| protected RefTestData(String name, |
| I state, |
| Function<I, Stream<T>> streamFn, |
| Function<I, Stream<T>> parStreamFn, |
| Function<I, Spliterator<T>> splitrFn, |
| ToIntFunction<I> sizeFn) { |
| super(name, StreamShape.REFERENCE, state, streamFn, parStreamFn, splitrFn, sizeFn); |
| } |
| |
| } |
| |
| static class IntTestData<I> |
| extends AbstractTestData<Integer, IntStream, I, Spliterator.OfInt> |
| implements TestData.OfInt { |
| |
| protected IntTestData(String name, |
| I state, |
| Function<I, IntStream> streamFn, |
| Function<I, IntStream> parStreamFn, |
| Function<I, Spliterator.OfInt> splitrFn, |
| ToIntFunction<I> sizeFn) { |
| super(name, StreamShape.INT_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn); |
| } |
| |
| @Override |
| public PrimitiveIterator.OfInt iterator() { |
| return Spliterators.iterator(spliterator()); |
| } |
| |
| @Override |
| public <A extends Collection<? super Integer>> A into(A target) { |
| spliterator().forEachRemaining((IntConsumer) target::add); |
| return target; |
| } |
| } |
| |
| static class LongTestData<I> |
| extends AbstractTestData<Long, LongStream, I, Spliterator.OfLong> |
| implements TestData.OfLong { |
| |
| protected LongTestData(String name, |
| I state, |
| Function<I, LongStream> streamFn, |
| Function<I, LongStream> parStreamFn, |
| Function<I, Spliterator.OfLong> splitrFn, |
| ToIntFunction<I> sizeFn) { |
| super(name, StreamShape.LONG_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn); |
| } |
| |
| @Override |
| public PrimitiveIterator.OfLong iterator() { |
| return Spliterators.iterator(spliterator()); |
| } |
| |
| @Override |
| public <A extends Collection<? super Long>> A into(A target) { |
| spliterator().forEachRemaining((LongConsumer) target::add); |
| return target; |
| } |
| } |
| |
| static class DoubleTestData<I> |
| extends AbstractTestData<Double, DoubleStream, I, Spliterator.OfDouble> |
| implements OfDouble { |
| |
| protected DoubleTestData(String name, |
| I state, |
| Function<I, DoubleStream> streamFn, |
| Function<I, DoubleStream> parStreamFn, |
| Function<I, Spliterator.OfDouble> splitrFn, |
| ToIntFunction<I> sizeFn) { |
| super(name, StreamShape.DOUBLE_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn); |
| } |
| |
| @Override |
| public PrimitiveIterator.OfDouble iterator() { |
| return Spliterators.iterator(spliterator()); |
| } |
| |
| @Override |
| public <A extends Collection<? super Double>> A into(A target) { |
| spliterator().forEachRemaining((DoubleConsumer) target::add); |
| return target; |
| } |
| } |
| } |
| } |