xiangfu0 commented on code in PR #19795:
URL: https://github.com/apache/pinot/pull/19795#discussion_r4254155360
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/customobject/tdigest/TDigestAccumulator.java:
##########
@@ -536,59 +753,96 @@ public double quantile(double quantile) {
if (Double.isNaN(quantile) || quantile < 0.0 || quantile > 1.0) {
throw new IllegalArgumentException("q should be in [0,1], got " +
quantile);
}
+ if (_legacyDegraded) {
+ return Double.NaN;
+ }
materializePendingSerializedTDigest();
flush();
- if (_numCentroids == 0) {
+ return quantile(quantile, _numCentroids, _totalWeight, _min, _max,
_centroidMeans, _centroidWeights, null);
+ }
+
+ /// Interpolates the same distribution from primitive centroids or validated
encoded centroids, without a copy.
+ static double quantile(double quantile, int count, double totalWeight,
double min, double max, double[] means,
+ double[] weights, SerializedTDigestState encoded) {
+ if (count == 0) {
return Double.NaN;
}
- if (_numCentroids == 1) {
- return _centroidMeans[0];
+ if (count == 1) {
+ return mean(means, encoded, 0);
+ }
+ if (quantile == 0.0) {
+ return min;
+ }
+ if (quantile == 1.0) {
+ return max;
}
- double index = quantile * _totalWeight;
- if (index < 1.0) {
- return _min;
+ double index = quantile * totalWeight;
+ double firstWeight = weight(weights, encoded, 0);
+ if (firstWeight < 1.0 && index < firstWeight / 2.0) {
+ return weightedAverage(min, firstWeight / 2.0 - index, mean(means,
encoded, 0), index);
}
- if (_centroidWeights[0] > 1.0 && index < _centroidWeights[0] / 2.0) {
- return _min + (index - 1.0) / (_centroidWeights[0] / 2.0 - 1.0) *
(_centroidMeans[0] - _min);
+ if (firstWeight >= 1.0 && index < 1.0) {
+ return min;
}
- int lastIndex = _numCentroids - 1;
- if (index > _totalWeight - 1.0) {
- return _max;
+ if (weight(weights, encoded, 0) > 1.0 && index < weight(weights, encoded,
0) / 2.0) {
+ return min + (index - 1.0) / (weight(weights, encoded, 0) / 2.0 - 1.0) *
(mean(means, encoded, 0) - min);
}
- if (_centroidWeights[lastIndex] > 1.0
- && _totalWeight - index <= _centroidWeights[lastIndex] / 2.0) {
- return _max - (_totalWeight - index - 1.0) /
(_centroidWeights[lastIndex] / 2.0 - 1.0)
- * (_max - _centroidMeans[lastIndex]);
+ int lastIndex = count - 1;
+ double lastWeight = weight(weights, encoded, lastIndex);
+ if (lastWeight < 1.0 && index >= totalWeight - lastWeight / 2.0) {
+ return weightedAverage(mean(means, encoded, lastIndex), totalWeight -
index, max,
+ index - (totalWeight - lastWeight / 2.0));
+ }
+ if (lastWeight >= 1.0 && index > totalWeight - 1.0) {
+ return max;
+ }
+ if (weight(weights, encoded, lastIndex) > 1.0
+ && totalWeight - index <= weight(weights, encoded, lastIndex) / 2.0) {
+ return max - (totalWeight - index - 1.0) / (weight(weights, encoded,
lastIndex) / 2.0 - 1.0)
Review Comment:
Addressed in 21d26f9798. Fixed the singular weight-two last-centroid center
by returning its live mean. The reported q=.75 is now -21.23, matching the
real3.3 same-byte query; adjacent quantiles stay monotonic. The new regression
covers direct/encoded paths and RAW ordering, and fails before the fix. Writer
compatibility is verified separately with actual3.2/3.3 readers under global
assertions.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]