@@ -2,10 +2,10 @@ package batch
2
2
3
3
import (
4
4
"github.com/prometheus/common/model"
5
+ "github.com/prometheus/prometheus/model/histogram"
5
6
"github.com/prometheus/prometheus/tsdb/chunkenc"
6
7
7
8
"github.com/cortexproject/cortex/pkg/chunk"
8
- "github.com/cortexproject/cortex/pkg/querier/iterators"
9
9
)
10
10
11
11
// GenericChunk is a generic chunk used by the batch iterator, in order to make the batch
@@ -31,11 +31,11 @@ func (c GenericChunk) Iterator(reuse chunk.Iterator) chunk.Iterator {
31
31
32
32
// iterator iterates over batches.
33
33
type iterator interface {
34
- // Seek to the batch at (or after) time t.
35
- Seek (t int64 , size int ) bool
34
+ // Seek to the batch at (or after) time t and returns chunk value type .
35
+ Seek (t int64 , size int ) chunkenc. ValueType
36
36
37
- // Next moves to the next batch.
38
- Next (size int ) bool
37
+ // Next moves to the next batch and returns chunk value type .
38
+ Next (size int ) chunkenc. ValueType
39
39
40
40
// AtTime returns the start time of the next batch. Must only be called after
41
41
// Seek or Next have returned true.
@@ -44,7 +44,7 @@ type iterator interface {
44
44
// MaxCurrentChunkTime returns the max time on the current chunk.
45
45
MaxCurrentChunkTime () int64
46
46
47
- // Batch returns the current batch. Must only be called after Seek or Next
47
+ // Batch returns the current batch. Must only be called after Seek or Next
48
48
// have returned true.
49
49
Batch () chunk.Batch
50
50
@@ -78,62 +78,71 @@ type iteratorAdapter struct {
78
78
}
79
79
80
80
func newIteratorAdapter (underlying iterator ) chunkenc.Iterator {
81
- return iterators . NewCompatibleChunksIterator ( & iteratorAdapter {
81
+ return & iteratorAdapter {
82
82
batchSize : 1 ,
83
83
underlying : underlying ,
84
- })
84
+ }
85
85
}
86
86
87
87
// Seek implements chunkenc.Iterator.
88
- func (a * iteratorAdapter ) Seek (t int64 ) bool {
88
+ func (a * iteratorAdapter ) Seek (t int64 ) chunkenc. ValueType {
89
89
90
90
// Optimisation: fulfill the seek using current batch if possible.
91
91
if a .curr .Length > 0 && a .curr .Index < a .curr .Length {
92
92
if t <= a .curr .Timestamps [a .curr .Index ] {
93
93
//In this case, the interface's requirement is met, so state of this
94
94
//iterator does not need any change.
95
- return true
95
+ return a . curr . ValType
96
96
} else if t <= a .curr .Timestamps [a .curr .Length - 1 ] {
97
97
//In this case, some timestamp between current sample and end of batch can fulfill
98
98
//the seek. Let's find it.
99
99
for a .curr .Index < a .curr .Length && t > a .curr .Timestamps [a .curr .Index ] {
100
100
a .curr .Index ++
101
101
}
102
- return true
102
+ return a . curr . ValType
103
103
} else if t <= a .underlying .MaxCurrentChunkTime () {
104
104
// In this case, some timestamp inside the current underlying chunk can fulfill the seek.
105
105
// In this case we will call next until we find the sample as it will be faster than calling
106
106
// `a.underlying.Seek` directly as this would cause the iterator to start from the beginning of the chunk.
107
107
// See: https://github.com/cortexproject/cortex/blob/f69452975877c67ac307709e5f60b8d20477764c/pkg/querier/batch/chunk.go#L26-L45
108
108
// https://github.com/cortexproject/cortex/blob/f69452975877c67ac307709e5f60b8d20477764c/pkg/chunk/encoding/prometheus_chunk.go#L90-L95
109
- for a .Next () {
109
+ for {
110
+ valType := a .Next ()
111
+ if valType == chunkenc .ValNone {
112
+ break
113
+ }
110
114
if t <= a .curr .Timestamps [a .curr .Index ] {
111
- return true
115
+ return valType
112
116
}
113
117
}
114
118
}
115
119
}
116
120
117
121
a .curr .Length = - 1
118
122
a .batchSize = 1
119
- if a .underlying .Seek (t , a .batchSize ) {
123
+ if valType := a .underlying .Seek (t , a .batchSize ); valType != chunkenc . ValNone {
120
124
a .curr = a .underlying .Batch ()
121
- return a .curr .Index < a .curr .Length
125
+ if a .curr .Index < a .curr .Length {
126
+ return a .curr .ValType
127
+ }
122
128
}
123
- return false
129
+ return chunkenc . ValNone
124
130
}
125
131
126
132
// Next implements chunkenc.Iterator.
127
- func (a * iteratorAdapter ) Next () bool {
133
+ func (a * iteratorAdapter ) Next () chunkenc. ValueType {
128
134
a .curr .Index ++
129
- for a .curr .Index >= a .curr .Length && a .underlying .Next (a .batchSize ) {
135
+ for a .curr .Index >= a .curr .Length && a .underlying .Next (a .batchSize ) != chunkenc . ValNone {
130
136
a .curr = a .underlying .Batch ()
131
137
a .batchSize = a .batchSize * 2
132
138
if a .batchSize > chunk .BatchSize {
133
139
a .batchSize = chunk .BatchSize
134
140
}
135
141
}
136
- return a .curr .Index < a .curr .Length
142
+ if a .curr .Index < a .curr .Length {
143
+ return a .curr .ValType
144
+ }
145
+ return chunkenc .ValNone
137
146
}
138
147
139
148
// At implements chunkenc.Iterator.
@@ -145,3 +154,18 @@ func (a *iteratorAdapter) At() (int64, float64) {
145
154
func (a * iteratorAdapter ) Err () error {
146
155
return nil
147
156
}
157
+
158
+ // AtHistogram implements chunkenc.Iterator.
159
+ func (a * iteratorAdapter ) AtHistogram (h * histogram.Histogram ) (int64 , * histogram.Histogram ) {
160
+ return a .curr .Timestamps [a .curr .Index ], a .curr .Histograms [a .curr .Index ]
161
+ }
162
+
163
+ // AtFloatHistogram implements chunkenc.Iterator.
164
+ func (a * iteratorAdapter ) AtFloatHistogram (h * histogram.FloatHistogram ) (int64 , * histogram.FloatHistogram ) {
165
+ return a .curr .Timestamps [a .curr .Index ], a .curr .FloatHistograms [a .curr .Index ]
166
+ }
167
+
168
+ // AtT implements chunkenc.Iterator.
169
+ func (a * iteratorAdapter ) AtT () int64 {
170
+ return a .curr .Timestamps [a .curr .Index ]
171
+ }
0 commit comments