|
14 | 14 | package model
|
15 | 15 |
|
16 | 16 | import (
|
| 17 | + "bytes" |
17 | 18 | "encoding/json"
|
18 | 19 | "fmt"
|
| 20 | + "slices" |
19 | 21 | "sort"
|
20 |
| - "strings" |
| 22 | + "strconv" |
21 | 23 | )
|
22 | 24 |
|
23 | 25 | // A LabelSet is a collection of LabelName and LabelValue pairs. The LabelSet
|
@@ -129,17 +131,27 @@ func (l LabelSet) Merge(other LabelSet) LabelSet {
|
129 | 131 | return result
|
130 | 132 | }
|
131 | 133 |
|
| 134 | +// String will look like `{foo="bar", more="less"}`. Names are sorted alphabetically. |
132 | 135 | func (l LabelSet) String() string {
|
133 |
| - labelNames := make([]string, 0, len(l)) |
| 136 | + var lna [32]LabelName // On stack to avoid memory allocation for sorting names. |
| 137 | + labelNames := lna[:0] |
134 | 138 | for name := range l {
|
135 |
| - labelNames = append(labelNames, string(name)) |
| 139 | + labelNames = append(labelNames, name) |
136 | 140 | }
|
137 |
| - sort.Strings(labelNames) |
138 |
| - lstrs := make([]string, 0, len(l)) |
139 |
| - for _, name := range labelNames { |
140 |
| - lstrs = append(lstrs, fmt.Sprintf("%s=%q", name, l[LabelName(name)])) |
| 141 | + slices.Sort(labelNames) |
| 142 | + var bytea [1024]byte // On stack to avoid memory allocation while building the output. |
| 143 | + b := bytes.NewBuffer(bytea[:0]) |
| 144 | + b.WriteByte('{') |
| 145 | + for i, name := range labelNames { |
| 146 | + if i > 0 { |
| 147 | + b.WriteString(", ") |
| 148 | + } |
| 149 | + b.WriteString(string(name)) |
| 150 | + b.WriteByte('=') |
| 151 | + b.Write(strconv.AppendQuote(b.AvailableBuffer(), string(l[name]))) |
141 | 152 | }
|
142 |
| - return fmt.Sprintf("{%s}", strings.Join(lstrs, ", ")) |
| 153 | + b.WriteByte('}') |
| 154 | + return b.String() |
143 | 155 | }
|
144 | 156 |
|
145 | 157 | // Fingerprint returns the LabelSet's fingerprint.
|
|
0 commit comments