github.com/haraldrudell/parl@v0.4.176/counter/averager.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package counter 7 8 import "time" 9 10 // Averager is a fixed-sized 64-bit container returning float64 averages per time 11 type Averager struct { 12 values []datapoint 13 n int 14 size int 15 } 16 17 type datapoint struct { 18 value uint64 19 duration time.Duration 20 } 21 22 // NewAverager returns an 64-bit averager over size values 23 func NewAverager(size int) (averager *Averager) { 24 return &Averager{ 25 values: make([]datapoint, size), 26 size: size, 27 } 28 } 29 30 // Add adds a new value and computes current average 31 func (av *Averager) Add(value uint64, duration time.Duration) (average float64) { 32 if av.n < av.size { 33 // slice not full, use another position 34 var dpp = &av.values[av.n] 35 dpp.value = value 36 dpp.duration = duration 37 av.n++ 38 } else { 39 copy(av.values, av.values[1:]) // drop the oldest value 40 var dpp = &av.values[av.n-1] 41 dpp.value = value 42 dpp.duration = duration 43 } 44 45 var valueTotal float64 46 var durationTotal time.Duration 47 for i := 0; i < av.n; i++ { 48 valueTotal += float64(av.values[i].value) 49 durationTotal += av.values[i].duration 50 } 51 average = valueTotal / durationTotal.Seconds() 52 return 53 }