12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- package stats
- import (
- "time"
- )
- type TimedValue struct {
- t time.Time
- val int64
- }
- func NewTimedValue(t time.Time, val int64) *TimedValue {
- return &TimedValue{t: t, val: val}
- }
- type RoundRobinCounter struct {
- LastIndex int
- Values []int64
- Counts []int64
- }
- func NewRoundRobinCounter(slots int) *RoundRobinCounter {
- return &RoundRobinCounter{LastIndex: -1, Values: make([]int64, slots), Counts: make([]int64, slots)}
- }
- func (rrc *RoundRobinCounter) Add(index int, val int64) {
- if index >= len(rrc.Values) {
- return
- }
- for rrc.LastIndex != index {
- rrc.LastIndex = (rrc.LastIndex + 1) % len(rrc.Values)
- rrc.Values[rrc.LastIndex] = 0
- rrc.Counts[rrc.LastIndex] = 0
- }
- rrc.Values[index] += val
- rrc.Counts[index]++
- }
- func (rrc *RoundRobinCounter) Max() (max int64) {
- for _, val := range rrc.Values {
- if max < val {
- max = val
- }
- }
- return
- }
- func (rrc *RoundRobinCounter) Count() (cnt int64) {
- for _, c := range rrc.Counts {
- cnt += c
- }
- return
- }
- func (rrc *RoundRobinCounter) Sum() (sum int64) {
- for _, val := range rrc.Values {
- sum += val
- }
- return
- }
- func (rrc *RoundRobinCounter) ToList() (ret []int64) {
- index := rrc.LastIndex
- step := len(rrc.Values)
- for step > 0 {
- step--
- index++
- if index >= len(rrc.Values) {
- index = 0
- }
- ret = append(ret, rrc.Values[index])
- }
- return
- }
- type DurationCounter struct {
- MinuteCounter *RoundRobinCounter
- HourCounter *RoundRobinCounter
- DayCounter *RoundRobinCounter
- WeekCounter *RoundRobinCounter
- }
- func NewDurationCounter() *DurationCounter {
- return &DurationCounter{
- MinuteCounter: NewRoundRobinCounter(60),
- HourCounter: NewRoundRobinCounter(60),
- DayCounter: NewRoundRobinCounter(24),
- WeekCounter: NewRoundRobinCounter(7),
- }
- }
- // Add is for cumulative counts
- func (sc *DurationCounter) Add(tv *TimedValue) {
- sc.MinuteCounter.Add(tv.t.Second(), tv.val)
- sc.HourCounter.Add(tv.t.Minute(), tv.val)
- sc.DayCounter.Add(tv.t.Hour(), tv.val)
- sc.WeekCounter.Add(int(tv.t.Weekday()), tv.val)
- }
|