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 * @paramtype 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