github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/storage/stores/tsdb/head_read.go (about)

     1  // Copyright 2021 The Prometheus Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package tsdb
    15  
    16  import (
    17  	"math"
    18  	"sort"
    19  
    20  	"github.com/prometheus/prometheus/model/labels"
    21  	"github.com/prometheus/prometheus/storage"
    22  
    23  	"github.com/grafana/loki/pkg/storage/stores/tsdb/index"
    24  )
    25  
    26  // Index returns an IndexReader against the block.
    27  func (h *Head) Index() IndexReader {
    28  	return h.indexRange(math.MinInt64, math.MaxInt64)
    29  }
    30  
    31  func (h *Head) indexRange(mint, maxt int64) *headIndexReader {
    32  	if hmin := h.MinTime(); hmin > mint {
    33  		mint = hmin
    34  	}
    35  	return &headIndexReader{head: h, mint: mint, maxt: maxt}
    36  }
    37  
    38  type headIndexReader struct {
    39  	head       *Head
    40  	mint, maxt int64
    41  }
    42  
    43  func (h *headIndexReader) Bounds() (int64, int64) {
    44  	return h.head.MinTime(), h.head.MaxTime()
    45  }
    46  
    47  func (h *headIndexReader) Checksum() uint32 { return 0 }
    48  
    49  func (h *headIndexReader) Close() error {
    50  	return nil
    51  }
    52  
    53  func (h *headIndexReader) Symbols() index.StringIter {
    54  	return h.head.postings.Symbols()
    55  }
    56  
    57  // SortedLabelValues returns label values present in the head for the
    58  // specific label name that are within the time range mint to maxt.
    59  // If matchers are specified the returned result set is reduced
    60  // to label values of metrics matching the matchers.
    61  func (h *headIndexReader) SortedLabelValues(name string, matchers ...*labels.Matcher) ([]string, error) {
    62  	values, err := h.LabelValues(name, matchers...)
    63  	if err == nil {
    64  		sort.Strings(values)
    65  	}
    66  	return values, err
    67  }
    68  
    69  // LabelValues returns label values present in the head for the
    70  // specific label name that are within the time range mint to maxt.
    71  // If matchers are specified the returned result set is reduced
    72  // to label values of metrics matching the matchers.
    73  func (h *headIndexReader) LabelValues(name string, matchers ...*labels.Matcher) ([]string, error) {
    74  	if h.maxt < h.head.MinTime() || h.mint > h.head.MaxTime() {
    75  		return []string{}, nil
    76  	}
    77  
    78  	if len(matchers) == 0 {
    79  		return h.head.postings.LabelValues(name), nil
    80  	}
    81  
    82  	return labelValuesWithMatchers(h, name, matchers...)
    83  }
    84  
    85  // LabelNames returns all the unique label names present in the head
    86  // that are within the time range mint to maxt.
    87  func (h *headIndexReader) LabelNames(matchers ...*labels.Matcher) ([]string, error) {
    88  	if h.maxt < h.head.MinTime() || h.mint > h.head.MaxTime() {
    89  		return []string{}, nil
    90  	}
    91  
    92  	if len(matchers) == 0 {
    93  		labelNames := h.head.postings.LabelNames()
    94  		sort.Strings(labelNames)
    95  		return labelNames, nil
    96  	}
    97  
    98  	return labelNamesWithMatchers(h, matchers...)
    99  }
   100  
   101  // Postings returns the postings list iterator for the label pairs.
   102  func (h *headIndexReader) Postings(name string, shard *index.ShardAnnotation, values ...string) (index.Postings, error) {
   103  	var p index.Postings
   104  	switch len(values) {
   105  	case 0:
   106  		p = index.EmptyPostings()
   107  	case 1:
   108  		p = h.head.postings.Get(name, values[0])
   109  	default:
   110  		res := make([]index.Postings, 0, len(values))
   111  		for _, value := range values {
   112  			res = append(res, h.head.postings.Get(name, value))
   113  		}
   114  		p = index.Merge(res...)
   115  	}
   116  
   117  	if shard != nil {
   118  		return index.NewShardedPostings(p, *shard, nil), nil
   119  	}
   120  	return p, nil
   121  }
   122  
   123  // Series returns the series for the given reference.
   124  func (h *headIndexReader) Series(ref storage.SeriesRef, lbls *labels.Labels, chks *[]index.ChunkMeta) (uint64, error) {
   125  	s := h.head.series.getByID(uint64(ref))
   126  
   127  	if s == nil {
   128  		h.head.metrics.seriesNotFound.Inc()
   129  		return 0, storage.ErrNotFound
   130  	}
   131  	*lbls = append((*lbls)[:0], s.ls...)
   132  
   133  	s.Lock()
   134  	*chks = append((*chks)[:0], s.chks...)
   135  	s.Unlock()
   136  
   137  	return s.fp, nil
   138  }
   139  
   140  // LabelValueFor returns label value for the given label name in the series referred to by ID.
   141  func (h *headIndexReader) LabelValueFor(id storage.SeriesRef, label string) (string, error) {
   142  	memSeries := h.head.series.getByID(uint64(id))
   143  	if memSeries == nil {
   144  		return "", storage.ErrNotFound
   145  	}
   146  
   147  	value := memSeries.ls.Get(label)
   148  	if value == "" {
   149  		return "", storage.ErrNotFound
   150  	}
   151  
   152  	return value, nil
   153  }
   154  
   155  // LabelNamesFor returns all the label names for the series referred to by IDs.
   156  // The names returned are sorted.
   157  func (h *headIndexReader) LabelNamesFor(ids ...storage.SeriesRef) ([]string, error) {
   158  	namesMap := make(map[string]struct{})
   159  	for _, id := range ids {
   160  		memSeries := h.head.series.getByID(uint64(id))
   161  		if memSeries == nil {
   162  			return nil, storage.ErrNotFound
   163  		}
   164  		for _, lbl := range memSeries.ls {
   165  			namesMap[lbl.Name] = struct{}{}
   166  		}
   167  	}
   168  	names := make([]string, 0, len(namesMap))
   169  	for name := range namesMap {
   170  		names = append(names, name)
   171  	}
   172  	sort.Strings(names)
   173  	return names, nil
   174  }