-
Notifications
You must be signed in to change notification settings - Fork 83
/
label.go
73 lines (65 loc) · 1.63 KB
/
label.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
package tstorage
import (
"sort"
"github.com/nakabonne/tstorage/internal/encoding"
)
const (
// The maximum length of label name.
//
// Longer names are truncated.
maxLabelNameLen = 256
// The maximum length of label value.
//
// Longer values are truncated.
maxLabelValueLen = 16 * 1024
)
// Label is a time-series label.
// A label with missing name or value is invalid.
type Label struct {
Name string
Value string
}
// marshalMetricName builds a unique bytes by encoding labels.
func marshalMetricName(metric string, labels []Label) string {
if len(labels) == 0 {
return metric
}
invalid := func(name, value string) bool {
return name == "" || value == ""
}
// Determine the bytes size in advance.
size := len(metric) + 2
sort.Slice(labels, func(i, j int) bool {
return labels[i].Name < labels[j].Name
})
for i := range labels {
label := &labels[i]
if invalid(label.Name, label.Value) {
continue
}
if len(label.Name) > maxLabelNameLen {
label.Name = label.Name[:maxLabelNameLen]
}
if len(label.Value) > maxLabelValueLen {
label.Value = label.Value[:maxLabelValueLen]
}
size += len(label.Name)
size += len(label.Value)
size += 4
}
// Start building the bytes.
out := make([]byte, 0, size)
out = encoding.MarshalUint16(out, uint16(len(metric)))
out = append(out, metric...)
for i := range labels {
label := &labels[i]
if invalid(label.Name, label.Value) {
continue
}
out = encoding.MarshalUint16(out, uint16(len(label.Name)))
out = append(out, label.Name...)
out = encoding.MarshalUint16(out, uint16(len(label.Value)))
out = append(out, label.Value...)
}
return string(out)
}