/** * Creates new instance. */ PlanImplementation(PlanEnumeration planEnumeration, Map<OutputSlot<?>, Junction> junctions, OptimizationContext optimizationContext) { this(planEnumeration, junctions, new Canonicalizer<>(), optimizationContext); }
public Canonicalizer(T... objs) { this(objs.length); for (T obj : objs) { this.add(obj); } }
public Canonicalizer(Iterable<? extends T> objs) { this(); this.addAll(objs); }
/** * 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()); }
@Override public boolean removeAll(Collection<?> c) { return this.removeAll(c); }
/** * 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()); }
/** * Create a new instance. */ PlanImplementation( PlanEnumeration planEnumeration, Map<OutputSlot<?>, Junction> junctions, Collection<ExecutionOperator> operators, OptimizationContext optimizationContext) { this(planEnumeration, junctions, new Canonicalizer<>(operators), optimizationContext); }
public Canonicalizer(Collection<? extends T> objs) { this(objs.size()); this.addAll(objs); }
/** * 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; }
/** * Copy constructor. */ public PlanImplementation(PlanImplementation original) { this.planEnumeration = original.planEnumeration; this.junctions = new HashMap<>(original.junctions); this.operators = new Canonicalizer<>(original.getOperators()); this.settledAlternatives.putAll(original.settledAlternatives); this.loopImplementations.putAll(original.loopImplementations); this.optimizationContext = original.optimizationContext; }
); concatenation.operators.addAll(this.operators); concatenation.junctions.putAll(this.junctions); concatenation.settledAlternatives.putAll(this.settledAlternatives); return null; concatenation.operators.addAll(targetPlan.operators); concatenation.loopImplementations.putAll(targetPlan.loopImplementations); concatenation.junctions.putAll(targetPlan.junctions);
sinkOperators = this.operators.stream() .filter(op -> op.getNumOutputs() == 0) .collect(Collectors.toSet());
/** * 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; }
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();