/** * Build the {@link CardinalityEstimationTraversal}. * * @return the build {@link CardinalityEstimationTraversal} */ CardinalityEstimationTraversal build() { this.execute(); return this.result; }
@Override public CardinalityPusher getCardinalityPusher( final Configuration configuration) { return SubplanCardinalityPusher.createFor(this, configuration); }
@Override protected void doPush(OptimizationContext.OperatorContext opCtx, Configuration configuration) { // Trigger the push for each of the alternativeTraversals. this.pushThroughAlternatives(opCtx, configuration); // Somehow merge the CardinalityEstimates from the alternativeTraversals to the final ones for the opCtx. this.pickCardinalities(opCtx); }
public CardinalityEstimate plus(CardinalityEstimate that) { return new CardinalityEstimate( addSafe(this.getLowerEstimate(), that.getLowerEstimate()), addSafe(this.getUpperEstimate(), that.getUpperEstimate()), Math.min(this.getCorrectnessProbability(), that.getCorrectnessProbability()) ); }
@Override public CardinalityEstimate estimate(OptimizationContext optimizationContext, CardinalityEstimate... inputEstimates) { double probability = .5d; long upperEstimate = 1L; for (CardinalityEstimate inputEstimate : inputEstimates) { if (inputEstimate == null) { inputEstimate = CardinalityEstimate.EMPTY_ESTIMATE; } probability *= inputEstimate.getCorrectnessProbability(); upperEstimate *= 1 + 10 * inputEstimate.getUpperEstimate(); if (upperEstimate < 0L) { upperEstimate = Long.MAX_VALUE; } } return new CardinalityEstimate(1L, upperEstimate, probability); }
private long[] extractEstimateValues(CardinalityEstimate[] inputEstimates) { long[] lowerAndUpperEstimates = new long[this.numInputs * 2]; for (int i = 0; i < this.numInputs; i++) { final CardinalityEstimate inputEstimate = inputEstimates[i]; lowerAndUpperEstimates[i << 1] = inputEstimate.getLowerEstimate(); lowerAndUpperEstimates[(i << 1) + 1] = inputEstimate.getUpperEstimate(); } return lowerAndUpperEstimates; } }
/** * Injects the cardinalities of a current {@link ExecutionState} into its associated {@link RheemPlan} * (or its {@link OptimizationContext}, respectively) and then reperforms the cardinality estimation. * * @return whether any cardinalities have been injected */ public boolean pushCardinalityUpdates(ExecutionState executionState, PlanImplementation planImplementation) { boolean isInjected = this.injectMeasuredCardinalities(executionState); if (isInjected) this.pushCardinalities(planImplementation); return isInjected; }
@Override public CardinalityEstimate estimate(OptimizationContext optimizationContext, CardinalityEstimate... inputEstimates) { return new CardinalityEstimate(this.outputSize, this.outputSize, 1d, this.isOverride); } }
/** * Extracts the geometric mean values of the given {@link CardinalityEstimate}s. * * @param estimates the input {@link CardinalityEstimate}s * @return an array containing the average estimates * @see CardinalityEstimate#getGeometricMeanEstimate() */ private static long[] extractMeanValues(CardinalityEstimate[] estimates) { long[] averages = new long[estimates.length]; for (int i = 0; i < estimates.length; i++) { CardinalityEstimate inputEstimate = estimates[i]; if (inputEstimate == null) inputEstimate = CardinalityEstimate.EMPTY_ESTIMATE; averages[i] = inputEstimate.getGeometricMeanEstimate(); } return averages; }
/** * Traverse the {@link RheemPlan}, thereby updating {@link CardinalityEstimate}s. * * @return whether any {@link CardinalityEstimate}s have been updated */ public boolean pushCardinalities() { boolean isUpdated = this.getPlanTraversal().traverse(this.optimizationContext, this.configuration); this.optimizationContext.clearMarks(); return isUpdated; }
public DefaultCardinalityPusher(Operator operator, KeyValueProvider<OutputSlot<?>, CardinalityEstimator> estimationProvider) { super(operator); this.cardinalityEstimators = this.initializeCardinalityEstimators(operator, estimationProvider); }
/** * Go over the given {@link RheemPlan} and update the cardinalities of data being passed between its * {@link Operator}s using the given {@link ExecutionState}. * * @return whether any cardinalities have been updated */ private boolean reestimateCardinalities(ExecutionState executionState) { return this.cardinalityEstimatorManager.pushCardinalityUpdates(executionState, this.planImplementation); }
@Override public CardinalityPusher getCardinalityPusher(final Configuration configuration) { return new OperatorAlternativeCardinalityPusher(this, configuration); }
/** * Trigger the {@link CardinalityEstimationTraversal} for the given {@code traversal}. */ private void pushThroughPath(Tuple<OperatorAlternative.Alternative, CardinalityEstimationTraversal> traversal, Configuration configuration, OptimizationContext optimizationCtx) { // Perform the push. traversal.field1.traverse(optimizationCtx, configuration); }
@Override public CardinalityPusher getCardinalityPusher(Configuration configuration) { return new LoopSubplanCardinalityPusher(this, configuration); }
protected Activation createActivation(int inputIndex) { return new Activation(inputIndex, this); }
/** * Normalize the given estimates by dividing them by a number of executions. * * @param estimates that should be normalized * @param numExecutions the number execution * @return the normalized estimates (and {@code estimates} if {@code numExecution == 1} */ static CardinalityEstimate[] normalize(CardinalityEstimate[] estimates, int numExecutions) { if (numExecutions == 1 || estimates.length == 0) return estimates; CardinalityEstimate[] normalizedEstimates = new CardinalityEstimate[estimates.length]; for (int i = 0; i < estimates.length; i++) { final CardinalityEstimate estimate = estimates[i]; if (estimate != null) normalizedEstimates[i] = estimate.divideBy(numExecutions); } return normalizedEstimates; }
/** * Triggers the {@link #dependentActivations} and puts newly activated {@link Activator}s onto the * {@code activatorQueue}. */ private void processDependentActivations(Collection<Activation> activations, Queue<Activator> activatorQueue) { // Otherwise, we update/activate the dependent estimators. activations.forEach(activation -> activation.fire(activatorQueue)); }
public double calculateSpread(CardinalityEstimate cardinalityEstimate) { return ((double) cardinalityEstimate.getUpperEstimate() + this.spreadSmoothing) / ((double) cardinalityEstimate.getLowerEstimate() + this.spreadSmoothing); }
public DefaultCardinalityPusher(Operator operator, int[] relevantInputIndices, int[] relevantOutputIndices, KeyValueProvider<OutputSlot<?>, CardinalityEstimator> estimationProvider) { super(relevantInputIndices, relevantOutputIndices); this.cardinalityEstimators = this.initializeCardinalityEstimators(operator, estimationProvider); }