/** * Collect the {@link OutputSlot} of the producer and the {@link InputSlot}s of the consumers that are implemented * by this instance. * * @return a {@link Stream} of said {@link Slot}s */ private Stream<Slot<?>> getCorrespondingSlotsLocal() { final Stream<? extends OutputSlot<?>> outputSlotStream = streamNullable(this.getProducerSlot()); final Stream<? extends InputSlot<?>> inputSlotStream = this.consumers.stream().flatMap(consumer -> streamNullable(consumer.getInputSlotFor(this))); return Stream.concat(inputSlotStream, outputSlotStream); }
/** * 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(); }
/** * Registers the {@code inputChannelInstance} as input of the wrapped {@link #task}. * * @param inputChannelInstance the input {@link ChannelInstance} */ public void accept(ChannelInstance inputChannelInstance) { // Identify the input index of the inputChannelInstance wrt. the ExecutionTask. final Channel channel = inputChannelInstance.getChannel(); final int inputIndex; if (this.task.getOperator().getNumInputs() == 0) { // If we have a ChannelInstance but no InputSlots, we fall-back to index 0 as per convention. assert this.inputChannelInstances.isEmpty(); this.inputChannelInstances.add(null); inputIndex = 0; } else { final InputSlot<?> inputSlot = this.task.getInputSlotFor(channel); assert inputSlot != null : String.format("Could not identify an InputSlot in %s for %s.", this.task, inputChannelInstance); inputIndex = inputSlot.getIndex(); } // Register the inputChannelInstance (and check for conflicts). assert this.inputChannelInstances.get(inputIndex) == null : String.format("Tried to replace %s with %s as %dth input of %s.", this.inputChannelInstances.get(inputIndex), inputChannelInstance, inputIndex, this.task); this.inputChannelInstances.set(inputIndex, inputChannelInstance); inputChannelInstance.noteObtainedReference(); }
HashMap<String, Object> jsonThatOp = new HashMap<>(); jsonThatOp.put(consumer.getOperator().getName(), (consumer.getInputSlotFor(channel)==null) ? 0 : consumer.getInputSlotFor(channel).getIndex()); jsonThatOp.put("via", prettyPrint(channel)); perOutputThatList.add(jsonThatOp);
/** * Determine the consuming {@link InputSlot}s of the given {@link Channel} that lie within a {@link RheemPlan} and * have not been executed yet. * We follow non-RheemPlan {@link ExecutionOperator}s because they should merely forward data. */ private Collection<InputSlot<?>> findRheemPlanInputSlotFor(Channel channel, Set<ExecutionStage> executedStages) { Collection<InputSlot<?>> result = new LinkedList<>(); for (ExecutionTask consumerTask : channel.getConsumers()) { if (executedStages.contains(consumerTask.getStage())) continue; if (!consumerTask.getOperator().isAuxiliary()) { result.add(consumerTask.getInputSlotFor(channel)); } else { for (Channel consumerOutputChannel : consumerTask.getOutputChannels()) { result.addAll(this.findRheemPlanInputSlotFor(consumerOutputChannel, executedStages)); } } } return result; }
/** * Determines whether the given input {@link Channel} implements a feedback {@link InputSlot} of the enclosed * {@link ExecutionOperator}. * * @param inputChannel the {@link Channel} * @return whether it implements a feedback {@link InputSlot} * @see InputSlot#isFeedback() */ public boolean isFeedbackInput(Channel inputChannel) { // Check if we have a LoopHeadOperator in this instance. final ExecutionOperator operator = this.getOperator(); if (!operator.isLoopHead()) return false; // Check whether and to which InputSlot the inputChannel corresponds. final InputSlot<?> input = this.getInputSlotFor(inputChannel); if (input == null) return false; // Determine if that InputSlot is a feedback InputSlot. return input.isFeedback(); }
/** * Traverse the given {@link Channel} downstream and collect any {@link Channel} that feeds some * {@link InputSlot} of a non-conversion {@link ExecutionOperator}. * * @param channel the {@link Channel} to traverse from * @see #existingChannels * @see #existingDestinationChannels */ private void collectExistingChannels(Channel channel) { this.existingChannels.put(channel.getDescriptor(), channel); for (ExecutionTask consumer : channel.getConsumers()) { final ExecutionOperator operator = consumer.getOperator(); if (!operator.isAuxiliary()) { final InputSlot<?> input = consumer.getInputSlotFor(channel); this.existingDestinationChannels.put(input, channel); int destIndex = 0; while (this.destInputs.get(destIndex) != input) destIndex++; this.existingDestinationChannelIndices.set(destIndex); } else { for (Channel outputChannel : consumer.getOutputChannels()) { if (outputChannel != null) this.collectExistingChannels(outputChannel); } } } }
final InputSlot<?> targetInput = executionTask.getInputSlotFor(inboundChannel); if (loopHead.getLoopBodyInputs().contains(targetInput)) { this.iterationInboundChannels.add(inboundChannel);