use local fnv hash everywhere
This commit is contained in:
parent
cfd904193d
commit
5d4fdca1a5
|
@ -1,10 +1,8 @@
|
|||
package prometheus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
@ -131,31 +129,24 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
|
|||
d.err = errors.New("duplicate label names")
|
||||
return d
|
||||
}
|
||||
h := fnv.New64a()
|
||||
var b bytes.Buffer // To copy string contents into, avoiding []byte allocations.
|
||||
vh := hashNew()
|
||||
for _, val := range labelValues {
|
||||
b.Reset()
|
||||
b.WriteString(val)
|
||||
b.WriteByte(separatorByte)
|
||||
h.Write(b.Bytes())
|
||||
vh = hashAdd(vh, val)
|
||||
vh = hashAddByte(vh, separatorByte)
|
||||
}
|
||||
d.id = h.Sum64()
|
||||
d.id = vh
|
||||
// Sort labelNames so that order doesn't matter for the hash.
|
||||
sort.Strings(labelNames)
|
||||
// Now hash together (in this order) the help string and the sorted
|
||||
// label names.
|
||||
h.Reset()
|
||||
b.Reset()
|
||||
b.WriteString(help)
|
||||
b.WriteByte(separatorByte)
|
||||
h.Write(b.Bytes())
|
||||
lh := hashNew()
|
||||
lh = hashAdd(lh, help)
|
||||
lh = hashAddByte(lh, separatorByte)
|
||||
for _, labelName := range labelNames {
|
||||
b.Reset()
|
||||
b.WriteString(labelName)
|
||||
b.WriteByte(separatorByte)
|
||||
h.Write(b.Bytes())
|
||||
lh = hashAdd(lh, labelName)
|
||||
lh = hashAddByte(lh, separatorByte)
|
||||
}
|
||||
d.dimHash = h.Sum64()
|
||||
d.dimHash = lh
|
||||
|
||||
d.constLabelPairs = make([]*dto.LabelPair, 0, len(constLabels))
|
||||
for n, v := range constLabels {
|
||||
|
|
|
@ -20,3 +20,10 @@ func hashAdd(h uint64, s string) uint64 {
|
|||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.
|
||||
func hashAddByte(h uint64, b byte) uint64 {
|
||||
h ^= uint64(b)
|
||||
h *= prime64
|
||||
return h
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
@ -528,30 +527,25 @@ func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *d
|
|||
}
|
||||
|
||||
// Is the metric unique (i.e. no other metric with the same name and the same label values)?
|
||||
h := fnv.New64a()
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(metricFamily.GetName())
|
||||
buf.WriteByte(separatorByte)
|
||||
h.Write(buf.Bytes())
|
||||
h := hashNew()
|
||||
h = hashAdd(h, metricFamily.GetName())
|
||||
h = hashAddByte(h, separatorByte)
|
||||
// Make sure label pairs are sorted. We depend on it for the consistency
|
||||
// check. Label pairs must be sorted by contract. But the point of this
|
||||
// method is to check for contract violations. So we better do the sort
|
||||
// now.
|
||||
sort.Sort(LabelPairSorter(dtoMetric.Label))
|
||||
for _, lp := range dtoMetric.Label {
|
||||
buf.Reset()
|
||||
buf.WriteString(lp.GetValue())
|
||||
buf.WriteByte(separatorByte)
|
||||
h.Write(buf.Bytes())
|
||||
h = hashAdd(h, lp.GetValue())
|
||||
h = hashAddByte(h, separatorByte)
|
||||
}
|
||||
metricHash := h.Sum64()
|
||||
if _, exists := metricHashes[metricHash]; exists {
|
||||
if _, exists := metricHashes[h]; exists {
|
||||
return fmt.Errorf(
|
||||
"collected metric %s %s was collected before with the same name and label values",
|
||||
metricFamily.GetName(), dtoMetric,
|
||||
)
|
||||
}
|
||||
metricHashes[metricHash] = struct{}{}
|
||||
metricHashes[h] = struct{}{}
|
||||
|
||||
if desc == nil {
|
||||
return nil // Nothing left to check if we have no desc.
|
||||
|
|
Loading…
Reference in New Issue