SSE: Support time series frames with non-nullable float64 values (#32608)
* SSE: fix reduce to handle non-null * add type for data.Field that is float64 or *float64 * resample fix for non-null input case, add couple non-null tests
This commit is contained in:
@@ -86,6 +86,7 @@ func (ccc *ConditionsCmd) Execute(ctx context.Context, vars mathexp.Vars) (mathe
|
||||
}
|
||||
|
||||
reducedNum := c.Reducer.Reduce(series)
|
||||
|
||||
// TODO handle error / no data signals
|
||||
thisCondNoDataFound := reducedNum.GetFloat64Value() == nil
|
||||
|
||||
|
||||
+65
-74
@@ -4,7 +4,6 @@ import (
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana/pkg/expr/mathexp"
|
||||
)
|
||||
|
||||
@@ -35,44 +34,42 @@ func (cr classicReducer) Reduce(series mathexp.Series) mathexp.Number {
|
||||
allNull := true
|
||||
|
||||
vF := series.Frame.Fields[series.ValueIdx]
|
||||
ff := mathexp.Float64Field(*vF)
|
||||
|
||||
switch cr {
|
||||
case "avg":
|
||||
validPointsCount := 0
|
||||
for i := 0; i < vF.Len(); i++ {
|
||||
if f, ok := vF.At(i).(*float64); ok {
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
value += *f
|
||||
validPointsCount++
|
||||
allNull = false
|
||||
for i := 0; i < ff.Len(); i++ {
|
||||
f := ff.GetValue(i)
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
value += *f
|
||||
validPointsCount++
|
||||
allNull = false
|
||||
}
|
||||
if validPointsCount > 0 {
|
||||
value /= float64(validPointsCount)
|
||||
}
|
||||
case "sum":
|
||||
for i := 0; i < vF.Len(); i++ {
|
||||
if f, ok := vF.At(i).(*float64); ok {
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
value += *f
|
||||
allNull = false
|
||||
for i := 0; i < ff.Len(); i++ {
|
||||
f := ff.GetValue(i)
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
value += *f
|
||||
allNull = false
|
||||
}
|
||||
case "min":
|
||||
value = math.MaxFloat64
|
||||
for i := 0; i < vF.Len(); i++ {
|
||||
if f, ok := vF.At(i).(*float64); ok {
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
allNull = false
|
||||
if value > *f {
|
||||
value = *f
|
||||
}
|
||||
for i := 0; i < ff.Len(); i++ {
|
||||
f := ff.GetValue(i)
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
allNull = false
|
||||
if value > *f {
|
||||
value = *f
|
||||
}
|
||||
}
|
||||
if allNull {
|
||||
@@ -80,43 +77,40 @@ func (cr classicReducer) Reduce(series mathexp.Series) mathexp.Number {
|
||||
}
|
||||
case "max":
|
||||
value = -math.MaxFloat64
|
||||
for i := 0; i < vF.Len(); i++ {
|
||||
if f, ok := vF.At(i).(*float64); ok {
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
allNull = false
|
||||
if value < *f {
|
||||
value = *f
|
||||
}
|
||||
for i := 0; i < ff.Len(); i++ {
|
||||
f := ff.GetValue(i)
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
allNull = false
|
||||
if value < *f {
|
||||
value = *f
|
||||
}
|
||||
}
|
||||
if allNull {
|
||||
value = 0
|
||||
}
|
||||
case "count":
|
||||
value = float64(vF.Len())
|
||||
value = float64(ff.Len())
|
||||
allNull = false
|
||||
case "last":
|
||||
for i := vF.Len() - 1; i >= 0; i-- {
|
||||
if f, ok := vF.At(i).(*float64); ok {
|
||||
if !nilOrNaN(f) {
|
||||
value = *f
|
||||
allNull = false
|
||||
break
|
||||
}
|
||||
for i := ff.Len() - 1; i >= 0; i-- {
|
||||
f := ff.GetValue(i)
|
||||
if !nilOrNaN(f) {
|
||||
value = *f
|
||||
allNull = false
|
||||
break
|
||||
}
|
||||
}
|
||||
case "median":
|
||||
var values []float64
|
||||
for i := 0; i < vF.Len(); i++ {
|
||||
if f, ok := vF.At(i).(*float64); ok {
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
allNull = false
|
||||
values = append(values, *f)
|
||||
for i := 0; i < ff.Len(); i++ {
|
||||
f := ff.GetValue(i)
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
allNull = false
|
||||
values = append(values, *f)
|
||||
}
|
||||
if len(values) >= 1 {
|
||||
sort.Float64s(values)
|
||||
@@ -128,21 +122,20 @@ func (cr classicReducer) Reduce(series mathexp.Series) mathexp.Number {
|
||||
}
|
||||
}
|
||||
case "diff":
|
||||
allNull, value = calculateDiff(vF, allNull, value, diff)
|
||||
allNull, value = calculateDiff(ff, allNull, value, diff)
|
||||
case "diff_abs":
|
||||
allNull, value = calculateDiff(vF, allNull, value, diffAbs)
|
||||
allNull, value = calculateDiff(ff, allNull, value, diffAbs)
|
||||
case "percent_diff":
|
||||
allNull, value = calculateDiff(vF, allNull, value, percentDiff)
|
||||
allNull, value = calculateDiff(ff, allNull, value, percentDiff)
|
||||
case "percent_diff_abs":
|
||||
allNull, value = calculateDiff(vF, allNull, value, percentDiffAbs)
|
||||
allNull, value = calculateDiff(ff, allNull, value, percentDiffAbs)
|
||||
case "count_non_null":
|
||||
for i := 0; i < vF.Len(); i++ {
|
||||
if f, ok := vF.At(i).(*float64); ok {
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
value++
|
||||
for i := 0; i < ff.Len(); i++ {
|
||||
f := ff.GetValue(i)
|
||||
if nilOrNaN(f) {
|
||||
continue
|
||||
}
|
||||
value++
|
||||
}
|
||||
|
||||
if value > 0 {
|
||||
@@ -158,30 +151,28 @@ func (cr classicReducer) Reduce(series mathexp.Series) mathexp.Number {
|
||||
return num
|
||||
}
|
||||
|
||||
func calculateDiff(vF *data.Field, allNull bool, value float64, fn func(float64, float64) float64) (bool, float64) {
|
||||
func calculateDiff(ff mathexp.Float64Field, allNull bool, value float64, fn func(float64, float64) float64) (bool, float64) {
|
||||
var (
|
||||
first float64
|
||||
i int
|
||||
)
|
||||
// get the newest point
|
||||
for i = vF.Len() - 1; i >= 0; i-- {
|
||||
if f, ok := vF.At(i).(*float64); ok {
|
||||
if !nilOrNaN(f) {
|
||||
first = *f
|
||||
allNull = false
|
||||
break
|
||||
}
|
||||
for i = ff.Len() - 1; i >= 0; i-- {
|
||||
f := ff.GetValue(i)
|
||||
if !nilOrNaN(f) {
|
||||
first = *f
|
||||
allNull = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if i >= 1 {
|
||||
// get the oldest point
|
||||
for i := 0; i < vF.Len(); i++ {
|
||||
if f, ok := vF.At(i).(*float64); ok {
|
||||
if !nilOrNaN(f) {
|
||||
value = fn(first, *f)
|
||||
allNull = false
|
||||
break
|
||||
}
|
||||
for i := 0; i < ff.Len(); i++ {
|
||||
f := ff.GetValue(i)
|
||||
if !nilOrNaN(f) {
|
||||
value = fn(first, *f)
|
||||
allNull = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user