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