Skip to content

Commit be9157f

Browse files
authored
Merge pull request #534 from spacefreak86/fix-summarize-values
fix SummarizeValues
2 parents 301f761 + 57762a2 commit be9157f

File tree

4 files changed

+40
-20
lines changed

4 files changed

+40
-20
lines changed

pkg/expr/functions/legendValue/function.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func (f *legendValue) Do(ctx context.Context, e parser.Expr, from, until int32,
5757
for _, a := range arg {
5858
var values []string
5959
for _, method := range methods {
60-
summaryVal, _, err := helper.SummarizeValues(method, a.Values)
60+
summaryVal, _, err := helper.SummarizeValues(method, a.Values, a.IsAbsent)
6161
if err != nil {
6262
return []*types.MetricData{}, err
6363
}

pkg/expr/functions/sortBy/function.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ func (f *sortBy) Do(ctx context.Context, e parser.Expr, from, until int32, value
4242
for i, a := range arg {
4343
switch e.Target() {
4444
case "sortByTotal":
45-
vals[i], _, _ = helper.SummarizeValues("sum", a.Values)
45+
vals[i], _, _ = helper.SummarizeValues("sum", a.Values, a.IsAbsent)
4646
case "sortByMaxima":
47-
vals[i], _, _ = helper.SummarizeValues("max", a.Values)
47+
vals[i], _, _ = helper.SummarizeValues("max", a.Values, a.IsAbsent)
4848
case "sortByMinima":
49-
min, _, _ := helper.SummarizeValues("min", a.Values)
49+
min, _, _ := helper.SummarizeValues("min", a.Values, a.IsAbsent)
5050
vals[i] = 1 / min
5151
}
5252
}

pkg/expr/functions/summarize/function.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,14 @@ func (f *summarize) Do(ctx context.Context, e parser.Expr, from, until int32, va
117117
t := arg.StartTime // unadjusted
118118
bucketEnd := start + bucketSize
119119
values := make([]float64, 0, bucketSize/arg.StepTime)
120+
absent := make([]bool, 0, bucketSize/arg.StepTime)
120121
ridx := 0
121122
bucketItems := 0
122123
for i, v := range arg.Values {
123124
bucketItems++
124125
if !arg.IsAbsent[i] {
125126
values = append(values, v)
127+
absent = append(absent, false)
126128
}
127129

128130
t += arg.StepTime
@@ -132,20 +134,21 @@ func (f *summarize) Do(ctx context.Context, e parser.Expr, from, until int32, va
132134
}
133135

134136
if t >= bucketEnd {
135-
r.Values[ridx], r.IsAbsent[ridx], err = helper.SummarizeValues(summarizeFunction, values)
137+
r.Values[ridx], r.IsAbsent[ridx], err = helper.SummarizeValues(summarizeFunction, values, absent)
136138
if err != nil {
137139
return []*types.MetricData{}, err
138140
}
139141
ridx++
140142
bucketEnd += bucketSize
141143
bucketItems = 0
142144
values = values[:0]
145+
absent = absent[:0]
143146
}
144147
}
145148

146149
// last partial bucket
147150
if bucketItems > 0 {
148-
r.Values[ridx], r.IsAbsent[ridx], err = helper.SummarizeValues(summarizeFunction, values)
151+
r.Values[ridx], r.IsAbsent[ridx], err = helper.SummarizeValues(summarizeFunction, values, absent)
149152
if err != nil {
150153
return []*types.MetricData{}, err
151154
}

pkg/expr/helper/helper.go

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ func AggregateSeriesWithWildcards(name string, args []*types.MetricData, fields
188188
}
189189

190190
// SummarizeValues summarizes values
191-
func SummarizeValues(f string, values []float64) (float64, bool, error) {
191+
func SummarizeValues(f string, values []float64, absent []bool) (float64, bool, error) {
192192
rv := 0.0
193193

194194
if len(values) == 0 {
@@ -201,10 +201,16 @@ func SummarizeValues(f string, values []float64) (float64, bool, error) {
201201
rv += av
202202
}
203203
case "avg", "average":
204-
for _, av := range values {
205-
rv += av
204+
total := 0
205+
for i, av := range values {
206+
if !absent[i] {
207+
rv += av
208+
total++
209+
}
210+
}
211+
if total > 0 {
212+
rv /= float64(total)
206213
}
207-
rv /= float64(len(values))
208214
case "max":
209215
rv = math.Inf(-1)
210216
for _, av := range values {
@@ -214,20 +220,31 @@ func SummarizeValues(f string, values []float64) (float64, bool, error) {
214220
}
215221
case "min":
216222
rv = math.Inf(1)
217-
for _, av := range values {
218-
if av < rv {
219-
rv = av
223+
for i, av := range values {
224+
if !absent[i] {
225+
if av < rv {
226+
rv = av
227+
}
220228
}
221229
}
222230
case "last":
223-
if len(values) > 0 {
224-
rv = values[len(values)-1]
231+
for i := len(values) - 1; i >= 0; i-- {
232+
if !absent[i] {
233+
rv = values[i]
234+
break
235+
}
225236
}
226237
case "count":
227-
rv = float64(len(values))
238+
total := 0
239+
for i := range values {
240+
if !absent[i] {
241+
total++
242+
}
243+
}
244+
rv = float64(total)
228245
case "median":
229-
val, absent := Percentile(values, 50, true)
230-
return val, absent, nil
246+
val, abs := Percentile(values, 50, true)
247+
return val, abs, nil
231248
default:
232249
looks_like_percentile, err := regexp.MatchString(`^p\d\d?$`, f)
233250
if err != nil {
@@ -239,8 +256,8 @@ func SummarizeValues(f string, values []float64) (float64, bool, error) {
239256
if err != nil {
240257
return 0, true, parser.ParseError(err.Error())
241258
}
242-
val, absent := Percentile(values, percent, true)
243-
return val, absent, nil
259+
val, abs := Percentile(values, percent, true)
260+
return val, abs, nil
244261
} else {
245262
return 0, true, parser.ParseError(fmt.Sprintf("unsupported aggregation function: %s", f))
246263
}

0 commit comments

Comments
 (0)