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