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 }