-
Notifications
You must be signed in to change notification settings - Fork 153
/
window.go
63 lines (52 loc) · 1.46 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
package execute
type Window struct {
Every Duration
Period Duration
Offset Duration
}
// NewWindow creates a window with the given parameters,
// and normalizes the offset to a small positive duration.
func NewWindow(every, period, offset Duration) Window {
// Normalize the offset to a small positive duration
if offset < 0 {
offset += every * ((offset / -every) + 1)
} else if offset > every {
offset -= every * (offset / every)
}
return Window{
Every: every,
Period: period,
Offset: offset,
}
}
// GetEarliestBounds returns the bounds for the earliest window bounds
// that contains the given time t. For underlapping windows that
// do not contain time t, the window directly after time t will be returned.
func (w Window) GetEarliestBounds(t Time) Bounds {
// translate to not-offset coordinate
t = t.Add(-w.Offset)
stop := t.Truncate(w.Every).Add(w.Every)
// translate to offset coordinate
stop = stop.Add(w.Offset)
start := stop.Add(-w.Period)
return Bounds{
Start: start,
Stop: stop,
}
}
// GetOverlappingBounds returns a slice of bounds for each window
// that overlaps the input bounds b.
func (w Window) GetOverlappingBounds(b Bounds) []Bounds {
if b.IsEmpty() {
return []Bounds{}
}
c := (b.Duration() / w.Every) + (w.Period / w.Every)
bs := make([]Bounds, 0, c)
bi := w.GetEarliestBounds(b.Start)
for bi.Start < b.Stop {
bs = append(bs, bi)
bi.Start = bi.Start.Add(w.Every)
bi.Stop = bi.Stop.Add(w.Every)
}
return bs
}