Skip to content

Commit df0de47

Browse files
committed
Merge branch 'metric-id'
2 parents 9890e50 + f106b03 commit df0de47

File tree

11 files changed

+172
-115
lines changed

11 files changed

+172
-115
lines changed

helper/point/func.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func CleanUp(points []Point) []Point {
1313
squashed := 0
1414

1515
for i := 0; i < l; i++ {
16-
if points[i].Metric == "" || math.IsNaN(points[i].Value) {
16+
if points[i].MetricID == 0 || math.IsNaN(points[i].Value) {
1717
squashed++
1818
continue
1919
}
@@ -33,7 +33,7 @@ func Uniq(points []Point) []Point {
3333
// n - position on first record with current key (metric + time)
3434

3535
for i = 1; i < l; i++ {
36-
if points[i].Metric != points[n].Metric ||
36+
if points[i].MetricID != points[n].MetricID ||
3737
points[i].Time != points[n].Time {
3838
n = i
3939
continue
@@ -43,7 +43,7 @@ func Uniq(points []Point) []Point {
4343
points[n] = points[i]
4444
}
4545

46-
points[i].Metric = "" // mark for remove
46+
points[i].MetricID = 0 // mark for remove
4747
}
4848

4949
return CleanUp(points)
@@ -55,7 +55,7 @@ func AssertListEq(t *testing.T, expected, actual []Point) {
5555
}
5656

5757
for i := 0; i < len(actual); i++ {
58-
if (actual[i].Metric != expected[i].Metric) ||
58+
if (actual[i].MetricID != expected[i].MetricID) ||
5959
(actual[i].Time != expected[i].Time) ||
6060
(actual[i].Timestamp != expected[i].Timestamp) ||
6161
(actual[i].Value != expected[i].Value) {

helper/point/func_test.go

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,34 @@ func TestUniq(t *testing.T) {
1010
tests := [][2][]Point{
1111
{
1212
{ // in
13-
Point{Metric: "metric", Time: 1478025152, Timestamp: 1, Value: 1},
14-
Point{Metric: "metric", Time: 1478025152, Timestamp: 2, Value: 2},
15-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: 1},
13+
Point{MetricID: 1, Time: 1478025152, Timestamp: 1, Value: 1},
14+
Point{MetricID: 1, Time: 1478025152, Timestamp: 2, Value: 2},
15+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: 1},
1616
},
1717
{ // out
18-
Point{Metric: "metric", Time: 1478025152, Timestamp: 2, Value: 2},
19-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: 1},
18+
Point{MetricID: 1, Time: 1478025152, Timestamp: 2, Value: 2},
19+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: 1},
2020
},
2121
},
2222
{
2323
{ // in
24-
Point{Metric: "metric", Time: 1478025152, Timestamp: 3, Value: 1},
25-
Point{Metric: "metric", Time: 1478025152, Timestamp: 2, Value: 2},
26-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: 1},
24+
Point{MetricID: 1, Time: 1478025152, Timestamp: 3, Value: 1},
25+
Point{MetricID: 1, Time: 1478025152, Timestamp: 2, Value: 2},
26+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: 1},
2727
},
2828
{ // out
29-
Point{Metric: "metric", Time: 1478025152, Timestamp: 3, Value: 1},
30-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: 1},
29+
Point{MetricID: 1, Time: 1478025152, Timestamp: 3, Value: 1},
30+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: 1},
3131
},
3232
},
3333
{
3434
{ // in
35-
Point{Metric: "metric", Time: 1478025152, Timestamp: 3, Value: math.NaN()},
36-
Point{Metric: "metric", Time: 1478025152, Timestamp: 2, Value: 2},
37-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: 1},
35+
Point{MetricID: 1, Time: 1478025152, Timestamp: 3, Value: math.NaN()},
36+
Point{MetricID: 1, Time: 1478025152, Timestamp: 2, Value: 2},
37+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: 1},
3838
},
3939
{ // out
40-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: 1},
40+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: 1},
4141
},
4242
},
4343
}
@@ -52,42 +52,42 @@ func TestCleanUp(t *testing.T) {
5252
tests := [][2][]Point{
5353
{
5454
{ // in
55-
Point{Metric: "metric", Time: 1478025152, Timestamp: 1, Value: 1},
56-
Point{Metric: "", Time: 1478025152, Timestamp: 2, Value: 2},
57-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: 1},
55+
Point{MetricID: 1, Time: 1478025152, Timestamp: 1, Value: 1},
56+
Point{MetricID: 0, Time: 1478025152, Timestamp: 2, Value: 2},
57+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: 1},
5858
},
5959
{ // out
60-
Point{Metric: "metric", Time: 1478025152, Timestamp: 1, Value: 1},
61-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: 1},
60+
Point{MetricID: 1, Time: 1478025152, Timestamp: 1, Value: 1},
61+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: 1},
6262
},
6363
},
6464
{
6565
{ // in
66-
Point{Metric: "", Time: 1478025152, Timestamp: 3, Value: 1},
67-
Point{Metric: "", Time: 1478025152, Timestamp: 2, Value: 2},
68-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: 1},
66+
Point{MetricID: 0, Time: 1478025152, Timestamp: 3, Value: 1},
67+
Point{MetricID: 0, Time: 1478025152, Timestamp: 2, Value: 2},
68+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: 1},
6969
},
7070
{ // out
71-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: 1},
71+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: 1},
7272
},
7373
},
7474
{
7575
{ // in
76-
Point{Metric: "", Time: 1478025152, Timestamp: 3, Value: 1},
77-
Point{Metric: "", Time: 1478025152, Timestamp: 2, Value: 2},
78-
Point{Metric: "", Time: 1478025155, Timestamp: 1, Value: 1},
76+
Point{MetricID: 0, Time: 1478025152, Timestamp: 3, Value: 1},
77+
Point{MetricID: 0, Time: 1478025152, Timestamp: 2, Value: 2},
78+
Point{MetricID: 0, Time: 1478025155, Timestamp: 1, Value: 1},
7979
},
8080
{ // out
8181
},
8282
},
8383
{
8484
{ // in
85-
Point{Metric: "metric", Time: 1478025152, Timestamp: 3, Value: math.NaN()},
86-
Point{Metric: "metric", Time: 1478025152, Timestamp: 2, Value: 2},
87-
Point{Metric: "metric", Time: 1478025155, Timestamp: 1, Value: math.NaN()},
85+
Point{MetricID: 1, Time: 1478025152, Timestamp: 3, Value: math.NaN()},
86+
Point{MetricID: 1, Time: 1478025152, Timestamp: 2, Value: 2},
87+
Point{MetricID: 1, Time: 1478025155, Timestamp: 1, Value: math.NaN()},
8888
},
8989
{ // out
90-
Point{Metric: "metric", Time: 1478025152, Timestamp: 2, Value: 2},
90+
Point{MetricID: 1, Time: 1478025152, Timestamp: 2, Value: 2},
9191
},
9292
},
9393
}

helper/point/point.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package point
22

33
type Point struct {
4-
Metric string
4+
MetricID uint32
55
Value float64
66
Time uint32
77
Timestamp uint32 // keep max if metric and time equal on two points

helper/point/points.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package point
2+
3+
import "sort"
4+
5+
type Points struct {
6+
list []Point
7+
idMap map[string]uint32
8+
metrics []string
9+
}
10+
11+
func NewPoints() *Points {
12+
return &Points{
13+
list: make([]Point, 0),
14+
idMap: make(map[string]uint32),
15+
metrics: make([]string, 0),
16+
}
17+
}
18+
19+
func (pp *Points) AppendPoint(metricID uint32, value float64, time uint32, version uint32) {
20+
pp.list = append(pp.list, Point{
21+
MetricID: metricID,
22+
Value: value,
23+
Time: time,
24+
Timestamp: version,
25+
})
26+
}
27+
28+
func (pp *Points) MetricID(metricName string) uint32 {
29+
id := pp.idMap[metricName]
30+
if id == 0 {
31+
pp.metrics = append(pp.metrics, metricName)
32+
id = uint32(len(pp.metrics))
33+
pp.idMap[metricName] = id
34+
}
35+
return id
36+
}
37+
38+
func (pp *Points) MetricName(metricID uint32) string {
39+
i := int(metricID)
40+
if i > len(pp.metrics) || i < 1 {
41+
return ""
42+
}
43+
return pp.metrics[i-1]
44+
}
45+
46+
func (pp *Points) List() []Point {
47+
return pp.list
48+
}
49+
50+
func (pp *Points) Len() int {
51+
return len(pp.list)
52+
}
53+
54+
func (pp *Points) Less(i, j int) bool {
55+
if pp.list[i].MetricID == pp.list[j].MetricID {
56+
return pp.list[i].Time < pp.list[j].Time
57+
}
58+
59+
return pp.list[i].MetricID < pp.list[j].MetricID
60+
}
61+
62+
func (pp *Points) Swap(i, j int) {
63+
pp.list[i], pp.list[j] = pp.list[j], pp.list[i]
64+
}
65+
66+
func (pp *Points) Sort() {
67+
sort.Sort(pp)
68+
}
69+
70+
func (pp *Points) Uniq() {
71+
pp.list = Uniq(pp.list)
72+
}

helper/rollup/rollup.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ func doMetricPrecision(points []point.Point, precision uint32, aggr func([]point
182182
points[i].Time = t
183183

184184
if points[n].Time == t {
185-
points[i].Metric = ""
185+
points[i].MetricID = 0
186186
} else {
187187
if i > n+1 {
188188
points[n].Value = aggr(points[n:i])
@@ -199,7 +199,7 @@ func doMetricPrecision(points []point.Point, precision uint32, aggr func([]point
199199

200200
// RollupMetric rolling up list of points of ONE metric sorted by key "time"
201201
// returns (new points slice, precision)
202-
func (r *Rollup) RollupMetric(points []point.Point) ([]point.Point, uint32) {
202+
func (r *Rollup) RollupMetric(metricName string, points []point.Point) ([]point.Point, uint32) {
203203
// pp.Println(points)
204204

205205
l := len(points)
@@ -208,7 +208,7 @@ func (r *Rollup) RollupMetric(points []point.Point) ([]point.Point, uint32) {
208208
}
209209

210210
now := uint32(time.Now().Unix())
211-
rule := r.Match(points[0].Metric)
211+
rule := r.Match(metricName)
212212
precision := uint32(1)
213213

214214
for _, retention := range rule.Retention {

helper/rollup/rollup_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,13 @@ func TestMetricPrecision(t *testing.T) {
109109
tests := [][2][]point.Point{
110110
{
111111
{ // in
112-
{Metric: "metric", Time: 1478025152, Value: 3},
113-
{Metric: "metric", Time: 1478025154, Value: 2},
114-
{Metric: "metric", Time: 1478025255, Value: 1},
112+
{MetricID: 1, Time: 1478025152, Value: 3},
113+
{MetricID: 1, Time: 1478025154, Value: 2},
114+
{MetricID: 1, Time: 1478025255, Value: 1},
115115
},
116116
{ // out
117-
{Metric: "metric", Time: 1478025120, Value: 5},
118-
{Metric: "metric", Time: 1478025240, Value: 1},
117+
{MetricID: 1, Time: 1478025120, Value: 5},
118+
{MetricID: 1, Time: 1478025240, Value: 1},
119119
},
120120
},
121121
}

render/data.go

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"bytes"
66
"encoding/binary"
77
"errors"
8-
"fmt"
98
"io"
109
"math"
1110
"strings"
@@ -54,11 +53,13 @@ func ReadUvarint(array []byte) (uint64, int, error) {
5453

5554
type Data struct {
5655
body []byte // raw RowBinary from clickhouse
57-
Points []point.Point
56+
Points *point.Points
5857
nameMap map[string]string
5958
Aliases map[string][]string
6059
}
6160

61+
var EmptyData *Data = &Data{Points: point.NewPoints()}
62+
6263
func (d *Data) finalName(name string) string {
6364
s, ok := d.nameMap[name]
6465
if !ok {
@@ -100,24 +101,29 @@ func DataSplitFunc(data []byte, atEOF bool) (advance int, token []byte, err erro
100101
return tokenLen, data[:tokenLen], nil
101102
}
102103

103-
func DataParse(bodyReader io.Reader, extraPoints []point.Point, isReverse bool) (*Data, error) {
104-
104+
func DataParse(bodyReader io.Reader, extraPoints *point.Points, isReverse bool) (*Data, error) {
105105
d := &Data{
106-
Points: make([]point.Point, 0, len(extraPoints)),
107-
nameMap: make(map[string]string),
106+
Points: point.NewPoints(),
108107
}
109108

110-
var p point.Point
109+
pp := d.Points
111110

112111
// add extraPoints. With NameToID
113-
for i := 0; i < len(extraPoints); i++ {
114-
extraPoints[i].Metric = d.finalName(extraPoints[i].Metric)
115-
d.Points = append(d.Points, extraPoints[i])
112+
if extraPoints != nil {
113+
extraList := extraPoints.List()
114+
for i := 0; i < len(extraList); i++ {
115+
pp.AppendPoint(
116+
pp.MetricID(extraPoints.MetricName(extraList[i].MetricID)),
117+
extraList[i].Value,
118+
extraList[i].Time,
119+
extraList[i].Timestamp,
120+
)
121+
}
116122
}
117123

118124
nameBuf := make([]byte, 65536)
119125
name := []byte{}
120-
finalName := ""
126+
var metricID uint32
121127

122128
scanner := bufio.NewScanner(bodyReader)
123129
scanner.Buffer(make([]byte, 1048576), 1048576)
@@ -135,7 +141,6 @@ func DataParse(bodyReader io.Reader, extraPoints []point.Point, isReverse bool)
135141
newName := row[:int(namelen)]
136142
row = row[int(namelen):]
137143

138-
fmt.Println("cmp", string(name), string(newName))
139144
if bytes.Compare(newName, name) != 0 {
140145
if len(newName) > len(nameBuf) {
141146
name = make([]byte, len(newName))
@@ -145,9 +150,9 @@ func DataParse(bodyReader io.Reader, extraPoints []point.Point, isReverse bool)
145150
name = nameBuf[:len(newName)]
146151
}
147152
if isReverse {
148-
finalName = d.finalName(reversePath(string(name)))
153+
metricID = pp.MetricID(reversePath(string(name)))
149154
} else {
150-
finalName = d.finalName(string(name))
155+
metricID = pp.MetricID(string(name))
151156
}
152157
}
153158

@@ -159,11 +164,7 @@ func DataParse(bodyReader io.Reader, extraPoints []point.Point, isReverse bool)
159164

160165
timestamp := binary.LittleEndian.Uint32(row[:4])
161166

162-
p.Metric = finalName
163-
p.Time = time
164-
p.Value = value
165-
p.Timestamp = timestamp
166-
d.Points = append(d.Points, p)
167+
pp.AppendPoint(metricID, value, time, timestamp)
167168
}
168169

169170
if err := scanner.Err(); err != nil {
@@ -172,19 +173,3 @@ func DataParse(bodyReader io.Reader, extraPoints []point.Point, isReverse bool)
172173

173174
return d, nil
174175
}
175-
176-
func (d *Data) Len() int {
177-
return len(d.Points)
178-
}
179-
180-
func (d *Data) Less(i, j int) bool {
181-
if d.Points[i].Metric == d.Points[j].Metric {
182-
return d.Points[i].Time < d.Points[j].Time
183-
}
184-
185-
return d.Points[i].Metric < d.Points[j].Metric
186-
}
187-
188-
func (d *Data) Swap(i, j int) {
189-
d.Points[i], d.Points[j] = d.Points[j], d.Points[i]
190-
}

0 commit comments

Comments
 (0)