duration_counter.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package stats
  2. import (
  3. "time"
  4. )
  5. type TimedValue struct {
  6. t time.Time
  7. val int64
  8. }
  9. func NewTimedValue(t time.Time, val int64) *TimedValue {
  10. return &TimedValue{t: t, val: val}
  11. }
  12. type RoundRobinCounter struct {
  13. LastIndex int
  14. Values []int64
  15. Counts []int64
  16. }
  17. func NewRoundRobinCounter(slots int) *RoundRobinCounter {
  18. return &RoundRobinCounter{LastIndex: -1, Values: make([]int64, slots), Counts: make([]int64, slots)}
  19. }
  20. func (rrc *RoundRobinCounter) Add(index int, val int64) {
  21. if index >= len(rrc.Values) {
  22. return
  23. }
  24. for rrc.LastIndex != index {
  25. rrc.LastIndex = (rrc.LastIndex + 1) % len(rrc.Values)
  26. rrc.Values[rrc.LastIndex] = 0
  27. rrc.Counts[rrc.LastIndex] = 0
  28. }
  29. rrc.Values[index] += val
  30. rrc.Counts[index]++
  31. }
  32. func (rrc *RoundRobinCounter) Max() (max int64) {
  33. for _, val := range rrc.Values {
  34. if max < val {
  35. max = val
  36. }
  37. }
  38. return
  39. }
  40. func (rrc *RoundRobinCounter) Count() (cnt int64) {
  41. for _, c := range rrc.Counts {
  42. cnt += c
  43. }
  44. return
  45. }
  46. func (rrc *RoundRobinCounter) Sum() (sum int64) {
  47. for _, val := range rrc.Values {
  48. sum += val
  49. }
  50. return
  51. }
  52. func (rrc *RoundRobinCounter) ToList() (ret []int64) {
  53. index := rrc.LastIndex
  54. step := len(rrc.Values)
  55. for step > 0 {
  56. step--
  57. index++
  58. if index >= len(rrc.Values) {
  59. index = 0
  60. }
  61. ret = append(ret, rrc.Values[index])
  62. }
  63. return
  64. }
  65. type DurationCounter struct {
  66. MinuteCounter *RoundRobinCounter
  67. HourCounter *RoundRobinCounter
  68. DayCounter *RoundRobinCounter
  69. WeekCounter *RoundRobinCounter
  70. }
  71. func NewDurationCounter() *DurationCounter {
  72. return &DurationCounter{
  73. MinuteCounter: NewRoundRobinCounter(60),
  74. HourCounter: NewRoundRobinCounter(60),
  75. DayCounter: NewRoundRobinCounter(24),
  76. WeekCounter: NewRoundRobinCounter(7),
  77. }
  78. }
  79. // Add is for cumulative counts
  80. func (sc *DurationCounter) Add(tv *TimedValue) {
  81. sc.MinuteCounter.Add(tv.t.Second(), tv.val)
  82. sc.HourCounter.Add(tv.t.Minute(), tv.val)
  83. sc.DayCounter.Add(tv.t.Hour(), tv.val)
  84. sc.WeekCounter.Add(int(tv.t.Weekday()), tv.val)
  85. }