forked from grafana/loki
/
chunk.go
78 lines (59 loc) · 1.68 KB
/
chunk.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
package index
import (
"sort"
"github.com/prometheus/common/model"
)
// Meta holds information about a chunk of data.
type ChunkMeta struct {
Checksum uint32
MinTime, MaxTime int64
// Bytes stored, rounded to nearest KB
KB uint32
Entries uint32
}
func (c ChunkMeta) From() model.Time { return model.Time(c.MinTime) }
func (c ChunkMeta) Through() model.Time { return model.Time(c.MaxTime) }
func (c ChunkMeta) Bounds() (model.Time, model.Time) { return c.From(), c.Through() }
type ChunkMetas []ChunkMeta
func (c ChunkMetas) Len() int { return len(c) }
func (c ChunkMetas) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
// Sort by (MinTime, MaxTime, Checksum)
func (c ChunkMetas) Less(i, j int) bool {
a, b := c[i], c[j]
if a.MinTime != b.MinTime {
return a.MinTime < b.MinTime
}
if a.MaxTime != b.MaxTime {
return a.MaxTime < b.MaxTime
}
return a.Checksum < b.Checksum
}
// finalize sorts and dedupes
// TODO(owen-d): can we remove the need for this by ensuring we only push
// in order and without duplicates?
func (c ChunkMetas) finalize() ChunkMetas {
sort.Sort(c)
if len(c) == 0 {
return c
}
var res ChunkMetas
lastDuplicate := -1
prior := c[0]
// minimize reslicing costs due to duplicates
for i := 1; i < len(c); i++ {
x := c[i]
if x.MinTime == prior.MinTime && x.MaxTime == prior.MaxTime && x.Checksum == prior.Checksum {
res = append(res, c[lastDuplicate+1:i]...)
lastDuplicate = i
}
prior = x
}
// no duplicates were found, short circuit
// by returning unmodified underlying slice
if len(res) == 0 {
return c
}
// otherwise, append any remaining values
res = append(res, c[lastDuplicate+1:]...)
return res
}