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.

97 lines
2.0 KiB

10 years ago
  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. func (rrc *RoundRobinCounter) ToList() (ret []int64) {
  56. index := rrc.LastIndex
  57. step := len(rrc.Values)
  58. for step > 0 {
  59. step--
  60. index++
  61. if index >= len(rrc.Values) {
  62. index = 0
  63. }
  64. ret = append(ret, rrc.Values[index])
  65. }
  66. return
  67. }
  68. type DurationCounter struct {
  69. MinuteCounter *RoundRobinCounter
  70. HourCounter *RoundRobinCounter
  71. DayCounter *RoundRobinCounter
  72. WeekCounter *RoundRobinCounter
  73. }
  74. func NewDurationCounter() *DurationCounter {
  75. return &DurationCounter{
  76. MinuteCounter: NewRoundRobinCounter(60),
  77. HourCounter: NewRoundRobinCounter(60),
  78. DayCounter: NewRoundRobinCounter(24),
  79. WeekCounter: NewRoundRobinCounter(7),
  80. }
  81. }
  82. // Add is for cumulative counts
  83. func (sc *DurationCounter) Add(tv *TimedValue) {
  84. sc.MinuteCounter.Add(tv.t.Second(), tv.val)
  85. sc.HourCounter.Add(tv.t.Minute(), tv.val)
  86. sc.DayCounter.Add(tv.t.Hour(), tv.val)
  87. sc.WeekCounter.Add(int(tv.t.Weekday()), tv.val)
  88. }