github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/ingester/label_pairs.go (about)

     1  package ingester
     2  
     3  import (
     4  	"sort"
     5  	"strings"
     6  
     7  	"github.com/prometheus/common/model"
     8  	"github.com/prometheus/prometheus/pkg/labels"
     9  
    10  	"github.com/cortexproject/cortex/pkg/cortexpb"
    11  	"github.com/cortexproject/cortex/pkg/util/extract"
    12  )
    13  
    14  // A series is uniquely identified by its set of label name/value
    15  // pairs, which may arrive in any order over the wire
    16  type labelPairs []cortexpb.LabelAdapter
    17  
    18  func (a labelPairs) String() string {
    19  	var b strings.Builder
    20  
    21  	metricName, err := extract.MetricNameFromLabelAdapters(a)
    22  	numLabels := len(a) - 1
    23  	if err != nil {
    24  		numLabels = len(a)
    25  	}
    26  	b.WriteString(metricName)
    27  	b.WriteByte('{')
    28  	count := 0
    29  	for _, pair := range a {
    30  		if pair.Name != model.MetricNameLabel {
    31  			b.WriteString(pair.Name)
    32  			b.WriteString("=\"")
    33  			b.WriteString(pair.Value)
    34  			b.WriteByte('"')
    35  			count++
    36  			if count < numLabels {
    37  				b.WriteByte(',')
    38  			}
    39  		}
    40  	}
    41  	b.WriteByte('}')
    42  	return b.String()
    43  }
    44  
    45  // Remove any label where the value is "" - Prometheus 2+ will remove these
    46  // before sending, but other clients such as Prometheus 1.x might send us blanks.
    47  func (a *labelPairs) removeBlanks() {
    48  	for i := 0; i < len(*a); {
    49  		if len((*a)[i].Value) == 0 {
    50  			// Delete by swap with the value at the end of the slice
    51  			(*a)[i] = (*a)[len(*a)-1]
    52  			(*a) = (*a)[:len(*a)-1]
    53  			continue // go round and check the data that is now at position i
    54  		}
    55  		i++
    56  	}
    57  }
    58  
    59  func valueForName(s labels.Labels, name string) (string, bool) {
    60  	pos := sort.Search(len(s), func(i int) bool { return s[i].Name >= name })
    61  	if pos == len(s) || s[pos].Name != name {
    62  		return "", false
    63  	}
    64  	return s[pos].Value, true
    65  }
    66  
    67  // Check if a and b contain the same name/value pairs
    68  func (a labelPairs) equal(b labels.Labels) bool {
    69  	if len(a) != len(b) {
    70  		return false
    71  	}
    72  	// Check as many as we can where the two sets are in the same order
    73  	i := 0
    74  	for ; i < len(a); i++ {
    75  		if b[i].Name != string(a[i].Name) {
    76  			break
    77  		}
    78  		if b[i].Value != string(a[i].Value) {
    79  			return false
    80  		}
    81  	}
    82  	// Now check remaining values using binary search
    83  	for ; i < len(a); i++ {
    84  		v, found := valueForName(b, a[i].Name)
    85  		if !found || v != a[i].Value {
    86  			return false
    87  		}
    88  	}
    89  	return true
    90  }