changeset 7324:d094d12b3a61

More Javadoc
author briangoetz
date Wed, 13 Feb 2013 16:08:58 -0500
parents a1258221db82
children 076eba2ba95c
files src/share/classes/java/util/stream/PipelineHelper.java src/share/classes/java/util/stream/Stream.java src/share/classes/java/util/stream/StreamOpFlag.java src/share/classes/java/util/stream/package-info.java
diffstat 4 files changed, 91 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/PipelineHelper.java	Wed Feb 13 18:30:02 2013 +0100
+++ b/src/share/classes/java/util/stream/PipelineHelper.java	Wed Feb 13 16:08:58 2013 -0500
@@ -28,119 +28,157 @@
 import java.util.function.IntFunction;
 
 /**
- * @param <P_IN>  Type of elements input to the pipeline.
- * @param <P_OUT> Type of elements output from the pipeline.
+ * Helper class for executing  <a href="package-summary.html#StreamPipelines">stream pipelines</a>, capturing
+ * all of the information about a stream pipeline (source, output shape, stream flags, parallelism, etc)
+ * in one place.
+ *
+ * @apiNote
+ * A stream pipeline consists of a source, zero or more intermediate operations, and a terminal operation.
+ * Execution of the stream pipeline begins when the terminal operation is executed.
+ * A {@code PipelineHelper} describes the portion of a stream pipeline including its source, some or all of its
+ * intermediate operations, and certain information about the terminal (or stateful) operation which follows
+ * the last intermediate operation described by this {@code PipelineHelper}.The
+ * {@code PipelineHelper} is passed to the {@link TerminalOp#evaluateParallel(PipelineHelper)},
+ * {@link TerminalOp#evaluateSequential(PipelineHelper)}, and {@link StatefulOp#evaluateParallel(PipelineHelper)},
+ * methods, which can use the {@code PipelineHelper} to access the source {@code Spliterator} for the pipeline,
+ * information about the pipeline such as input shape, output shape, stream flags, and size, and use the helper
+ * methods such as {@link #into(Sink, Spliterator)}, {@link #intoWrapped(Sink, Spliterator)},
+ * and {@link #wrapSink(Sink)} to execute pipeline operations.
+ *
+ * @param <P_IN>  Type of input elements to the pipeline
+ * @param <P_OUT> Type of output elements from the pipeline
  */
 interface PipelineHelper<P_IN, P_OUT> {
 
     /**
-     *
-     * @return
+     * Get the {@code StreamShape} describing the input shape of the pipeline
+     * @return The input shape of the pipeline
      */
     StreamShape getInputShape();
 
     /**
-     *
-     * @return
+     * Get the {@code StreamShape} describing the output shape of the pipeline
+     * @return The output shape of the pipeline
      */
     StreamShape getOutputShape();
 
     /**
-     * @return the combined stream and operation flags for the output of the pipeline.
+     * Get the combined stream and operation flags for the output of the pipeline.  This will incorporate
+     * stream flags from the stream source and all the intermediate operations, but not the terminal operation.
+     *
+     * @return the combined stream and operation flags for the output of the pipeline
      * @see StreamOpFlag
      */
     int getStreamAndOpFlags();
 
     /**
+     * Get the operation flags for the terminal or stateful operation that follows the last intermediate
+     * operation described by this {@code PipelineHelper}.
+     *
      * @return the operation flags for the terminal operation.
      * @see StreamOpFlag
      */
     int getTerminalOpFlags();
 
     /**
-     * @return true if the pipeline is a parallel pipeline, otherwise false and the pipeline is a sequential pipeline.
+     * Returns whether this pipeline is parallel or sequential
+     *
+     * @return true if the pipeline is a parallel pipeline, otherwise false
      */
     boolean isParallel();
 
     /**
-     * Get the spliterator for the source of hte pipeline.
+     * Get the {@code Spliterator} for the source of the pipeline.  This {@code Spliterator} reflects
+     * only the source elements, not the actions of any of the intermediate stages.
      *
-     * @return the source spliterator.
+     * @return the source spliterator
      */
     Spliterator<P_IN> sourceSpliterator();
 
     /**
-     * Returns the exact output size of the pipeline if known.
+     * Returns the exact output size of the portion of the output resulting from applying the pipeline stages
+     * described by this {@code PipelineHelper} to the the portion of the input described by the provided
+     * {@code Spliterator}, if known.  If not known or known infinite, will return {@code -1}.
      *
-     * <p>The exact output size is known if {@link Spliterator#getExactSizeIfKnown()} ()}
-     * returns a non negative value, and  {@link StreamOpFlag#SIZED} is known on the combined stream
-     * and operation flags.
+     * @apiNote
+     * The exact output size is known if the {@code Spliterator} has the {@code SIZED} characteristic,
+     * and the operation flags {@link StreamOpFlag#SIZED} is known on the combined stream and operation
+     * flags.
      *
-     * @param spliterator the spliterator.
-     * @return the exact size if known, or a negative value if infinite or unknown.
+     * @param spliterator the spliterator describing the relevant portion of the source data
+     * @return the exact size if known, or -1 if infinite or unknown
      */
     long exactOutputSizeIfKnown(Spliterator<P_IN> spliterator);
 
     /**
-     * Wrap a sink (see {@link #wrapSink(Sink)} that corresponds to the sink that
-     * accepts elements output from the pipeline, then push all elements obtained
-     * from the spliterator into that wrapped sink.
+     * Apply the pipeline stages described by this {@code PipelineHelper} to the provided {@code Spliterator} and
+     * send the results to the provided {@code Sink}.
      *
-     * @param sink the sink in which to wrap.
-     * @param spliterator the spliterator.
+     * @implSpec
+     * The implementation behaves as if:
+     * <pre>
+     *     intoWrapped(wrapSink(sink), spliterator);
+     * </pre>
+     *
+     * @param sink the {@code Sink} to receive the results
+     * @param spliterator the spliterator describing the portion of the source input to process
      */
     <S extends Sink<P_OUT>> S into(S sink, Spliterator<P_IN> spliterator);
 
     /**
-     * Push all elements obtained from the spliterator into the wrapped sink.
+     * Push elements obtained from the {@code Spliterator} into the provided {@code Sink}.  If the stream
+     * pipeline is known to have short-circuiting stages in it (see {@link StreamOpFlag#SHORT_CIRCUIT}), then the
+     * elements are delivered as per {@link #intoWrappedWithCancel(Sink, Spliterator)}.
      *
-     * @param wrappedSink the wrapped sink.
-     * @param spliterator the spliterator.
+     * @param wrappedSink the destination {@code Sink}
+     * @param spliterator the source {@code Spliterator}
      */
     void intoWrapped(Sink<P_IN> wrappedSink, Spliterator<P_IN> spliterator);
 
     /**
-     * Push elements obtained from the spliterator into the wrapped sink
-     * until the sink is cancelled or all elements have been pushed.</p>
+     * Push elements obtained from the {@code Spliterator} into the provided {@code Sink}, checking
+     * {@link Sink#cancellationRequested()} after each element, and stopping if cancellation is requested.
      *
-     * @param wrappedSink the sink to push elements to.
-     * @param spliterator the spliterator to pull elements from
+     * @param wrappedSink the destination {@code Sink}
+     * @param spliterator the source {@code Spliterator}
      */
     void intoWrappedWithCancel(Sink<P_IN> wrappedSink, Spliterator<P_IN> spliterator);
 
     /**
-     * Create a sink chain.
+     * Take a {@code Sink} that accepts elements of the output type of the {@code PipelineHelper}, and wrap it with
+     * a {@code Sink} that accepts elements of the input type and implements all the intermediate operations described
+     * by this {@code PipelineHelper}, delivering the result into the provided {@code Sink}.
      *
-     * @param sink the last sink in the chain that accepts output elements.
-     * @return the first sink in the chain that accepts input elements.
+     * @param sink the {@code Sink} to receive the results
+     * @return a {@code Sink} that implements the pipeline stages and sends results to the provided {@code Sink}
      */
     Sink<P_IN> wrapSink(Sink<P_OUT> sink);
 
     /**
-     * Make a node builder, compatible with this stream shape.
+     * Construct a @{link Node.Builder} compatible with the output shape of this {@code PipelineHelper}
      *
-     * @param exactSizeIfKnown if >=0 then a node builder will be created that has a fixed capacity of at most
-     *                         sizeIfKnown elements.
-     *                         If < 0 then the node builder has an unfixed capacity.
-     *                         A fixed capacity node builder will throw exceptions if an element is added and
-     *                         the builder has reached capacity.
-     * @return the node builder.
+     * @param exactSizeIfKnown if >=0 then a builder will be created that has a fixed capacity of exactly
+     *                         sizeIfKnown elements; if < 0 then the builder has variable capacity.
+     *                         A fixed capacity builder will fail if an element is added and the builder has reached
+     *                         capacity.
+     * @return A {@code Node.Builder} compatible with the output shape of this {@code PipelineHelper}
      */
     Node.Builder<P_OUT> makeNodeBuilder(long exactSizeIfKnown);
 
     /**
-     * Collect all output elements to a {@link Node}.
+     * Collect all output elements resulting from applying the pipeline stages to the source {@code Spliterator}
+     * into a {@code Node}.
      *
-     * @param flatten if true the Node returned will contain no children,
-     *                otherwise the Node represents the root in a tree that
-     *                reflects the computation tree.
-     * @return the node containing all output elements.
+     * @param flatten if true the {@code Node} returned will contain no children, otherwise the {@code Node} may
+     *                represent the root in a tree that reflects the shape of the computation tree.
+     * @return the {@code Node} containing all output elements
      */
     Node<P_OUT> collectOutput(boolean flatten);
 
     /**
+     * Get an array factory associated with the output type of this pipeline.
      *
-     * @return the array generator for creating an array of elements output from this pipeline.
+     * @return a factory for arrays of the output type of this pipeline.
      */
     IntFunction<P_OUT[]> arrayGenerator();
 }
--- a/src/share/classes/java/util/stream/Stream.java	Wed Feb 13 18:30:02 2013 +0100
+++ b/src/share/classes/java/util/stream/Stream.java	Wed Feb 13 16:08:58 2013 -0500
@@ -201,7 +201,7 @@
 
     Optional<T> reduce(BinaryOperator<T> reducer);
 
-        <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> reducer);
+    <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> reducer);
 
     <R> R collect(Supplier<R> resultFactory,
                   BiConsumer<R, ? super T> accumulator,
--- a/src/share/classes/java/util/stream/StreamOpFlag.java	Wed Feb 13 18:30:02 2013 +0100
+++ b/src/share/classes/java/util/stream/StreamOpFlag.java	Wed Feb 13 16:08:58 2013 -0500
@@ -54,10 +54,10 @@
  * spliterator when transformed to stream flags will be a proper subset of stream flags of that first stream.
  * For example:
  * <pre> {@code
- * Spliterator s = ...;
- * Stream stream = Streams.stream(s);
- * flagsFromSpliterator = fromCharacteristics(s.characteristics());
- * assert(flagsFromSpliterator & stream.getStreamFlags() == flagsFromSpliterator);
+ *     Spliterator s = ...;
+ *     Stream stream = Streams.stream(s);
+ *     flagsFromSpliterator = fromCharacteristics(s.characteristics());
+ *     assert(flagsFromSpliterator & stream.getStreamFlags() == flagsFromSpliterator);
  * }</pre>
  *
  * <p>
@@ -100,18 +100,18 @@
  * The upstream combined stream and operation flags of the first operation in the pipeline is calculated as
  * follows:
  * <pre> {@code
- * int flagsForFirstOp = combineOpFlags(firstStream.getStreamFlags(), INITIAL_OPS_VALUE);
+ *     int flagsForFirstOp = combineOpFlags(firstStream.getStreamFlags(), INITIAL_OPS_VALUE);
  * }</pre>
  *
  * The upstream combined stream and operation flags of the second operation in the pipeline is calculated as
  * follows:
  * <pre> {@code
- * int flagsForSecondOp = combineOpFlags(firstIntermediateOp.getOpFlags(), flagsForFirstOp);
+ *     int flagsForSecondOp = combineOpFlags(firstIntermediateOp.getOpFlags(), flagsForFirstOp);
  * }</pre>
  *
  * and so on for all the remaining operations to obtain the upstream flags output from the pipeline, as follows:
  * <pre> {@code
- * int upstreamFlagsForPipeline = combineOpFlags(lastIntermediateOp.getOpFlags(), flagsForLastOp);
+ *     int upstreamFlagsForPipeline = combineOpFlags(lastIntermediateOp.getOpFlags(), flagsForLastOp);
  * }</pre>
  *
  * For specific details see the {@link AbstractPipeline} constructors.
--- a/src/share/classes/java/util/stream/package-info.java	Wed Feb 13 18:30:02 2013 +0100
+++ b/src/share/classes/java/util/stream/package-info.java	Wed Feb 13 16:08:58 2013 -0500
@@ -57,7 +57,7 @@
  *     to complete in finite time.</li>
  * </ul>
  *
- * <h2>Stream pipelines</h2>
+ * <h2><a name="StreamPipelines">Stream pipelines</a></h2>
  *
  * <p>Streams are used to create <em>pipelines</em> of operations.  A complete stream pipeline has
  * several components: a source (which may be a {@code Collection}, an array, a generator function,