Merge pull request #89691 from ingvagabund/quantile-inf

quantile: if the last upper bound is +Inf, return the previous upper bound
This commit is contained in:
Kubernetes Prow Robot 2020-04-01 20:50:37 -07:00 committed by GitHub
commit 96109680a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 21 deletions

View File

@ -262,6 +262,10 @@ func bucketQuantile(q float64, buckets []bucket) float64 {
return buckets[0].upperBound * (rank / buckets[0].count) return buckets[0].upperBound * (rank / buckets[0].count)
} }
if b == len(buckets)-1 && math.IsInf(buckets[b].upperBound, 1) {
return buckets[len(buckets)-2].upperBound
}
// linear approximation of b-th bucket // linear approximation of b-th bucket
brank := rank - buckets[b-1].count brank := rank - buckets[b-1].count
bSize := buckets[b].upperBound - buckets[b-1].upperBound bSize := buckets[b].upperBound - buckets[b-1].upperBound

View File

@ -18,6 +18,7 @@ package testutil
import ( import (
"fmt" "fmt"
"math"
"testing" "testing"
"k8s.io/utils/pointer" "k8s.io/utils/pointer"
@ -54,6 +55,7 @@ func samples2Histogram(samples []float64, upperBounds []float64) Histogram {
func TestHistogramQuantile(t *testing.T) { func TestHistogramQuantile(t *testing.T) {
tests := []struct { tests := []struct {
name string
samples []float64 samples []float64
bounds []float64 bounds []float64
q50 float64 q50 float64
@ -61,7 +63,7 @@ func TestHistogramQuantile(t *testing.T) {
q99 float64 q99 float64
}{ }{
{ {
// repeating numbers name: "Repeating numbers",
samples: []float64{0.5, 0.5, 0.5, 0.5, 1.5, 1.5, 1.5, 1.5, 3, 3, 3, 3, 6, 6, 6, 6}, samples: []float64{0.5, 0.5, 0.5, 0.5, 1.5, 1.5, 1.5, 1.5, 3, 3, 3, 3, 6, 6, 6, 6},
bounds: []float64{1, 2, 4, 8}, bounds: []float64{1, 2, 4, 8},
q50: 2, q50: 2,
@ -69,7 +71,7 @@ func TestHistogramQuantile(t *testing.T) {
q99: 7.84, q99: 7.84,
}, },
{ {
// random numbers name: "Random numbers",
samples: []float64{11, 67, 61, 21, 40, 36, 52, 63, 8, 3, 67, 35, 61, 1, 36, 58}, samples: []float64{11, 67, 61, 21, 40, 36, 52, 63, 8, 3, 67, 35, 61, 1, 36, 58},
bounds: []float64{10, 20, 40, 80}, bounds: []float64{10, 20, 40, 80},
q50: 40, q50: 40,
@ -77,16 +79,25 @@ func TestHistogramQuantile(t *testing.T) {
q99: 79.2, q99: 79.2,
}, },
{ {
// the last bucket is empty name: "The last bucket is empty",
samples: []float64{6, 34, 30, 10, 20, 18, 26, 31, 4, 2, 33, 17, 30, 1, 18, 29}, samples: []float64{6, 34, 30, 10, 20, 18, 26, 31, 4, 2, 33, 17, 30, 1, 18, 29},
bounds: []float64{10, 20, 40, 80}, bounds: []float64{10, 20, 40, 80},
q50: 20, q50: 20,
q90: 36, q90: 36,
q99: 39.6, q99: 39.6,
}, },
{
name: "The last bucket has positive infinity upper bound",
samples: []float64{5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 500},
bounds: []float64{10, 20, 40, math.Inf(1)},
q50: 5.3125,
q90: 9.5625,
q99: 40,
},
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
h := samples2Histogram(test.samples, test.bounds) h := samples2Histogram(test.samples, test.bounds)
q50 := h.Quantile(0.5) q50 := h.Quantile(0.5)
q90 := h.Quantile(0.9) q90 := h.Quantile(0.9)
@ -106,6 +117,7 @@ func TestHistogramQuantile(t *testing.T) {
if !(q999999 < lastUpperBound) { if !(q999999 < lastUpperBound) {
t.Errorf("Expected q999999 to be less than %v, got %v instead", lastUpperBound, q999999) t.Errorf("Expected q999999 to be less than %v, got %v instead", lastUpperBound, q999999)
} }
})
} }
} }