diff --git a/app/vmselect/promql/rollup.go b/app/vmselect/promql/rollup.go index f23ef36fe5..9ab64b3be6 100644 --- a/app/vmselect/promql/rollup.go +++ b/app/vmselect/promql/rollup.go @@ -116,13 +116,11 @@ type rollupFuncArg struct { currTimestamp int64 idx int step int64 + window int64 // Real previous value even if it is located too far from the current window. // It matches prevValue if prevValue is not nan. realPrevValue float64 - - // Global scrape interval across all the data points in [Start...End] time range. - scrapeInterval int64 } func (rfa *rollupFuncArg) reset() { @@ -133,8 +131,8 @@ func (rfa *rollupFuncArg) reset() { rfa.currTimestamp = 0 rfa.idx = 0 rfa.step = 0 + rfa.window = 0 rfa.realPrevValue = nan - rfa.scrapeInterval = 0 } // rollupFunc must return rollup value for the given rfa. @@ -214,8 +212,8 @@ func (rc *rollupConfig) Do(dstValues []float64, values []float64, timestamps []i rfa := getRollupFuncArg() rfa.idx = 0 rfa.step = rc.Step + rfa.window = window rfa.realPrevValue = nan - rfa.scrapeInterval = scrapeInterval i := 0 j := 0 @@ -729,16 +727,13 @@ func rollupDeltaInternal(rfa *rollupFuncArg, canUseRealPrevValue bool) float64 { if len(values) == 0 { return nan } - 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. - return values[0] + // Assume that the previous non-existing value was 0. + if canUseRealPrevValue && !math.IsNaN(rfa.realPrevValue) { + // Fix against removeCounterResets. + prevValue = rfa.realPrevValue + } else { + prevValue = 0 } - prevValue = values[0] - values = values[1:] } if len(values) == 0 { // Assume that the value didn't change on the given interval. @@ -797,19 +792,14 @@ func rollupDerivFastInternal(rfa *rollupFuncArg, canUseRealPrevValue bool) float if len(values) == 0 { return nan } - if len(values) == 1 { - // Assume that the value changed from 0 to the current value during rfa.scrapeInterval. - delta := values[0] - if canUseRealPrevValue && !math.IsNaN(rfa.realPrevValue) { - // Fix against removeCounterResets. - delta -= rfa.realPrevValue - } - return float64(delta) / float64(rfa.scrapeInterval) + // Assume that the value changed from 0 to the current value during rfa.window + if canUseRealPrevValue && !math.IsNaN(rfa.realPrevValue) { + // Fix against removeCounterResets. + prevValue = rfa.realPrevValue + } else { + prevValue = 0 } - prevValue = values[0] - prevTimestamp = timestamps[0] - values = values[1:] - timestamps = timestamps[1:] + prevTimestamp = timestamps[0] - rfa.window } if len(values) == 0 { // Assume that the value didn't change on the given interval. diff --git a/app/vmselect/promql/rollup_test.go b/app/vmselect/promql/rollup_test.go index 76ca7ec61d..10deae47f9 100644 --- a/app/vmselect/promql/rollup_test.go +++ b/app/vmselect/promql/rollup_test.go @@ -272,13 +272,13 @@ func TestRollupNewRollupFuncSuccess(t *testing.T) { f("default_rollup", 34) f("changes", 11) - f("delta", -89) + f("delta", 34) f("deriv", -266.85860231406065) - f("deriv_fast", -712) + f("deriv_fast", 272) f("idelta", 0) - f("increase", 275) + f("increase", 398) f("irate", 0) - f("rate", 2200) + f("rate", 3184) f("resets", 5) f("avg_over_time", 47.083333333333336) f("min_over_time", 12) @@ -614,7 +614,7 @@ func TestRollupFuncsNoWindow(t *testing.T) { } rc.Timestamps = getTimestamps(rc.Start, rc.End, rc.Step) values := rc.Do(nil, testValues, testTimestamps) - valuesExpected := []float64{nan, -102, -9, 22, 0} + valuesExpected := []float64{nan, nan, -9, 22, 0} timestampsExpected := []int64{0, 40, 80, 120, 160} testRowsEqual(t, values, rc.Timestamps, valuesExpected, timestampsExpected) }) @@ -782,7 +782,7 @@ func TestRollupFuncsNoWindow(t *testing.T) { } rc.Timestamps = getTimestamps(rc.Start, rc.End, rc.Step) values := rc.Do(nil, testValues, testTimestamps) - valuesExpected := []float64{nan, nan, 10.25, 0, -8900, 0} + valuesExpected := []float64{nan, nan, 30750, 0, -8900, 0} timestampsExpected := []int64{0, 4, 8, 12, 16, 20} testRowsEqual(t, values, rc.Timestamps, valuesExpected, timestampsExpected) })