rcrowley / go-metrics

Go port of Coda Hale's Metrics library
Other
3.43k stars 493 forks source link

Slice reuse issue in ExpDecaySample.update #207

Open jerryjxj opened 7 years ago

jerryjxj commented 7 years ago

Suspecious code in file sample.go

func (s *ExpDecaySample) update(t time.Time, v int64) {
    s.mutex.Lock()
    defer s.mutex.Unlock()
    s.count++
    if s.values.Size() == s.reservoirSize {
        s.values.Pop()
    }
    s.values.Push(expDecaySample{
        k: math.Exp(t.Sub(s.t0).Seconds()*s.alpha) / rand.Float64(),
        v: v,
    })
    if t.After(s.t1) {
        values := s.values.Values()
        t0 := s.t0
        s.values.Clear()
        s.t0 = t
        s.t1 = s.t0.Add(rescaleThreshold)
        for _, v := range values {
            v.k = v.k * math.Exp(-s.alpha*s.t0.Sub(t0).Seconds())
            s.values.Push(v)
        }
    }
}

In if t.After(s.t1) {} block, values and s.values share the same memory block, because s.values.Clear() doesn't abandon the address (The address of the inherent Array) actually. s.values.Push(v) might overwrite values