protected ExecutionOperator getOperator() { return this.task.getOperator(); }
private String prettyPrint(ExecutionTask task) { return task.getOperator().toString(); }
/** * Tells whether the given {@link Channel} connects a {@link LoopHeadOperator}. * * @see StageSplittingCriterion#shouldSplit(ExecutionTask, Channel, ExecutionTask) */ private static boolean isLoopHeadInvolved(ExecutionTask producer, Channel channel, ExecutionTask consumer) { return producer.getOperator().isLoopHead() || consumer.getOperator().isLoopHead(); }
void setProducer(ExecutionTask producer) { assert this.producerSlot == null || producer.getOperator() == this.producerSlot.getOwner(); this.producer = producer; }
/** * Fetches the {@link OptimizationContext.OperatorContext} for the given {@link ExecutionTask}. * * @param task the {@link ExecutionTask} * @return the {@link OptimizationContext.OperatorContext} */ private OptimizationContext.OperatorContext fetchOperatorContext(ExecutionTask task) { final OptimizationContext.OperatorContext opCtx = this.optimizationContext.getOperatorContext(task.getOperator()); if (opCtx == null) { logger.warn("No OperatorContext for {} available.", task); } return opCtx; }
/** * Try to obtain the {@link ExecutionOperator} producing this instance, either from a given {@link OutputSlot} or * a {@link ExecutionTask} that was specified as producer. * * @return the {@link ExecutionOperator} or {@code null} if none is set up */ public ExecutionOperator getProducerOperator() { if (this.producerSlot != null) { return (ExecutionOperator) this.producerSlot.getOwner(); } else if (this.producer != null) { return this.producer.getOperator(); } return null; }
/** * Tells whether the given {@link Channel} leaves or enters a loop. * * @see StageSplittingCriterion#shouldSplit(ExecutionTask, Channel, ExecutionTask) */ private static boolean isLoopBoarder(ExecutionTask producer, Channel channel, ExecutionTask consumer) { final ExecutionOperator producerOperator = producer.getOperator(); final LinkedList<LoopSubplan> producerLoopStack = producerOperator.getLoopStack(); final ExecutionOperator consumerOperator = consumer.getOperator(); final LinkedList<LoopSubplan> consumerLoopStack = consumerOperator.getLoopStack(); return !producerLoopStack.equals(consumerLoopStack); }
/** * Assign the given {@link ExecutionTask} to the given {@link InterimStage}s and set up {@link #requiredStages} * for it. */ private void assign(ExecutionTask task, InterimStage newStage) { assert task.getOperator().getPlatform().equals(newStage.getPlatform()); newStage.addTask(task); final InterimStage oldStage = this.assignedInterimStages.put(task, newStage); logger.trace("Reassigned {} from {} to {}.", task, oldStage, newStage); }
/** * Copies the consumers of the given {@code channel} into this instance. */ private void copyConsumersFrom(Channel channel) { assert channel.getOriginal() == this; for (ExecutionTask consumer : new ArrayList<>(channel.getConsumers())) { // We must take care not to copy back channels, that we already have in the original. assert this.consumers.stream() .noneMatch(existingConsumer -> existingConsumer.getOperator().equals(consumer.getOperator())) : String.format("Conflict when copying consumers from %s (%s) to %s (%s).", this, this.consumers, channel, channel.getConsumers() ); consumer.exchangeInputChannel(channel, this); } }
/** * Checks whether the given {@link ExecutionTask} is the {@link LoopHeadOperator} of the {@link #loopSubplan}. * * @param task to be checked * @return whether it is the {@link LoopHeadOperator} */ private boolean isLoopHead(ExecutionTask task) { final ExecutionOperator operator = task.getOperator(); return operator.isLoopHead() && operator.getInnermostLoop() == this.loopSubplan; }
/** * Returns the {@link OutputSlot} of the {@link ExecutionOperator} that is associated to the given {@link Channel}. * * @return the {@link OutputSlot} or {@code null} if none */ public OutputSlot<?> getOutputSlotFor(Channel channel) { // Simple implementation: linear search. for (int outputIndex = 0; outputIndex < this.getNumOuputChannels(); outputIndex++) { if (this.getOutputChannel(outputIndex) == channel) { return outputIndex < this.getOperator().getNumOutputs() ? this.getOperator().getOutput(outputIndex) : null; } } throw new IllegalArgumentException(String.format("%s does not belong to %s.", channel, this)); }
/** * Returns the {@link InputSlot} of the {@link ExecutionOperator} that is associated to the given {@link Channel}. * * @return the {@link InputSlot} or {@code null} if none */ public InputSlot<?> getInputSlotFor(Channel channel) { // Simple implementation: linear search. for (int inputIndex = 0; inputIndex < this.getNumInputChannels(); inputIndex++) { if (this.getInputChannel(inputIndex) == channel) { return inputIndex < this.getOperator().getNumInputs() ? this.getOperator().getInput(inputIndex) : null; } } throw new IllegalArgumentException(String.format("%s does not belong to %s.", channel, this)); }
/** * @return the {@link InputSlot} that is used to activate the following {@link Activator} */ protected InputSlot<?> getActivatedInput() { return this.getTargetActivator().executionTask.getOperator().getInput(this.inputIndex); }
/** * Handle a given {@code task} by expanding the {@code expandableStage} if possible. */ private void handleTaskWithoutPlatformExecution(ExecutionTask task, InterimStage expandableStage) { final Platform operatorPlatform = task.getOperator().getPlatform(); if (expandableStage != null && operatorPlatform.equals(expandableStage.getPlatform())) { this.assignTaskAndExpand(task, expandableStage); } }
/** * Sets an input {@link Channel} for this instance. Consider using {@link Channel#addConsumer(ExecutionTask, int)} * instead. */ void setInputChannel(int index, Channel channel) { assert channel == null || this.getInputChannel(index) == null : String.format("Cannot set up %s for %s@%d: There is already %s.", channel, this.getOperator(), index, this.getInputChannel(index)); this.getInputChannels()[index] = channel; }
/** * Checks if the given {@code channel} is a feedback to {@code task} (i.e., it closes a data flow cycle). */ private boolean checkIfFeedbackChannel(ExecutionTask task, Channel channel) { if (!task.getOperator().isLoopHead()) return false; final InputSlot<?> input = task.getInputSlotFor(channel); return input != null && input.isFeedback(); }
/** * Checks if the given {@code channel} is a feedforward to {@code task} (i.e., it constitutes the beginning of a data flow cycle). */ private boolean checkIfFeedforwardChannel(ExecutionTask task, Channel channel) { if (!task.getOperator().isLoopHead()) return false; final OutputSlot<?> output = task.getOutputSlotFor(channel); return output != null && output.isFeedforward(); } }
/** * Tells whether this instance is in a {@link ExecutionStageLoop} that has finished iterating. * * @return whether this instance is in a finished {@link ExecutionStageLoop} * @see #isLoopHead() */ public boolean isInFinishedLoop() { if (this.executionStageLoop == null) { return false; } final LoopHeadOperator loopHeadOperator = (LoopHeadOperator) this.executionStageLoop.getLoopHead().getLoopHeadTask().getOperator(); return loopHeadOperator.getState() == LoopHeadOperator.State.FINISHED; }
TaskActivator(ExecutionTask task, OptimizationContext.OperatorContext operatorContext, ExecutionState executionState) { assert operatorContext == null || task.getOperator() == operatorContext.getOperator() : String.format("Mismatch between %s and %s.", task, operatorContext); this.task = task; this.operatorContext = operatorContext; this.inputChannelInstances = RheemCollections.createNullFilledArrayList(this.getOperator().getNumInputs()); this.acceptFrom(executionState); }
/** * Put new {@link ChannelInstance}s to the {@link #executionState} and release input {@link ChannelInstance}s. */ private void updateExecutionState() { for (final ChannelInstance channelInstance : this.allChannelInstances) { // Capture outbound ChannelInstances. if (channelInstance.getChannel().isBetweenStages() || channelInstance.getChannel().getConsumers().stream() .anyMatch(consumer -> consumer.getOperator().isLoopHead())) { this.executionState.register(channelInstance); } // Release the ChannelInstance. channelInstance.noteDiscardedReference(true); } this.allChannelInstances.clear(); } }