Repository: prometheus/prometheus
File: promql/quantile.go (Go)

Code before:
//
// If q<0, -Inf is returned.
//
// If q>1, +Inf is returned.
//
// We also return extra info, see doc for ensureMonotonicAndIgnoreSmallDeltas.
//
// Generically speaking, BucketQuantile is for calculating the
// histogram_quantile() of classic histograms. See also: HistogramQuantile
// for native histograms.
//
// BucketQuantile is exported as a useful quantile function over a set of
// given buckets. It may be used by other PromQL engine implementations.
func BucketQuantile(q float64, buckets Buckets) (res, forcedMonotonicMinBucket, forcedMonotonicMaxBucket, forcedMonotonicMaxDiff float64, forcedMonotonic, fixedPrecision bool) {
	if math.IsNaN(q) {
		res = math.NaN()
		return res, forcedMonotonicMinBucket, forcedMonotonicMaxBucket, forcedMonotonicMaxDiff, forcedMonotonic, fixedPrecision
	}
	if q < 0 {
		res = math.Inf(-1)
		return res, forcedMonotonicMinBucket, forcedMonotonicMaxBucket, forcedMonotonicMaxDiff, forcedMonotonic, fixedPrecision
	}
	if q > 1 {
		res = math.Inf(+1)
		return res, forcedMonotonicMinBucket, forcedMonotonicMaxBucket, forcedMonotonicMaxDiff, forcedMonotonic, fixedPrecision
	}
	slices.SortFunc(buckets, func(a, b Bucket) int {
		// We don't expect the bucket boundary to be a NaN.
		if a.UpperBound < b.UpperBound {
			return -1
		}
		if a.UpperBound > b.UpperBound {
			return +1
		}
		return 0
	})
	if !math.IsInf(buckets[len(buckets)-1].UpperBound, +1) {
		res = math.NaN()
		return res, forcedMonotonicMinBucket, forcedMonotonicMaxBucket, forcedMonotonicMaxDiff, forcedMonotonic, fixedPrecision
	}

	buckets = coalesceBuckets(buckets)
	forcedMonotonicMinBucket, forcedMonotonicMaxBucket, forcedMonotonicMaxDiff, forcedMonotonic, fixedPrecision = ensureMonotonicAndIgnoreSmallDeltas(buckets, smallDeltaTolerance)

	if len(buckets) < 2 {
		res = math.NaN()
		return res, forcedMonotonicMinBucket, forcedMonotonicMaxBucket, forcedMonotonicMaxDiff, forcedMonotonic, fixedPrecision
	}
	observations := buckets[len(buckets)-1].Count
	if observations == 0 {
		res = math.NaN()

Review comment (suggestion):
This would probably benefit from a `switch` statement. (It's only one line shorter, but shows the intent more clearly.

(I acknowledge that this has nothing to do with your changes.)

Code after:
//
// If q<0, -Inf is returned.
//
// If q>1, +Inf is returned.
//
// We also return extra info, see doc for ensureMonotonicAndIgnoreSmallDeltas.
//
// Generically speaking, BucketQuantile is for calculating the
// histogram_quantile() of classic histograms. See also: HistogramQuantile
// for native histograms.
//
// BucketQuantile is exported as a useful quantile function over a set of
// given buckets. It may be used by other PromQL engine implementations.
func BucketQuantile(q float64, buckets Buckets) (
	quantile float64,
	forcedMonotonic, fixedPrecision bool,
	minBucket, maxBucket, maxDiff float64,
) {
	switch {
	case math.IsNaN(q):
		quantile = math.NaN()
		return quantile, forcedMonotonic, fixedPrecision, minBucket, maxBucket, maxDiff
	case q < 0:
		quantile = math.Inf(-1)
		return quantile, forcedMonotonic, fixedPrecision, minBucket, maxBucket, maxDiff
	case q > 1:
		quantile = math.Inf(+1)
		return quantile, forcedMonotonic, fixedPrecision, minBucket, maxBucket, maxDiff
	}
	slices.SortFunc(buckets, func(a, b Bucket) int {
		// We don't expect the bucket boundary to be a NaN.
		if a.UpperBound < b.UpperBound {
			return -1
		}
		if a.UpperBound > b.UpperBound {
			return +1
		}
		return 0
	})
	if !math.IsInf(buckets[len(buckets)-1].UpperBound, +1) {
		quantile = math.NaN()
		return quantile, forcedMonotonic, fixedPrecision, minBucket, maxBucket, maxDiff
	}

	buckets = coalesceBuckets(buckets)
	forcedMonotonic, fixedPrecision, minBucket, maxBucket, maxDiff = ensureMonotonicAndIgnoreSmallDeltas(buckets, smallDeltaTolerance)

	if len(buckets) < 2 {
		quantile = math.NaN()
		return quantile, forcedMonotonic, fixedPrecision, minBucket, maxBucket, maxDiff
	}