-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstatistics.go
55 lines (48 loc) · 1.03 KB
/
statistics.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package main
import (
"sync"
"time"
)
type FlightTimeStats struct {
m sync.Mutex
buckets SortedMap[uint64, uint64]
count uint64
Average time.Duration
Median time.Duration
}
func NewFlightTimeStats() FlightTimeStats {
return FlightTimeStats{
buckets: NewSortedMap[uint64, uint64](),
}
}
func (f *FlightTimeStats) Count() uint64 {
f.m.Lock()
defer f.m.Unlock()
return f.count
}
func (f *FlightTimeStats) Add(duration time.Duration) {
// Add to bucket for fast median calculation
durAsInt := uint64(duration.Milliseconds())
f.m.Lock()
defer f.m.Unlock()
val := f.buckets.m[durAsInt]
f.buckets.Put(durAsInt, val+1)
// Avg calculation
f.count++
f.Average += (duration - f.Average) / time.Duration(f.count)
}
func (f *FlightTimeStats) calcMedian() {
f.m.Lock()
defer f.m.Unlock()
middle := f.count / 2
var count uint64
node := f.buckets.keys
for node != nil {
count += f.buckets.m[node.value]
if count >= middle {
f.Median = time.Duration(node.value) * time.Millisecond
return
}
node = node.next
}
}