forked from cortexproject/cortex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plan_file.go
112 lines (86 loc) · 2.57 KB
/
plan_file.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
package blocksconvert
import (
"compress/gzip"
"fmt"
"io"
"regexp"
"strconv"
"strings"
"time"
"github.com/golang/snappy"
)
// Plan file describes which series must be included in a block for given user and day.
// It consists of JSON objects, each written on its own line.
// Plan file starts with single header, many plan entries and single footer.
type PlanEntry struct {
// Header
User string `json:"user,omitempty"`
DayIndex int `json:"day_index,omitempty"`
// Entries
SeriesID string `json:"sid,omitempty"`
Chunks []string `json:"cs,omitempty"`
// Footer
Complete bool `json:"complete,omitempty"`
}
func (pe *PlanEntry) Reset() {
*pe = PlanEntry{}
}
// Returns true and "base name" or false and empty string.
func IsPlanFilename(name string) (bool, string) {
switch {
case strings.HasSuffix(name, ".plan.gz"):
return true, name[:len(name)-len(".plan.gz")]
case strings.HasSuffix(name, ".plan.snappy"):
return true, name[:len(name)-len(".plan.snappy")]
case strings.HasSuffix(name, ".plan"):
return true, name[:len(name)-len(".plan")]
}
return false, ""
}
func PreparePlanFileReader(planFile string, in io.Reader) (io.Reader, error) {
switch {
case strings.HasSuffix(planFile, ".snappy"):
return snappy.NewReader(in), nil
case strings.HasSuffix(planFile, ".gz"):
return gzip.NewReader(in)
}
return in, nil
}
func StartingFilename(planBaseName string, t time.Time) string {
return fmt.Sprintf("%s.starting.%d", planBaseName, t.Unix())
}
func ProgressFilename(planBaseName string, t time.Time) string {
return fmt.Sprintf("%s.inprogress.%d", planBaseName, t.Unix())
}
var progress = regexp.MustCompile(`^(.+)\.(starting|progress|inprogress)\.(\d+)$`)
func IsProgressFilename(name string) (bool, string, time.Time) {
m := progress.FindStringSubmatch(name)
if len(m) == 0 {
return false, "", time.Time{}
}
ts, err := strconv.ParseInt(m[3], 10, 64)
if err != nil {
return false, "", time.Time{}
}
return true, m[1], time.Unix(ts, 0)
}
func FinishedFilename(planBaseName string, id string) string {
return fmt.Sprintf("%s.finished.%s", planBaseName, id)
}
var finished = regexp.MustCompile(`^(.+)\.finished\.([a-zA-Z0-9]+)$`)
func IsFinishedFilename(name string) (bool, string, string) {
m := finished.FindStringSubmatch(name)
if len(m) == 0 {
return false, "", ""
}
return true, m[1], m[2]
}
func ErrorFilename(planBaseName string) string {
return planBaseName + ".error"
}
func IsErrorFilename(name string) (bool, string) {
if strings.HasSuffix(name, ".error") {
return true, name[:len(name)-len(".error")]
}
return false, ""
}