--- /dev/null 2013-03-09 17:25:01.184291984 -0500
+++ new/src/share/classes/java/util/stream/Node.java 2013-03-11 17:44:01.000000000 -0400
@@ -0,0 +1,523 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
+import java.util.function.LongConsumer;
+
+/**
+ * An immutable container for describing an ordered sequence of elements of some
+ * type {@code T}.
+ *
+ *
A {@code Node} contains a fixed number of elements, which can be accessed
+ * via the {@link #count}, {@link #spliterator}, {@link #forEach},
+ * {@link #asArray}, or {@link #copyInto} methods. A {@code Node} may have zero
+ * or more child {@code Node}s; if it has no children (accessed via
+ * {@link #getChildCount} and {@link #getChild(int)}, it is considered flat
+ * or a leaf; if it has children, it is considered an
+ * internal node. The size of an internal node is the sum of sizes of
+ * its children.
+ *
+ * @apiNote
+ *
A {@code Node} typically does not store the elements directly, but instead
+ * mediates access to one or more existing (effectively immutable) data
+ * structures such as a {@code Collection}, array, or a set of other
+ * {@code Node}s. {@code Node}s directly representing existing data structures
+ * are considered flat (have no children); commonly {@code Node}s are
+ * formed into a tree whose shape corresponds to the computation tree that
+ * produced the elements that are contained in the leaf nodes. The use of
+ * {@code Node} within the stream framework is largely to avoid copying data
+ * unnecessarily during parallel operations.
+ *
+ * @param the type of elements.
+ * @since 1.8
+ */
+interface Node {
+
+ /**
+ * Returns a {@link Spliterator} describing the elements contained in this
+ * {@code Node}.
+ *
+ * @return a {@code Spliterator describing the elements contained in this
+ * {@code Node}.
+ */
+ Spliterator spliterator();
+
+ /**
+ * Traverses the elements of this node, and invoke the provided
+ * {@code Consumer} with each element.
+ *
+ * @param consumer A {@code Consumer} that is to be invoked with each
+ * element in this {@code Node}
+ */
+ void forEach(Consumer super T> consumer);
+
+ /**
+ * Returns the number of child nodes of this node.
+ *
+ * @implSpec The default implementation returns zero
+ * @return the number of child nodes
+ */
+ default int getChildCount() {
+ return 0;
+ }
+
+ /**
+ * Retrieves the child {@code Node} at a given index.
+ *
+ * @implSpec The default implementation throws
+ * {@code IndexOutOfBoundsException}
+ * @param i the index to the child node
+ * @return the child node
+ * @throws IndexOutOfBoundsException if the index is less than 0 or greater
+ * than or equal to the
+ * number of child nodes.
+ */
+ default Node getChild(int i) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ /**
+ * Views this node as an array.
+ *
+ * Depending on the underlying implementation this may return a reference
+ * to an internal array rather than a copy. It is the callers
+ * responsibility to decide if either this node or the array is utilized as
+ * the primary reference for the data.
+ *
+ * @return an array containing the contents of this {@code Node}
+ */
+ T[] asArray(IntFunction generator);
+
+ /**
+ * Copies the content of this {@code Node} into an array, starting at a given
+ * offset into the array. It is the caller's responsibility to ensure there
+ * is sufficient room in the array.
+ *
+ * @param array the array into which to copy the contents of this
+ * {@code Node}
+ * @param offset the starting offset within the array
+ * @throws IndexOutOfBoundsException if copying would cause access of data
+ * outside array bounds
+ * @throws NullPointerException if {@code array} is {@code null}
+ */
+ void copyInto(T[] array, int offset);
+
+ /**
+ * Gets the {@code StreamShape} associated with this {@code Node}.
+ *
+ * @implSpec The default in {@code Node} returns
+ * {@code StreamShape.REFERENCE}
+ * @return the stream shape associated with this node
+ */
+ default StreamShape getShape() {
+ return StreamShape.REFERENCE;
+ }
+
+ /**
+ * Returns the number of elements contained in this node
+ *
+ * @return the number of elements contained in this node
+ */
+ long count();
+
+ /**
+ * A mutable builder for a {@code Node} that implements {@link Sink}, which
+ * builds a flat node containing the elements that have been pushed to it.
+ *
+ */
+ interface Builder extends Sink {
+
+ /**
+ * Builds the node. Should be called after all elements have been pushed
+ * and signalled with an invocation of {@link Sink#end()}.
+ *
+ * @return the resulting {@code Node}
+ */
+ Node build();
+
+ /** Specialized @{code Node.Builder} for int elements */
+ interface OfInt extends Node.Builder, Sink.OfInt {
+ @Override
+ Node.OfInt build();
+ }
+
+ /** Specialized @{code Node.Builder} for long elements */
+ interface OfLong extends Node.Builder, Sink.OfLong {
+ @Override
+ Node.OfLong build();
+ }
+
+ /** Specialized @{code Node.Builder} for double elements */
+ interface OfDouble extends Node.Builder, Sink.OfDouble {
+ @Override
+ Node.OfDouble build();
+ }
+ }
+
+ /** Specialized {@code Node} for int elements */
+ interface OfInt extends Node {
+
+ /**
+ * {@inheritDoc}
+ * @return A {@link Spliterator.OfInt} describing the elements of this
+ * node
+ */
+ @Override
+ Spliterator.OfInt spliterator();
+
+ /**
+ * {@inheritDoc}
+ * @param consumer A {@code Consumer} that is to be invoked with each
+ * element in this {@code Node}. If this is an
+ * {@code IntConsumer}, it is cast to {@code IntConsumer} so the
+ * elements may be processed without boxing.
+ */
+ @Override
+ default void forEach(Consumer super Integer> consumer) {
+ if (consumer instanceof IntConsumer) {
+ forEach((IntConsumer) consumer);
+ }
+ else {
+ if (Tripwire.ENABLED)
+ Tripwire.trip(getClass(), "{0} calling Node.OfInt.forEach(Consumer)");
+ spliterator().forEach(consumer);
+ }
+ }
+
+ /**
+ * Traverses the elements of this node, and invoke the provided
+ * {@code IntConsumer} with each element.
+ *
+ * @param consumer A {@code IntConsumer} that is to be invoked with each
+ * element in this {@code Node}
+ */
+ void forEach(IntConsumer consumer);
+
+ /**
+ * {@inheritDoc}
+ * @implSpec the default implementation invokes the generator to create
+ * an instance of an Integer[] array with a length of {@link #count()}
+ * and then invokes {@link #copyInto(Integer[], int)} with that
+ * Integer[] array at an offset of 0. This is not efficient and it is
+ * recommended to invoke {@link #asIntArray()}.
+ */
+ @Override
+ default Integer[] asArray(IntFunction generator) {
+ Integer[] boxed = generator.apply((int) count());
+ copyInto(boxed, 0);
+ return boxed;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @implSpec the default implementation invokes {@link #asIntArray()} to
+ * obtain an int[] array then and copies the elements from that int[]
+ * array into the boxed Integer[] array. This is not efficient and it
+ * is recommended to invoke {@link #copyInto(int[], int)}.
+ */
+ @Override
+ default void copyInto(Integer[] boxed, int offset) {
+ if (Tripwire.ENABLED)
+ Tripwire.trip(getClass(), "{0} calling Node.OfInt.copyInto(Integer[], int)");
+
+ int[] array = asIntArray();
+ for (int i = 0; i < array.length; i++) {
+ boxed[offset + i] = array[i];
+ }
+ }
+
+ @Override
+ default Node.OfInt getChild(int i) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ /**
+ * Views this node as an int[] array.
+ *
+ * Depending on the underlying implementation this may return a
+ * reference to an internal array rather than a copy. It is the callers
+ * responsibility to decide if either this node or the array is utilized
+ * as the primary reference for the data.
+ *
+ * @return an array containing the contents of this {@code Node}
+ */
+ int[] asIntArray();
+
+ /**
+ * Copies the content of this {@code Node} into an int[] array, starting
+ * at a given offset into the array. It is the caller's responsibility
+ * to ensure there is sufficient room in the array.
+ *
+ * @param array the array into which to copy the contents of this {@code Node}
+ * @param offset the starting offset within the array
+ * @throws IndexOutOfBoundsException if copying would cause access of
+ * data outside array bounds
+ * @throws NullPointerException if {@code array} is {@code null}
+ */
+ void copyInto(int[] array, int offset);
+
+ /**
+ * {@inheritDoc}
+ * @implSpec The default in {@code Node.OfInt} returns
+ * {@code StreamShape.INT_VALUE}
+ */
+ default StreamShape getShape() {
+ return StreamShape.INT_VALUE;
+ }
+ }
+
+ /** Specialized {@code Node} for long elements */
+ interface OfLong extends Node {
+
+ /**
+ * {@inheritDoc}
+ * @return A {@link Spliterator.OfLong} describing the elements of this
+ * node
+ */
+ @Override
+ Spliterator.OfLong spliterator();
+
+ /**
+ * {@inheritDoc}
+ * @param consumer A {@code Consumer} that is to be invoked with each
+ * element in this {@code Node}. If this is an
+ * {@code LongConsumer}, it is cast to {@code LongConsumer} so
+ * the elements may be processed without boxing.
+ */
+ @Override
+ default void forEach(Consumer super Long> consumer) {
+ if (consumer instanceof LongConsumer) {
+ forEach((LongConsumer) consumer);
+ }
+ else {
+ if (Tripwire.ENABLED)
+ Tripwire.trip(getClass(), "{0} calling Node.OfLong.forEach(Consumer)");
+ spliterator().forEach(consumer);
+ }
+ }
+
+ /**
+ * Traverses the elements of this node, and invoke the provided
+ * {@code LongConsumer} with each element.
+ *
+ * @param consumer A {@code LongConsumer} that is to be invoked with
+ * each element in this {@code Node}
+ */
+ void forEach(LongConsumer consumer);
+
+ /**
+ * {@inheritDoc}
+ * @implSpec the default implementation invokes the generator to create
+ * an instance of a Long[] array with a length of {@link #count()} and
+ * then invokes {@link #copyInto(Long[], int)} with that Long[] array at
+ * an offset of 0. This is not efficient and it is recommended to
+ * invoke {@link #asLongArray()}.
+ */
+ @Override
+ default Long[] asArray(IntFunction generator) {
+ Long[] boxed = generator.apply((int) count());
+ copyInto(boxed, 0);
+ return boxed;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @implSpec the default implementation invokes {@link #asLongArray()}
+ * to obtain a long[] array then and copies the elements from that
+ * long[] array into the boxed Long[] array. This is not efficient and
+ * it is recommended to invoke {@link #copyInto(long[], int)}.
+ */
+ @Override
+ default void copyInto(Long[] boxed, int offset) {
+ if (Tripwire.ENABLED)
+ Tripwire.trip(getClass(), "{0} calling Node.OfInt.copyInto(Long[], int)");
+
+ long[] array = asLongArray();
+ for (int i = 0; i < array.length; i++) {
+ boxed[offset + i] = array[i];
+ }
+ }
+
+ @Override
+ default Node.OfLong getChild(int i) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ /**
+ * Views this node as a long[] array.
+ *
+ * Depending on the underlying implementation this may return a
+ * reference to an internal array rather than a copy. It is the callers
+ * responsibility to decide if either this node or the array is utilized
+ * as the primary reference for the data.
+ *
+ * @return an array containing the contents of this {@code Node}
+ */
+ long[] asLongArray();
+
+ /**
+ * Copies the content of this {@code Node} into a long[] array, starting
+ * at a given offset into the array. It is the caller's responsibility
+ * to ensure there is sufficient room in the array.
+ *
+ * @param array the array into which to copy the contents of this
+ * {@code Node}
+ * @param offset the starting offset within the array
+ * @throws IndexOutOfBoundsException if copying would cause access of
+ * data outside array bounds
+ * @throws NullPointerException if {@code array} is {@code null}
+ */
+ void copyInto(long[] array, int offset);
+
+ /**
+ * {@inheritDoc}
+ * @implSpec The default in {@code Node.OfLong} returns
+ * {@code StreamShape.LONG_VALUE}
+ */
+ default StreamShape getShape() {
+ return StreamShape.LONG_VALUE;
+ }
+ }
+
+ /** Specialized {@code Node} for double elements */
+ interface OfDouble extends Node {
+
+ /**
+ * {@inheritDoc}
+ * @return A {@link Spliterator.OfDouble} describing the elements of
+ * this node
+ */
+ @Override
+ Spliterator.OfDouble spliterator();
+
+ /**
+ * {@inheritDoc}
+ * @param consumer A {@code Consumer} that is to be invoked with each
+ * element in this {@code Node}. If this is an
+ * {@code DoubleConsumer}, it is cast to {@code DoubleConsumer}
+ * so the elements may be processed without boxing.
+ */
+ @Override
+ default void forEach(Consumer super Double> consumer) {
+ if (consumer instanceof DoubleConsumer) {
+ forEach((DoubleConsumer) consumer);
+ }
+ else {
+ if (Tripwire.ENABLED)
+ Tripwire.trip(getClass(), "{0} calling Node.OfLong.forEach(Consumer)");
+ spliterator().forEach(consumer);
+ }
+ }
+
+ /**
+ * Traverses the elements of this node, and invoke the provided
+ * {@code DoubleConsumer} with each element.
+ *
+ * @param consumer A {@code DoubleConsumer} that is to be invoked with
+ * each element in this {@code Node}
+ */
+ void forEach(DoubleConsumer consumer);
+
+ //
+
+ /**
+ * {@inheritDoc}
+ * @implSpec the default implementation invokes the generator to create
+ * an instance of a Double[] array with a length of {@link #count()} and
+ * then invokes {@link #copyInto(Double[], int)} with that Double[]
+ * array at an offset of 0. This is not efficient and it is recommended
+ * to invoke {@link #asDoubleArray()}.
+ */
+ @Override
+ default Double[] asArray(IntFunction generator) {
+ Double[] boxed = generator.apply((int) count());
+ copyInto(boxed, 0);
+ return boxed;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @implSpec the default implementation invokes {@link #asDoubleArray()}
+ * to obtain a double[] array then and copies the elements from that
+ * double[] array into the boxed Double[] array. This is not efficient
+ * and it is recommended to invoke {@link #copyInto(double[], int)}.
+ */
+ @Override
+ default void copyInto(Double[] boxed, int offset) {
+ if (Tripwire.ENABLED)
+ Tripwire.trip(getClass(), "{0} calling Node.OfDouble.copyInto(Double[], int)");
+
+ double[] array = asDoubleArray();
+ for (int i = 0; i < array.length; i++) {
+ boxed[offset + i] = array[i];
+ }
+ }
+
+ @Override
+ default Node.OfDouble getChild(int i) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ /**
+ * Views this node as a double[] array.
+ *
+ * Depending on the underlying implementation this may return a
+ * reference to an internal array rather than a copy. It is the callers
+ * responsibility to decide if either this node or the array is utilized
+ * as the primary reference for the data.
+ *
+ * @return an array containing the contents of this {@code Node}
+ */
+ double[] asDoubleArray();
+
+ /**
+ * Copies the content of this {@code Node} into a double[] array, starting
+ * at a given offset into the array. It is the caller's responsibility
+ * to ensure there is sufficient room in the array.
+ *
+ * @param array the array into which to copy the contents of this
+ * {@code Node}
+ * @param offset the starting offset within the array
+ * @throws IndexOutOfBoundsException if copying would cause access of
+ * data outside array bounds
+ * @throws NullPointerException if {@code array} is {@code null}
+ */
+ void copyInto(double[] array, int offset);
+
+ /**
+ * {@inheritDoc}
+ * @implSpec The default in {@code Node.OfDouble} returns
+ * {@code StreamShape.DOUBLE_VALUE}
+ */
+ default StreamShape getShape() {
+ return StreamShape.DOUBLE_VALUE;
+ }
+ }
+}