/** * Checks if the given {@link Channel} (inbound to {@link #stage}), is entering an {@link ExecutionStageLoop} * when serving the {@link #stage}. * * @param inboundChannel {@link Channel} that is inbound to {@link #stage} and that might be a {@link ExecutionStageLoop} input * @return whether the {@link Channel} is a {@link ExecutionStageLoop} input, i.e., it is not produced in an {@link ExecutionStageLoop} * while this {@link #stage} is part of a {@link ExecutionStageLoop} */ private boolean checkIfIsLoopInput(Channel inboundChannel) { // NB: This code assumes no nested loops. return this.stage.getLoop() != null && this.stage.getLoop() != inboundChannel.getProducer().getStage().getLoop(); }
@Override public boolean permitsExecutionOf(ExecutionStage stage, ExecutionState state, OptimizationContext context) { // TODO: We could break, if we enter a loop, however, multi-stage loop heads have feedback predecessors. return stage.getLoop() != null && stage.getPredecessors().stream().anyMatch( predecessor -> predecessor.getLoop() != null ); }
/** * Find the initial {@link OptimizationContext} for a {@link StageActivator}. * * @param stage the {@link ExecutionStage} whose {@link OptimizationContext} is to be determined * @return the {@link OptimizationContext} */ private OptimizationContext determineInitialOptimizationContext(ExecutionStage stage, OptimizationContext rootOptimizationContext) { if (stage.getLoop() == null) return rootOptimizationContext; // TODO: Assumes non-nested loops. return rootOptimizationContext.getNestedLoopContext(stage.getLoop().getLoopSubplan()).getInitialIterationContext(); }
/** * Checks whether the given {@link Channel} is inside of a {@link ExecutionStageLoop}. * * @param channel the said {@link Channel} * @return whether the {@link Channel} is in a {@link ExecutionStageLoop} */ private static boolean checkIfIsInLoopChannel(Channel channel) { final ExecutionStageLoop producerLoop = channel.getProducer().getStage().getLoop(); return producerLoop != null && channel.getConsumers().stream().anyMatch( consumer -> consumer.getStage().getLoop() == producerLoop ); }
/** * Determine the {@link ExecutionStageLoop} the given {@link Channel} belongs to. * * @param channel the {@link Channel} * @return the {@link ExecutionStageLoop} or {@code null} if none */ private static ExecutionStageLoop getExecutionStageLoop(Channel channel) { final ExecutionStage producerStage = channel.getProducer().getStage(); if (producerStage.getLoop() == null) return null; final OutputSlot<?> output = channel.getProducer().getOutputSlotFor(channel); if (output != null && output.getOwner().isLoopHead() && ((LoopHeadOperator) output.getOwner()).getFinalLoopOutputs().contains(output)) { return null; } return producerStage.getLoop(); }
this.crossPlatformExecutor.getOrCreateLoopContext(stage.getLoop()).scrapPreviousTransitionContext();
/** * Tries to execute the given {@link ExecutionStage}. * * @param stageActivator that should be executed * @return whether the {@link ExecutionStage} was really executed */ private void execute(StageActivator stageActivator) { final ExecutionStage stage = stageActivator.getStage(); final OptimizationContext optimizationContext = stageActivator.getOptimizationContext(); // Find parts of the stage to instrument. this.instrumentationStrategy.applyTo(stage); // Obtain an Executor for the stage. Executor executor = this.getOrCreateExecutorFor(stage); // Have the execution done. CrossPlatformExecutor.this.logger.info("Having {} execute {}:\n{}", executor, stage, stage.getPlanAsString("> ")); long startTime = System.currentTimeMillis(); executor.execute(stage, optimizationContext, this); long finishTime = System.currentTimeMillis(); CrossPlatformExecutor.this.logger.info("Executed {} in {}.", stage, Formats.formatDuration(finishTime - startTime, true)); // Remember that we have executed the stage. this.completedStages.add(stage); if (stage.isLoopHead()) { this.getOrCreateLoopContext(stage.getLoop()).scrapPreviousTransitionContext(); } }