MCPcopy
hub / github.com/prometheus/prometheus / labelValuesWithMatchers

Function labelValuesWithMatchers

tsdb/querier.go:464–535  ·  view source on GitHub ↗
(ctx context.Context, r IndexReader, name string, hints *storage.LabelHints, matchers ...*labels.Matcher)

Source from the content-addressed store, hash-verified

462}
463
464func labelValuesWithMatchers(ctx context.Context, r IndexReader, name string, hints *storage.LabelHints, matchers ...*labels.Matcher) ([]string, error) {
465 // Limit is applied at the end, after filtering.
466 allValues, err := r.LabelValues(ctx, name, nil)
467 if err != nil {
468 return nil, fmt.Errorf("fetching values of label %s: %w", name, err)
469 }
470
471 // If we have a matcher for the label name, we can filter out values that don't match
472 // before we fetch postings. This is especially useful for labels with many values.
473 // e.g. __name__ with a selector like {__name__="xyz"}
474 hasMatchersForOtherLabels := false
475 for _, m := range matchers {
476 if m.Name != name {
477 hasMatchersForOtherLabels = true
478 continue
479 }
480
481 // re-use the allValues slice to avoid allocations
482 // this is safe because the iteration is always ahead of the append
483 filteredValues := allValues[:0]
484 count := 1
485 for _, v := range allValues {
486 if count%checkContextEveryNIterations == 0 && ctx.Err() != nil {
487 return nil, ctx.Err()
488 }
489 count++
490 if m.Matches(v) {
491 filteredValues = append(filteredValues, v)
492 }
493 }
494 allValues = filteredValues
495 }
496
497 if len(allValues) == 0 {
498 return nil, nil
499 }
500
501 // If we don't have any matchers for other labels, then we're done.
502 if !hasMatchersForOtherLabels {
503 if hints != nil && hints.Limit > 0 && len(allValues) > hints.Limit {
504 allValues = allValues[:hints.Limit]
505 }
506 return allValues, nil
507 }
508
509 p, err := PostingsForMatchers(ctx, r, matchers...)
510 if err != nil {
511 return nil, fmt.Errorf("fetching postings for matchers: %w", err)
512 }
513
514 valuesPostings := make([]index.Postings, len(allValues))
515 for i, value := range allValues {
516 valuesPostings[i], err = r.Postings(ctx, name, value)
517 if err != nil {
518 return nil, fmt.Errorf("fetching postings for %s=%q: %w", name, value, err)
519 }
520 }
521 indexes, err := index.FindIntersectingPostings(p, valuesPostings)

Callers 5

LabelValuesMethod · 0.85
LabelValuesMethod · 0.85
LabelValuesMethod · 0.85

Calls 6

FindIntersectingPostingsFunction · 0.92
PostingsForMatchersFunction · 0.85
LabelValuesMethod · 0.65
ErrMethod · 0.65
MatchesMethod · 0.65
PostingsMethod · 0.65

Used in the wild real call sites across dependent graphs

searching dependent graphs…