github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/util/math/rate.go (about) 1 package math 2 3 import ( 4 "sync" 5 "time" 6 7 "go.uber.org/atomic" 8 ) 9 10 // EwmaRate tracks an exponentially weighted moving average of a per-second rate. 11 type EwmaRate struct { 12 newEvents atomic.Int64 13 14 alpha float64 15 interval time.Duration 16 17 mutex sync.RWMutex 18 lastRate float64 19 init bool 20 } 21 22 func NewEWMARate(alpha float64, interval time.Duration) *EwmaRate { 23 return &EwmaRate{ 24 alpha: alpha, 25 interval: interval, 26 } 27 } 28 29 // Rate returns the per-second rate. 30 func (r *EwmaRate) Rate() float64 { 31 r.mutex.RLock() 32 defer r.mutex.RUnlock() 33 return r.lastRate 34 } 35 36 // Tick assumes to be called every r.interval. 37 func (r *EwmaRate) Tick() { 38 newEvents := r.newEvents.Swap(0) 39 instantRate := float64(newEvents) / r.interval.Seconds() 40 41 r.mutex.Lock() 42 defer r.mutex.Unlock() 43 44 if r.init { 45 r.lastRate += r.alpha * (instantRate - r.lastRate) 46 } else { 47 r.init = true 48 r.lastRate = instantRate 49 } 50 } 51 52 // Inc counts one event. 53 func (r *EwmaRate) Inc() { 54 r.newEvents.Inc() 55 } 56 57 func (r *EwmaRate) Add(delta int64) { 58 r.newEvents.Add(delta) 59 }