提交 5efe1d17 编写于 作者: F Fabian Reinartz

labels: add Compare and String methods

上级 0d0c5cfa
package labels
import (
"bytes"
"sort"
"strconv"
"strings"
"github.com/cespare/xxhash"
)
......@@ -21,6 +24,23 @@ func (ls Labels) Len() int { return len(ls) }
func (ls Labels) Swap(i, j int) { ls[i], ls[j] = ls[j], ls[i] }
func (ls Labels) Less(i, j int) bool { return ls[i].Name < ls[j].Name }
func (ls Labels) String() string {
var b bytes.Buffer
b.WriteByte('{')
for i, l := range ls {
if i > 0 {
b.WriteByte(',')
}
b.WriteString(l.Name)
b.WriteByte('=')
b.WriteString(strconv.Quote(l.Value))
}
b.WriteByte('}')
return b.String()
}
// Hash returns a hash value for the label set.
func (ls Labels) Hash() uint64 {
b := make([]byte, 0, 1024)
......@@ -101,3 +121,23 @@ func FromStrings(ss ...string) Labels {
sort.Sort(res)
return res
}
// Compare compares the two label sets.
// The result will be 0 if a==b, <0 if a < b, and >0 if a > b.
func Compare(a, b Labels) int {
l := len(a)
if len(b) < l {
l = len(b)
}
for i := 0; i < l; i++ {
if d := strings.Compare(a[i].Name, b[i].Name); d != 0 {
return d
}
if d := strings.Compare(a[i].Value, b[i].Value); d != 0 {
return d
}
}
// If all labels so far were in common, the set with fewer labels comes first.
return len(a) - len(b)
}
......@@ -340,26 +340,6 @@ func newShardSeriesSet(a, b SeriesSet) *shardSeriesSet {
return s
}
// compareLabels compares the two label sets.
// The result will be 0 if a==b, <0 if a < b, and >0 if a > b.
func compareLabels(a, b labels.Labels) int {
l := len(a)
if len(b) < l {
l = len(b)
}
for i := 0; i < l; i++ {
if d := strings.Compare(a[i].Name, b[i].Name); d != 0 {
return d
}
if d := strings.Compare(a[i].Value, b[i].Value); d != 0 {
return d
}
}
// If all labels so far were in common, the set with fewer labels comes first.
return len(a) - len(b)
}
func (s *shardSeriesSet) Series() Series {
return s.cur
}
......@@ -378,7 +358,7 @@ func (s *shardSeriesSet) compare() int {
if s.bs == nil {
return -1
}
return compareLabels(s.as.Labels(), s.bs.Labels())
return labels.Compare(s.as.Labels(), s.bs.Labels())
}
func (s *shardSeriesSet) advanceA() {
......
......@@ -175,58 +175,6 @@ func expandSeriesIterator(it SeriesIterator) (r []sample, err error) {
return r, it.Err()
}
func TestCompareLabels(t *testing.T) {
cases := []struct {
a, b []labels.Label
res int
}{
{
a: []labels.Label{},
b: []labels.Label{},
res: 0,
},
{
a: []labels.Label{{"a", ""}},
b: []labels.Label{{"a", ""}, {"b", ""}},
res: -1,
},
{
a: []labels.Label{{"a", ""}},
b: []labels.Label{{"a", ""}},
res: 0,
},
{
a: []labels.Label{{"aa", ""}, {"aa", ""}},
b: []labels.Label{{"aa", ""}, {"ab", ""}},
res: -1,
},
{
a: []labels.Label{{"aa", ""}, {"abb", ""}},
b: []labels.Label{{"aa", ""}, {"ab", ""}},
res: 1,
},
{
a: []labels.Label{
{"__name__", "go_gc_duration_seconds"},
{"job", "prometheus"},
{"quantile", "0.75"},
},
b: []labels.Label{
{"__name__", "go_gc_duration_seconds"},
{"job", "prometheus"},
{"quantile", "1"},
},
res: -1,
},
}
for _, c := range cases {
// Use constructor to ensure sortedness.
a, b := labels.New(c.a...), labels.New(c.b...)
require.Equal(t, c.res, compareLabels(a, b))
}
}
func TestSampleRing(t *testing.T) {
cases := []struct {
input []int64
......
......@@ -325,7 +325,7 @@ func (w *indexWriter) writeSeries() error {
series = append(series, s)
}
slice.Sort(series, func(i, j int) bool {
return compareLabels(series[i].labels, series[j].labels) < 0
return labels.Compare(series[i].labels, series[j].labels) < 0
})
// Current end of file plus 5 bytes for section header.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册