Merge pull request #75 from prometheus/beorn7/timestamp

Reduce allocations during fingerprinting.
This commit is contained in:
Björn Rabenstein 2015-02-12 20:02:02 +01:00
commit 70f54973fb
2 changed files with 37 additions and 6 deletions

View File

@ -22,6 +22,8 @@ import (
"strings"
)
var separator = []byte{0}
// A Metric is similar to a LabelSet, but the key difference is that a Metric is
// a singleton and refers to one and only one stream of samples.
type Metric map[LabelName]LabelValue
@ -64,23 +66,34 @@ func (m Metric) String() string {
// Fingerprint returns a Metric's Fingerprint.
func (m Metric) Fingerprint() Fingerprint {
labelLength := len(m)
labelNames := make([]string, 0, labelLength)
labelNames := make([]string, 0, len(m))
maxLength := 0
for labelName := range m {
for labelName, labelValue := range m {
labelNames = append(labelNames, string(labelName))
if len(labelName) > maxLength {
maxLength = len(labelName)
}
if len(labelValue) > maxLength {
maxLength = len(labelValue)
}
}
sort.Strings(labelNames)
summer := fnv.New64a()
buf := make([]byte, maxLength)
for _, labelName := range labelNames {
labelValue := m[LabelName(labelName)]
summer.Write([]byte(labelName))
summer.Write([]byte{0})
summer.Write([]byte(labelValue))
copy(buf, labelName)
summer.Write(buf[:len(labelName)])
summer.Write(separator)
copy(buf, labelValue)
summer.Write(buf[:len(labelValue)])
}
return Fingerprint(binary.LittleEndian.Uint64(summer.Sum(nil)))

View File

@ -38,6 +38,24 @@ func testMetric(t testing.TB) {
},
fingerprint: 1470933794305433534,
},
// The following two demonstrate a bug in fingerprinting. They
// should not have the same fingerprint with a sane
// fingerprinting function. See
// https://github.com/prometheus/client_golang/issues/74 .
{
input: Metric{
"a": "bb",
"b": "c",
},
fingerprint: 3734646176939799877,
},
{
input: Metric{
"a": "b",
"bb": "c",
},
fingerprint: 3734646176939799877,
},
}
for i, scenario := range scenarios {