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. 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.Spliterator; 28 import java.util.function.Consumer; 29 import java.util.function.DoubleConsumer; 30 import java.util.function.IntConsumer; 31 import java.util.function.IntFunction; 32 import java.util.function.LongConsumer; 33 34 /** 35 * An immutable container for describing an ordered sequence of elements of some 36 * type {@code T}. 37 * 38 * <p>A {@code Node} contains a fixed number of elements, which can be accessed 39 * via the {@link #count}, {@link #spliterator}, {@link #forEach}, 40 * {@link #asArray}, or {@link #copyInto} methods. A {@code Node} may have zero 41 * or more child {@code Node}s; if it has no children (accessed via 42 * {@link #getChildCount} and {@link #getChild(int)}, it is considered <em>flat 43 * </em> or a <em>leaf</em>; if it has children, it is considered an 44 * <em>internal</em> node. The size of an internal node is the sum of sizes of 45 * its children. 46 * 47 * @apiNote 48 * <p>A {@code Node} typically does not store the elements directly, but instead 49 * mediates access to one or more existing (effectively immutable) data 50 * structures such as a {@code Collection}, array, or a set of other 51 * {@code Node}s. Commonly {@code Node}s are formed into a tree whose shape 52 * corresponds to the computation tree that produced the elements that are 53 * contained in the leaf nodes. The use of {@code Node} within the stream 54 * framework is largely to avoid copying data unnecessarily during parallel 55 * operations. 56 * 57 * @param <T> the type of elements. 58 * @since 1.8 59 * @hide Visible for CTS testing only (OpenJDK8 tests). 60 */ 61 public interface Node<T> { 62 63 /** 64 * Returns a {@link Spliterator} describing the elements contained in this 65 * {@code Node}. 66 * 67 * @return a {@code Spliterator} describing the elements contained in this 68 * {@code Node} 69 */ 70 Spliterator<T> spliterator(); 71 72 /** 73 * Traverses the elements of this node, and invoke the provided 74 * {@code Consumer} with each element. Elements are provided in encounter 75 * order if the source for the {@code Node} has a defined encounter order. 76 * 77 * @param consumer a {@code Consumer} that is to be invoked with each 78 * element in this {@code Node} 79 */ 80 void forEach(Consumer<? super T> consumer); 81 82 /** 83 * Returns the number of child nodes of this node. 84 * 85 * @implSpec The default implementation returns zero. 86 * 87 * @return the number of child nodes 88 */ 89 default int getChildCount() { 90 return 0; 91 } 92 93 /** 94 * Retrieves the child {@code Node} at a given index. 95 * 96 * @implSpec The default implementation always throws 97 * {@code IndexOutOfBoundsException}. 98 * 99 * @param i the index to the child node 100 * @return the child node 101 * @throws IndexOutOfBoundsException if the index is less than 0 or greater 102 * than or equal to the number of child nodes 103 */ 104 default Node<T> getChild(int i) { 105 throw new IndexOutOfBoundsException(); 106 } 107 108 /** 109 * Return a node describing a subsequence of the elements of this node, 110 * starting at the given inclusive start offset and ending at the given 111 * exclusive end offset. 112 * 113 * @param from The (inclusive) starting offset of elements to include, must 114 * be in range 0..count(). 115 * @param to The (exclusive) end offset of elements to include, must be 116 * in range 0..count(). 117 * @param generator A function to be used to create a new array, if needed, 118 * for reference nodes. 119 * @return the truncated node 120 */ 121 default Node<T> truncate(long from, long to, IntFunction<T[]> generator) { 122 if (from == 0 && to == count()) 123 return this; 124 Spliterator<T> spliterator = spliterator(); 125 long size = to - from; 126 Node.Builder<T> nodeBuilder = Nodes.builder(size, generator); 127 nodeBuilder.begin(size); 128 for (int i = 0; i < from && spliterator.tryAdvance(e -> { }); i++) { } 129 for (int i = 0; (i < size) && spliterator.tryAdvance(nodeBuilder); i++) { } 130 nodeBuilder.end(); 131 return nodeBuilder.build(); 132 } 133 134 /** 135 * Provides an array view of the contents of this node. 136 * 137 * <p>Depending on the underlying implementation, this may return a 138 * reference to an internal array rather than a copy. Since the returned 139 * array may be shared, the returned array should not be modified. The 140 * {@code generator} function may be consulted to create the array if a new 141 * array needs to be created. 142 * 143 * @param generator a factory function which takes an integer parameter and 144 * returns a new, empty array of that size and of the appropriate 145 * array type 146 * @return an array containing the contents of this {@code Node} 147 */ 148 T[] asArray(IntFunction<T[]> generator); 149 150 /** 151 * Copies the content of this {@code Node} into an array, starting at a 152 * given offset into the array. It is the caller's responsibility to ensure 153 * there is sufficient room in the array, otherwise unspecified behaviour 154 * will occur if the array length is less than the number of elements 155 * contained in this node. 156 * 157 * @param array the array into which to copy the contents of this 158 * {@code Node} 159 * @param offset the starting offset within the array 160 * @throws IndexOutOfBoundsException if copying would cause access of data 161 * outside array bounds 162 * @throws NullPointerException if {@code array} is {@code null} 163 */ 164 void copyInto(T[] array, int offset); 165 166 /** 167 * Gets the {@code StreamShape} associated with this {@code Node}. 168 * 169 * @implSpec The default in {@code Node} returns 170 * {@code StreamShape.REFERENCE} 171 * 172 * @return the stream shape associated with this node 173 */ 174 default StreamShape getShape() { 175 return StreamShape.REFERENCE; 176 } 177 178 /** 179 * Returns the number of elements contained in this node. 180 * 181 * @return the number of elements contained in this node 182 */ 183 long count(); 184 185 /** 186 * A mutable builder for a {@code Node} that implements {@link Sink}, which 187 * builds a flat node containing the elements that have been pushed to it. 188 */ 189 interface Builder<T> extends Sink<T> { 190 191 /** 192 * Builds the node. Should be called after all elements have been 193 * pushed and signalled with an invocation of {@link Sink#end()}. 194 * 195 * @return the resulting {@code Node} 196 */ 197 Node<T> build(); 198 199 /** 200 * Specialized @{code Node.Builder} for int elements 201 */ 202 interface OfInt extends Node.Builder<Integer>, Sink.OfInt { 203 @Override 204 Node.OfInt build(); 205 } 206 207 /** 208 * Specialized @{code Node.Builder} for long elements 209 */ 210 interface OfLong extends Node.Builder<Long>, Sink.OfLong { 211 @Override 212 Node.OfLong build(); 213 } 214 215 /** 216 * Specialized @{code Node.Builder} for double elements 217 */ 218 interface OfDouble extends Node.Builder<Double>, Sink.OfDouble { 219 @Override 220 Node.OfDouble build(); 221 } 222 } 223 224 public interface OfPrimitive<T, T_CONS, T_ARR, 225 T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>, 226 T_NODE extends OfPrimitive<T, T_CONS, T_ARR, T_SPLITR, T_NODE>> 227 extends Node<T> { 228 229 /** 230 * {@inheritDoc} 231 * 232 * @return a {@link Spliterator.OfPrimitive} describing the elements of 233 * this node 234 */ 235 @Override 236 T_SPLITR spliterator(); 237 238 /** 239 * Traverses the elements of this node, and invoke the provided 240 * {@code action} with each element. 241 * 242 * @param action a consumer that is to be invoked with each 243 * element in this {@code Node.OfPrimitive} 244 */ 245 @SuppressWarnings("overloads") 246 void forEach(T_CONS action); 247 248 @Override 249 default T_NODE getChild(int i) { 250 throw new IndexOutOfBoundsException(); 251 } 252 253 T_NODE truncate(long from, long to, IntFunction<T[]> generator); 254 255 /** 256 * {@inheritDoc} 257 * 258 * @implSpec the default implementation invokes the generator to create 259 * an instance of a boxed primitive array with a length of 260 * {@link #count()} and then invokes {@link #copyInto(T[], int)} with 261 * that array at an offset of 0. 262 */ 263 @Override 264 default T[] asArray(IntFunction<T[]> generator) { 265 if (java.util.stream.Tripwire.ENABLED) 266 java.util.stream.Tripwire.trip(getClass(), "{0} calling Node.OfPrimitive.asArray"); 267 268 long size = count(); 269 if (size >= Nodes.MAX_ARRAY_SIZE) 270 throw new IllegalArgumentException(Nodes.BAD_SIZE); 271 T[] boxed = generator.apply((int) count()); 272 copyInto(boxed, 0); 273 return boxed; 274 } 275 276 /** 277 * Views this node as a primitive array. 278 * 279 * <p>Depending on the underlying implementation this may return a 280 * reference to an internal array rather than a copy. It is the callers 281 * responsibility to decide if either this node or the array is utilized 282 * as the primary reference for the data.</p> 283 * 284 * @return an array containing the contents of this {@code Node} 285 */ 286 T_ARR asPrimitiveArray(); 287 288 /** 289 * Creates a new primitive array. 290 * 291 * @param count the length of the primitive array. 292 * @return the new primitive array. 293 */ 294 T_ARR newArray(int count); 295 296 /** 297 * Copies the content of this {@code Node} into a primitive array, 298 * starting at a given offset into the array. It is the caller's 299 * responsibility to ensure there is sufficient room in the array. 300 * 301 * @param array the array into which to copy the contents of this 302 * {@code Node} 303 * @param offset the starting offset within the array 304 * @throws IndexOutOfBoundsException if copying would cause access of 305 * data outside array bounds 306 * @throws NullPointerException if {@code array} is {@code null} 307 */ 308 void copyInto(T_ARR array, int offset); 309 } 310 311 /** 312 * Specialized {@code Node} for int elements 313 */ 314 interface OfInt extends OfPrimitive<Integer, IntConsumer, int[], Spliterator.OfInt, OfInt> { 315 316 /** 317 * {@inheritDoc} 318 * 319 * @param consumer a {@code Consumer} that is to be invoked with each 320 * element in this {@code Node}. If this is an 321 * {@code IntConsumer}, it is cast to {@code IntConsumer} so the 322 * elements may be processed without boxing. 323 */ 324 @Override 325 default void forEach(Consumer<? super Integer> consumer) { 326 if (consumer instanceof IntConsumer) { 327 forEach((IntConsumer) consumer); 328 } 329 else { 330 if (Tripwire.ENABLED) 331 Tripwire.trip(getClass(), "{0} calling Node.OfInt.forEachRemaining(Consumer)"); 332 spliterator().forEachRemaining(consumer); 333 } 334 } 335 336 /** 337 * {@inheritDoc} 338 * 339 * @implSpec the default implementation invokes {@link #asPrimitiveArray()} to 340 * obtain an int[] array then and copies the elements from that int[] 341 * array into the boxed Integer[] array. This is not efficient and it 342 * is recommended to invoke {@link #copyInto(Object, int)}. 343 */ 344 @Override 345 default void copyInto(Integer[] boxed, int offset) { 346 if (Tripwire.ENABLED) 347 Tripwire.trip(getClass(), "{0} calling Node.OfInt.copyInto(Integer[], int)"); 348 349 int[] array = asPrimitiveArray(); 350 for (int i = 0; i < array.length; i++) { 351 boxed[offset + i] = array[i]; 352 } 353 } 354 355 @Override 356 default Node.OfInt truncate(long from, long to, IntFunction<Integer[]> generator) { 357 if (from == 0 && to == count()) 358 return this; 359 long size = to - from; 360 Spliterator.OfInt spliterator = spliterator(); 361 Node.Builder.OfInt nodeBuilder = Nodes.intBuilder(size); 362 nodeBuilder.begin(size); 363 for (int i = 0; i < from && spliterator.tryAdvance((IntConsumer) e -> { }); i++) { } 364 for (int i = 0; (i < size) && spliterator.tryAdvance((IntConsumer) nodeBuilder); i++) { } 365 nodeBuilder.end(); 366 return nodeBuilder.build(); 367 } 368 369 @Override 370 default int[] newArray(int count) { 371 return new int[count]; 372 } 373 374 /** 375 * {@inheritDoc} 376 * @implSpec The default in {@code Node.OfInt} returns 377 * {@code StreamShape.INT_VALUE} 378 */ 379 default StreamShape getShape() { 380 return StreamShape.INT_VALUE; 381 } 382 } 383 384 /** 385 * Specialized {@code Node} for long elements 386 */ 387 interface OfLong extends OfPrimitive<Long, LongConsumer, long[], Spliterator.OfLong, OfLong> { 388 389 /** 390 * {@inheritDoc} 391 * 392 * @param consumer A {@code Consumer} that is to be invoked with each 393 * element in this {@code Node}. If this is an 394 * {@code LongConsumer}, it is cast to {@code LongConsumer} so 395 * the elements may be processed without boxing. 396 */ 397 @Override 398 default void forEach(Consumer<? super Long> consumer) { 399 if (consumer instanceof LongConsumer) { 400 forEach((LongConsumer) consumer); 401 } 402 else { 403 if (Tripwire.ENABLED) 404 Tripwire.trip(getClass(), "{0} calling Node.OfLong.forEachRemaining(Consumer)"); 405 spliterator().forEachRemaining(consumer); 406 } 407 } 408 409 /** 410 * {@inheritDoc} 411 * 412 * @implSpec the default implementation invokes {@link #asPrimitiveArray()} 413 * to obtain a long[] array then and copies the elements from that 414 * long[] array into the boxed Long[] array. This is not efficient and 415 * it is recommended to invoke {@link #copyInto(Object, int)}. 416 */ 417 @Override 418 default void copyInto(Long[] boxed, int offset) { 419 if (Tripwire.ENABLED) 420 Tripwire.trip(getClass(), "{0} calling Node.OfInt.copyInto(Long[], int)"); 421 422 long[] array = asPrimitiveArray(); 423 for (int i = 0; i < array.length; i++) { 424 boxed[offset + i] = array[i]; 425 } 426 } 427 428 @Override 429 default Node.OfLong truncate(long from, long to, IntFunction<Long[]> generator) { 430 if (from == 0 && to == count()) 431 return this; 432 long size = to - from; 433 Spliterator.OfLong spliterator = spliterator(); 434 Node.Builder.OfLong nodeBuilder = Nodes.longBuilder(size); 435 nodeBuilder.begin(size); 436 for (int i = 0; i < from && spliterator.tryAdvance((LongConsumer) e -> { }); i++) { } 437 for (int i = 0; (i < size) && spliterator.tryAdvance((LongConsumer) nodeBuilder); i++) { } 438 nodeBuilder.end(); 439 return nodeBuilder.build(); 440 } 441 442 @Override 443 default long[] newArray(int count) { 444 return new long[count]; 445 } 446 447 /** 448 * {@inheritDoc} 449 * @implSpec The default in {@code Node.OfLong} returns 450 * {@code StreamShape.LONG_VALUE} 451 */ 452 default StreamShape getShape() { 453 return StreamShape.LONG_VALUE; 454 } 455 } 456 457 /** 458 * Specialized {@code Node} for double elements 459 */ 460 interface OfDouble extends OfPrimitive<Double, DoubleConsumer, double[], Spliterator.OfDouble, OfDouble> { 461 462 /** 463 * {@inheritDoc} 464 * 465 * @param consumer A {@code Consumer} that is to be invoked with each 466 * element in this {@code Node}. If this is an 467 * {@code DoubleConsumer}, it is cast to {@code DoubleConsumer} 468 * so the elements may be processed without boxing. 469 */ 470 @Override 471 default void forEach(Consumer<? super Double> consumer) { 472 if (consumer instanceof DoubleConsumer) { 473 forEach((DoubleConsumer) consumer); 474 } 475 else { 476 if (Tripwire.ENABLED) 477 Tripwire.trip(getClass(), "{0} calling Node.OfLong.forEachRemaining(Consumer)"); 478 spliterator().forEachRemaining(consumer); 479 } 480 } 481 482 // 483 484 /** 485 * {@inheritDoc} 486 * 487 * @implSpec the default implementation invokes {@link #asPrimitiveArray()} 488 * to obtain a double[] array then and copies the elements from that 489 * double[] array into the boxed Double[] array. This is not efficient 490 * and it is recommended to invoke {@link #copyInto(Object, int)}. 491 */ 492 @Override 493 default void copyInto(Double[] boxed, int offset) { 494 if (Tripwire.ENABLED) 495 Tripwire.trip(getClass(), "{0} calling Node.OfDouble.copyInto(Double[], int)"); 496 497 double[] array = asPrimitiveArray(); 498 for (int i = 0; i < array.length; i++) { 499 boxed[offset + i] = array[i]; 500 } 501 } 502 503 @Override 504 default Node.OfDouble truncate(long from, long to, IntFunction<Double[]> generator) { 505 if (from == 0 && to == count()) 506 return this; 507 long size = to - from; 508 Spliterator.OfDouble spliterator = spliterator(); 509 Node.Builder.OfDouble nodeBuilder = Nodes.doubleBuilder(size); 510 nodeBuilder.begin(size); 511 for (int i = 0; i < from && spliterator.tryAdvance((DoubleConsumer) e -> { }); i++) { } 512 for (int i = 0; (i < size) && spliterator.tryAdvance((DoubleConsumer) nodeBuilder); i++) { } 513 nodeBuilder.end(); 514 return nodeBuilder.build(); 515 } 516 517 @Override 518 default double[] newArray(int count) { 519 return new double[count]; 520 } 521 522 /** 523 * {@inheritDoc} 524 * 525 * @implSpec The default in {@code Node.OfDouble} returns 526 * {@code StreamShape.DOUBLE_VALUE} 527 */ 528 default StreamShape getShape() { 529 return StreamShape.DOUBLE_VALUE; 530 } 531 } 532 } 533