63 lines
1.6 KiB
Go
Raw Normal View History

package ratecounter
import (
"strconv"
"time"
)
// An AvgRateCounter is a thread-safe counter which returns
// the ratio between the number of calls 'Incr' and the counter value in the last interval
type AvgRateCounter struct {
hits *RateCounter
counter *RateCounter
interval time.Duration
}
// NewAvgRateCounter constructs a new AvgRateCounter, for the interval provided
func NewAvgRateCounter(intrvl time.Duration) *AvgRateCounter {
return &AvgRateCounter{
hits: NewRateCounter(intrvl),
counter: NewRateCounter(intrvl),
interval: intrvl,
}
}
// WithResolution determines the minimum resolution of this counter
func (a *AvgRateCounter) WithResolution(resolution int) *AvgRateCounter {
if resolution < 1 {
panic("AvgRateCounter resolution cannot be less than 1")
}
a.hits = a.hits.WithResolution(resolution)
a.counter = a.counter.WithResolution(resolution)
return a
}
// Incr Adds an event into the AvgRateCounter
func (a *AvgRateCounter) Incr(val int64) {
a.hits.Incr(1)
a.counter.Incr(val)
}
// Rate Returns the current ratio between the events count and its values during the last interval
func (a *AvgRateCounter) Rate() float64 {
hits, value := a.hits.Rate(), a.counter.Rate()
if hits == 0 {
return 0 // Avoid division by zero
}
return float64(value) / float64(hits)
}
// Hits returns the number of calling method Incr during specified interval
func (a *AvgRateCounter) Hits() int64 {
return a.hits.Rate()
}
// String returns counter's rate formatted to string
func (a *AvgRateCounter) String() string {
return strconv.FormatFloat(a.Rate(), 'e', 5, 64)
}