forked from ipfs-cluster/ipfs-cluster
-
Notifications
You must be signed in to change notification settings - Fork 2
/
window.go
79 lines (68 loc) · 1.89 KB
/
window.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
// Package metrics provides common functionality for working with metrics,
// particulary useful for monitoring components. It includes types to store,
// check and filter metrics.
package metrics
import (
"errors"
"github.com/elastos/Elastos.NET.Hive.Cluster/api"
)
// DefaultWindowCap sets the amount of metrics to store per peer.
var DefaultWindowCap = 25
// ErrNoMetrics is returned when there are no metrics in a Window.
var ErrNoMetrics = errors.New("no metrics have been added to this window")
// Window implements a circular queue to store metrics.
type Window struct {
last int
window []api.Metric
}
// NewWindow creates an instance with the given
// window capacity.
func NewWindow(windowCap int) *Window {
if windowCap <= 0 {
panic("invalid windowCap")
}
w := make([]api.Metric, 0, windowCap)
return &Window{
last: 0,
window: w,
}
}
// Add adds a new metric to the window. If the window capacity
// has been reached, the oldest metric (by the time it was added),
// will be discarded.
func (mw *Window) Add(m api.Metric) {
if len(mw.window) < cap(mw.window) {
mw.window = append(mw.window, m)
mw.last = len(mw.window) - 1
return
}
// len == cap
mw.last = (mw.last + 1) % cap(mw.window)
mw.window[mw.last] = m
return
}
// Latest returns the last metric added. It returns an error
// if no metrics were added.
func (mw *Window) Latest() (api.Metric, error) {
if len(mw.window) == 0 {
return api.Metric{}, ErrNoMetrics
}
return mw.window[mw.last], nil
}
// All returns all the metrics in the window, in the inverse order
// they were Added. That is, result[0] will be the last added
// metric.
func (mw *Window) All() []api.Metric {
wlen := len(mw.window)
res := make([]api.Metric, 0, wlen)
if wlen == 0 {
return res
}
for i := mw.last; i >= 0; i-- {
res = append(res, mw.window[i])
}
for i := wlen - 1; i > mw.last; i-- {
res = append(res, mw.window[i])
}
return res
}