/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.flink.api.common.operators; import java.util.List; import org.apache.flink.annotation.Internal; import org.apache.flink.api.common.ExecutionConfig; import org.apache.flink.api.common.functions.Function; import org.apache.flink.api.common.functions.RuntimeContext; import org.apache.flink.api.common.operators.util.UserCodeWrapper; import org.apache.flink.util.Visitor; /** * Abstract superclass for for all operators that have one input like "map" or "reduce". * * @param <IN> Input type of the user function * @param <OUT> Output type of the user function * @param <FT> Type of the user function */ @Internal public abstract class SingleInputOperator<IN, OUT, FT extends Function> extends AbstractUdfOperator<OUT, FT> { /** The input which produces the data consumed by this operator. */ protected Operator<IN> input; /** The positions of the keys in the tuple. */ private final int[] keyFields; /** Semantic properties of the associated function. */ private SingleInputSemanticProperties semanticProperties = new SingleInputSemanticProperties(); // -------------------------------------------------------------------------------------------- /** * Creates a new abstract single-input operator with the given name wrapping the given user function. * * @param stub The object containing the user function. * @param keyPositions The field positions of the input records that act as keys. * @param name The given name for the operator, used in plans, logs and progress messages. */ protected SingleInputOperator(UserCodeWrapper<FT> stub, UnaryOperatorInformation<IN, OUT> operatorInfo, int[] keyPositions, String name) { super(stub, operatorInfo, name); this.keyFields = keyPositions; } /** * Creates a new abstract single-input operator with the given name wrapping the given user function. * This constructor is specialized only for operators that require no keys for their processing. * * @param stub The object containing the user function. * @param name The given name for the operator, used in plans, logs and progress messages. */ protected SingleInputOperator(UserCodeWrapper<FT> stub, UnaryOperatorInformation<IN, OUT> operatorInfo, String name) { super(stub, operatorInfo, name); this.keyFields = new int[0]; } // -------------------------------------------------------------------------------------------- /** * Gets the information about the operators input/output types. */ @Override @SuppressWarnings("unchecked") public UnaryOperatorInformation<IN, OUT> getOperatorInfo() { return (UnaryOperatorInformation<IN, OUT>) this.operatorInfo; } /** * Returns the input operator or data source, or null, if none is set. * * @return This operator's input. */ public Operator<IN> getInput() { return this.input; } /** * Removes all inputs. */ public void clearInputs() { this.input = null; } /** * Sets the given operator as the input to this operator. * * @param input The operator to use as the input. */ public void setInput(Operator<IN> input) { this.input = input; } /** * Sets the input to the union of the given operators. * * @param input The operator(s) that form the input. * @deprecated This method will be removed in future versions. Use the {@link Union} operator instead. */ @Deprecated public void setInput(Operator<IN>... input) { this.input = Operator.createUnionCascade(null, input); } /** * Sets the input to the union of the given operators. * * @param inputs The operator(s) that form the input. * @deprecated This method will be removed in future versions. Use the {@link Union} operator instead. */ @Deprecated @SuppressWarnings("unchecked") public void setInputs(List<Operator<IN>> inputs) { this.input = Operator.createUnionCascade(null, inputs.toArray(new Operator[inputs.size()])); } /** * Adds to the input the union of the given operators. * * @param input The operator(s) that form the input. * @deprecated This method will be removed in future versions. Use the {@link Union} operator instead. */ @Deprecated public void addInput(Operator<IN>... input) { this.input = Operator.createUnionCascade(this.input, input); } /** * Adds to the input the union of the given operators. * * @param inputs The operator(s) that form the input. * @deprecated This method will be removed in future versions. Use the {@link Union} operator instead. */ @Deprecated @SuppressWarnings("unchecked") public void addInput(List<Operator<IN>> inputs) { this.input = Operator.createUnionCascade(this.input, inputs.toArray(new Operator[inputs.size()])); } // -------------------------------------------------------------------------------------------- public SingleInputSemanticProperties getSemanticProperties() { return this.semanticProperties; } public void setSemanticProperties(SingleInputSemanticProperties semanticProperties) { this.semanticProperties = semanticProperties; } // -------------------------------------------------------------------------------------------- @Override public final int getNumberOfInputs() { return 1; } @Override public int[] getKeyColumns(int inputNum) { if (inputNum == 0) { return this.keyFields; } else { throw new IndexOutOfBoundsException(); } } // -------------------------------------------------------------------------------------------- /** * Accepts the visitor and applies it this instance. The visitors pre-visit method is called and, if returning * <tt>true</tt>, the visitor is recursively applied on the single input. After the recursion returned, * the post-visit method is called. * * @param visitor The visitor. * * @see org.apache.flink.util.Visitable#accept(org.apache.flink.util.Visitor) */ @Override public void accept(Visitor<Operator<?>> visitor) { if (visitor.preVisit(this)) { this.input.accept(visitor); for (Operator<?> c : this.broadcastInputs.values()) { c.accept(visitor); } visitor.postVisit(this); } } // -------------------------------------------------------------------------------------------- protected abstract List<OUT> executeOnCollections(List<IN> inputData, RuntimeContext runtimeContext, ExecutionConfig executionConfig) throws Exception; }