/** * Traverse this instance and all its predecessors unless they are marked as executed. * * @param accumulator state that is maintained over the traversal * @param aggregator visits the traversed instances * @param isMark whether traversed instances should be marked * @param <T> * @return the {@code accumulator} in its final state */ public <T> T traverse(T accumulator, Aggregator<T> aggregator, boolean isMark) { if (!this.isExecuted) { for (Iterator<LazyExecutionLineageNode> i = this.predecessors.iterator(); i.hasNext(); ) { LazyExecutionLineageNode predecessor = i.next(); accumulator = predecessor.traverse(accumulator, aggregator, isMark); if (predecessor.isExecuted) { i.remove(); } } accumulator = this.accept(accumulator, aggregator); if (isMark) this.markAsExecuted(); } return accumulator; }
/** * Collect and mark all unmarked {@link ExecutionLineageNode}s in this instance. * * @return the collected {@link ExecutionLineageNode}s and produced {@link ChannelInstance}s */ public Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> collectAndMark() { return this.collectAndMark(new LinkedList<>(), new LinkedList<>()); }
/** * Models lazy execution by not marking any {@link LazyExecutionLineageNode}s. * * @param inputs the input {@link ChannelInstance}s * @param outputs the output {@link ChannelInstance}s * @param operatorContext the executed {@link OptimizationContext.OperatorContext} * @return the executed {@link OptimizationContext.OperatorContext} and produced {@link ChannelInstance}s */ static Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> modelLazyExecution(ChannelInstance[] inputs, ChannelInstance[] outputs, OptimizationContext.OperatorContext operatorContext) { final ExecutionLineageNode executionLineageNode = new ExecutionLineageNode(operatorContext); executionLineageNode.addAtomicExecutionFromOperatorContext(); LazyExecutionLineageNode.connectAll(inputs, executionLineageNode, outputs); return new Tuple<>(Collections.emptyList(), Collections.emptyList()); }
public <T> T traverseAndMark(T accumulator, Aggregator<T> aggregator) { return this.traverse(accumulator, aggregator, true); }
/** * Collect and mark all unmarked {@link LazyExecutionLineageNode}s in this instance. * * @param executionLineageCollector collects the unmarked {@link ExecutionLineageNode} * @param channelInstanceCollector collects the {@link ChannelInstance} in the unmarked {@link LazyExecutionLineageNode}s * @return the two collectors */ public Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> collectAndMark( Collection<ExecutionLineageNode> executionLineageCollector, Collection<ChannelInstance> channelInstanceCollector ) { return this.traverseAndMark( new Tuple<>(executionLineageCollector, channelInstanceCollector), new CollectingAggregator() ); }
@Override protected void markAsExecuted() { super.markAsExecuted(); assert !this.channelInstance.wasProduced(); this.channelInstance.markProduced(); this.channelInstance.noteDiscardedReference(false); }
/** * Models eager execution by marking all {@link LazyExecutionLineageNode}s as executed and collecting all marked ones. * However, the output {@link ChannelInstance}s are not yet produced. * * @param inputs the input {@link ChannelInstance}s * @param outputs the output {@link ChannelInstance}s * @param operatorContext the executed {@link OptimizationContext.OperatorContext} * @return the executed {@link OptimizationContext.OperatorContext} and produced {@link ChannelInstance}s */ static Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> modelQuasiEagerExecution( ChannelInstance[] inputs, ChannelInstance[] outputs, OptimizationContext.OperatorContext operatorContext) { final ExecutionLineageNode executionLineageNode = new ExecutionLineageNode(operatorContext); executionLineageNode.addAtomicExecutionFromOperatorContext(); LazyExecutionLineageNode.connectAll(inputs, executionLineageNode, outputs); return executionLineageNode.collectAndMark(); }
public <T> T traverse(T accumulator, Aggregator<T> aggregator) { return this.traverse(accumulator, aggregator, false); }
/** * Models eager execution by marking all {@link LazyExecutionLineageNode}s as executed and collecting all marked ones. * * @param inputs the input {@link ChannelInstance}s * @param outputs the output {@link ChannelInstance}s * @param operatorContext the executed {@link OptimizationContext.OperatorContext} * @return the executed {@link OptimizationContext.OperatorContext} and produced {@link ChannelInstance}s */ static Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> modelEagerExecution( ChannelInstance[] inputs, ChannelInstance[] outputs, OptimizationContext.OperatorContext operatorContext) { final ExecutionLineageNode executionLineageNode = new ExecutionLineageNode(operatorContext); executionLineageNode.addAtomicExecutionFromOperatorContext(); LazyExecutionLineageNode.connectAll(inputs, executionLineageNode, outputs); final Tuple<Collection<ExecutionLineageNode>, Collection<ChannelInstance>> collectors; if (outputs.length == 0) { collectors = executionLineageNode.collectAndMark(); } else { collectors = new Tuple<>(new LinkedList<>(), new LinkedList<>()); for (ChannelInstance output : outputs) { output.getLineage().collectAndMark(collectors.getField0(), collectors.getField1()); } } return collectors; }