github.com/thanos-io/thanos@v0.32.5/pkg/store/storepb/prompb/samples.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package prompb
     5  
     6  import (
     7  	"github.com/prometheus/common/model"
     8  	"github.com/prometheus/prometheus/model/histogram"
     9  	"github.com/prometheus/prometheus/promql"
    10  )
    11  
    12  // SamplesFromSamplePairs converts a slice of model.SamplePair
    13  // to a slice of Sample.
    14  func SamplesFromSamplePairs(samples []model.SamplePair) []Sample {
    15  	result := make([]Sample, 0, len(samples))
    16  	for _, s := range samples {
    17  		result = append(result, Sample{
    18  			Value:     float64(s.Value),
    19  			Timestamp: int64(s.Timestamp),
    20  		})
    21  	}
    22  
    23  	return result
    24  }
    25  
    26  // SamplesFromPromqlSamples converts a slice of promql.Sample
    27  // to a slice of Sample.
    28  func SamplesFromPromqlSamples(samples ...promql.Sample) ([]Sample, []Histogram) {
    29  	floats := make([]Sample, 0, len(samples))
    30  	histograms := make([]Histogram, 0, len(samples))
    31  	for _, s := range samples {
    32  		if s.H == nil {
    33  			floats = append(floats, Sample{
    34  				Value:     s.F,
    35  				Timestamp: s.T,
    36  			})
    37  		} else {
    38  			histograms = append(histograms, FloatHistogramToHistogramProto(s.T, s.H))
    39  		}
    40  	}
    41  
    42  	return floats, histograms
    43  }
    44  
    45  // SamplesFromPromqlSeries converts promql.Series to a slice of Sample and a slice of Histogram.
    46  func SamplesFromPromqlSeries(series promql.Series) ([]Sample, []Histogram) {
    47  	floats := make([]Sample, 0, len(series.Floats))
    48  	for _, f := range series.Floats {
    49  		floats = append(floats, Sample{
    50  			Value:     f.F,
    51  			Timestamp: f.T,
    52  		})
    53  	}
    54  	histograms := make([]Histogram, 0, len(series.Histograms))
    55  	for _, h := range series.Histograms {
    56  		histograms = append(histograms, FloatHistogramToHistogramProto(h.T, h.H))
    57  	}
    58  
    59  	return floats, histograms
    60  }
    61  
    62  // HistogramProtoToHistogram extracts a (normal integer) Histogram from the
    63  // provided proto message. The caller has to make sure that the proto message
    64  // represents an interger histogram and not a float histogram.
    65  // Copied from https://github.com/prometheus/prometheus/blob/0ab95536115adfe50af249d36d73674be694ca3f/storage/remote/codec.go#L626-L645
    66  func HistogramProtoToHistogram(hp Histogram) *histogram.Histogram {
    67  	if hp.IsFloatHistogram() {
    68  		panic("HistogramProtoToHistogram called with a float histogram")
    69  	}
    70  	return &histogram.Histogram{
    71  		CounterResetHint: histogram.CounterResetHint(hp.ResetHint),
    72  		Schema:           hp.Schema,
    73  		ZeroThreshold:    hp.ZeroThreshold,
    74  		ZeroCount:        hp.GetZeroCountInt(),
    75  		Count:            hp.GetCountInt(),
    76  		Sum:              hp.Sum,
    77  		PositiveSpans:    spansProtoToSpans(hp.GetPositiveSpans()),
    78  		PositiveBuckets:  hp.GetPositiveDeltas(),
    79  		NegativeSpans:    spansProtoToSpans(hp.GetNegativeSpans()),
    80  		NegativeBuckets:  hp.GetNegativeDeltas(),
    81  	}
    82  }
    83  
    84  // FloatHistogramToHistogramProto converts a float histogram to a protobuf type.
    85  // Copied from https://github.com/prometheus/prometheus/blob/0ab95536115adfe50af249d36d73674be694ca3f/storage/remote/codec.go#L647-L667
    86  func FloatHistogramProtoToFloatHistogram(hp Histogram) *histogram.FloatHistogram {
    87  	if !hp.IsFloatHistogram() {
    88  		panic("FloatHistogramProtoToFloatHistogram called with an integer histogram")
    89  	}
    90  	return &histogram.FloatHistogram{
    91  		CounterResetHint: histogram.CounterResetHint(hp.ResetHint),
    92  		Schema:           hp.Schema,
    93  		ZeroThreshold:    hp.ZeroThreshold,
    94  		ZeroCount:        hp.GetZeroCountFloat(),
    95  		Count:            hp.GetCountFloat(),
    96  		Sum:              hp.Sum,
    97  		PositiveSpans:    spansProtoToSpans(hp.GetPositiveSpans()),
    98  		PositiveBuckets:  hp.GetPositiveCounts(),
    99  		NegativeSpans:    spansProtoToSpans(hp.GetNegativeSpans()),
   100  		NegativeBuckets:  hp.GetNegativeCounts(),
   101  	}
   102  }
   103  
   104  // HistogramProtoToFloatHistogram extracts a (normal integer) Histogram from the
   105  // provided proto message to a Float Histogram. The caller has to make sure that
   106  // the proto message represents an float histogram and not a integer histogram.
   107  // Copied from https://github.com/prometheus/prometheus/blob/0ab95536115adfe50af249d36d73674be694ca3f/storage/remote/codec.go#L669-L688
   108  func HistogramProtoToFloatHistogram(hp Histogram) *histogram.FloatHistogram {
   109  	if hp.IsFloatHistogram() {
   110  		panic("HistogramProtoToFloatHistogram called with a float histogram")
   111  	}
   112  	return &histogram.FloatHistogram{
   113  		CounterResetHint: histogram.CounterResetHint(hp.ResetHint),
   114  		Schema:           hp.Schema,
   115  		ZeroThreshold:    hp.ZeroThreshold,
   116  		ZeroCount:        float64(hp.GetZeroCountInt()),
   117  		Count:            float64(hp.GetCountInt()),
   118  		Sum:              hp.Sum,
   119  		PositiveSpans:    spansProtoToSpans(hp.GetPositiveSpans()),
   120  		PositiveBuckets:  deltasToCounts(hp.GetPositiveDeltas()),
   121  		NegativeSpans:    spansProtoToSpans(hp.GetNegativeSpans()),
   122  		NegativeBuckets:  deltasToCounts(hp.GetNegativeDeltas()),
   123  	}
   124  }
   125  
   126  func spansProtoToSpans(s []BucketSpan) []histogram.Span {
   127  	spans := make([]histogram.Span, len(s))
   128  	for i := 0; i < len(s); i++ {
   129  		spans[i] = histogram.Span{Offset: s[i].Offset, Length: s[i].Length}
   130  	}
   131  
   132  	return spans
   133  }
   134  
   135  func deltasToCounts(deltas []int64) []float64 {
   136  	counts := make([]float64, len(deltas))
   137  	var cur float64
   138  	for i, d := range deltas {
   139  		cur += float64(d)
   140  		counts[i] = cur
   141  	}
   142  	return counts
   143  }
   144  
   145  // Copied from https://github.com/prometheus/prometheus/blob/0ab95536115adfe50af249d36d73674be694ca3f/storage/remote/codec.go#L709-L723
   146  func HistogramToHistogramProto(timestamp int64, h *histogram.Histogram) Histogram {
   147  	return Histogram{
   148  		Count:          &Histogram_CountInt{CountInt: h.Count},
   149  		Sum:            h.Sum,
   150  		Schema:         h.Schema,
   151  		ZeroThreshold:  h.ZeroThreshold,
   152  		ZeroCount:      &Histogram_ZeroCountInt{ZeroCountInt: h.ZeroCount},
   153  		NegativeSpans:  spansToSpansProto(h.NegativeSpans),
   154  		NegativeDeltas: h.NegativeBuckets,
   155  		PositiveSpans:  spansToSpansProto(h.PositiveSpans),
   156  		PositiveDeltas: h.PositiveBuckets,
   157  		ResetHint:      Histogram_ResetHint(h.CounterResetHint),
   158  		Timestamp:      timestamp,
   159  	}
   160  }
   161  
   162  // Copied from https://github.com/prometheus/prometheus/blob/0ab95536115adfe50af249d36d73674be694ca3f/storage/remote/codec.go#L725-L739
   163  func FloatHistogramToHistogramProto(timestamp int64, fh *histogram.FloatHistogram) Histogram {
   164  	return Histogram{
   165  		Count:          &Histogram_CountFloat{CountFloat: fh.Count},
   166  		Sum:            fh.Sum,
   167  		Schema:         fh.Schema,
   168  		ZeroThreshold:  fh.ZeroThreshold,
   169  		ZeroCount:      &Histogram_ZeroCountFloat{ZeroCountFloat: fh.ZeroCount},
   170  		NegativeSpans:  spansToSpansProto(fh.NegativeSpans),
   171  		NegativeCounts: fh.NegativeBuckets,
   172  		PositiveSpans:  spansToSpansProto(fh.PositiveSpans),
   173  		PositiveCounts: fh.PositiveBuckets,
   174  		ResetHint:      Histogram_ResetHint(fh.CounterResetHint),
   175  		Timestamp:      timestamp,
   176  	}
   177  }
   178  
   179  func spansToSpansProto(s []histogram.Span) []BucketSpan {
   180  	spans := make([]BucketSpan, len(s))
   181  	for i := 0; i < len(s); i++ {
   182  		spans[i] = BucketSpan{Offset: s[i].Offset, Length: s[i].Length}
   183  	}
   184  
   185  	return spans
   186  }