Improve the Metric.Equal and Metric.Before methods.
This commit is contained in:
parent
0e0e6bff80
commit
41ecb6c6b2
|
@ -26,16 +26,68 @@ var separator = []byte{0}
|
||||||
// a singleton and refers to one and only one stream of samples.
|
// a singleton and refers to one and only one stream of samples.
|
||||||
type Metric map[LabelName]LabelValue
|
type Metric map[LabelName]LabelValue
|
||||||
|
|
||||||
// Equal compares the fingerprints of both metrics.
|
// Equal compares the metrics.
|
||||||
func (m Metric) Equal(o Metric) bool {
|
func (m Metric) Equal(o Metric) bool {
|
||||||
// TODO do an actual map comparison
|
if len(m) != len(o) {
|
||||||
return m.Fingerprint().Equal(o.Fingerprint())
|
return false
|
||||||
|
}
|
||||||
|
for ln, lv := range m {
|
||||||
|
olv, ok := o[ln]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if olv != lv {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before compares the fingerprints of both metrics.
|
// Before compares the metrics, using the following criteria:
|
||||||
|
//
|
||||||
|
// If m has fewer labels than o, it is before o. If it has more, it is not.
|
||||||
|
//
|
||||||
|
// If the number of labels is the same, the superset of all label names is
|
||||||
|
// sorted alphanumerically. The first differing label pair found in that order
|
||||||
|
// determines the outcome: If the label does not exist at all in m, then m is
|
||||||
|
// before o, and vice versa. Otherwise the label value is compared
|
||||||
|
// alphanumerically.
|
||||||
|
//
|
||||||
|
// If m and o are equal, the method returns false.
|
||||||
func (m Metric) Before(o Metric) bool {
|
func (m Metric) Before(o Metric) bool {
|
||||||
// TODO do an actual map comparison
|
if len(m) < len(o) {
|
||||||
return m.Fingerprint().Less(o.Fingerprint())
|
return true
|
||||||
|
}
|
||||||
|
if len(m) > len(o) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
lns := make(LabelNames, 0, len(m)+len(o))
|
||||||
|
for ln := range m {
|
||||||
|
lns = append(lns, ln)
|
||||||
|
}
|
||||||
|
for ln := range o {
|
||||||
|
lns = append(lns, ln)
|
||||||
|
}
|
||||||
|
// It's probably not worth it to de-dup lns.
|
||||||
|
sort.Sort(lns)
|
||||||
|
for _, ln := range lns {
|
||||||
|
mlv, ok := m[ln]
|
||||||
|
if !ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
olv, ok := o[ln]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if mlv < olv {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if mlv > olv {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements Stringer.
|
// String implements Stringer.
|
||||||
|
|
|
@ -21,42 +21,36 @@ import (
|
||||||
func TestSamplesSort(t *testing.T) {
|
func TestSamplesSort(t *testing.T) {
|
||||||
input := Samples{
|
input := Samples{
|
||||||
&Sample{
|
&Sample{
|
||||||
// Fingerprint: 81f9c9ed24563f8f.
|
|
||||||
Metric: Metric{
|
Metric: Metric{
|
||||||
MetricNameLabel: "A",
|
MetricNameLabel: "A",
|
||||||
},
|
},
|
||||||
Timestamp: 1,
|
Timestamp: 1,
|
||||||
},
|
},
|
||||||
&Sample{
|
&Sample{
|
||||||
// Fingerprint: 81f9c9ed24563f8f.
|
|
||||||
Metric: Metric{
|
Metric: Metric{
|
||||||
MetricNameLabel: "A",
|
MetricNameLabel: "A",
|
||||||
},
|
},
|
||||||
Timestamp: 2,
|
Timestamp: 2,
|
||||||
},
|
},
|
||||||
&Sample{
|
&Sample{
|
||||||
// Fingerprint: 1bf6c9ed24543f8f.
|
|
||||||
Metric: Metric{
|
Metric: Metric{
|
||||||
MetricNameLabel: "C",
|
MetricNameLabel: "C",
|
||||||
},
|
},
|
||||||
Timestamp: 1,
|
Timestamp: 1,
|
||||||
},
|
},
|
||||||
&Sample{
|
&Sample{
|
||||||
// Fingerprint: 1bf6c9ed24543f8f.
|
|
||||||
Metric: Metric{
|
Metric: Metric{
|
||||||
MetricNameLabel: "C",
|
MetricNameLabel: "C",
|
||||||
},
|
},
|
||||||
Timestamp: 2,
|
Timestamp: 2,
|
||||||
},
|
},
|
||||||
&Sample{
|
&Sample{
|
||||||
// Fingerprint: 68f4c9ed24533f8f.
|
|
||||||
Metric: Metric{
|
Metric: Metric{
|
||||||
MetricNameLabel: "B",
|
MetricNameLabel: "B",
|
||||||
},
|
},
|
||||||
Timestamp: 1,
|
Timestamp: 1,
|
||||||
},
|
},
|
||||||
&Sample{
|
&Sample{
|
||||||
// Fingerprint: 68f4c9ed24533f8f.
|
|
||||||
Metric: Metric{
|
Metric: Metric{
|
||||||
MetricNameLabel: "B",
|
MetricNameLabel: "B",
|
||||||
},
|
},
|
||||||
|
@ -66,47 +60,41 @@ func TestSamplesSort(t *testing.T) {
|
||||||
|
|
||||||
expected := Samples{
|
expected := Samples{
|
||||||
&Sample{
|
&Sample{
|
||||||
// Fingerprint: 1bf6c9ed24543f8f.
|
|
||||||
Metric: Metric{
|
|
||||||
MetricNameLabel: "C",
|
|
||||||
},
|
|
||||||
Timestamp: 1,
|
|
||||||
},
|
|
||||||
&Sample{
|
|
||||||
// Fingerprint: 1bf6c9ed24543f8f.
|
|
||||||
Metric: Metric{
|
|
||||||
MetricNameLabel: "C",
|
|
||||||
},
|
|
||||||
Timestamp: 2,
|
|
||||||
},
|
|
||||||
&Sample{
|
|
||||||
// Fingerprint: 68f4c9ed24533f8f.
|
|
||||||
Metric: Metric{
|
|
||||||
MetricNameLabel: "B",
|
|
||||||
},
|
|
||||||
Timestamp: 1,
|
|
||||||
},
|
|
||||||
&Sample{
|
|
||||||
// Fingerprint: 68f4c9ed24533f8f.
|
|
||||||
Metric: Metric{
|
|
||||||
MetricNameLabel: "B",
|
|
||||||
},
|
|
||||||
Timestamp: 2,
|
|
||||||
},
|
|
||||||
&Sample{
|
|
||||||
// Fingerprint: 81f9c9ed24563f8f.
|
|
||||||
Metric: Metric{
|
Metric: Metric{
|
||||||
MetricNameLabel: "A",
|
MetricNameLabel: "A",
|
||||||
},
|
},
|
||||||
Timestamp: 1,
|
Timestamp: 1,
|
||||||
},
|
},
|
||||||
&Sample{
|
&Sample{
|
||||||
// Fingerprint: 81f9c9ed24563f8f.
|
|
||||||
Metric: Metric{
|
Metric: Metric{
|
||||||
MetricNameLabel: "A",
|
MetricNameLabel: "A",
|
||||||
},
|
},
|
||||||
Timestamp: 2,
|
Timestamp: 2,
|
||||||
},
|
},
|
||||||
|
&Sample{
|
||||||
|
Metric: Metric{
|
||||||
|
MetricNameLabel: "B",
|
||||||
|
},
|
||||||
|
Timestamp: 1,
|
||||||
|
},
|
||||||
|
&Sample{
|
||||||
|
Metric: Metric{
|
||||||
|
MetricNameLabel: "B",
|
||||||
|
},
|
||||||
|
Timestamp: 2,
|
||||||
|
},
|
||||||
|
&Sample{
|
||||||
|
Metric: Metric{
|
||||||
|
MetricNameLabel: "C",
|
||||||
|
},
|
||||||
|
Timestamp: 1,
|
||||||
|
},
|
||||||
|
&Sample{
|
||||||
|
Metric: Metric{
|
||||||
|
MetricNameLabel: "C",
|
||||||
|
},
|
||||||
|
Timestamp: 2,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(input)
|
sort.Sort(input)
|
||||||
|
|
|
@ -52,7 +52,7 @@ func putHashAndBuf(hb *hashAndBuf) {
|
||||||
hashAndBufPool.Put(hb)
|
hashAndBufPool.Put(hb)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LabelsToSignature returns an quasi-unique signature (i.e., fingerprint) for a
|
// LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a
|
||||||
// given label set. (Collisions are possible but unlikely if the number of label
|
// given label set. (Collisions are possible but unlikely if the number of label
|
||||||
// sets the function is applied to is small.)
|
// sets the function is applied to is small.)
|
||||||
func LabelsToSignature(labels map[string]string) uint64 {
|
func LabelsToSignature(labels map[string]string) uint64 {
|
||||||
|
|
Loading…
Reference in New Issue