forked from sstark/snaprd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschedules.go
138 lines (123 loc) · 3.17 KB
/
schedules.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* See the file "LICENSE.txt" for the full license governing this code. */
// Define snapshot schedules (duration tables) and how to handle them
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"sort"
"strings"
"time"
)
const (
second = time.Second
minute = time.Minute
hour = time.Hour
day = hour * 24
week = day * 7
month = week * 4
year = day * 365
long = year * 100
)
type intervalList []time.Duration
// offset returns how long ago the given interval started
func (il intervalList) offset(i int) time.Duration {
if i == 0 {
return 0
}
return il[i] + il.offset(i-1)
}
// goal returns how many snapshots are the goal in the given interval
func (il intervalList) goal(i int) int {
if i > len(il)-2 {
panic("this should not happen: highest interval is innumerable!")
}
return int(il[i+1] / il[i])
}
type scheduleList map[string]intervalList
type jsonInterval []map[string]time.Duration
func (schl *scheduleList) String() string {
a := []string{}
for sch := range *schl {
a = append(a, sch)
}
return strings.Join(a, ",")
}
// schedules is a list of available snapshot schedules. Defines how often
// snapshots are made or purged. The span of an interval is always the snapshot
// distance of the next interval.
var schedules = scheduleList{
"longterm": {hour * 6, day, week, month, long},
"shortterm": {minute * 10, hour * 2, day, week, month, long},
}
// addFromFile adds an external JSON file to the list of available scheds
func (schl scheduleList) addFromFile(file string) error {
// If we are using the default file name, and it doesn't exist, no problem, just return
if _, err := os.Stat(file); os.IsNotExist(err) && file == defaultSchedFileName {
return nil
}
schedFile, err := ioutil.ReadFile(file)
if err != nil {
return fmt.Errorf("Error opening schedule file: %v", err)
}
var readData map[string]jsonInterval
err = json.Unmarshal(schedFile, &readData)
if err != nil {
return fmt.Errorf("Error parsing schedule file: %v", err)
}
for k, v := range readData {
schl[k] = v.intervalList()
}
return nil
}
// list prints the stored schedules in the list
func (schl scheduleList) list() {
var sKeys []string
for k := range schl {
sKeys = append(sKeys, k)
}
sort.Strings(sKeys)
for _, name := range sKeys {
fmt.Printf("%s: %s\n", name, schl[name])
}
}
// Transform a JSON formatted intervalList like this:
// [
// { "day" : 1, "hour" : 12 },
// { "week" : 2 },
// { "month" : 1, "week" : 2}
// { "long" : 1}
// ]
// and it makes it equivalent to
// { 1*day + 12*hour, 2*week, 1*month + 2*week, long }
func (json jsonInterval) intervalList() intervalList {
il := make(intervalList, len(json))
for i, interval := range json {
var duration time.Duration
Loop:
for k, v := range interval {
switch k {
case "s", "second":
duration += v * second
case "m", "minute":
duration += v * minute
case "h", "hour":
duration += v * hour
case "d", "day":
duration += v * day
case "w", "week":
duration += v * week
case "M", "month":
duration += v * month
case "y", "year":
duration += v * year
case "l", "long":
duration = long
break Loop
}
}
il[i] = duration
}
return il
}