Skip to content

Commit 6fa68aa

Browse files
committed
Merge pull request #116 from prometheus/beorn7/fingerprint
Fingerprinting fixes in client_golang
2 parents 86bd077 + 41ecb6c commit 6fa68aa

File tree

5 files changed

+221
-76
lines changed

5 files changed

+221
-76
lines changed

model/metric.go

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +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-
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
3244
}
3345

34-
// 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.
3557
func (m Metric) Before(o Metric) bool {
36-
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
3791
}
3892

3993
// String implements Stringer.
@@ -67,6 +121,12 @@ func (m Metric) Fingerprint() Fingerprint {
67121
return metricToFingerprint(m)
68122
}
69123

124+
// Fingerprint returns a Metric's Fingerprint calculated by a faster hashing
125+
// algorithm, which is, however, more susceptible to hash collisions.
126+
func (m Metric) FastFingerprint() Fingerprint {
127+
return metricToFastFingerprint(m)
128+
}
129+
70130
// Clone returns a copy of the Metric.
71131
func (m Metric) Clone() Metric {
72132
clone := Metric{}

model/metric_test.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,47 +17,56 @@ import "testing"
1717

1818
func testMetric(t testing.TB) {
1919
var scenarios = []struct {
20-
input Metric
21-
fingerprint Fingerprint
20+
input Metric
21+
fingerprint Fingerprint
22+
fastFingerprint Fingerprint
2223
}{
2324
{
24-
input: Metric{},
25-
fingerprint: 14695981039346656037,
25+
input: Metric{},
26+
fingerprint: 14695981039346656037,
27+
fastFingerprint: 14695981039346656037,
2628
},
2729
{
2830
input: Metric{
2931
"first_name": "electro",
3032
"occupation": "robot",
3133
"manufacturer": "westinghouse",
3234
},
33-
fingerprint: 11310079640881077873,
35+
fingerprint: 5911716720268894962,
36+
fastFingerprint: 11310079640881077873,
3437
},
3538
{
3639
input: Metric{
3740
"x": "y",
3841
},
39-
fingerprint: 13948396922932177635,
42+
fingerprint: 8241431561484471700,
43+
fastFingerprint: 13948396922932177635,
4044
},
4145
{
4246
input: Metric{
4347
"a": "bb",
4448
"b": "c",
4549
},
46-
fingerprint: 3198632812309449502,
50+
fingerprint: 3016285359649981711,
51+
fastFingerprint: 3198632812309449502,
4752
},
4853
{
4954
input: Metric{
5055
"a": "b",
5156
"bb": "c",
5257
},
53-
fingerprint: 5774953389407657638,
58+
fingerprint: 7122421792099404749,
59+
fastFingerprint: 5774953389407657638,
5460
},
5561
}
5662

5763
for i, scenario := range scenarios {
5864
if scenario.fingerprint != scenario.input.Fingerprint() {
5965
t.Errorf("%d. expected %d, got %d", i, scenario.fingerprint, scenario.input.Fingerprint())
6066
}
67+
if scenario.fastFingerprint != scenario.input.FastFingerprint() {
68+
t.Errorf("%d. expected %d, got %d", i, scenario.fastFingerprint, scenario.input.FastFingerprint())
69+
}
6170
}
6271
}
6372

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
},

0 commit comments

Comments
 (0)