Do metrics on the given source of data and merge the results into the working set. Optionally, if provided, uses the known time range of the data for last-minute optimizations. Time range is unix nanos
(ctx context.Context, f SpansetFetcher, fetcherStart, fetcherEnd uint64, maxSeries int)
| 1264 | // uses the known time range of the data for last-minute optimizations. Time range is unix nanos |
| 1265 | |
| 1266 | func (e *MetricsEvaluator) Do(ctx context.Context, f SpansetFetcher, fetcherStart, fetcherEnd uint64, maxSeries int) error { |
| 1267 | if !e.needsFullTrace && e.spanOnlyFetch { |
| 1268 | // The query can operate at a span level so attempt. |
| 1269 | // This is faster. If not supported then fallback to spanset level. |
| 1270 | err := e.DoSpansOnly(ctx, f, fetcherStart, fetcherEnd, maxSeries) |
| 1271 | if !errors.Is(err, util.ErrUnsupported) { |
| 1272 | // We ran successfully or some other error. |
| 1273 | // In the case of unsupported, keep going and use original SpansetFetcher. |
| 1274 | return err |
| 1275 | } |
| 1276 | } |
| 1277 | |
| 1278 | // Make a copy of the request so we can modify it. |
| 1279 | storageReq := *e.storageReq |
| 1280 | |
| 1281 | if fetcherStart > 0 && fetcherEnd > 0 && |
| 1282 | // exclude special case for a block with the same start and end |
| 1283 | fetcherStart != fetcherEnd { |
| 1284 | // Dynamically decide whether to use the trace-level timestamp columns |
| 1285 | // for filtering. |
| 1286 | overlap := timeRangeOverlap(e.start, e.end, fetcherStart, fetcherEnd) |
| 1287 | |
| 1288 | if overlap == 0.0 { |
| 1289 | // This shouldn't happen but might as well check. |
| 1290 | // No overlap == nothing to do |
| 1291 | return nil |
| 1292 | } |
| 1293 | |
| 1294 | // Our heuristic is if the overlap between the given fetcher (i.e. block) |
| 1295 | // and the request is less than X%, use them. Above X%, the cost of loading |
| 1296 | // them doesn't outweight the benefits. The default 20% was measured in |
| 1297 | // local benchmarking. |
| 1298 | if overlap < e.timeOverlapCutoff { |
| 1299 | storageReq.StartTimeUnixNanos = e.start |
| 1300 | storageReq.EndTimeUnixNanos = e.end // Should this be exclusive? |
| 1301 | } |
| 1302 | } |
| 1303 | |
| 1304 | fetch, err := f.Fetch(ctx, storageReq) |
| 1305 | if errors.Is(err, util.ErrUnsupported) { |
| 1306 | return nil |
| 1307 | } |
| 1308 | if err != nil { |
| 1309 | return err |
| 1310 | } |
| 1311 | |
| 1312 | defer fetch.Results.Close() |
| 1313 | |
| 1314 | seriesCount := 0 |
| 1315 | |
| 1316 | for { |
| 1317 | ss, err := fetch.Results.Next(ctx) |
| 1318 | if err != nil { |
| 1319 | return err |
| 1320 | } |
| 1321 | if ss == nil { |
| 1322 | break |
| 1323 | } |
nothing calls this directly
no test coverage detected