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