forked from mirror/client_golang
Inline hash/fnv.
This commit is contained in:
parent
39a26f2e35
commit
1312da4c0c
|
@ -15,7 +15,6 @@ package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"hash/fnv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Counter is a Metric that represents a single numerical value that only ever
|
// Counter is a Metric that represents a single numerical value that only ever
|
||||||
|
@ -97,7 +96,6 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
|
||||||
MetricVec: MetricVec{
|
MetricVec: MetricVec{
|
||||||
children: map[uint64]Metric{},
|
children: map[uint64]Metric{},
|
||||||
desc: desc,
|
desc: desc,
|
||||||
hash: fnv.New64a(),
|
|
||||||
newMetric: func(lvs ...string) Metric {
|
newMetric: func(lvs ...string) Metric {
|
||||||
result := &counter{value: value{
|
result := &counter{value: value{
|
||||||
desc: desc,
|
desc: desc,
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package prometheus
|
||||||
|
|
||||||
|
// Inline and byte-free variant of hash/fnv's fnv64a.
|
||||||
|
|
||||||
|
const (
|
||||||
|
offset64 = 14695981039346656037
|
||||||
|
prime64 = 1099511628211
|
||||||
|
)
|
||||||
|
|
||||||
|
// hashNew initializies a new fnv64a hash value.
|
||||||
|
func hashNew() uint64 {
|
||||||
|
return offset64
|
||||||
|
}
|
||||||
|
|
||||||
|
// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
|
||||||
|
func hashAdd(h uint64, s string) uint64 {
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
h ^= uint64(s[i])
|
||||||
|
h *= prime64
|
||||||
|
}
|
||||||
|
return h
|
||||||
|
}
|
|
@ -13,8 +13,6 @@
|
||||||
|
|
||||||
package prometheus
|
package prometheus
|
||||||
|
|
||||||
import "hash/fnv"
|
|
||||||
|
|
||||||
// Gauge is a Metric that represents a single numerical value that can
|
// Gauge is a Metric that represents a single numerical value that can
|
||||||
// arbitrarily go up and down.
|
// arbitrarily go up and down.
|
||||||
//
|
//
|
||||||
|
@ -77,7 +75,6 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
|
||||||
MetricVec: MetricVec{
|
MetricVec: MetricVec{
|
||||||
children: map[uint64]Metric{},
|
children: map[uint64]Metric{},
|
||||||
desc: desc,
|
desc: desc,
|
||||||
hash: fnv.New64a(),
|
|
||||||
newMetric: func(lvs ...string) Metric {
|
newMetric: func(lvs ...string) Metric {
|
||||||
return newValue(desc, GaugeValue, 0, lvs...)
|
return newValue(desc, GaugeValue, 0, lvs...)
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,7 +15,6 @@ package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -305,7 +304,6 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
|
||||||
MetricVec: MetricVec{
|
MetricVec: MetricVec{
|
||||||
children: map[uint64]Metric{},
|
children: map[uint64]Metric{},
|
||||||
desc: desc,
|
desc: desc,
|
||||||
hash: fnv.New64a(),
|
|
||||||
newMetric: func(lvs ...string) Metric {
|
newMetric: func(lvs ...string) Metric {
|
||||||
return newHistogram(desc, opts, lvs...)
|
return newHistogram(desc, opts, lvs...)
|
||||||
},
|
},
|
||||||
|
|
|
@ -127,7 +127,7 @@ func TestHistogramConcurrency(t *testing.T) {
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("Skipping test in short mode.")
|
t.Skip("Skipping test in short mode.")
|
||||||
}
|
}
|
||||||
|
|
||||||
rand.Seed(42)
|
rand.Seed(42)
|
||||||
|
|
||||||
it := func(n uint32) bool {
|
it := func(n uint32) bool {
|
||||||
|
|
|
@ -15,7 +15,6 @@ package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -408,7 +407,6 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
|
||||||
MetricVec: MetricVec{
|
MetricVec: MetricVec{
|
||||||
children: map[uint64]Metric{},
|
children: map[uint64]Metric{},
|
||||||
desc: desc,
|
desc: desc,
|
||||||
hash: fnv.New64a(),
|
|
||||||
newMetric: func(lvs ...string) Metric {
|
newMetric: func(lvs ...string) Metric {
|
||||||
return newSummary(desc, opts, lvs...)
|
return newSummary(desc, opts, lvs...)
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
|
|
||||||
package prometheus
|
package prometheus
|
||||||
|
|
||||||
import "hash/fnv"
|
|
||||||
|
|
||||||
// Untyped is a Metric that represents a single numerical value that can
|
// Untyped is a Metric that represents a single numerical value that can
|
||||||
// arbitrarily go up and down.
|
// arbitrarily go up and down.
|
||||||
//
|
//
|
||||||
|
@ -75,7 +73,6 @@ func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec {
|
||||||
MetricVec: MetricVec{
|
MetricVec: MetricVec{
|
||||||
children: map[uint64]Metric{},
|
children: map[uint64]Metric{},
|
||||||
desc: desc,
|
desc: desc,
|
||||||
hash: fnv.New64a(),
|
|
||||||
newMetric: func(lvs ...string) Metric {
|
newMetric: func(lvs ...string) Metric {
|
||||||
return newValue(desc, UntypedValue, 0, lvs...)
|
return newValue(desc, UntypedValue, 0, lvs...)
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,9 +14,7 @@
|
||||||
package prometheus
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash"
|
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,16 +24,10 @@ import (
|
||||||
// type. GaugeVec, CounterVec, SummaryVec, and UntypedVec are examples already
|
// type. GaugeVec, CounterVec, SummaryVec, and UntypedVec are examples already
|
||||||
// provided in this package.
|
// provided in this package.
|
||||||
type MetricVec struct {
|
type MetricVec struct {
|
||||||
mtx sync.RWMutex // Protects not only children, but also hash and buf.
|
mtx sync.RWMutex // Protects the children.
|
||||||
children map[uint64]Metric
|
children map[uint64]Metric
|
||||||
desc *Desc
|
desc *Desc
|
||||||
|
|
||||||
// hash is our own hash instance to avoid repeated allocations.
|
|
||||||
hash hash.Hash64
|
|
||||||
// buf is used to copy string contents into it for hashing,
|
|
||||||
// again to avoid allocations.
|
|
||||||
buf bytes.Buffer
|
|
||||||
|
|
||||||
newMetric func(labelValues ...string) Metric
|
newMetric func(labelValues ...string) Metric
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,30 +200,26 @@ func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
|
||||||
if len(vals) != len(m.desc.variableLabels) {
|
if len(vals) != len(m.desc.variableLabels) {
|
||||||
return 0, errInconsistentCardinality
|
return 0, errInconsistentCardinality
|
||||||
}
|
}
|
||||||
m.hash.Reset()
|
h := hashNew()
|
||||||
for _, val := range vals {
|
for _, val := range vals {
|
||||||
m.buf.Reset()
|
h = hashAdd(h, val)
|
||||||
m.buf.WriteString(val)
|
|
||||||
m.hash.Write(m.buf.Bytes())
|
|
||||||
}
|
}
|
||||||
return m.hash.Sum64(), nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
|
func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
|
||||||
if len(labels) != len(m.desc.variableLabels) {
|
if len(labels) != len(m.desc.variableLabels) {
|
||||||
return 0, errInconsistentCardinality
|
return 0, errInconsistentCardinality
|
||||||
}
|
}
|
||||||
m.hash.Reset()
|
h := hashNew()
|
||||||
for _, label := range m.desc.variableLabels {
|
for _, label := range m.desc.variableLabels {
|
||||||
val, ok := labels[label]
|
val, ok := labels[label]
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, fmt.Errorf("label name %q missing in label map", label)
|
return 0, fmt.Errorf("label name %q missing in label map", label)
|
||||||
}
|
}
|
||||||
m.buf.Reset()
|
h = hashAdd(h, val)
|
||||||
m.buf.WriteString(val)
|
|
||||||
m.hash.Write(m.buf.Bytes())
|
|
||||||
}
|
}
|
||||||
return m.hash.Sum64(), nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MetricVec) getOrCreateMetric(hash uint64, labelValues ...string) Metric {
|
func (m *MetricVec) getOrCreateMetric(hash uint64, labelValues ...string) Metric {
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
package prometheus
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"hash/fnv"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,7 +22,6 @@ func TestDelete(t *testing.T) {
|
||||||
vec := MetricVec{
|
vec := MetricVec{
|
||||||
children: map[uint64]Metric{},
|
children: map[uint64]Metric{},
|
||||||
desc: desc,
|
desc: desc,
|
||||||
hash: fnv.New64a(),
|
|
||||||
newMetric: func(lvs ...string) Metric {
|
newMetric: func(lvs ...string) Metric {
|
||||||
return newValue(desc, UntypedValue, 0, lvs...)
|
return newValue(desc, UntypedValue, 0, lvs...)
|
||||||
},
|
},
|
||||||
|
@ -63,7 +61,6 @@ func TestDeleteLabelValues(t *testing.T) {
|
||||||
vec := MetricVec{
|
vec := MetricVec{
|
||||||
children: map[uint64]Metric{},
|
children: map[uint64]Metric{},
|
||||||
desc: desc,
|
desc: desc,
|
||||||
hash: fnv.New64a(),
|
|
||||||
newMetric: func(lvs ...string) Metric {
|
newMetric: func(lvs ...string) Metric {
|
||||||
return newValue(desc, UntypedValue, 0, lvs...)
|
return newValue(desc, UntypedValue, 0, lvs...)
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue