1 /* 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.util.stream; 26 27 import java.util.Arrays; 28 import java.util.Collection; 29 import java.util.Iterator; 30 import java.util.PrimitiveIterator; 31 import java.util.Spliterator; 32 import java.util.Spliterators; 33 import java.util.function.DoubleConsumer; 34 import java.util.function.Function; 35 import java.util.function.IntConsumer; 36 import java.util.function.LongConsumer; 37 import java.util.function.Supplier; 38 import java.util.function.ToIntFunction; 39 40 /** Describes a test data set for use in stream tests */ 41 public interface TestData<T, S extends BaseStream<T, S>> 42 extends Iterable<T> { 43 44 default int size() { 45 throw new UnsupportedOperationException(); 46 } 47 48 @Override 49 default Iterator<T> iterator() { 50 return Spliterators.iteratorFromSpliterator(spliterator()); 51 } 52 53 Spliterator<T> spliterator(); 54 55 default boolean isOrdered() { 56 return spliterator().hasCharacteristics(Spliterator.ORDERED); 57 } 58 59 StreamShape getShape(); 60 61 default <A extends Collection<? super T>> A into(A target) { 62 spliterator().forEachRemaining(target::add); 63 return target; 64 } 65 66 S stream(); 67 68 S parallelStream(); 69 70 public interface OfRef<T> extends TestData<T, Stream<T>> { } 71 72 public interface OfInt extends TestData<Integer, IntStream> { } 73 74 public interface OfLong extends TestData<Long, LongStream> { } 75 76 public interface OfDouble extends TestData<Double, DoubleStream> { } 77 78 // @@@ Temporary garbage class to avoid triggering bugs with lambdas in static methods in interfaces 79 public static class Factory { 80 public static <T> OfRef<T> ofArray(String name, T[] array) { 81 return new AbstractTestData.RefTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(), 82 Arrays::spliterator, a -> a.length); 83 } 84 85 public static <T> OfRef<T> ofCollection(String name, Collection<T> collection) { 86 return new AbstractTestData.RefTestData<>(name, collection, Collection::stream, Collection::parallelStream, 87 Collection::spliterator, Collection::size); 88 } 89 90 public static <T> OfRef<T> ofSpinedBuffer(String name, SpinedBuffer<T> buffer) { 91 return new AbstractTestData.RefTestData<>(name, buffer, 92 b -> StreamSupport.stream(b.spliterator()), 93 b -> StreamSupport.parallelStream(b.spliterator()), 94 SpinedBuffer::spliterator, 95 b -> (int) b.count()); 96 } 97 98 public static <T> OfRef<T> ofSupplier(String name, Supplier<Stream<T>> supplier) { 99 return new AbstractTestData.RefTestData<>(name, supplier, 100 Supplier::get, 101 s -> s.get().parallel(), 102 s -> s.get().spliterator(), 103 s -> (int) s.get().spliterator().getExactSizeIfKnown()); 104 } 105 106 public static <T> OfRef<T> ofRefNode(String name, Node<T> node) { 107 return new AbstractTestData.RefTestData<>(name, node, 108 n -> StreamSupport.stream(n::spliterator, Spliterator.SIZED | Spliterator.ORDERED), 109 n -> StreamSupport.parallelStream(n::spliterator, Spliterator.SIZED | Spliterator.ORDERED), 110 Node::spliterator, 111 n -> (int) n.count()); 112 } 113 114 // int factories 115 public static <T> OfInt ofArray(String name, int[] array) { 116 return new AbstractTestData.IntTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(), 117 Arrays::spliterator, a -> a.length); 118 } 119 120 public static OfInt ofSpinedBuffer(String name, SpinedBuffer.OfInt buffer) { 121 return new AbstractTestData.IntTestData<>(name, buffer, 122 b -> StreamSupport.intStream(b.spliterator()), 123 b -> StreamSupport.intParallelStream(b.spliterator()), 124 SpinedBuffer.OfInt::spliterator, 125 b -> (int) b.count()); 126 } 127 128 public static OfInt ofIntSupplier(String name, Supplier<IntStream> supplier) { 129 return new AbstractTestData.IntTestData<>(name, supplier, 130 Supplier::get, 131 s -> s.get().parallel(), 132 s -> s.get().spliterator(), 133 s -> (int) s.get().spliterator().getExactSizeIfKnown()); 134 } 135 136 public static OfInt ofNode(String name, Node.OfInt node) { 137 int characteristics = Spliterator.SIZED | Spliterator.ORDERED; 138 return new AbstractTestData.IntTestData<>(name, node, 139 n -> StreamSupport.intStream(n::spliterator, characteristics), 140 n -> StreamSupport.intParallelStream(n::spliterator, characteristics), 141 Node.OfInt::spliterator, 142 n -> (int) n.count()); 143 } 144 145 // long factories 146 public static <T> OfLong ofArray(String name, long[] array) { 147 return new AbstractTestData.LongTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(), 148 Arrays::spliterator, a -> a.length); 149 } 150 151 public static OfLong ofSpinedBuffer(String name, SpinedBuffer.OfLong buffer) { 152 return new AbstractTestData.LongTestData<>(name, buffer, 153 b -> StreamSupport.longStream(b.spliterator()), 154 b -> StreamSupport.longParallelStream(b.spliterator()), 155 SpinedBuffer.OfLong::spliterator, 156 b -> (int) b.count()); 157 } 158 159 public static OfLong ofLongSupplier(String name, Supplier<LongStream> supplier) { 160 return new AbstractTestData.LongTestData<>(name, supplier, 161 Supplier::get, 162 s -> s.get().parallel(), 163 s -> s.get().spliterator(), 164 s -> (int) s.get().spliterator().getExactSizeIfKnown()); 165 } 166 167 public static OfLong ofNode(String name, Node.OfLong node) { 168 int characteristics = Spliterator.SIZED | Spliterator.ORDERED; 169 return new AbstractTestData.LongTestData<>(name, node, 170 n -> StreamSupport.longStream(n::spliterator, characteristics), 171 n -> StreamSupport.longParallelStream(n::spliterator, characteristics), 172 Node.OfLong::spliterator, 173 n -> (int) n.count()); 174 } 175 176 // double factories 177 public static <T> OfDouble ofArray(String name, double[] array) { 178 return new AbstractTestData.DoubleTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(), 179 Arrays::spliterator, a -> a.length); 180 } 181 182 public static OfDouble ofSpinedBuffer(String name, SpinedBuffer.OfDouble buffer) { 183 return new AbstractTestData.DoubleTestData<>(name, buffer, 184 b -> StreamSupport.doubleStream(b.spliterator()), 185 b -> StreamSupport.doubleParallelStream(b.spliterator()), 186 SpinedBuffer.OfDouble::spliterator, 187 b -> (int) b.count()); 188 } 189 190 public static OfDouble ofDoubleSupplier(String name, Supplier<DoubleStream> supplier) { 191 return new AbstractTestData.DoubleTestData<>(name, supplier, 192 Supplier::get, 193 s -> s.get().parallel(), 194 s -> s.get().spliterator(), 195 s -> (int) s.get().spliterator().getExactSizeIfKnown()); 196 } 197 198 public static OfDouble ofNode(String name, Node.OfDouble node) { 199 int characteristics = Spliterator.SIZED | Spliterator.ORDERED; 200 return new AbstractTestData.DoubleTestData<>(name, node, 201 n -> StreamSupport.doubleStream(n::spliterator, characteristics), 202 n -> StreamSupport.doubleParallelStream(n::spliterator, characteristics), 203 Node.OfDouble::spliterator, 204 n -> (int) n.count()); 205 } 206 } 207 208 209 abstract class AbstractTestData<T, S extends BaseStream<T, S>, 210 T_STATE, 211 T_SPLITR extends Spliterator<T>> 212 implements TestData<T, S> { 213 private final String name; 214 private final StreamShape shape; 215 protected final T_STATE state; 216 private final ToIntFunction<T_STATE> sizeFn; 217 private final Function<T_STATE, S> streamFn; 218 private final Function<T_STATE, S> parStreamFn; 219 private final Function<T_STATE, T_SPLITR> splitrFn; 220 221 AbstractTestData(String name, 222 StreamShape shape, 223 T_STATE state, 224 Function<T_STATE, S> streamFn, 225 Function<T_STATE, S> parStreamFn, 226 Function<T_STATE, T_SPLITR> splitrFn, 227 ToIntFunction<T_STATE> sizeFn) { 228 this.name = name; 229 this.shape = shape; 230 this.state = state; 231 this.streamFn = streamFn; 232 this.parStreamFn = parStreamFn; 233 this.splitrFn = splitrFn; 234 this.sizeFn = sizeFn; 235 } 236 237 @Override 238 public StreamShape getShape() { 239 return shape; 240 } 241 242 @Override 243 public String toString() { 244 return getClass().getSimpleName() + "[" + name + "]"; 245 } 246 247 @Override 248 public int size() { 249 return sizeFn.applyAsInt(state); 250 } 251 252 @Override 253 public T_SPLITR spliterator() { 254 return splitrFn.apply(state); 255 } 256 257 @Override 258 public S stream() { 259 return streamFn.apply(state); 260 } 261 262 @Override 263 public S parallelStream() { 264 return parStreamFn.apply(state); 265 } 266 267 public static class RefTestData<T, I> 268 extends AbstractTestData<T, Stream<T>, I, Spliterator<T>> 269 implements TestData.OfRef<T> { 270 271 protected RefTestData(String name, 272 I state, 273 Function<I, Stream<T>> streamFn, 274 Function<I, Stream<T>> parStreamFn, 275 Function<I, Spliterator<T>> splitrFn, 276 ToIntFunction<I> sizeFn) { 277 super(name, StreamShape.REFERENCE, state, streamFn, parStreamFn, splitrFn, sizeFn); 278 } 279 280 } 281 282 static class IntTestData<I> 283 extends AbstractTestData<Integer, IntStream, I, Spliterator.OfInt> 284 implements TestData.OfInt { 285 286 protected IntTestData(String name, 287 I state, 288 Function<I, IntStream> streamFn, 289 Function<I, IntStream> parStreamFn, 290 Function<I, Spliterator.OfInt> splitrFn, 291 ToIntFunction<I> sizeFn) { 292 super(name, StreamShape.INT_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn); 293 } 294 295 @Override 296 public PrimitiveIterator.OfInt iterator() { 297 return Spliterators.iteratorFromSpliterator(spliterator()); 298 } 299 300 @Override 301 public <A extends Collection<? super Integer>> A into(A target) { 302 spliterator().forEachRemaining((IntConsumer) target::add); 303 return target; 304 } 305 } 306 307 static class LongTestData<I> 308 extends AbstractTestData<Long, LongStream, I, Spliterator.OfLong> 309 implements TestData.OfLong { 310 311 protected LongTestData(String name, 312 I state, 313 Function<I, LongStream> streamFn, 314 Function<I, LongStream> parStreamFn, 315 Function<I, Spliterator.OfLong> splitrFn, 316 ToIntFunction<I> sizeFn) { 317 super(name, StreamShape.LONG_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn); 318 } 319 320 @Override 321 public PrimitiveIterator.OfLong iterator() { 322 return Spliterators.iteratorFromSpliterator(spliterator()); 323 } 324 325 @Override 326 public <A extends Collection<? super Long>> A into(A target) { 327 spliterator().forEachRemaining((LongConsumer) target::add); 328 return target; 329 } 330 } 331 332 static class DoubleTestData<I> 333 extends AbstractTestData<Double, DoubleStream, I, Spliterator.OfDouble> 334 implements OfDouble { 335 336 protected DoubleTestData(String name, 337 I state, 338 Function<I, DoubleStream> streamFn, 339 Function<I, DoubleStream> parStreamFn, 340 Function<I, Spliterator.OfDouble> splitrFn, 341 ToIntFunction<I> sizeFn) { 342 super(name, StreamShape.DOUBLE_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn); 343 } 344 345 @Override 346 public PrimitiveIterator.OfDouble iterator() { 347 return Spliterators.iteratorFromSpliterator(spliterator()); 348 } 349 350 @Override 351 public <A extends Collection<? super Double>> A into(A target) { 352 spliterator().forEachRemaining((DoubleConsumer) target::add); 353 return target; 354 } 355 } 356 } 357 }