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