-
Notifications
You must be signed in to change notification settings - Fork 34
/
reducer.go
108 lines (97 loc) · 1.98 KB
/
reducer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package conditions
import (
"math"
"sort"
"github.com/grafana/grafana/pkg/tsdb"
"gopkg.in/guregu/null.v3"
)
type QueryReducer interface {
Reduce(timeSeries *tsdb.TimeSeries) null.Float
}
type SimpleReducer struct {
Type string
}
func (s *SimpleReducer) Reduce(series *tsdb.TimeSeries) null.Float {
if len(series.Points) == 0 {
return null.FloatFromPtr(nil)
}
value := float64(0)
allNull := true
switch s.Type {
case "avg":
validPointsCount := 0
for _, point := range series.Points {
if point[0].Valid {
value += point[0].Float64
validPointsCount += 1
allNull = false
}
}
if validPointsCount > 0 {
value = value / float64(validPointsCount)
}
case "sum":
for _, point := range series.Points {
if point[0].Valid {
value += point[0].Float64
allNull = false
}
}
case "min":
value = math.MaxFloat64
for _, point := range series.Points {
if point[0].Valid {
allNull = false
if value > point[0].Float64 {
value = point[0].Float64
}
}
}
case "max":
value = -math.MaxFloat64
for _, point := range series.Points {
if point[0].Valid {
allNull = false
if value < point[0].Float64 {
value = point[0].Float64
}
}
}
case "count":
value = float64(len(series.Points))
allNull = false
case "last":
points := series.Points
for i := len(points) - 1; i >= 0; i-- {
if points[i][0].Valid {
value = points[i][0].Float64
allNull = false
break
}
}
case "median":
var values []float64
for _, v := range series.Points {
if v[0].Valid {
allNull = false
values = append(values, v[0].Float64)
}
}
if len(values) >= 1 {
sort.Float64s(values)
length := len(values)
if length%2 == 1 {
value = values[(length-1)/2]
} else {
value = (values[(length/2)-1] + values[length/2]) / 2
}
}
}
if allNull {
return null.FloatFromPtr(nil)
}
return null.FloatFrom(value)
}
func NewSimpleReducer(typ string) *SimpleReducer {
return &SimpleReducer{Type: typ}
}