forked from grafana/loki
/
dumb_chunk.go
127 lines (103 loc) · 2.55 KB
/
dumb_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
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
package chunkenc
import (
"sort"
"time"
"github.com/grafana/loki/pkg/iter"
"github.com/grafana/loki/pkg/logproto"
"github.com/grafana/loki/pkg/logql"
)
const (
tmpNumEntries = 1024
)
// NewDumbChunk returns a new chunk that isn't very good.
func NewDumbChunk() Chunk {
return &dumbChunk{}
}
type dumbChunk struct {
entries []logproto.Entry
}
func (c *dumbChunk) Bounds() (time.Time, time.Time) {
if len(c.entries) == 0 {
return time.Time{}, time.Time{}
}
return c.entries[0].Timestamp, c.entries[len(c.entries)-1].Timestamp
}
func (c *dumbChunk) SpaceFor(_ *logproto.Entry) bool {
return len(c.entries) < tmpNumEntries
}
func (c *dumbChunk) Append(entry *logproto.Entry) error {
if len(c.entries) == tmpNumEntries {
return ErrChunkFull
}
if len(c.entries) > 0 && c.entries[len(c.entries)-1].Timestamp.After(entry.Timestamp) {
return ErrOutOfOrder
}
c.entries = append(c.entries, *entry)
return nil
}
func (c *dumbChunk) Size() int {
return len(c.entries)
}
// UncompressedSize implements Chunk.
func (c *dumbChunk) UncompressedSize() int {
return c.Size()
}
// Utilization implements Chunk
func (c *dumbChunk) Utilization() float64 {
return float64(len(c.entries)) / float64(tmpNumEntries)
}
// Returns an iterator that goes from _most_ recent to _least_ recent (ie,
// backwards).
func (c *dumbChunk) Iterator(from, through time.Time, direction logproto.Direction, _ logql.Filter) (iter.EntryIterator, error) {
i := sort.Search(len(c.entries), func(i int) bool {
return !from.After(c.entries[i].Timestamp)
})
j := sort.Search(len(c.entries), func(j int) bool {
return !through.After(c.entries[j].Timestamp)
})
if from == through {
return nil, nil
}
start := -1
if direction == logproto.BACKWARD {
start = j - i
}
// Take a copy of the entries to avoid locking
return &dumbChunkIterator{
direction: direction,
i: start,
entries: c.entries[i:j],
}, nil
}
func (c *dumbChunk) Bytes() ([]byte, error) {
return nil, nil
}
type dumbChunkIterator struct {
direction logproto.Direction
i int
entries []logproto.Entry
}
func (i *dumbChunkIterator) Next() bool {
switch i.direction {
case logproto.BACKWARD:
i.i--
return i.i >= 0
case logproto.FORWARD:
i.i++
return i.i < len(i.entries)
default:
panic(i.direction)
}
}
func (i *dumbChunkIterator) Entry() logproto.Entry {
return i.entries[i.i]
}
func (i *dumbChunkIterator) Labels() string {
panic("Labels() called on chunk iterator")
}
func (i *dumbChunkIterator) Error() error {
return nil
}
func (i *dumbChunkIterator) Close() error {
return nil
}