/** * Find the {@link ExecutionOperator} that do not depend on any other {@link ExecutionOperator} as input. * * @return the start {@link ElementaryOperator}s */ public List<ExecutionOperator> getStartOperators() { return this.operators.stream() .filter(this::isStartOperator) .collect(Collectors.toList()); }
/** * Stream all the {@link ExecutionOperator}s in this instance. * * @return a {@link Stream} containing every {@link ExecutionOperator} at least once */ Stream<ExecutionOperator> streamOperators() { Stream<ExecutionOperator> operatorStream = Stream.concat( this.operators.stream(), this.junctions.values().stream().flatMap(j -> j.getConversionTasks().stream()).map(ExecutionTask::getOperator) ); if (!this.loopImplementations.isEmpty()) { operatorStream = Stream.concat( operatorStream, this.loopImplementations.values().stream().flatMap(LoopImplementation::streamOperators) ); } return operatorStream; }
/** * @return those contained {@link ExecutionOperator}s that have a {@link Slot} that is yet to be connected * to a further {@link ExecutionOperator} in the further plan enumeration process */ public Collection<ExecutionOperator> getInterfaceOperators() { Validate.notNull(this.getPlanEnumeration()); final Set<OutputSlot> outputSlots = this.getPlanEnumeration().servingOutputSlots.stream() .map(Tuple::getField0) .distinct() .collect(Collectors.toSet()); final Set<InputSlot<?>> inputSlots = this.getPlanEnumeration().requestedInputSlots; return this.operators.stream() .filter(operator -> this.allOutermostInputSlots(operator).anyMatch(inputSlots::contains) || this.allOutermostOutputSlots(operator).anyMatch(outputSlots::contains)) .collect(Collectors.toList()); }
/** * Retrieves the {@link TimeEstimate} for this instance, including platform overhead. * * @param isIncludeOverhead whether to include any incurring global overhead * @return the {@link TimeEstimate} */ public TimeEstimate getTimeEstimate(boolean isIncludeOverhead) { final TimeEstimate operatorTimeEstimate = this.operators.stream() .map(op -> this.optimizationContext.getOperatorContext(op).getTimeEstimate()) .reduce(TimeEstimate.ZERO, TimeEstimate::plus); final TimeEstimate junctionTimeEstimate = this.optimizationContext.getDefaultOptimizationContexts().stream() .flatMap(optCtx -> this.junctions.values().stream().map(jct -> jct.getTimeEstimate(optCtx))) .reduce(TimeEstimate.ZERO, TimeEstimate::plus); final TimeEstimate loopTimeEstimate = this.loopImplementations.values().stream() .map(LoopImplementation::getTimeEstimate) .reduce(TimeEstimate.ZERO, TimeEstimate::plus); TimeEstimate timeEstimate = operatorTimeEstimate.plus(junctionTimeEstimate).plus(loopTimeEstimate); if (isIncludeOverhead) { final long platformInitializationTime = this.getUtilizedPlatforms().stream() .map(platform -> this.optimizationContext.getConfiguration().getPlatformStartUpTimeProvider().provideFor(platform)) .reduce(0L, (a, b) -> a + b); timeEstimate = timeEstimate.plus(platformInitializationTime); } return timeEstimate; }
assert Double.isNaN(this.squashedCostEstimateCache) == Double.isNaN(this.squashedCostEstimateWithoutOverheadCache); if (Double.isNaN(this.squashedCostEstimateCache)) { final double operatorCosts = this.operators.stream() .mapToDouble(op -> this.optimizationContext.getOperatorContext(op).getSquashedCostEstimate()) .sum();
/** * Retrieves the cost estimate for this instance. * * @param isIncludeOverhead whether to include global overhead in the {@link TimeEstimate} (to avoid repeating * overhead in nested instances) * @return the cost estimate */ ProbabilisticDoubleInterval getCostEstimate(boolean isIncludeOverhead) { ProbabilisticDoubleInterval costEstimateWithoutOverheadCache, costEstimateCache; final ProbabilisticDoubleInterval operatorCosts = this.operators.stream() .map(op -> this.optimizationContext.getOperatorContext(op).getCostEstimate()) .reduce(ProbabilisticDoubleInterval.zero, ProbabilisticDoubleInterval::plus); final ProbabilisticDoubleInterval junctionCosts = this.optimizationContext.getDefaultOptimizationContexts().stream() .flatMap(optCtx -> this.junctions.values().stream().map(jct -> jct.getCostEstimate(optCtx))) .reduce(ProbabilisticDoubleInterval.zero, ProbabilisticDoubleInterval::plus); final ProbabilisticDoubleInterval loopCosts = this.loopImplementations.values().stream() .map(LoopImplementation::getCostEstimate) .reduce(ProbabilisticDoubleInterval.zero, ProbabilisticDoubleInterval::plus); costEstimateWithoutOverheadCache = operatorCosts.plus(junctionCosts).plus(loopCosts); ProbabilisticDoubleInterval overheadCosts = this.getUtilizedPlatforms().stream() .map(platform -> { Configuration configuraiton = this.optimizationContext.getConfiguration(); long startUpTime = configuraiton.getPlatformStartUpTimeProvider().provideFor(platform); TimeToCostConverter timeToCostConverter = configuraiton.getTimeToCostConverterProvider().provideFor(platform); return timeToCostConverter.convert(new TimeEstimate(startUpTime, startUpTime, 1d)); }) .reduce(ProbabilisticDoubleInterval.zero, ProbabilisticDoubleInterval::plus); costEstimateCache = costEstimateWithoutOverheadCache.plus(overheadCosts); return isIncludeOverhead ? costEstimateCache : costEstimateWithoutOverheadCache; }
sinkOperators = this.operators.stream() .filter(op -> op.getNumOutputs() == 0) .collect(Collectors.toSet());