You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
1.8 KiB

  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. for rrc.LastIndex != index {
  22. rrc.LastIndex++
  23. if rrc.LastIndex >= len(rrc.Values) {
  24. if index >= len(rrc.Values) {
  25. break //just avoid endless loop
  26. }
  27. rrc.LastIndex = 0
  28. }
  29. rrc.Values[rrc.LastIndex] = 0
  30. rrc.Counts[rrc.LastIndex] = 0
  31. }
  32. rrc.Values[index] += val
  33. rrc.Counts[index]++
  34. }
  35. func (rrc *RoundRobinCounter) Max() (max int64) {
  36. for _, val := range rrc.Values {
  37. if max < val {
  38. max = val
  39. }
  40. }
  41. return
  42. }
  43. func (rrc *RoundRobinCounter) Count() (cnt int64) {
  44. for _, c := range rrc.Counts {
  45. cnt += c
  46. }
  47. return
  48. }
  49. func (rrc *RoundRobinCounter) Sum() (sum int64) {
  50. for _, val := range rrc.Values {
  51. sum += val
  52. }
  53. return
  54. }
  55. type DurationCounter struct {
  56. MinuteCounter *RoundRobinCounter
  57. HourCounter *RoundRobinCounter
  58. DayCounter *RoundRobinCounter
  59. WeekCounter *RoundRobinCounter
  60. }
  61. func NewDurationCounter() *DurationCounter {
  62. return &DurationCounter{
  63. MinuteCounter: NewRoundRobinCounter(60),
  64. HourCounter: NewRoundRobinCounter(60),
  65. DayCounter: NewRoundRobinCounter(24),
  66. WeekCounter: NewRoundRobinCounter(7),
  67. }
  68. }
  69. // Add is for cumulative counts
  70. func (sc *DurationCounter) Add(tv *TimedValue) {
  71. sc.MinuteCounter.Add(tv.t.Second(), tv.val)
  72. sc.HourCounter.Add(tv.t.Minute(), tv.val)
  73. sc.DayCounter.Add(tv.t.Hour(), tv.val)
  74. sc.WeekCounter.Add(int(tv.t.Weekday()), tv.val)
  75. }