-
Notifications
You must be signed in to change notification settings - Fork 1
/
util.go
77 lines (65 loc) · 1.4 KB
/
util.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
package instruments
import (
"strings"
"sync"
)
var bufferPool sync.Pool
func pooledBuffer(minCap int) []byte {
if v := bufferPool.Get(); v != nil {
if p := *(v.(*[]byte)); cap(p) <= minCap {
return p[:0]
}
}
return make([]byte, 0, minCap)
}
// MetricID takes a name and tags and generates a consistent
// metric identifier
func MetricID(name string, tags []string) string {
if len(tags) == 0 {
return name
}
size := len(name)
for _, t := range tags {
if t != "" {
size += len(t) + 1
}
}
buf := pooledBuffer(size)
buf = append(buf, name...)
defer bufferPool.Put(&buf)
for pos, tag := 0, ""; pos < len(tags); pos++ {
if next := findMinString(tags, tag); next > tag {
tag = next
} else {
break
}
if pos == 0 {
buf = append(buf, '|')
} else {
buf = append(buf, ',')
}
buf = append(buf, tag...)
}
return string(buf)
}
// SplitMetricID takes a metric ID and splits it into
// name and tags.
func SplitMetricID(metricID string) (name string, tags []string) {
if metricID == "" {
return "", nil
}
pos := strings.LastIndexByte(metricID, '|')
if pos > 0 && pos < len(metricID)-1 {
return metricID[:pos], strings.Split(metricID[pos+1:], ",")
}
return metricID, nil
}
func findMinString(slice []string, greaterThan string) string {
min := greaterThan
for _, s := range slice {
if s > greaterThan && (min == greaterThan || s < min) {
min = s
}
}
return min
}