Skip to content

Commit 41ecb6c

Browse files
author
beorn7
committed
Improve the Metric.Equal and Metric.Before methods.
1 parent 0e0e6bf commit 41ecb6c

File tree

3 files changed

+63
-23
lines changed

3 files changed

+63
-23
lines changed

model/metric.go

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,68 @@ var separator = []byte{0}
2626
// a singleton and refers to one and only one stream of samples.
2727
type Metric map[LabelName]LabelValue
2828

29-
// Equal compares the fingerprints of both metrics.
29+
// Equal compares the metrics.
3030
func (m Metric) Equal(o Metric) bool {
31-
// TODO do an actual map comparison
32-
return m.Fingerprint().Equal(o.Fingerprint())
31+
if len(m) != len(o) {
32+
return false
33+
}
34+
for ln, lv := range m {
35+
olv, ok := o[ln]
36+
if !ok {
37+
return false
38+
}
39+
if olv != lv {
40+
return false
41+
}
42+
}
43+
return true
3344
}
3445

35-
// Before compares the fingerprints of both metrics.
46+
// Before compares the metrics, using the following criteria:
47+
//
48+
// If m has fewer labels than o, it is before o. If it has more, it is not.
49+
//
50+
// If the number of labels is the same, the superset of all label names is
51+
// sorted alphanumerically. The first differing label pair found in that order
52+
// determines the outcome: If the label does not exist at all in m, then m is
53+
// before o, and vice versa. Otherwise the label value is compared
54+
// alphanumerically.
55+
//
56+
// If m and o are equal, the method returns false.
3657
func (m Metric) Before(o Metric) bool {
37-
// TODO do an actual map comparison
38-
return m.Fingerprint().Less(o.Fingerprint())
58+
if len(m) < len(o) {
59+
return true
60+
}
61+
if len(m) > len(o) {
62+
return false
63+
}
64+
65+
lns := make(LabelNames, 0, len(m)+len(o))
66+
for ln := range m {
67+
lns = append(lns, ln)
68+
}
69+
for ln := range o {
70+
lns = append(lns, ln)
71+
}
72+
// It's probably not worth it to de-dup lns.
73+
sort.Sort(lns)
74+
for _, ln := range lns {
75+
mlv, ok := m[ln]
76+
if !ok {
77+
return true
78+
}
79+
olv, ok := o[ln]
80+
if !ok {
81+
return false
82+
}
83+
if mlv < olv {
84+
return true
85+
}
86+
if mlv > olv {
87+
return false
88+
}
89+
}
90+
return false
3991
}
4092

4193
// String implements Stringer.

model/sample_test.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,42 +21,36 @@ import (
2121
func TestSamplesSort(t *testing.T) {
2222
input := Samples{
2323
&Sample{
24-
// Fingerprint: 81f9c9ed24563f8f.
2524
Metric: Metric{
2625
MetricNameLabel: "A",
2726
},
2827
Timestamp: 1,
2928
},
3029
&Sample{
31-
// Fingerprint: 81f9c9ed24563f8f.
3230
Metric: Metric{
3331
MetricNameLabel: "A",
3432
},
3533
Timestamp: 2,
3634
},
3735
&Sample{
38-
// Fingerprint: 1bf6c9ed24543f8f.
3936
Metric: Metric{
4037
MetricNameLabel: "C",
4138
},
4239
Timestamp: 1,
4340
},
4441
&Sample{
45-
// Fingerprint: 1bf6c9ed24543f8f.
4642
Metric: Metric{
4743
MetricNameLabel: "C",
4844
},
4945
Timestamp: 2,
5046
},
5147
&Sample{
52-
// Fingerprint: 68f4c9ed24533f8f.
5348
Metric: Metric{
5449
MetricNameLabel: "B",
5550
},
5651
Timestamp: 1,
5752
},
5853
&Sample{
59-
// Fingerprint: 68f4c9ed24533f8f.
6054
Metric: Metric{
6155
MetricNameLabel: "B",
6256
},
@@ -66,44 +60,38 @@ func TestSamplesSort(t *testing.T) {
6660

6761
expected := Samples{
6862
&Sample{
69-
// Fingerprint: 1bf6c9ed24543f8f.
7063
Metric: Metric{
71-
MetricNameLabel: "C",
64+
MetricNameLabel: "A",
7265
},
7366
Timestamp: 1,
7467
},
7568
&Sample{
76-
// Fingerprint: 1bf6c9ed24543f8f.
7769
Metric: Metric{
78-
MetricNameLabel: "C",
70+
MetricNameLabel: "A",
7971
},
8072
Timestamp: 2,
8173
},
8274
&Sample{
83-
// Fingerprint: 68f4c9ed24533f8f.
8475
Metric: Metric{
8576
MetricNameLabel: "B",
8677
},
8778
Timestamp: 1,
8879
},
8980
&Sample{
90-
// Fingerprint: 68f4c9ed24533f8f.
9181
Metric: Metric{
9282
MetricNameLabel: "B",
9383
},
9484
Timestamp: 2,
9585
},
9686
&Sample{
97-
// Fingerprint: 81f9c9ed24563f8f.
9887
Metric: Metric{
99-
MetricNameLabel: "A",
88+
MetricNameLabel: "C",
10089
},
10190
Timestamp: 1,
10291
},
10392
&Sample{
104-
// Fingerprint: 81f9c9ed24563f8f.
10593
Metric: Metric{
106-
MetricNameLabel: "A",
94+
MetricNameLabel: "C",
10795
},
10896
Timestamp: 2,
10997
},

model/signature.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func putHashAndBuf(hb *hashAndBuf) {
5252
hashAndBufPool.Put(hb)
5353
}
5454

55-
// LabelsToSignature returns an quasi-unique signature (i.e., fingerprint) for a
55+
// LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a
5656
// given label set. (Collisions are possible but unlikely if the number of label
5757
// sets the function is applied to is small.)
5858
func LabelsToSignature(labels map[string]string) uint64 {

0 commit comments

Comments
 (0)