-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquantile.go
106 lines (91 loc) · 1.83 KB
/
quantile.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package mrgraphite
import (
"errors"
"sort"
"sync"
)
type valuesType []int64
var valPool = sync.Pool{
New: func() interface{} {
return make(valuesType, 0, 1024)
},
}
var EmptyListError = errors.New("Empty list")
type Quantile struct {
c *Client
name string
qVal float64
values valuesType
mtx sync.Mutex
}
func NewQuantile(name string, qVal float64) *Quantile {
return NewQuantileC(defaultClient, name, qVal)
}
func NewQuantileC(c *Client, name string, qVal float64) *Quantile {
if qVal < 0.0 || qVal > 100.0 {
panic("Wrong qVal")
}
q := &Quantile{
c: c,
name: name,
qVal: qVal,
values: valPool.Get().(valuesType),
}
if c != nil {
c.quantileList = append(c.quantileList, q)
} else {
quantileListPreinit = append(quantileListPreinit, q)
}
return q
}
func (q *Quantile) GetTimer() *Timer {
if q.c == nil {
if defaultClient == nil {
// Pass to glabal GetTimer which is empty object
return GetTimer(q.name)
}
// Late default client initializaion
q.c = defaultClient
}
t := q.c.GetTimer(q.name)
t.AddQuantile(q)
return t
}
func (q *Quantile) AddValue(v int64) {
q.mtx.Lock()
defer q.mtx.Unlock()
q.values = append(q.values, v)
}
func (q *Quantile) GetName() string {
return q.name
}
func (q *Quantile) GetQVal() float64 {
return q.qVal
}
func (q *Quantile) GetValue() (retval int64, err error) {
q.mtx.Lock()
vc := q.values
q.values = valPool.Get().(valuesType)
q.mtx.Unlock()
n := len(vc)
if n == 0 {
valPool.Put(vc[:0])
return 0, EmptyListError
}
sort.Slice(vc, func(i, j int) bool { return vc[i] < vc[j] })
nElem := float64(n) * q.qVal / 100.0
ofs := int(nElem)
switch {
case ofs == 0:
retval = vc[0]
case ofs >= n:
retval = vc[n-1]
default:
retval = vc[ofs]
}
if cap(vc) > 100000 {
vc = valPool.New().(valuesType)
}
valPool.Put(vc[:0])
return
}