aboutsummaryrefslogtreecommitdiff
path: root/weed/stats/duration_counter.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/stats/duration_counter.go')
-rw-r--r--weed/stats/duration_counter.go94
1 files changed, 94 insertions, 0 deletions
diff --git a/weed/stats/duration_counter.go b/weed/stats/duration_counter.go
new file mode 100644
index 000000000..69c8be61d
--- /dev/null
+++ b/weed/stats/duration_counter.go
@@ -0,0 +1,94 @@
+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)
+}