app/vmselect/promql: improve further the accuracy of buckets_limit() function

The accuracy is increased by mergin the smallest bucket with the smallest adjacent bucket.
This commit is contained in:
Aliaksandr Valialkin 2020-07-26 12:06:40 +03:00
parent 43871e79c6
commit b191e425b3
2 changed files with 6 additions and 4 deletions

View file

@ -3066,6 +3066,7 @@ func TestExecSuccess(t *testing.T) {
t.Parallel()
q := `sort(buckets_limit(2, (
alias(label_set(100, "le", "inf", "x", "y"), "metric"),
alias(label_set(98, "le", "300", "x", "y"), "metric"),
alias(label_set(52, "le", "200", "x", "y"), "metric"),
alias(label_set(50, "le", "120", "x", "y"), "metric"),
alias(label_set(20, "le", "70", "x", "y"), "metric"),
@ -3074,14 +3075,14 @@ func TestExecSuccess(t *testing.T) {
)))`
r1 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{50, 50, 50, 50, 50, 50},
Values: []float64{52, 52, 52, 52, 52, 52},
Timestamps: timestampsExpected,
}
r1.MetricName.MetricGroup = []byte("metric")
r1.MetricName.Tags = []storage.Tag{
{
Key: []byte("le"),
Value: []byte("120"),
Value: []byte("200"),
},
{
Key: []byte("x"),

View file

@ -363,8 +363,9 @@ func transformBucketsLimit(tfa *transformFuncArg) ([]*timeseries, error) {
xxMinIdx = i
}
}
if xxMinIdx+1 == len(leGroup) {
// Merge the `inf` bucket with the previous bucket in order to save accuracy.
// Merge the leGroup[xxMinIdx] bucket with the smallest adjacent bucket in order to preserve
// the maximum accuracy.
if xxMinIdx+1 == len(leGroup) || (xxMinIdx > 0 && leGroup[xxMinIdx-1].hits < leGroup[xxMinIdx+1].hits) {
xxMinIdx--
}
leGroup[xxMinIdx+1].hits += leGroup[xxMinIdx].hits