Skip to content
This repository was archived by the owner on Aug 23, 2023. It is now read-only.

Commit 2694dbf

Browse files
authored
Merge pull request #1324 from DeleurApps/group
Added group function
2 parents eeb3107 + 0065466 commit 2694dbf

File tree

4 files changed

+191
-1
lines changed

4 files changed

+191
-1
lines changed

docs/graphite.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ See also:
7777
| fallbackSeries | | Stable |
7878
| filterSeries(seriesList, func, operator, threshold) seriesList | | Stable |
7979
| grep(seriesList, pattern) seriesList | | Stable |
80-
| group | | No |
80+
| group | | Stable |
8181
| groupByNode | | No |
8282
| groupByNodes | | No |
8383
| groupByTags(seriesList, func, tagList) seriesList | | Stable |

expr/func_group.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package expr
2+
3+
import (
4+
"github.com/grafana/metrictank/api/models"
5+
)
6+
7+
type FuncGroup struct {
8+
in []GraphiteFunc
9+
}
10+
11+
func NewGroup() GraphiteFunc {
12+
return &FuncGroup{}
13+
}
14+
15+
func (s *FuncGroup) Signature() ([]Arg, []Arg) {
16+
return []Arg{
17+
ArgSeriesLists{val: &s.in}}, []Arg{ArgSeriesList{}}
18+
}
19+
20+
func (s *FuncGroup) Context(context Context) Context {
21+
return context
22+
}
23+
24+
func (s *FuncGroup) Exec(cache map[Req][]models.Series) ([]models.Series, error) {
25+
series, _, err := consumeFuncs(cache, s.in)
26+
if err != nil {
27+
return nil, err
28+
}
29+
30+
return series, nil
31+
}

expr/func_group_test.go

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package expr
2+
3+
import (
4+
"strconv"
5+
"testing"
6+
7+
"github.com/grafana/metrictank/api/models"
8+
"github.com/grafana/metrictank/test"
9+
"github.com/raintank/schema"
10+
)
11+
12+
func getNewGroup(in [][]models.Series) *FuncGroup {
13+
f := NewGroup()
14+
s := f.(*FuncGroup)
15+
for i := range in {
16+
s.in = append(s.in, NewMock(in[i]))
17+
}
18+
return s
19+
}
20+
21+
func TestGroup(t *testing.T) {
22+
f := getNewGroup([][]models.Series{
23+
{
24+
{
25+
Interval: 10,
26+
QueryPatt: "a",
27+
Target: "a",
28+
Datapoints: getCopy(a),
29+
},
30+
},
31+
{
32+
{
33+
Interval: 10,
34+
QueryPatt: "b",
35+
Target: "b",
36+
Datapoints: getCopy(b),
37+
},
38+
},
39+
{
40+
{
41+
Interval: 10,
42+
QueryPatt: "abc",
43+
Target: "abc",
44+
Datapoints: getCopy(a),
45+
},
46+
{
47+
Interval: 10,
48+
QueryPatt: "abc",
49+
Target: "abc",
50+
Datapoints: getCopy(b),
51+
},
52+
{
53+
Interval: 10,
54+
QueryPatt: "abc",
55+
Target: "abc",
56+
Datapoints: getCopy(c),
57+
},
58+
},
59+
},
60+
)
61+
out := []models.Series{
62+
{
63+
Interval: 10,
64+
QueryPatt: "a",
65+
Target: "a",
66+
Datapoints: getCopy(a),
67+
},
68+
{
69+
Interval: 10,
70+
QueryPatt: "b",
71+
Target: "b",
72+
Datapoints: getCopy(b),
73+
},
74+
{
75+
Interval: 10,
76+
QueryPatt: "abc",
77+
Target: "abc",
78+
Datapoints: getCopy(a),
79+
},
80+
{
81+
Interval: 10,
82+
QueryPatt: "abc",
83+
Target: "abc",
84+
Datapoints: getCopy(b),
85+
},
86+
{
87+
Interval: 10,
88+
QueryPatt: "abc",
89+
Target: "abc",
90+
Datapoints: getCopy(c),
91+
},
92+
}
93+
94+
got, err := f.Exec(make(map[Req][]models.Series))
95+
if err := equalOutput(out, got, nil, err); err != nil {
96+
t.Fatal(err)
97+
}
98+
}
99+
func BenchmarkGroup10k_1NoNulls(b *testing.B) {
100+
benchmarkGroup(b, 1, test.RandFloats10k, test.RandFloats10k)
101+
}
102+
func BenchmarkGroup10k_10NoNulls(b *testing.B) {
103+
benchmarkGroup(b, 10, test.RandFloats10k, test.RandFloats10k)
104+
}
105+
func BenchmarkGroup10k_100NoNulls(b *testing.B) {
106+
benchmarkGroup(b, 100, test.RandFloats10k, test.RandFloats10k)
107+
}
108+
func BenchmarkGroup10k_1000NoNulls(b *testing.B) {
109+
benchmarkGroup(b, 1000, test.RandFloats10k, test.RandFloats10k)
110+
}
111+
func BenchmarkGroup10k_1SomeSeriesHalfNulls(b *testing.B) {
112+
benchmarkGroup(b, 1, test.RandFloats10k, test.RandFloatsWithNulls10k)
113+
}
114+
func BenchmarkGroup10k_10SomeSeriesHalfNulls(b *testing.B) {
115+
benchmarkGroup(b, 10, test.RandFloats10k, test.RandFloatsWithNulls10k)
116+
}
117+
func BenchmarkGroup10k_100SomeSeriesHalfNulls(b *testing.B) {
118+
benchmarkGroup(b, 100, test.RandFloats10k, test.RandFloatsWithNulls10k)
119+
}
120+
func BenchmarkGroup10k_1000SomeSeriesHalfNulls(b *testing.B) {
121+
benchmarkGroup(b, 1000, test.RandFloats10k, test.RandFloatsWithNulls10k)
122+
}
123+
func BenchmarkGroup10k_1AllSeriesHalfNulls(b *testing.B) {
124+
benchmarkGroup(b, 1, test.RandFloatsWithNulls10k, test.RandFloatsWithNulls10k)
125+
}
126+
func BenchmarkGroup10k_10AllSeriesHalfNulls(b *testing.B) {
127+
benchmarkGroup(b, 10, test.RandFloatsWithNulls10k, test.RandFloatsWithNulls10k)
128+
}
129+
func BenchmarkGroup10k_100AllSeriesHalfNulls(b *testing.B) {
130+
benchmarkGroup(b, 100, test.RandFloatsWithNulls10k, test.RandFloatsWithNulls10k)
131+
}
132+
func BenchmarkGroup10k_1000AllSeriesHalfNulls(b *testing.B) {
133+
benchmarkGroup(b, 1000, test.RandFloatsWithNulls10k, test.RandFloatsWithNulls10k)
134+
}
135+
func benchmarkGroup(b *testing.B, numSeries int, fn0, fn1 func() []schema.Point) {
136+
var input []models.Series
137+
for i := 0; i < numSeries; i++ {
138+
series := models.Series{
139+
QueryPatt: strconv.Itoa(i),
140+
}
141+
if i%2 == 0 {
142+
series.Datapoints = fn0()
143+
} else {
144+
series.Datapoints = fn1()
145+
}
146+
input = append(input, series)
147+
}
148+
b.ResetTimer()
149+
for i := 0; i < b.N; i++ {
150+
f := NewGroup()
151+
f.(*FuncGroup).in = append(f.(*FuncGroup).in, NewMock(input))
152+
got, err := f.Exec(make(map[Req][]models.Series))
153+
if err != nil {
154+
b.Fatalf("%s", err)
155+
}
156+
results = got
157+
}
158+
}

expr/funcs.go

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ func init() {
7171
"fallbackSeries": {NewFallbackSeries, true},
7272
"filterSeries": {NewFilterSeries, true},
7373
"grep": {NewGrep, true},
74+
"group": {NewGroup, true},
7475
"groupByTags": {NewGroupByTags, true},
7576
"highest": {NewHighestLowestConstructor("", true), true},
7677
"highestAverage": {NewHighestLowestConstructor("average", true), true},

0 commit comments

Comments
 (0)