/** * Finds the single input {@link Channel} of the given {@code channel}'s producing {@link ExecutionTask}. * * @param channel whose predecessor is requested * @return the preceeding {@link Channel} */ public static Channel getPredecessorChannel(Channel channel) { final ExecutionTask producer = channel.getProducer(); assert producer != null && producer.getNumInputChannels() == 1; return producer.getInputChannel(0); }
/** * Removes the given {@link Channel} as input of this instance. * * @return the former input index the {@link Channel} */ public int removeInputChannel(Channel inputChannel) { int inputIndex; for (inputIndex = 0; inputIndex < this.getNumInputChannels(); inputIndex++) { if (this.getInputChannel(inputIndex) == inputChannel) { this.getInputChannels()[inputIndex] = null; inputChannel.getConsumers().remove(this); return inputIndex; } } throw new IllegalArgumentException(String.format("%s is not an input of %s.", inputChannel, this)); }
/** * Exchanges input {@link Channel}. Will also update the {@link Channel}'s consumers appropriately. */ public void exchangeInputChannel(Channel currentChannel, Channel newChannel) { for (int inputIndex = 0; inputIndex < this.getNumInputChannels(); inputIndex++) { if (this.getInputChannel(inputIndex) == currentChannel) { currentChannel.getConsumers().remove(this); this.setInputChannel(inputIndex, null); newChannel.addConsumer(this, inputIndex); return; } } throw new IllegalArgumentException(String.format("%s is not an input of %s.", currentChannel, this)); }
/** * Accept input {@link ChannelInstance}s from the given {@link ExecutionState}. * * @param executionState provides {@link ChannelInstance}s */ private void acceptFrom(ExecutionState executionState) { for (int inputIndex = 0; inputIndex < this.task.getNumInputChannels(); inputIndex++) { final Channel channel = this.task.getInputChannel(inputIndex); final ChannelInstance channelInstance = executionState.getChannelInstance(channel); if (channelInstance != null) { this.accept(channelInstance); } } }
/** * 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)); }
/** * Determine the producing {@link OutputSlot} of this {@link Channel} that lies within a {@link RheemPlan}. * We follow non-RheemPlan {@link ExecutionOperator}s because they should merely forward data. */ public static OutputSlot<?> findRheemPlanOutputSlotFor(Channel openChannel) { OutputSlot<?> producerOutput = null; Channel tracedChannel = openChannel; do { final ExecutionTask producer = tracedChannel.getProducer(); final ExecutionOperator producerOperator = producer.getOperator(); if (!producerOperator.isAuxiliary()) { producerOutput = producer.getOutputSlotFor(tracedChannel); } else { assert producer.getNumInputChannels() == 1; tracedChannel = producer.getInputChannel(0); } } while (producerOutput == null); return producerOutput; }
final ExecutionTask producer = targetChannel.getProducer(); producer.getOperator().setContainer(sourceLoop); assert producer.getNumInputChannels() == 1 : String.format( "Glue operator %s was expected to have exactly one input channel.", producer
/** * Brings the given {@code task} into execution. */ private void execute(ExecutionTask task, OptimizationContext optimizationContext, ExecutionState executionState) { final GraphChiExecutionOperator graphChiExecutionOperator = (GraphChiExecutionOperator) task.getOperator(); ChannelInstance[] inputChannelInstances = new ChannelInstance[task.getNumInputChannels()]; for (int i = 0; i < inputChannelInstances.length; i++) { inputChannelInstances[i] = executionState.getChannelInstance(task.getInputChannel(i)); } final OptimizationContext.OperatorContext operatorContext = optimizationContext.getOperatorContext(graphChiExecutionOperator); ChannelInstance[] outputChannelInstances = new ChannelInstance[task.getNumOuputChannels()]; for (int i = 0; i < outputChannelInstances.length; i++) { outputChannelInstances[i] = task.getOutputChannel(i).createInstance(this, operatorContext, i); } long startTime = System.currentTimeMillis(); final Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> results = graphChiExecutionOperator.execute(inputChannelInstances, outputChannelInstances, operatorContext); long endTime = System.currentTimeMillis(); final Collection<ExecutionLineageNode> executionLineageNodes = results.getField0(); final Collection<ChannelInstance> producedChannelInstances = results.getField1(); for (ChannelInstance outputChannelInstance : outputChannelInstances) { if (outputChannelInstance != null) { executionState.register(outputChannelInstance); } } final PartialExecution partialExecution = this.createPartialExecution(executionLineageNodes, endTime - startTime); executionState.add(partialExecution); this.registerMeasuredCardinalities(producedChannelInstances); }