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  }