Safer and faster atomicity

This commit is contained in:
Justin Li 2014-07-22 12:47:17 -04:00
parent ff77a29b0a
commit 0a4c290ecb

View file

@ -4,7 +4,6 @@ import (
"math" "math"
"sort" "sort"
"sync/atomic" "sync/atomic"
"unsafe"
) )
type Percentile struct { type Percentile struct {
@ -14,18 +13,13 @@ type Percentile struct {
offset int64 offset int64
values []float64 values []float64
value *unsafe.Pointer value uint64 // These bits are really a float64.
} }
func NewPercentile(percentile float64, sampleWindow int) *Percentile { func NewPercentile(percentile float64, sampleWindow int) *Percentile {
initial := 0
ptr := unsafe.Pointer(&initial)
return &Percentile{ return &Percentile{
percentile: percentile, percentile: percentile,
values: make([]float64, 0, sampleWindow),
values: make([]float64, 0, sampleWindow),
value: &ptr,
} }
} }
@ -64,13 +58,13 @@ func (p *Percentile) AddSample(sample float64) {
p.values[idx] = sample p.values[idx] = sample
} }
value := p.values[p.index()] bits := math.Float64bits(p.values[p.index()])
atomic.SwapPointer(p.value, unsafe.Pointer(&value)) atomic.StoreUint64(&p.value, bits)
} }
func (p *Percentile) Value() float64 { func (p *Percentile) Value() float64 {
pointer := atomic.LoadPointer(p.value) bits := atomic.LoadUint64(&p.value)
return *(*float64)(pointer) return math.Float64frombits(bits)
} }
func (p *Percentile) index() int64 { func (p *Percentile) index() int64 {