Skip to content

Commit a511164

Browse files
[REFACTOR] PromQL: DRY stddev and stdvar functions (prometheus#16451)
* DRY stddev and stdvar --------- Signed-off-by: Neeraj Gartia <neerajgartia211002@gmail.com>
1 parent 5afa652 commit a511164

File tree

1 file changed

+25
-69
lines changed

1 file changed

+25
-69
lines changed

promql/functions.go

Lines changed: 25 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -932,8 +932,7 @@ func funcQuantileOverTime(vals []parser.Value, args parser.Expressions, enh *Eva
932932
return append(enh.Out, Sample{F: quantile(q, values)}), annos
933933
}
934934

935-
// === stddev_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) ===
936-
func funcStddevOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
935+
func varianceOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper, varianceToResult func(float64) float64) (Vector, annotations.Annotations) {
937936
samples := vals[0].(Matrix)[0]
938937
var annos annotations.Annotations
939938
if len(samples.Floats) == 0 {
@@ -953,33 +952,22 @@ func funcStddevOverTime(vals []parser.Value, args parser.Expressions, enh *EvalN
953952
mean, cMean = kahanSumInc(delta/count, mean, cMean)
954953
aux, cAux = kahanSumInc(delta*(f.F-(mean+cMean)), aux, cAux)
955954
}
956-
return math.Sqrt((aux + cAux) / count)
955+
variance := (aux + cAux) / count
956+
if varianceToResult == nil {
957+
return variance
958+
}
959+
return varianceToResult(variance)
957960
}), annos
958961
}
959962

963+
// === stddev_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) ===
964+
func funcStddevOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
965+
return varianceOverTime(vals, args, enh, math.Sqrt)
966+
}
967+
960968
// === stdvar_over_time(Matrix parser.ValueTypeMatrix) (Vector, Annotations) ===
961969
func funcStdvarOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
962-
samples := vals[0].(Matrix)[0]
963-
var annos annotations.Annotations
964-
if len(samples.Floats) == 0 {
965-
return enh.Out, nil
966-
}
967-
if len(samples.Histograms) > 0 {
968-
metricName := samples.Metric.Get(labels.MetricName)
969-
annos.Add(annotations.NewHistogramIgnoredInMixedRangeInfo(metricName, args[0].PositionRange()))
970-
}
971-
return aggrOverTime(vals, enh, func(s Series) float64 {
972-
var count float64
973-
var mean, cMean float64
974-
var aux, cAux float64
975-
for _, f := range s.Floats {
976-
count++
977-
delta := f.F - (mean + cMean)
978-
mean, cMean = kahanSumInc(delta/count, mean, cMean)
979-
aux, cAux = kahanSumInc(delta*(f.F-(mean+cMean)), aux, cAux)
980-
}
981-
return (aux + cAux) / count
982-
}), annos
970+
return varianceOverTime(vals, args, enh, nil)
983971
}
984972

985973
// === absent(Vector parser.ValueTypeVector) (Vector, Annotations) ===
@@ -1347,11 +1335,9 @@ func funcHistogramAvg(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHe
13471335
return enh.Out, nil
13481336
}
13491337

1350-
// === histogram_stddev(Vector parser.ValueTypeVector) (Vector, Annotations) ===
1351-
func funcHistogramStdDev(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
1352-
inVec := vals[0].(Vector)
1353-
1354-
for _, sample := range inVec {
1338+
func histogramVariance(vals []parser.Value, enh *EvalNodeHelper, varianceToResult func(float64) float64) (Vector, annotations.Annotations) {
1339+
vec := vals[0].(Vector)
1340+
for _, sample := range vec {
13551341
// Skip non-histogram samples.
13561342
if sample.H == nil {
13571343
continue
@@ -1381,56 +1367,26 @@ func funcHistogramStdDev(vals []parser.Value, _ parser.Expressions, enh *EvalNod
13811367
if !enh.enableDelayedNameRemoval {
13821368
sample.Metric = sample.Metric.DropMetricName()
13831369
}
1370+
if varianceToResult != nil {
1371+
variance = varianceToResult(variance)
1372+
}
13841373
enh.Out = append(enh.Out, Sample{
13851374
Metric: sample.Metric,
1386-
F: math.Sqrt(variance),
1375+
F: variance,
13871376
DropName: true,
13881377
})
13891378
}
13901379
return enh.Out, nil
13911380
}
13921381

1382+
// === histogram_stddev(Vector parser.ValueTypeVector) (Vector, Annotations) ===
1383+
func funcHistogramStdDev(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
1384+
return histogramVariance(vals, enh, math.Sqrt)
1385+
}
1386+
13931387
// === histogram_stdvar(Vector parser.ValueTypeVector) (Vector, Annotations) ===
13941388
func funcHistogramStdVar(vals []parser.Value, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
1395-
inVec := vals[0].(Vector)
1396-
1397-
for _, sample := range inVec {
1398-
// Skip non-histogram samples.
1399-
if sample.H == nil {
1400-
continue
1401-
}
1402-
mean := sample.H.Sum / sample.H.Count
1403-
var variance, cVariance float64
1404-
it := sample.H.AllBucketIterator()
1405-
for it.Next() {
1406-
bucket := it.At()
1407-
if bucket.Count == 0 {
1408-
continue
1409-
}
1410-
var val float64
1411-
if bucket.Lower <= 0 && 0 <= bucket.Upper {
1412-
val = 0
1413-
} else {
1414-
val = math.Sqrt(bucket.Upper * bucket.Lower)
1415-
if bucket.Upper < 0 {
1416-
val = -val
1417-
}
1418-
}
1419-
delta := val - mean
1420-
variance, cVariance = kahanSumInc(bucket.Count*delta*delta, variance, cVariance)
1421-
}
1422-
variance += cVariance
1423-
variance /= sample.H.Count
1424-
if !enh.enableDelayedNameRemoval {
1425-
sample.Metric = sample.Metric.DropMetricName()
1426-
}
1427-
enh.Out = append(enh.Out, Sample{
1428-
Metric: sample.Metric,
1429-
F: variance,
1430-
DropName: true,
1431-
})
1432-
}
1433-
return enh.Out, nil
1389+
return histogramVariance(vals, enh, nil)
14341390
}
14351391

14361392
// === histogram_fraction(lower, upper parser.ValueTypeScalar, Vector parser.ValueTypeVector) (Vector, Annotations) ===

0 commit comments

Comments
 (0)