Commit 714318be authored by Filippo Valsorda's avatar Filippo Valsorda Committed by Brad Fitzpatrick

expvar: add Value methods

Closes #15815

Change-Id: I08154dbff416198cf7787e446b1e00e62c03a972
Reviewed-on: https://go-review.googlesource.com/30917Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 46276d6b
...@@ -49,6 +49,10 @@ type Int struct { ...@@ -49,6 +49,10 @@ type Int struct {
i int64 i int64
} }
func (v *Int) Value() int64 {
return atomic.LoadInt64(&v.i)
}
func (v *Int) String() string { func (v *Int) String() string {
return strconv.FormatInt(atomic.LoadInt64(&v.i), 10) return strconv.FormatInt(atomic.LoadInt64(&v.i), 10)
} }
...@@ -66,6 +70,10 @@ type Float struct { ...@@ -66,6 +70,10 @@ type Float struct {
f uint64 f uint64
} }
func (v *Float) Value() float64 {
return math.Float64frombits(atomic.LoadUint64(&v.f))
}
func (v *Float) String() string { func (v *Float) String() string {
return strconv.FormatFloat( return strconv.FormatFloat(
math.Float64frombits(atomic.LoadUint64(&v.f)), 'g', -1, 64) math.Float64frombits(atomic.LoadUint64(&v.f)), 'g', -1, 64)
...@@ -219,6 +227,14 @@ type String struct { ...@@ -219,6 +227,14 @@ type String struct {
s string s string
} }
func (v *String) Value() string {
v.mu.RLock()
defer v.mu.RUnlock()
return v.s
}
// String implements the Val interface. To get the unquoted string
// use Value.
func (v *String) String() string { func (v *String) String() string {
v.mu.RLock() v.mu.RLock()
s := v.s s := v.s
...@@ -237,6 +253,10 @@ func (v *String) Set(value string) { ...@@ -237,6 +253,10 @@ func (v *String) Set(value string) {
// and formatting the returned value using JSON. // and formatting the returned value using JSON.
type Func func() interface{} type Func func() interface{}
func (f Func) Value() interface{} {
return f()
}
func (f Func) String() string { func (f Func) String() string {
v, _ := json.Marshal(f()) v, _ := json.Marshal(f())
return string(v) return string(v)
......
...@@ -7,13 +7,12 @@ package expvar ...@@ -7,13 +7,12 @@ package expvar
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"math"
"net" "net"
"net/http/httptest" "net/http/httptest"
"reflect"
"runtime" "runtime"
"strconv" "strconv"
"sync" "sync"
"sync/atomic"
"testing" "testing"
) )
...@@ -58,6 +57,10 @@ func TestInt(t *testing.T) { ...@@ -58,6 +57,10 @@ func TestInt(t *testing.T) {
if reqs.i != -2 { if reqs.i != -2 {
t.Errorf("reqs.i = %v, want -2", reqs.i) t.Errorf("reqs.i = %v, want -2", reqs.i)
} }
if v, want := reqs.Value(), int64(-2); v != want {
t.Errorf("reqs.Value() = %q, want %q", v, want)
}
} }
func BenchmarkIntAdd(b *testing.B) { func BenchmarkIntAdd(b *testing.B) {
...@@ -80,10 +83,6 @@ func BenchmarkIntSet(b *testing.B) { ...@@ -80,10 +83,6 @@ func BenchmarkIntSet(b *testing.B) {
}) })
} }
func (v *Float) val() float64 {
return math.Float64frombits(atomic.LoadUint64(&v.f))
}
func TestFloat(t *testing.T) { func TestFloat(t *testing.T) {
RemoveAll() RemoveAll()
reqs := NewFloat("requests-float") reqs := NewFloat("requests-float")
...@@ -96,8 +95,8 @@ func TestFloat(t *testing.T) { ...@@ -96,8 +95,8 @@ func TestFloat(t *testing.T) {
reqs.Add(1.5) reqs.Add(1.5)
reqs.Add(1.25) reqs.Add(1.25)
if v := reqs.val(); v != 2.75 { if v := reqs.Value(); v != 2.75 {
t.Errorf("reqs.val() = %v, want 2.75", v) t.Errorf("reqs.Value() = %v, want 2.75", v)
} }
if s := reqs.String(); s != "2.75" { if s := reqs.String(); s != "2.75" {
...@@ -105,8 +104,8 @@ func TestFloat(t *testing.T) { ...@@ -105,8 +104,8 @@ func TestFloat(t *testing.T) {
} }
reqs.Add(-2) reqs.Add(-2)
if v := reqs.val(); v != 0.75 { if v := reqs.Value(); v != 0.75 {
t.Errorf("reqs.val() = %v, want 0.75", v) t.Errorf("reqs.Value() = %v, want 0.75", v)
} }
} }
...@@ -146,6 +145,10 @@ func TestString(t *testing.T) { ...@@ -146,6 +145,10 @@ func TestString(t *testing.T) {
t.Errorf("from %q, name.String() = %q, want %q", name.s, s, want) t.Errorf("from %q, name.String() = %q, want %q", name.s, s, want)
} }
if s, want := name.Value(), "Mike"; s != want {
t.Errorf("from %q, name.Value() = %q, want %q", name.s, s, want)
}
// Make sure we produce safe JSON output. // Make sure we produce safe JSON output.
name.Set(`<`) name.Set(`<`)
if s, want := name.String(), "\"\\u003c\""; s != want { if s, want := name.String(), "\"\\u003c\""; s != want {
...@@ -177,7 +180,7 @@ func TestMapCounter(t *testing.T) { ...@@ -177,7 +180,7 @@ func TestMapCounter(t *testing.T) {
if x := colors.m["blue"].(*Int).i; x != 4 { if x := colors.m["blue"].(*Int).i; x != 4 {
t.Errorf("colors.m[\"blue\"] = %v, want 4", x) t.Errorf("colors.m[\"blue\"] = %v, want 4", x)
} }
if x := colors.m[`green "midori"`].(*Float).val(); x != 4.125 { if x := colors.m[`green "midori"`].(*Float).Value(); x != 4.125 {
t.Errorf("colors.m[`green \"midori\"] = %v, want 4.125", x) t.Errorf("colors.m[`green \"midori\"] = %v, want 4.125", x)
} }
...@@ -242,6 +245,9 @@ func TestFunc(t *testing.T) { ...@@ -242,6 +245,9 @@ func TestFunc(t *testing.T) {
if s, exp := f.String(), `["a","b"]`; s != exp { if s, exp := f.String(), `["a","b"]`; s != exp {
t.Errorf(`f.String() = %q, want %q`, s, exp) t.Errorf(`f.String() = %q, want %q`, s, exp)
} }
if v := f.Value(); !reflect.DeepEqual(v, x) {
t.Errorf(`f.Value() = %q, want %q`, v, x)
}
x = 17 x = 17
if s, exp := f.String(), `17`; s != exp { if s, exp := f.String(), `17`; s != exp {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment