app/vmselect/promql: fix calculations for histogram_share

This commit is contained in:
Aliaksandr Valialkin 2020-01-04 14:18:38 +02:00
parent 89b551201c
commit 76707b2ab9
2 changed files with 19 additions and 18 deletions

View File

@ -2686,14 +2686,14 @@ func TestExecSuccess(t *testing.T) {
}) })
t.Run(`histogram_share(normal-bucket-count)`, func(t *testing.T) { t.Run(`histogram_share(normal-bucket-count)`, func(t *testing.T) {
t.Parallel() t.Parallel()
q := `histogram_share(22, q := `histogram_share(35,
label_set(0, "foo", "bar", "le", "10") label_set(0, "foo", "bar", "le", "10")
or label_set(100, "foo", "bar", "le", "30") or label_set(100, "foo", "bar", "le", "30")
or label_set(300, "foo", "bar", "le", "+Inf") or label_set(300, "foo", "bar", "le", "+Inf")
)` )`
r := netstorage.Result{ r := netstorage.Result{
MetricName: metricNameExpected, MetricName: metricNameExpected,
Values: []float64{0.2, 0.2, 0.2, 0.2, 0.2, 0.2}, Values: []float64{0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333, 0.3333333333333333},
Timestamps: timestampsExpected, Timestamps: timestampsExpected,
} }
r.MetricName.Tags = []storage.Tag{{ r.MetricName.Tags = []storage.Tag{{

View File

@ -440,29 +440,30 @@ func transformHistogramShare(tfa *transformFuncArg) ([]*timeseries, error) {
if math.IsInf(leReq, 1) { if math.IsInf(leReq, 1) {
return 1, 1, 1 return 1, 1, 1
} }
for j, xs := range xss { var vPrev, lePrev float64
for _, xs := range xss {
v := xs.ts.Values[i] v := xs.ts.Values[i]
le := xs.le le := xs.le
if leReq < le { if leReq >= le {
vPrev = v
lePrev = le
continue continue
} }
// precondition: leReq >= le // precondition: lePrev <= leReq < le
if j+1 >= len(xss) {
return 1, 1, 1
}
vNext := xss[j+1].ts.Values[i]
leNext := xss[j+1].le
if math.IsInf(leNext, 1) {
return v / vNext, v / vNext, 1
}
vLast := xss[len(xss)-1].ts.Values[i] vLast := xss[len(xss)-1].ts.Values[i]
lower = v / vLast lower = vPrev / vLast
upper = vNext / vLast if math.IsInf(le, 1) {
q = lower + (vNext-v)/vLast*(leReq-le)/(leNext-le) return lower, lower, 1
}
if lePrev == leReq {
return lower, lower, lower
}
upper = v / vLast
q = lower + (v-vPrev)/vLast*(leReq-lePrev)/(le-lePrev)
return q, lower, upper return q, lower, upper
} }
leLast := xss[len(xss)-1].le // precondition: leReq > leLast
return leReq / leLast, 0, 1 return 1, 1, 1
} }
rvs := make([]*timeseries, 0, len(m)) rvs := make([]*timeseries, 0, len(m))
for _, xss := range m { for _, xss := range m {