@@ -111,12 +111,54 @@ func (c *seriesStore) Get(ctx context.Context, from, through model.Time, allMatc
111
111
return nil , err
112
112
}
113
113
114
+ chks , fetchers , err := c .GetChunkRefs (ctx , from , through , allMatchers ... )
115
+ if err != nil {
116
+ return nil , err
117
+ }
118
+
119
+ if len (chks ) == 0 {
120
+ // Shortcut
121
+ return nil , nil
122
+ }
123
+
124
+ chunks := chks [0 ]
125
+ fetcher := fetchers [0 ]
126
+ // Protect ourselves against OOMing.
127
+ maxChunksPerQuery := c .limits .MaxChunksPerQuery (userID )
128
+ if maxChunksPerQuery > 0 && len (chunks ) > maxChunksPerQuery {
129
+ err := httpgrpc .Errorf (http .StatusBadRequest , "Query %v fetched too many chunks (%d > %d)" , allMatchers , len (chunks ), maxChunksPerQuery )
130
+ level .Error (log ).Log ("err" , err )
131
+ return nil , err
132
+ }
133
+
134
+ // Now fetch the actual chunk data from Memcache / S3
135
+ keys := keysFromChunks (chunks )
136
+ allChunks , err := fetcher .FetchChunks (ctx , chunks , keys )
137
+ if err != nil {
138
+ level .Error (log ).Log ("msg" , "FetchChunks" , "err" , err )
139
+ return nil , err
140
+ }
141
+
142
+ // Filter out chunks based on the empty matchers in the query.
143
+ filteredChunks := filterChunksByMatchers (allChunks , allMatchers )
144
+ return filteredChunks , nil
145
+ }
146
+
147
+ func (c * seriesStore ) GetChunkRefs (ctx context.Context , from , through model.Time , allMatchers ... * labels.Matcher ) ([][]Chunk , []* Fetcher , error ) {
148
+ log , ctx := spanlogger .New (ctx , "SeriesStore.GetChunkRefs" )
149
+ defer log .Span .Finish ()
150
+
151
+ userID , err := user .ExtractOrgID (ctx )
152
+ if err != nil {
153
+ return nil , nil , err
154
+ }
155
+
114
156
// Validate the query is within reasonable bounds.
115
157
metricName , matchers , shortcut , err := c .validateQuery (ctx , from , & through , allMatchers )
116
158
if err != nil {
117
- return nil , err
159
+ return nil , nil , err
118
160
} else if shortcut {
119
- return nil , nil
161
+ return nil , nil , nil
120
162
}
121
163
122
164
level .Debug (log ).Log ("metric" , metricName )
@@ -126,46 +168,29 @@ func (c *seriesStore) Get(ctx context.Context, from, through model.Time, allMatc
126
168
_ , matchers = util .SplitFiltersAndMatchers (matchers )
127
169
seriesIDs , err := c .lookupSeriesByMetricNameMatchers (ctx , from , through , metricName , matchers )
128
170
if err != nil {
129
- return nil , err
171
+ return nil , nil , err
130
172
}
131
173
level .Debug (log ).Log ("series-ids" , len (seriesIDs ))
132
174
133
175
// Lookup the series in the index to get the chunks.
134
176
chunkIDs , err := c .lookupChunksBySeries (ctx , from , through , seriesIDs )
135
177
if err != nil {
136
178
level .Error (log ).Log ("msg" , "lookupChunksBySeries" , "err" , err )
137
- return nil , err
179
+ return nil , nil , err
138
180
}
139
181
level .Debug (log ).Log ("chunk-ids" , len (chunkIDs ))
140
182
141
183
chunks , err := c .convertChunkIDsToChunks (ctx , userID , chunkIDs )
142
184
if err != nil {
143
- level .Error (log ).Log ("err" , "convertChunkIDsToChunks" , "err" , err )
144
- return nil , err
145
- }
146
- // Filter out chunks that are not in the selected time range.
147
- filtered , keys := filterChunksByTime (from , through , chunks )
148
- level .Debug (log ).Log ("chunks-post-filtering" , len (chunks ))
149
- chunksPerQuery .Observe (float64 (len (filtered )))
150
-
151
- // Protect ourselves against OOMing.
152
- maxChunksPerQuery := c .limits .MaxChunksPerQuery (userID )
153
- if maxChunksPerQuery > 0 && len (chunkIDs ) > maxChunksPerQuery {
154
- err := httpgrpc .Errorf (http .StatusBadRequest , "Query %v fetched too many chunks (%d > %d)" , allMatchers , len (chunkIDs ), maxChunksPerQuery )
155
- level .Error (log ).Log ("err" , err )
156
- return nil , err
185
+ level .Error (log ).Log ("op" , "convertChunkIDsToChunks" , "err" , err )
186
+ return nil , nil , err
157
187
}
158
188
159
- // Now fetch the actual chunk data from Memcache / S3
160
- allChunks , err := c .FetchChunks (ctx , filtered , keys )
161
- if err != nil {
162
- level .Error (log ).Log ("msg" , "FetchChunks" , "err" , err )
163
- return nil , err
164
- }
189
+ chunks = filterChunksByTime (from , through , chunks )
190
+ level .Debug (log ).Log ("chunks-post-filtering" , len (chunks ))
191
+ chunksPerQuery .Observe (float64 (len (chunks )))
165
192
166
- // Filter out chunks based on the empty matchers in the query.
167
- filteredChunks := filterChunksByMatchers (allChunks , allMatchers )
168
- return filteredChunks , nil
193
+ return [][]Chunk {chunks }, []* Fetcher {c .store .Fetcher }, nil
169
194
}
170
195
171
196
func (c * seriesStore ) lookupSeriesByMetricNameMatchers (ctx context.Context , from , through model.Time , metricName string , matchers []* labels.Matcher ) ([]string , error ) {
0 commit comments