mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
app/vmselect/promql: fix corner case for increase
over time series with gaps
In this case `increase` could return invalid high value for the first point after the gap.
This commit is contained in:
parent
96492348cb
commit
75ff524a4e
1 changed files with 20 additions and 2 deletions
|
@ -22,8 +22,8 @@ var rollupFuncs = map[string]newRollupFunc{
|
||||||
"deriv_fast": newRollupFuncOneArg(rollupDerivFast),
|
"deriv_fast": newRollupFuncOneArg(rollupDerivFast),
|
||||||
"holt_winters": newRollupHoltWinters,
|
"holt_winters": newRollupHoltWinters,
|
||||||
"idelta": newRollupFuncOneArg(rollupIdelta),
|
"idelta": newRollupFuncOneArg(rollupIdelta),
|
||||||
"increase": newRollupFuncOneArg(rollupDelta), // + rollupFuncsRemoveCounterResets
|
"increase": newRollupFuncOneArg(rollupIncrease), // + rollupFuncsRemoveCounterResets
|
||||||
"irate": newRollupFuncOneArg(rollupIderiv), // + rollupFuncsRemoveCounterResets
|
"irate": newRollupFuncOneArg(rollupIderiv), // + rollupFuncsRemoveCounterResets
|
||||||
"predict_linear": newRollupPredictLinear,
|
"predict_linear": newRollupPredictLinear,
|
||||||
"rate": newRollupFuncOneArg(rollupDerivFast), // + rollupFuncsRemoveCounterResets
|
"rate": newRollupFuncOneArg(rollupDerivFast), // + rollupFuncsRemoveCounterResets
|
||||||
"resets": newRollupFuncOneArg(rollupResets),
|
"resets": newRollupFuncOneArg(rollupResets),
|
||||||
|
@ -116,6 +116,7 @@ type rollupFuncArg struct {
|
||||||
currTimestamp int64
|
currTimestamp int64
|
||||||
idx int
|
idx int
|
||||||
step int64
|
step int64
|
||||||
|
realPrevValue float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rfa *rollupFuncArg) reset() {
|
func (rfa *rollupFuncArg) reset() {
|
||||||
|
@ -126,6 +127,7 @@ func (rfa *rollupFuncArg) reset() {
|
||||||
rfa.currTimestamp = 0
|
rfa.currTimestamp = 0
|
||||||
rfa.idx = 0
|
rfa.idx = 0
|
||||||
rfa.step = 0
|
rfa.step = 0
|
||||||
|
rfa.realPrevValue = nan
|
||||||
}
|
}
|
||||||
|
|
||||||
// rollupFunc must return rollup value for the given rfa.
|
// rollupFunc must return rollup value for the given rfa.
|
||||||
|
@ -204,6 +206,7 @@ func (rc *rollupConfig) Do(dstValues []float64, values []float64, timestamps []i
|
||||||
rfa := getRollupFuncArg()
|
rfa := getRollupFuncArg()
|
||||||
rfa.idx = 0
|
rfa.idx = 0
|
||||||
rfa.step = rc.Step
|
rfa.step = rc.Step
|
||||||
|
rfa.realPrevValue = nan
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
j := 0
|
j := 0
|
||||||
|
@ -229,6 +232,9 @@ func (rc *rollupConfig) Do(dstValues []float64, values []float64, timestamps []i
|
||||||
rfa.values = values[i:j]
|
rfa.values = values[i:j]
|
||||||
rfa.timestamps = timestamps[i:j]
|
rfa.timestamps = timestamps[i:j]
|
||||||
rfa.currTimestamp = tEnd
|
rfa.currTimestamp = tEnd
|
||||||
|
if i > 0 {
|
||||||
|
rfa.realPrevValue = values[i-1]
|
||||||
|
}
|
||||||
value := rc.Func(rfa)
|
value := rc.Func(rfa)
|
||||||
rfa.idx++
|
rfa.idx++
|
||||||
dstValues = append(dstValues, value)
|
dstValues = append(dstValues, value)
|
||||||
|
@ -681,6 +687,14 @@ func rollupStdvar(rfa *rollupFuncArg) float64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func rollupDelta(rfa *rollupFuncArg) float64 {
|
func rollupDelta(rfa *rollupFuncArg) float64 {
|
||||||
|
return rollupDeltaInternal(rfa, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func rollupIncrease(rfa *rollupFuncArg) float64 {
|
||||||
|
return rollupDeltaInternal(rfa, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func rollupDeltaInternal(rfa *rollupFuncArg, canUseRealPrevValue bool) float64 {
|
||||||
// There is no need in handling NaNs here, since they must be cleaned up
|
// There is no need in handling NaNs here, since they must be cleaned up
|
||||||
// before calling rollup funcs.
|
// before calling rollup funcs.
|
||||||
values := rfa.values
|
values := rfa.values
|
||||||
|
@ -690,6 +704,10 @@ func rollupDelta(rfa *rollupFuncArg) float64 {
|
||||||
return nan
|
return nan
|
||||||
}
|
}
|
||||||
if len(values) == 1 {
|
if len(values) == 1 {
|
||||||
|
if canUseRealPrevValue && !math.IsNaN(rfa.realPrevValue) {
|
||||||
|
// Fix against removeCounterResets.
|
||||||
|
return values[0] - rfa.realPrevValue
|
||||||
|
}
|
||||||
// Assume that the previous non-existing value was 0.
|
// Assume that the previous non-existing value was 0.
|
||||||
return values[0]
|
return values[0]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue