github.com/grafana/pyroscope@v1.18.0/pkg/model/labels_merger.go (about)

     1  package model
     2  
     3  import (
     4  	"slices"
     5  	"sort"
     6  	"sync"
     7  
     8  	typesv1 "github.com/grafana/pyroscope/api/gen/proto/go/types/v1"
     9  )
    10  
    11  type LabelMerger struct {
    12  	mu     sync.Mutex
    13  	names  map[string]struct{}
    14  	values map[string]struct{}
    15  	series map[uint64]*typesv1.Labels
    16  }
    17  
    18  func NewLabelMerger() *LabelMerger {
    19  	return &LabelMerger{
    20  		names:  make(map[string]struct{}),
    21  		values: make(map[string]struct{}),
    22  		series: make(map[uint64]*typesv1.Labels),
    23  	}
    24  }
    25  
    26  func (m *LabelMerger) MergeLabelNames(names []string) {
    27  	m.mu.Lock()
    28  	defer m.mu.Unlock()
    29  	for _, n := range names {
    30  		m.names[n] = struct{}{}
    31  	}
    32  }
    33  
    34  func (m *LabelMerger) MergeLabelValues(values []string) {
    35  	m.mu.Lock()
    36  	defer m.mu.Unlock()
    37  	for _, v := range values {
    38  		m.values[v] = struct{}{}
    39  	}
    40  }
    41  
    42  func (m *LabelMerger) HasNames() bool {
    43  	return len(m.names) > 0
    44  }
    45  
    46  func (m *LabelMerger) LabelNames() []string {
    47  	m.mu.Lock()
    48  	defer m.mu.Unlock()
    49  	s := make([]string, len(m.names))
    50  	var i int
    51  	for n := range m.names {
    52  		s[i] = n
    53  		i++
    54  	}
    55  	sort.Strings(s)
    56  	return s
    57  }
    58  
    59  func (m *LabelMerger) HasValues() bool {
    60  	return len(m.values) > 0
    61  }
    62  
    63  func (m *LabelMerger) LabelValues() []string {
    64  	m.mu.Lock()
    65  	defer m.mu.Unlock()
    66  	s := make([]string, len(m.values))
    67  	var i int
    68  	for v := range m.values {
    69  		s[i] = v
    70  		i++
    71  	}
    72  	sort.Strings(s)
    73  	return s
    74  }
    75  
    76  func (m *LabelMerger) MergeSeries(series []*typesv1.Labels) {
    77  	m.mu.Lock()
    78  	defer m.mu.Unlock()
    79  	for _, s := range series {
    80  		m.series[Labels(s.Labels).Hash()] = s
    81  	}
    82  }
    83  
    84  func (m *LabelMerger) MergeLabels(ls []Labels) {
    85  	m.mu.Lock()
    86  	defer m.mu.Unlock()
    87  	for _, l := range ls {
    88  		m.series[l.Hash()] = &typesv1.Labels{Labels: l}
    89  	}
    90  }
    91  
    92  func (m *LabelMerger) Labels() []*typesv1.Labels {
    93  	m.mu.Lock()
    94  	defer m.mu.Unlock()
    95  	s := make([]*typesv1.Labels, len(m.series))
    96  	var i int
    97  	for _, v := range m.series {
    98  		s[i] = v
    99  		i++
   100  	}
   101  	slices.SortFunc(s, func(a, b *typesv1.Labels) int {
   102  		return CompareLabelPairs(a.Labels, b.Labels)
   103  	})
   104  	return s
   105  }
   106  
   107  func (m *LabelMerger) HasSeries() bool {
   108  	return len(m.series) > 0
   109  }