github.com/haraldrudell/parl@v0.4.176/ptime/averager3.go (about) 1 /* 2 © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package ptime 7 8 import ( 9 "sync/atomic" 10 "time" 11 12 "github.com/haraldrudell/parl/internal/cyclebreaker" 13 "golang.org/x/exp/constraints" 14 ) 15 16 // Averager3 is an average container with last, average and max values. 17 type Averager3[T constraints.Integer] struct { 18 Averager[T] 19 max cyclebreaker.AtomicMax[T] 20 index cyclebreaker.AtomicMax[Epoch] 21 last time.Duration // atomic 22 } 23 24 // NewAverager3 returns an calculator for last, average and max values. 25 func NewAverager3[T constraints.Integer]() (averager *Averager3[T]) { 26 return &Averager3[T]{Averager: *NewAverager[T]()} 27 } 28 29 // Status returns "[last]/[average]/[max]" 30 // - if no values at all: "-/-/-" 31 // - if no values avaiable to calculate average "1s/-/10s" 32 func (av *Averager3[T]) Status() (s string) { 33 34 // check if any values are present 35 max, hasValue := av.max.Max() 36 if !hasValue { 37 s = "-/-/-" 38 return // no values return 39 } 40 41 // check average 42 average, count := av.Averager.Average() 43 if count > 0 { 44 s = Duration(time.Duration(average)) 45 } else { 46 s = "-" 47 } 48 49 s = Duration(time.Duration(atomic.LoadInt64((*int64)(&av.last)))) + "/" + 50 s + "/" + 51 Duration(time.Duration(max)) 52 53 return 54 } 55 56 // Add updates last, average and max values 57 func (av *Averager3[T]) Add(value T, t ...time.Time) { 58 av.max.Value(value) 59 if av.index.Value(EpochNow(t...)) { 60 atomic.StoreInt64((*int64)(&av.last), int64(value)) 61 } 62 av.Averager.Add(value, t...) 63 }