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  }