Only track signs of surviving buckets

Signed-off-by: Linas Medziunas <linas.medziunas@gmail.com>
This commit is contained in:
Linas Medziunas 2026-01-28 15:11:10 +02:00
parent e6c07126a6
commit b69ec3f39c
2 changed files with 21 additions and 30 deletions

View File

@ -3243,9 +3243,18 @@ func trimHistogram(trimmedHist *histogram.FloatHistogram, rhs float64, isUpperTr
updatedCount := 0.0
origSum := trimmedHist.Sum
removedSum := 0.0
hasPositive, hasNegative := false, false
isCustomBucket := trimmedHist.UsesCustomBuckets()
var hasPositive, hasNegative bool
trackBucketSigns := func(bucket histogram.Bucket[float64]) {
if bucket.Lower < 0 {
hasNegative = true
}
if bucket.Upper > 0 {
hasPositive = true
}
}
if isUpperTrim {
// Calculate the fraction to keep for buckets that contain the trim value.
// For TRIM_UPPER, we keep observations below the trim point (rhs).
@ -3255,18 +3264,6 @@ func trimHistogram(trimmedHist *histogram.FloatHistogram, rhs float64, isUpperTr
if bucket.Count == 0 {
continue
}
if isCustomBucket {
if bucket.Upper <= 0 {
hasNegative = true
} else {
if bucket.Lower < 0 {
hasNegative = true
}
hasPositive = true
}
} else {
hasPositive = true
}
keepCount, bucketMidpoint := computeBucketTrim(bucket, rhs, isUpperTrim, true, isCustomBucket)
@ -3274,10 +3271,12 @@ func trimHistogram(trimmedHist *histogram.FloatHistogram, rhs float64, isUpperTr
case bucket.Upper <= rhs:
// Bucket is entirely below the trim point - keep all.
updatedCount += bucket.Count
trackBucketSigns(bucket)
case bucket.Lower < rhs:
// Bucket contains the trim point - interpolate.
removedCount := bucket.Count - keepCount
removedSum += removedCount * bucketMidpoint
trackBucketSigns(bucket)
updatedCount += keepCount
trimmedHist.PositiveBuckets[i] = keepCount
@ -3296,19 +3295,20 @@ func trimHistogram(trimmedHist *histogram.FloatHistogram, rhs float64, isUpperTr
if bucket.Count == 0 {
continue
}
hasNegative = true
keepCount, bucketMidpoint := computeBucketTrim(bucket, rhs, isUpperTrim, false, isCustomBucket)
switch {
case bucket.Upper <= rhs:
updatedCount += bucket.Count
trackBucketSigns(bucket)
case bucket.Lower < rhs:
removedCount := bucket.Count - keepCount
removedSum += removedCount * bucketMidpoint
trimmedHist.NegativeBuckets[i] = keepCount
updatedCount += keepCount
trackBucketSigns(bucket)
default:
bucketMidpoint = -math.Sqrt(bucket.Lower * bucket.Upper)
removedSum += bucket.Count * bucketMidpoint
@ -3323,30 +3323,20 @@ func trimHistogram(trimmedHist *histogram.FloatHistogram, rhs float64, isUpperTr
if bucket.Count == 0 {
continue
}
if isCustomBucket {
if bucket.Upper <= 0 {
hasNegative = true
} else {
if bucket.Lower < 0 {
hasNegative = true
}
hasPositive = true
}
} else {
hasPositive = true
}
keepCount, bucketMidpoint := computeBucketTrim(bucket, rhs, isUpperTrim, true, isCustomBucket)
switch {
case bucket.Lower >= rhs:
updatedCount += bucket.Count
trackBucketSigns(bucket)
case bucket.Upper > rhs:
removedCount := bucket.Count - keepCount
removedSum += removedCount * bucketMidpoint
trimmedHist.PositiveBuckets[i] = keepCount
updatedCount += keepCount
trackBucketSigns(bucket)
default:
if !isCustomBucket {
bucketMidpoint = math.Sqrt(bucket.Lower * bucket.Upper)
@ -3361,19 +3351,20 @@ func trimHistogram(trimmedHist *histogram.FloatHistogram, rhs float64, isUpperTr
if bucket.Count == 0 {
continue
}
hasNegative = true
keepCount, bucketMidpoint := computeBucketTrim(bucket, rhs, isUpperTrim, false, isCustomBucket)
switch {
case bucket.Lower >= rhs:
updatedCount += bucket.Count
trackBucketSigns(bucket)
case bucket.Upper > rhs:
removedCount := bucket.Count - keepCount
removedSum += removedCount * bucketMidpoint
trimmedHist.NegativeBuckets[i] = keepCount
updatedCount += keepCount
trackBucketSigns(bucket)
default:
bucketMidpoint = -math.Sqrt(bucket.Lower * bucket.Upper)
removedSum += bucket.Count * bucketMidpoint

View File

@ -1897,7 +1897,7 @@ eval instant at 1m h_test >/ 0
h_test {{schema:0 sum:127.28553390593274 count:30.5 z_bucket:0.5 z_bucket_w:0.001 buckets:[2 4 8 16]}}
eval instant at 1m h_test </ 0
h_test {{schema:0 sum:3.5418471982869164 count:3.5 z_bucket:0.5 z_bucket_w:0.001 n_buckets:[1 2]}}
h_test {{schema:0 sum:0.0 count:3.5 z_bucket:0.5 z_bucket_w:0.001 n_buckets:[1 2]}}
# Exponential buckets: trim uses exponential interpolation if cutoff is inside a bucket
eval instant at 1m h_test_2 </ 1.13
@ -1923,7 +1923,7 @@ eval instant at 1m h_test >/ -1
h_test{} {{count:32 sum:126.57842712474618 z_bucket:1 z_bucket_w:0.001 buckets:[2 4 8 16] n_buckets:[1]}}
eval instant at 1m h_test </ -1
h_test{} {{count:2 sum:4.24895397947347 z_bucket_w:0.001 n_offset:1 n_buckets:[2]}}
h_test{} {{count:2 sum:0.0 z_bucket_w:0.001 n_offset:1 n_buckets:[2]}}
# Custom buckets: trim on bucket boundary without interpolation
eval instant at 1m cbh </ 13
@ -2018,7 +2018,7 @@ eval instant at 1m cbh_two_buckets_split_at_zero </ 10.0
# Skip (0; +Inf] bucket (100).
eval instant at 1m cbh_two_buckets_split_at_zero </ 0.0
cbh_two_buckets_split_at_zero {{schema:-53 sum:33.0 count:1 custom_values:[0] buckets:[1 0]}}
cbh_two_buckets_split_at_zero {{schema:-53 sum:0.0 count:1 custom_values:[0] buckets:[1 0]}}
# Skip both buckets (1, 100).
eval instant at 1m cbh_two_buckets_split_at_zero </ -10.0