Adds a faster counter
This commit is contained in:
parent
661e31bf84
commit
ae6939214c
|
@ -28,11 +28,25 @@ func TestCounterAdd(t *testing.T) {
|
||||||
ConstLabels: Labels{"a": "1", "b": "2"},
|
ConstLabels: Labels{"a": "1", "b": "2"},
|
||||||
}).(*counter)
|
}).(*counter)
|
||||||
counter.Inc()
|
counter.Inc()
|
||||||
if expected, got := 1., math.Float64frombits(counter.valBits); expected != got {
|
if expected, got := 0.0, math.Float64frombits(counter.valBits); expected != got {
|
||||||
|
t.Errorf("Expected %f, got %f.", expected, got)
|
||||||
|
}
|
||||||
|
if expected, got := int64(1), counter.valInt; expected != got {
|
||||||
t.Errorf("Expected %f, got %f.", expected, got)
|
t.Errorf("Expected %f, got %f.", expected, got)
|
||||||
}
|
}
|
||||||
counter.Add(42)
|
counter.Add(42)
|
||||||
if expected, got := 43., math.Float64frombits(counter.valBits); expected != got {
|
if expected, got := 0.0, math.Float64frombits(counter.valBits); expected != got {
|
||||||
|
t.Errorf("Expected %f, got %f.", expected, got)
|
||||||
|
}
|
||||||
|
if expected, got := int64(43), counter.valInt; expected != got {
|
||||||
|
t.Errorf("Expected %f, got %f.", expected, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
counter.Add(24.42)
|
||||||
|
if expected, got := 24.42, math.Float64frombits(counter.valBits); expected != got {
|
||||||
|
t.Errorf("Expected %f, got %f.", expected, got)
|
||||||
|
}
|
||||||
|
if expected, got := int64(43), counter.valInt; expected != got {
|
||||||
t.Errorf("Expected %f, got %f.", expected, got)
|
t.Errorf("Expected %f, got %f.", expected, got)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +57,7 @@ func TestCounterAdd(t *testing.T) {
|
||||||
m := &dto.Metric{}
|
m := &dto.Metric{}
|
||||||
counter.Write(m)
|
counter.Write(m)
|
||||||
|
|
||||||
if expected, got := `label:<name:"a" value:"1" > label:<name:"b" value:"2" > counter:<value:43 > `, m.String(); expected != got {
|
if expected, got := `label:<name:"a" value:"1" > label:<name:"b" value:"2" > counter:<value:67.42 > `, m.String(); expected != got {
|
||||||
t.Errorf("expected %q, got %q", expected, got)
|
t.Errorf("expected %q, got %q", expected, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,9 @@ type value struct {
|
||||||
// operations. http://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
// operations. http://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||||
valBits uint64
|
valBits uint64
|
||||||
|
|
||||||
|
// valInt is used to store values that are exact integers
|
||||||
|
valInt int64
|
||||||
|
|
||||||
selfCollector
|
selfCollector
|
||||||
|
|
||||||
desc *Desc
|
desc *Desc
|
||||||
|
@ -82,15 +85,25 @@ func (v *value) SetToCurrentTime() {
|
||||||
v.Set(float64(time.Now().UnixNano()) / 1e9)
|
v.Set(float64(time.Now().UnixNano()) / 1e9)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add adjusts the underlying int64
|
||||||
|
func (v *value) add(delta int64) {
|
||||||
|
atomic.AddInt64(&v.valInt, delta)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *value) Inc() {
|
func (v *value) Inc() {
|
||||||
v.Add(1)
|
v.add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *value) Dec() {
|
func (v *value) Dec() {
|
||||||
v.Add(-1)
|
v.add(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *value) Add(val float64) {
|
func (v *value) Add(val float64) {
|
||||||
|
if math.Trunc(val) == val {
|
||||||
|
atomic.AddInt64(&v.valInt, int64(val))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
oldBits := atomic.LoadUint64(&v.valBits)
|
oldBits := atomic.LoadUint64(&v.valBits)
|
||||||
newBits := math.Float64bits(math.Float64frombits(oldBits) + val)
|
newBits := math.Float64bits(math.Float64frombits(oldBits) + val)
|
||||||
|
@ -105,7 +118,10 @@ func (v *value) Sub(val float64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *value) Write(out *dto.Metric) error {
|
func (v *value) Write(out *dto.Metric) error {
|
||||||
val := math.Float64frombits(atomic.LoadUint64(&v.valBits))
|
fval := math.Float64frombits(atomic.LoadUint64(&v.valBits))
|
||||||
|
ival := atomic.LoadInt64(&v.valInt)
|
||||||
|
val := fval + float64(ival)
|
||||||
|
|
||||||
return populateMetric(v.valType, val, v.labelPairs, out)
|
return populateMetric(v.valType, val, v.labelPairs, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue