1ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin/*
2ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
5ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * This code is free software; you can redistribute it and/or modify it
6ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * under the terms of the GNU General Public License version 2 only, as
7ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * published by the Free Software Foundation.  Oracle designates this
8ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * particular file as subject to the "Classpath" exception as provided
9ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * by Oracle in the LICENSE file that accompanied this code.
10ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
11ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * This code is distributed in the hope that it will be useful, but WITHOUT
12ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * version 2 for more details (a copy is included in the LICENSE file that
15ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * accompanied this code).
16ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
17ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * You should have received a copy of the GNU General Public License version
18ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 2 along with this work; if not, write to the Free Software Foundation,
19ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
21ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * or visit www.oracle.com if you need additional information or have any
23ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * questions.
24ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */
25ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinpackage java.util.stream;
26ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
27ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Spliterator;
28ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.IntFunction;
29ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
30ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin/**
31ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Helper class for executing <a href="package-summary.html#StreamOps">
32ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * stream pipelines</a>, capturing all of the information about a stream
33ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * pipeline (output shape, intermediate operations, stream flags, parallelism,
34ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * etc) in one place.
35ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
36ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>
37ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * A {@code PipelineHelper} describes the initial segment of a stream pipeline,
38ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * including its source, intermediate operations, and may additionally
39ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * incorporate information about the terminal (or stateful) operation which
40ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * follows the last intermediate operation described by this
41ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@code PipelineHelper}. The {@code PipelineHelper} is passed to the
42ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@link TerminalOp#evaluateParallel(PipelineHelper, java.util.Spliterator)},
43ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@link TerminalOp#evaluateSequential(PipelineHelper, java.util.Spliterator)},
44ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * and {@link AbstractPipeline#opEvaluateParallel(PipelineHelper, java.util.Spliterator,
45ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * java.util.function.IntFunction)}, methods, which can use the
46ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@code PipelineHelper} to access information about the pipeline such as
47ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * head shape, stream flags, and size, and use the helper methods
48ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * such as {@link #wrapAndCopyInto(Sink, Spliterator)},
49ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@link #copyInto(Sink, Spliterator)}, and {@link #wrapSink(Sink)} to execute
50ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * pipeline operations.
51ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
52ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param  type of output elements from the pipeline
53ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @since 1.8
54289e51c2258b001f2aa6d6e67b21be7bb65d5102Igor Murashkin * @hide Visible for CTS testing only (OpenJDK8 tests).
55ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */
56289e51c2258b001f2aa6d6e67b21be7bb65d5102Igor Murashkinpublic abstract class PipelineHelper<P_OUT> {
57ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
58ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
59ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Gets the stream shape for the source of the pipeline segment.
60ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
61ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return the stream shape for the source of the pipeline segment.
62ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
63ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    abstract StreamShape getSourceShape();
64ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
65ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
66ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Gets the combined stream and operation flags for the output of the described
67ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * pipeline.  This will incorporate stream flags from the stream source, all
68ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * the intermediate operations and the terminal operation.
69ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
70ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return the combined stream and operation flags
71ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @see StreamOpFlag
72ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
73289e51c2258b001f2aa6d6e67b21be7bb65d5102Igor Murashkin    public abstract int getStreamAndOpFlags();
74ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
75ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
76ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Returns the exact output size of the portion of the output resulting from
77ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * applying the pipeline stages described by this {@code PipelineHelper} to
78ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * the the portion of the input described by the provided
79ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code Spliterator}, if known.  If not known or known infinite, will
80ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * return {@code -1}.
81ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
82ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @apiNote
83ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * The exact output size is known if the {@code Spliterator} has the
84ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code SIZED} characteristic, and the operation flags
85ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@link StreamOpFlag#SIZED} is known on the combined stream and operation
86ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * flags.
87ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
88ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param spliterator the spliterator describing the relevant portion of the
89ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *        source data
90ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return the exact size if known, or -1 if infinite or unknown
91ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
92ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    abstract<P_IN> long exactOutputSizeIfKnown(Spliterator<P_IN> spliterator);
93ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
94ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
95ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Applies the pipeline stages described by this {@code PipelineHelper} to
96ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * the provided {@code Spliterator} and send the results to the provided
97ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code Sink}.
98ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
99ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @implSpec
100ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * The implementation behaves as if:
101ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * <pre>{@code
102ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *     intoWrapped(wrapSink(sink), spliterator);
103ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * }</pre>
104ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
105ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param sink the {@code Sink} to receive the results
106ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param spliterator the spliterator describing the source input to process
107ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
108ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    abstract<P_IN, S extends Sink<P_OUT>> S wrapAndCopyInto(S sink, Spliterator<P_IN> spliterator);
109ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
110ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
111ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Pushes elements obtained from the {@code Spliterator} into the provided
112ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code Sink}.  If the stream pipeline is known to have short-circuiting
113ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * stages in it (see {@link StreamOpFlag#SHORT_CIRCUIT}), the
114ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@link Sink#cancellationRequested()} is checked after each
115ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * element, stopping if cancellation is requested.
116ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
117ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @implSpec
118ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * This method conforms to the {@code Sink} protocol of calling
119ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code Sink.begin} before pushing elements, via {@code Sink.accept}, and
120ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * calling {@code Sink.end} after all elements have been pushed.
121ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
122ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param wrappedSink the destination {@code Sink}
123ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param spliterator the source {@code Spliterator}
124ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
125ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    abstract<P_IN> void copyInto(Sink<P_IN> wrappedSink, Spliterator<P_IN> spliterator);
126ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
127ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
128ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Pushes elements obtained from the {@code Spliterator} into the provided
129ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code Sink}, checking {@link Sink#cancellationRequested()} after each
130ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * element, and stopping if cancellation is requested.
131ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
132ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @implSpec
133ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * This method conforms to the {@code Sink} protocol of calling
134ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code Sink.begin} before pushing elements, via {@code Sink.accept}, and
135ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * calling {@code Sink.end} after all elements have been pushed or if
136ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * cancellation is requested.
137ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
138ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param wrappedSink the destination {@code Sink}
139ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param spliterator the source {@code Spliterator}
140ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
141ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    abstract <P_IN> void copyIntoWithCancel(Sink<P_IN> wrappedSink, Spliterator<P_IN> spliterator);
142ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
143ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
144ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Takes a {@code Sink} that accepts elements of the output type of the
145ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code PipelineHelper}, and wrap it with a {@code Sink} that accepts
146ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * elements of the input type and implements all the intermediate operations
147ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * described by this {@code PipelineHelper}, delivering the result into the
148ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * provided {@code Sink}.
149ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
150ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param sink the {@code Sink} to receive the results
151ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return a {@code Sink} that implements the pipeline stages and sends
152ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *         results to the provided {@code Sink}
153ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
154289e51c2258b001f2aa6d6e67b21be7bb65d5102Igor Murashkin    public abstract<P_IN> Sink<P_IN> wrapSink(Sink<P_OUT> sink);
155ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
156ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
157ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
158ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param spliterator
159ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param 
160ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return
161ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
162ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    abstract<P_IN> Spliterator<P_OUT> wrapSpliterator(Spliterator<P_IN> spliterator);
163ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
164ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
165ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Constructs a @{link Node.Builder} compatible with the output shape of
166ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * this {@code PipelineHelper}.
167ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
168ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param exactSizeIfKnown if >=0 then a builder will be created that has a
169ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *        fixed capacity of exactly sizeIfKnown elements; if < 0 then the
170ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *        builder has variable capacity.  A fixed capacity builder will fail
171ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *        if an element is added after the builder has reached capacity.
172ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param generator a factory function for array instances
173ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return a {@code Node.Builder} compatible with the output shape of this
174ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *         {@code PipelineHelper}
175ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
176ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    abstract Node.Builder<P_OUT> makeNodeBuilder(long exactSizeIfKnown,
177ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                                                 IntFunction<P_OUT[]> generator);
178ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
179ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
180ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Collects all output elements resulting from applying the pipeline stages
181ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * to the source {@code Spliterator} into a {@code Node}.
182ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
183ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @implNote
184ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * If the pipeline has no intermediate operations and the source is backed
185ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * by a {@code Node} then that {@code Node} will be returned (or flattened
186ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * and then returned). This reduces copying for a pipeline consisting of a
187ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * stateful operation followed by a terminal operation that returns an
188ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * array, such as:
189ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * <pre>{@code
190ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *     stream.sorted().toArray();
191ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * }</pre>
192ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
193ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param spliterator the source {@code Spliterator}
194ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param flatten if true and the pipeline is a parallel pipeline then the
195ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *        {@code Node} returned will contain no children, otherwise the
196ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *        {@code Node} may represent the root in a tree that reflects the
197ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *        shape of the computation tree.
198ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param generator a factory function for array instances
199ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return the {@code Node} containing all output elements
200ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
201289e51c2258b001f2aa6d6e67b21be7bb65d5102Igor Murashkin    public abstract<P_IN> Node<P_OUT> evaluate(Spliterator<P_IN> spliterator,
202ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                                        boolean flatten,
203ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                                        IntFunction<P_OUT[]> generator);
204ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin}
205