in wayang-commons/wayang-core/src/main/java/org/apache/wayang/core/optimizer/cardinality/DefaultCardinalityEstimator.java [69:107]
public CardinalityEstimate estimate(OptimizationContext optimizationContext, CardinalityEstimate... inputEstimates) {
assert inputEstimates.length == this.numInputs
|| (this.isAllowMoreInputs && inputEstimates.length > this.numInputs) :
String.format("Received %d input estimates, require %d%s.",
inputEstimates.length, this.numInputs, this.isAllowMoreInputs ? "+" : "");
if (this.numInputs == 0) {
final long estimate = this.singlePointEstimator.applyAsLong(new long[0], optimizationContext.getConfiguration());
return new CardinalityEstimate(estimate, estimate, this.certaintyProb);
}
long[] lowerAndUpperInputEstimates = this.extractEstimateValues(inputEstimates);
long lowerEstimate = -1, upperEstimate = -1;
long[] currentInputEstimates = new long[this.numInputs];
final int maximumBitMaskValue = 1 << this.numInputs;
for (long positionBitmask = 0; positionBitmask < maximumBitMaskValue; positionBitmask++) {
for (int pos = 0; pos < this.numInputs; pos++) {
int bit = (int) ((positionBitmask >>> pos) & 0x1);
currentInputEstimates[pos] = lowerAndUpperInputEstimates[(pos << 1) + bit];
}
long currentEstimate = Math.max(
this.singlePointEstimator.applyAsLong(currentInputEstimates, optimizationContext.getConfiguration()),
0
);
if (lowerEstimate == -1 || currentEstimate < lowerEstimate) {
lowerEstimate = currentEstimate;
}
if (upperEstimate == -1 || currentEstimate > upperEstimate) {
upperEstimate = currentEstimate;
}
}
double correctnessProb = this.certaintyProb * Arrays.stream(inputEstimates)
.mapToDouble(CardinalityEstimate::getCorrectnessProbability)
.min()
.orElseThrow(IllegalStateException::new);
return new CardinalityEstimate(lowerEstimate, upperEstimate, correctnessProb);
}