From 69201806f82d82e8e9dd421d81c81d2e12b9d670 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 17 Mar 2021 14:30:52 +0200 Subject: [PATCH] app/vmselect/promql: merge adjancent buckets with the smallest summary number of hits in `buckets_limit()` function This should improve accuracy for the returned buckets --- app/vmselect/promql/transform.go | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/app/vmselect/promql/transform.go b/app/vmselect/promql/transform.go index 495a174db8..4e37f1d4a7 100644 --- a/app/vmselect/promql/transform.go +++ b/app/vmselect/promql/transform.go @@ -347,8 +347,7 @@ func transformBucketsLimit(tfa *transformFuncArg) ([]*timeseries, error) { return nil, nil } if limit < 3 { - // Preserve the first and the last bucket for better accuracy, - // since these buckets are usually `[0...leMin]` and `(leMax ... +Inf]` + // Preserve the first and the last bucket for better accuracy for min and max values. limit = 3 } tss := vmrangeBucketsToLE(args[1]) @@ -412,21 +411,17 @@ func transformBucketsLimit(tfa *transformFuncArg) ([]*timeseries, error) { } } for len(leGroup) > limit { - // Preserve the first and the last bucket for better accuracy, - // since these buckets are usually `[0...leMin]` and `(leMax ... +Inf]` - xxMinIdx := 0 - for i, xx := range leGroup[1 : len(leGroup)-1] { - if xx.hits < leGroup[xxMinIdx].hits { - xxMinIdx = i + // Preserve the first and the last bucket for better accuracy for min and max values + xxMinIdx := 1 + minMergeHits := leGroup[1].hits + leGroup[2].hits + for i := range leGroup[1 : len(leGroup)-2] { + mergeHits := leGroup[i+1].hits + leGroup[i+2].hits + if mergeHits < minMergeHits { + xxMinIdx = i + 1 + minMergeHits = mergeHits } } - xxMinIdx++ - // Merge the leGroup[xxMinIdx] bucket with the smallest adjacent bucket in order to preserve - // the maximum accuracy. - if xxMinIdx > 1 && leGroup[xxMinIdx-1].hits < leGroup[xxMinIdx+1].hits { - xxMinIdx-- - } - leGroup[xxMinIdx+1].hits += leGroup[xxMinIdx].hits + leGroup[xxMinIdx].hits += leGroup[xxMinIdx+1].hits leGroup = append(leGroup[:xxMinIdx], leGroup[xxMinIdx+1:]...) } for _, xx := range leGroup {