promql/functions.go
func funcHistogramQuantile(vals []Value, args Expressions, enh *EvalNodeHelper) Vector {
	q := vals[0].(Vector)[0].V
	inVec := vals[1].(Vector)
	sigf := enh.signatureFunc(false, excludedLabels...)

	if enh.signatureToMetricWithBuckets == nil {
		enh.signatureToMetricWithBuckets = map[uint64]*metricWithBuckets{}
	} else {
		for _, v := range enh.signatureToMetricWithBuckets {
			v.buckets = v.buckets[:0]
		}
	}
	for _, el := range inVec {
		upperBound, err := strconv.ParseFloat(
			el.Metric.Get(model.BucketLabel), 64,
		)
		if err != nil {
			// Oops, no bucket label or malformed label value. Skip.
			// TODO(beorn7): Issue a warning somehow.
			continue
		}
		hash := sigf(el.Metric)

		mb, ok := enh.signatureToMetricWithBuckets[hash]
		if !ok {
			el.Metric = labels.NewBuilder(el.Metric).
				Del(labels.BucketLabel, labels.MetricName).
				Labels()

			mb = &metricWithBuckets{el.Metric, nil}
			enh.signatureToMetricWithBuckets[hash] = mb
		}
		mb.buckets = append(mb.buckets, bucket{upperBound, el.V})
	}

	for _, mb := range enh.signatureToMetricWithBuckets {
		if len(mb.buckets) > 0 {
			enh.out = append(enh.out, Sample{
				Metric: mb.metric,
				Point:  Point{V: bucketQuantile(q, mb.buckets)},
			})
		}
	}

	return enh.out
}
func funcHistogramQuantile(vals []Value, args Expressions, enh *EvalNodeHelper) Vector {
	q := vals[0].(Vector)[0].V
	inVec := vals[1].(Vector)
	sigf := enh.signatureFunc(false, excludedLabels...)

	if enh.signatureToMetricWithBuckets == nil {
		enh.signatureToMetricWithBuckets = map[uint64]*metricWithBuckets{}
	} else {
		for _, v := range enh.signatureToMetricWithBuckets {
			v.buckets = v.buckets[:0]
		}
	}
	for _, el := range inVec {
		upperBound, err := strconv.ParseFloat(
			el.Metric.Get(model.BucketLabel), 64,
		)
		if err != nil {
			// Oops, no bucket label or malformed label value. Skip.
			// TODO(beorn7): Issue a warning somehow.
			continue
		}
		hash := sigf(el.Metric)

		mb, ok := enh.signatureToMetricWithBuckets[hash]
		if !ok {
			el.Metric = labels.NewBuilder(el.Metric).
				Del(labels.BucketLabel, labels.MetricName).
				Labels()

			mb = &metricWithBuckets{el.Metric, nil}
			enh.signatureToMetricWithBuckets[hash] = mb
		}
		mb.buckets = append(mb.buckets, bucket{upperBound, el.V})
	}

	for _, mb := range enh.signatureToMetricWithBuckets {
		if len(mb.buckets) > 0 {
			enh.out = append(enh.out, Sample{
				Metric: mb.metric,
				Point:  Point{V: bucketQuantile(q, mb.buckets)},
			})
		}
	}

	return enh.out
}
func funcHistogramQuantile ( vals [ ] Value , args Expressions , enh * EvalNodeHelper ) Vector { q := vals [ 0 ] . ( Vector ) [ 0 ] . V inVec := vals [ 1 ] . ( Vector ) sigf := enh . signatureFunc ( false , excludedLabels ... ) if enh . signatureToMetricWithBuckets == nil { enh . signatureToMetricWithBuckets = map [ uint64 ] * metricWithBuckets { } } else { for _ , v := range enh . signatureToMetricWithBuckets { v . buckets = v . buckets [ : 0 ] } } for _ , el := range inVec { upperBound , err := strconv . ParseFloat ( el . Metric . Get ( model . BucketLabel ) , 64 , ) if err != nil { // Oops, no bucket label or malformed label value. Skip. // TODO(beorn7): Issue a warning somehow. continue } hash := sigf ( el . Metric ) mb , ok := enh . signatureToMetricWithBuckets [ hash ] if ! ok { el . Metric = labels . NewBuilder ( el . Metric ) . Del ( labels . BucketLabel , labels . MetricName ) . Labels ( ) mb = & metricWithBuckets { el . Metric , nil } enh . signatureToMetricWithBuckets [ hash ] = mb } mb . buckets = append ( mb . buckets , bucket { upperBound , el . V } ) } for _ , mb := range enh . signatureToMetricWithBuckets { if len ( mb . buckets ) > 0 { enh . out = append ( enh . out , Sample { Metric : mb . metric , Point : Point { V : bucketQuantile ( q , mb . buckets ) } , } ) } } return enh . out }
// === histogram_quantile(k ValueTypeScalar, Vector ValueTypeVector) Vector ===
=== histogram_quantile ( k ValueTypeScalar Vector ValueTypeVector ) Vector ===