From fbef76560b2e9ac839bccbc5afb25c0b84e962b1 Mon Sep 17 00:00:00 2001 From: Michail Safronov Date: Wed, 24 Jan 2024 19:42:02 +0500 Subject: [PATCH] expr: refactor for avoid global evaluator usage --- cmd/carbonapi/config/config.go | 14 +- cmd/carbonapi/http/main_test.go | 2 +- cmd/carbonapi/http/render_handler.go | 4 +- cmd/carbonapi/main.go | 6 +- expr/expr.go | 135 ++++++++++-------- expr/expr_test.go | 96 ++++++++----- expr/functions/absolute/function.go | 8 +- expr/functions/absolute/function_test.go | 13 +- expr/functions/aggregate/function.go | 10 +- expr/functions/aggregate/function_test.go | 23 +-- expr/functions/aggregateLine/function.go | 8 +- expr/functions/aggregateLine/function_test.go | 17 +-- .../aggregateSeriesLists/function.go | 10 +- .../aggregateSeriesLists/function_test.go | 33 +++-- .../aggregateWithWildcards/function.go | 8 +- .../aggregateWithWildcards/function_test.go | 39 ++--- expr/functions/alias/function.go | 8 +- expr/functions/alias/function_test.go | 16 ++- expr/functions/aliasByBase64/function.go | 8 +- expr/functions/aliasByBase64/function_test.go | 17 +-- expr/functions/aliasByMetric/function.go | 8 +- expr/functions/aliasByMetric/function_test.go | 17 +-- expr/functions/aliasByNode/function.go | 8 +- expr/functions/aliasByNode/function_test.go | 18 +-- expr/functions/aliasByPostgres/function.go | 5 +- expr/functions/aliasByRedis/function.go | 6 +- expr/functions/aliasByRedis/function_test.go | 15 +- expr/functions/aliasQuery/function.go | 16 +-- expr/functions/aliasQuery/function_test.go | 13 +- expr/functions/aliasSub/function.go | 8 +- expr/functions/aliasSub/function_test.go | 17 +-- expr/functions/asPercent/function.go | 12 +- expr/functions/asPercent/function_test.go | 27 ++-- .../averageOutsidePercentile/function.go | 8 +- .../averageOutsidePercentile/function_test.go | 13 +- expr/functions/baselines/function.go | 10 +- expr/functions/below/function.go | 8 +- expr/functions/below/function_test.go | 13 +- expr/functions/cactiStyle/function.go | 8 +- expr/functions/cactiStyle/function_test.go | 13 +- expr/functions/cairo/cairo_test.go | 10 +- expr/functions/cairo/function.go | 8 +- expr/functions/cairo/png/cairo.go | 17 +-- expr/functions/cairo/png/png.go | 4 +- expr/functions/changed/function.go | 8 +- expr/functions/changed/function_test.go | 13 +- .../compressPeriodicGaps/function.go | 11 +- .../compressPeriodicGaps/function_test.go | 18 +-- expr/functions/consolidateBy/function.go | 8 +- expr/functions/consolidateBy/function_test.go | 18 +-- expr/functions/constantLine/function.go | 6 +- expr/functions/constantLine/function_test.go | 13 +- expr/functions/cumulative/function.go | 8 +- expr/functions/cumulative/function_test.go | 13 +- expr/functions/delay/function.go | 8 +- expr/functions/delay/function_test.go | 21 +-- expr/functions/derivative/function.go | 8 +- expr/functions/derivative/function_test.go | 13 +- expr/functions/divideSeries/function.go | 10 +- expr/functions/divideSeries/function_test.go | 19 +-- expr/functions/ewma/function.go | 8 +- expr/functions/ewma/function_test.go | 13 +- expr/functions/example/function.go | 6 +- expr/functions/exclude/function.go | 8 +- expr/functions/exclude/function_test.go | 13 +- expr/functions/exp/function.go | 8 +- expr/functions/exp/function_test.go | 13 +- .../exponentialMovingAverage/function.go | 12 +- .../exponentialMovingAverage/function_test.go | 21 +-- expr/functions/fallbackSeries/function.go | 10 +- .../functions/fallbackSeries/function_test.go | 16 ++- expr/functions/fft/function.go | 8 +- expr/functions/filter/function.go | 8 +- expr/functions/filter/function_test.go | 13 +- expr/functions/graphiteWeb/function.go | 4 +- expr/functions/grep/function.go | 8 +- expr/functions/grep/function_test.go | 13 +- expr/functions/group/function.go | 8 +- expr/functions/groupByNode/function.go | 10 +- expr/functions/groupByNode/function_test.go | 23 +-- expr/functions/groupByTags/function.go | 10 +- expr/functions/groupByTags/function_test.go | 38 +++-- expr/functions/heatMap/function.go | 8 +- expr/functions/heatMap/function_test.go | 13 +- expr/functions/highestLowest/function.go | 8 +- expr/functions/highestLowest/function_test.go | 16 ++- expr/functions/hitcount/function.go | 15 +- expr/functions/hitcount/function_test.go | 16 ++- .../holtWintersAberration/function.go | 10 +- .../holtWintersAberration/function_test.go | 16 ++- .../holtWintersConfidenceArea/function.go | 6 +- .../function_cairo.go | 8 +- .../function_test.go | 16 ++- .../holtWintersConfidenceBands/function.go | 9 +- .../function_test.go | 19 +-- .../functions/holtWintersForecast/function.go | 8 +- .../holtWintersForecast/function_test.go | 13 +- expr/functions/identity/function.go | 6 +- expr/functions/identity/function_test.go | 13 +- expr/functions/ifft/function.go | 10 +- expr/functions/integral/function.go | 8 +- expr/functions/integral/function_test.go | 13 +- expr/functions/integralByInterval/function.go | 8 +- .../integralByInterval/function_test.go | 13 +- expr/functions/integralWithReset/function.go | 10 +- .../integralWithReset/function_test.go | 19 +-- expr/functions/interpolate/function.go | 8 +- expr/functions/interpolate/function_test.go | 13 +- expr/functions/invert/function.go | 8 +- expr/functions/invert/function_test.go | 13 +- expr/functions/isNotNull/function.go | 8 +- expr/functions/isNotNull/function_test.go | 13 +- expr/functions/join/function.go | 12 +- expr/functions/join/function_test.go | 13 +- expr/functions/keepLastValue/function.go | 8 +- expr/functions/keepLastValue/function_test.go | 13 +- .../kolmogorovSmirnovTest2/function.go | 10 +- expr/functions/legendValue/function.go | 8 +- expr/functions/legendValue/function_test.go | 13 +- expr/functions/limit/function.go | 8 +- expr/functions/limit/function_test.go | 13 +- expr/functions/linearRegression/function.go | 8 +- .../linearRegression/function_test.go | 17 +-- expr/functions/logarithm/function.go | 8 +- expr/functions/logarithm/function_test.go | 17 +-- expr/functions/logit/function.go | 8 +- expr/functions/logit/function_test.go | 13 +- expr/functions/lowPass/function.go | 8 +- expr/functions/lowPass/function_test.go | 13 +- expr/functions/mapSeries/function.go | 8 +- expr/functions/mapSeries/function_test.go | 13 +- expr/functions/minMax/function.go | 8 +- expr/functions/minMax/function_test.go | 13 +- expr/functions/mostDeviant/function.go | 8 +- expr/functions/mostDeviant/function_test.go | 13 +- expr/functions/moving/function.go | 14 +- expr/functions/moving/function_test.go | 58 ++++---- .../moving/moving_refetch/function_test.go | 76 ++++++++++ expr/functions/movingMedian/function.go | 6 +- expr/functions/movingMedian/function_test.go | 17 +-- expr/functions/nPercentile/function.go | 8 +- expr/functions/nPercentile/function_test.go | 13 +- .../nonNegativeDerivative/function.go | 8 +- .../nonNegativeDerivative/function_test.go | 13 +- expr/functions/offset/function.go | 8 +- expr/functions/offset/function_test.go | 13 +- expr/functions/offsetToZero/function.go | 8 +- expr/functions/offsetToZero/function_test.go | 13 +- expr/functions/pearson/function.go | 10 +- expr/functions/pearson/function_test.go | 13 +- expr/functions/pearsonClosest/function.go | 10 +- .../functions/pearsonClosest/function_test.go | 16 ++- expr/functions/perSecond/function.go | 8 +- expr/functions/perSecond/function_test.go | 13 +- expr/functions/percentileOfSeries/function.go | 6 +- .../percentileOfSeries/function_test.go | 16 ++- expr/functions/polyfit/function.go | 8 +- expr/functions/polyfit/function_test.go | 13 +- expr/functions/pow/function.go | 10 +- expr/functions/pow/function_test.go | 13 +- expr/functions/powSeries/function.go | 8 +- expr/functions/powSeries/function_test.go | 17 +-- expr/functions/randomWalk/function.go | 6 +- expr/functions/randomWalk/function_test.go | 13 +- expr/functions/rangeOfSeries/function.go | 8 +- expr/functions/rangeOfSeries/function_test.go | 13 +- expr/functions/reduce/function.go | 10 +- expr/functions/removeBelowSeries/function.go | 8 +- .../removeBelowSeries/function_test.go | 13 +- .../removeBetweenPercentile/function.go | 8 +- .../removeBetweenPercentile/function_test.go | 13 +- expr/functions/removeEmptySeries/function.go | 8 +- .../removeEmptySeries/function_test.go | 13 +- expr/functions/round/function.go | 8 +- expr/functions/round/function_test.go | 13 +- expr/functions/scale/function.go | 8 +- expr/functions/scale/function_test.go | 13 +- expr/functions/scaleToSeconds/function.go | 8 +- .../functions/scaleToSeconds/function_test.go | 13 +- expr/functions/seriesByTag/function.go | 6 +- expr/functions/seriesList/function.go | 10 +- expr/functions/seriesList/function_test.go | 19 +-- expr/functions/setXFilesFactor/function.go | 8 +- .../setXFilesFactor/function_test.go | 13 +- expr/functions/sigmoid/function.go | 8 +- expr/functions/sigmoid/function_test.go | 13 +- expr/functions/sinFunction/function.go | 6 +- expr/functions/sinFunction/function_test.go | 13 +- expr/functions/slo/function.go | 10 +- expr/functions/slo/function_test.go | 16 ++- expr/functions/smartSummarize/function.go | 8 +- .../functions/smartSummarize/function_test.go | 43 +++--- expr/functions/sortBy/function.go | 8 +- expr/functions/sortBy/function_test.go | 19 +-- expr/functions/sortByName/function.go | 8 +- expr/functions/sortByName/function_test.go | 17 +-- expr/functions/squareRoot/function.go | 8 +- expr/functions/squareRoot/function_test.go | 13 +- expr/functions/stdev/function.go | 8 +- expr/functions/stdev/function_test.go | 20 +-- expr/functions/substr/function.go | 8 +- expr/functions/substr/function_test.go | 13 +- expr/functions/summarize/function.go | 11 +- expr/functions/summarize/function_test.go | 16 ++- expr/functions/timeFunction/function.go | 6 +- expr/functions/timeFunction/function_test.go | 13 +- expr/functions/timeShift/function.go | 6 +- expr/functions/timeShift/function_test.go | 13 +- expr/functions/timeShiftByMetric/function.go | 14 +- .../timeShiftByMetric/function_test.go | 23 +-- expr/functions/timeSlice/function.go | 8 +- expr/functions/timeSlice/function_test.go | 13 +- expr/functions/timeStack/function.go | 8 +- expr/functions/timeStack/function_test.go | 13 +- expr/functions/toLowerCase/function.go | 9 +- expr/functions/toLowerCase/function_test.go | 13 +- expr/functions/toUpperCase/function.go | 9 +- expr/functions/toUpperCase/function_test.go | 13 +- expr/functions/transformNull/function.go | 10 +- expr/functions/transformNull/function_test.go | 13 +- expr/functions/tukey/function.go | 8 +- expr/functions/tukey/function_test.go | 13 +- expr/functions/unique/function.go | 8 +- expr/functions/unique/function_test.go | 13 +- expr/functions/verticalLine/function.go | 7 +- expr/functions/verticalLine/function_cairo.go | 6 +- expr/functions/verticalLine/function_test.go | 16 ++- expr/functions/weightedAverage/function.go | 10 +- .../weightedAverage/function_test.go | 17 +-- expr/helper/helper.go | 27 ++-- expr/interfaces/interface.go | 23 +-- expr/metadata/metadata.go | 26 +--- expr/rewrite/aboveSeries/function.go | 6 +- expr/rewrite/aboveSeries/function_test.go | 14 +- expr/rewrite/applyByNode/function.go | 6 +- expr/rewrite/applyByNode/function_test.go | 9 +- expr/types/types.go | 6 + tests/helper.go | 116 ++++++++++----- .../carbonapi => zipper}/interfaces/zipper.go | 0 239 files changed, 1648 insertions(+), 1601 deletions(-) create mode 100644 expr/functions/moving/moving_refetch/function_test.go rename {cmd/carbonapi => zipper}/interfaces/zipper.go (100%) diff --git a/cmd/carbonapi/config/config.go b/cmd/carbonapi/config/config.go index 39019e3c6..b752c94c4 100644 --- a/cmd/carbonapi/config/config.go +++ b/cmd/carbonapi/config/config.go @@ -5,10 +5,12 @@ import ( "time" "github.com/go-graphite/carbonapi/cache" - "github.com/go-graphite/carbonapi/cmd/carbonapi/interfaces" + "github.com/go-graphite/carbonapi/expr" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/limiter" "github.com/go-graphite/carbonapi/pkg/tlsconfig" zipperCfg "github.com/go-graphite/carbonapi/zipper/config" + zipper "github.com/go-graphite/carbonapi/zipper/interfaces" zipperTypes "github.com/go-graphite/carbonapi/zipper/types" "github.com/lomik/zapwriter" @@ -116,10 +118,12 @@ type ConfigType struct { DefaultTimeZone *time.Location `mapstructure:"-" json:"-"` // ZipperInstance is API entry to carbonzipper - ZipperInstance interfaces.CarbonZipper `mapstructure:"-" json:"-"` + ZipperInstance zipper.CarbonZipper `mapstructure:"-" json:"-"` // Limiter limits concurrent zipper requests Limiter limiter.SimpleLimiter `mapstructure:"-" json:"-"` + + Evaluator interfaces.Evaluator `mapstructure:"-" json:"-"` } // skipcq: CRT-P0003 @@ -132,6 +136,12 @@ func (c ConfigType) String() string { } } +func (c *ConfigType) SetZipper(zipper zipper.CarbonZipper) (err error) { + c.ZipperInstance = zipper + c.Evaluator, err = expr.NewEvaluator(c.Limiter, c.ZipperInstance) + return +} + var Config = ConfigType{ ExtrapolateExperiment: false, Buckets: 10, diff --git a/cmd/carbonapi/http/main_test.go b/cmd/carbonapi/http/main_test.go index 4e68fb987..fa4f93413 100644 --- a/cmd/carbonapi/http/main_test.go +++ b/cmd/carbonapi/http/main_test.go @@ -118,7 +118,7 @@ func init() { config.Config.Upstreams.Backends = []string{"dummy"} config.SetUpConfigUpstreams(logger) config.SetUpConfig(logger, "(test)") - config.Config.ZipperInstance = newMockCarbonZipper() + config.Config.SetZipper(newMockCarbonZipper()) emptyStringList := make([]string, 0) InitHandlers(emptyStringList, emptyStringList) } diff --git a/cmd/carbonapi/http/render_handler.go b/cmd/carbonapi/http/render_handler.go index db8fb9b49..79b8a71cd 100644 --- a/cmd/carbonapi/http/render_handler.go +++ b/cmd/carbonapi/http/render_handler.go @@ -306,7 +306,7 @@ func renderHandler(w http.ResponseWriter, r *http.Request) { ApiMetrics.RenderRequests.Add(1) - result, errs := expr.FetchAndEvalExprs(ctx, exprs, from32, until32, values) + result, errs := expr.FetchAndEvalExprs(ctx, config.Config.Evaluator, exprs, from32, until32, values) if errs != nil { errors = errs } @@ -324,7 +324,7 @@ func renderHandler(w http.ResponseWriter, r *http.Request) { ApiMetrics.RenderRequests.Add(1) - result, err := expr.FetchAndEvalExp(ctx, exp, from32, until32, values) + result, err := expr.FetchAndEvalExp(ctx, config.Config.Evaluator, exp, from32, until32, values) if err != nil { errors[target] = merry.Wrap(err) } diff --git a/cmd/carbonapi/main.go b/cmd/carbonapi/main.go index be9d623c0..df86e50ec 100644 --- a/cmd/carbonapi/main.go +++ b/cmd/carbonapi/main.go @@ -61,7 +61,11 @@ func main() { dns.UseDNSCache(config.Config.CachingDNSRefreshTime) } - config.Config.ZipperInstance = newZipper(carbonapiHttp.ZipperStats, &config.Config.Upstreams, config.Config.IgnoreClientTimeout, zapwriter.Logger("zipper")) + if err := config.Config.SetZipper(newZipper(carbonapiHttp.ZipperStats, &config.Config.Upstreams, config.Config.IgnoreClientTimeout, zapwriter.Logger("zipper"))); err != nil { + logger.Fatal("failed to setup zipper", + zap.Error(err), + ) + } wg := sync.WaitGroup{} serve := func(listen config.Listener, handler http.Handler) { diff --git a/expr/expr.go b/expr/expr.go index aaf8d284f..d5b78200f 100644 --- a/expr/expr.go +++ b/expr/expr.go @@ -2,26 +2,34 @@ package expr import ( "context" + "errors" "github.com/ansel1/merry" pb "github.com/go-graphite/protocol/carbonapi_v3_pb" - "github.com/go-graphite/carbonapi/cmd/carbonapi/config" _ "github.com/go-graphite/carbonapi/expr/functions" "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" + "github.com/go-graphite/carbonapi/limiter" "github.com/go-graphite/carbonapi/pkg/parser" utilctx "github.com/go-graphite/carbonapi/util/ctx" + zipper "github.com/go-graphite/carbonapi/zipper/interfaces" ) -type evaluator struct{} +var ErrZipperNotInit = errors.New("zipper not initialized") -func (eval evaluator) Fetch(ctx context.Context, exprs []parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (map[parser.MetricRequest][]*types.MetricData, error) { - if err := config.Config.Limiter.Enter(ctx); err != nil { +type Evaluator struct { + limiter limiter.SimpleLimiter + zipper zipper.CarbonZipper +} + +func (eval Evaluator) Fetch(ctx context.Context, exprs []parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (map[parser.MetricRequest][]*types.MetricData, error) { + if err := eval.limiter.Enter(ctx); err != nil { return nil, err } - defer config.Config.Limiter.Leave() + defer eval.limiter.Leave() multiFetchRequest := pb.MultiFetchRequest{} metricRequestCache := make(map[string]parser.MetricRequest) @@ -74,7 +82,7 @@ func (eval evaluator) Fetch(ctx context.Context, exprs []parser.Expr, from, unti } if len(multiFetchRequest.Metrics) > 0 { - metrics, _, err := config.Config.ZipperInstance.Render(ctx, multiFetchRequest) + metrics, _, err := eval.zipper.Render(ctx, multiFetchRequest) // If we had only partial result, we want to do our best to actually do our job if err != nil && merry.HTTPCode(err) >= 400 && !haveFallbackSeries { return nil, err @@ -97,7 +105,7 @@ func (eval evaluator) Fetch(ctx context.Context, exprs []parser.Expr, from, unti targetValues[m] = values[m] } - if config.Config.ZipperInstance.ScaleToCommonStep() { + if eval.zipper.ScaleToCommonStep() { targetValues = helper.ScaleValuesToCommonStep(targetValues) } @@ -105,8 +113,8 @@ func (eval evaluator) Fetch(ctx context.Context, exprs []parser.Expr, from, unti } // Eval evaluates expressions. -func (eval evaluator) Eval(ctx context.Context, exp parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (results []*types.MetricData, err error) { - rewritten, targets, err := RewriteExpr(ctx, exp, from, until, values) +func (eval Evaluator) Eval(ctx context.Context, exp parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (results []*types.MetricData, err error) { + rewritten, targets, err := RewriteExpr(ctx, eval, exp, from, until, values) if err != nil { return nil, err } @@ -128,63 +136,19 @@ func (eval evaluator) Eval(ctx context.Context, exp parser.Expr, from, until int } return results, nil } - return EvalExpr(ctx, exp, from, until, values) -} - -var _evaluator = evaluator{} - -func init() { - helper.SetEvaluator(_evaluator) - metadata.SetEvaluator(_evaluator) -} - -// FetchAndEvalExp fetch data and evaluates expressions -func FetchAndEvalExp(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, merry.Error) { - targetValues, err := _evaluator.Fetch(ctx, []parser.Expr{e}, from, until, values) - if err != nil { - return nil, merry.Wrap(err) - } - - res, err := _evaluator.Eval(ctx, e, from, until, targetValues) - if err != nil { - return nil, merry.Wrap(err) - } - - for mReq := range values { - SortMetrics(values[mReq], mReq) - } - - return res, nil + return EvalExpr(ctx, eval, exp, from, until, values) } -func FetchAndEvalExprs(ctx context.Context, exprs []parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, map[string]merry.Error) { - targetValues, err := _evaluator.Fetch(ctx, exprs, from, until, values) - if err != nil { - return nil, map[string]merry.Error{"*": merry.Wrap(err)} - } - - res := make([]*types.MetricData, 0, len(exprs)) - var errors map[string]merry.Error - for _, exp := range exprs { - evaluationResult, err := _evaluator.Eval(ctx, exp, from, until, targetValues) - if err != nil { - if errors == nil { - errors = make(map[string]merry.Error) - } - errors[exp.Target()] = merry.Wrap(err) - } - res = append(res, evaluationResult...) - } - - for mReq := range values { - SortMetrics(values[mReq], mReq) +// NewEvaluator create evaluator with limiter and zipper +func NewEvaluator(limiter limiter.SimpleLimiter, zipper zipper.CarbonZipper) (*Evaluator, error) { + if zipper == nil { + return nil, ErrZipperNotInit } - - return res, errors + return &Evaluator{limiter: limiter, zipper: zipper}, nil } // EvalExpr is the main expression evaluator. -func EvalExpr(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func EvalExpr(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.IsName() { return values[parser.MetricRequest{Metric: e.Target(), From: from, Until: until}], nil } else if e.IsConst() { @@ -212,7 +176,7 @@ func EvalExpr(ctx context.Context, e parser.Expr, from, until int64, values map[ f, ok := metadata.FunctionMD.Functions[e.Target()] metadata.FunctionMD.RUnlock() if ok { - v, err := f.Do(ctx, e, from, until, values) + v, err := f.Do(ctx, eval, e, from, until, values) if err != nil { err = merry.WithMessagef(err, "function=%s: %s", e.Target(), err.Error()) if merry.Is( @@ -242,14 +206,59 @@ func EvalExpr(ctx context.Context, e parser.Expr, from, until int64, values map[ // applyByNode(foo*, 1, "%") -> (true, ["foo1", "foo2"], nil) // sumSeries(foo) -> (false, nil, nil) // Assumes that applyByNode only appears as the outermost function. -func RewriteExpr(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (bool, []string, error) { +func RewriteExpr(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (bool, []string, error) { if e.IsFunc() { metadata.FunctionMD.RLock() f, ok := metadata.FunctionMD.RewriteFunctions[e.Target()] metadata.FunctionMD.RUnlock() if ok { - return f.Do(ctx, e, from, until, values) + return f.Do(ctx, eval, e, from, until, values) } } return false, nil, nil } + +// FetchAndEvalExp fetch data and evaluates expressions +func FetchAndEvalExp(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, merry.Error) { + targetValues, err := eval.Fetch(ctx, []parser.Expr{e}, from, until, values) + if err != nil { + return nil, merry.Wrap(err) + } + + res, err := eval.Eval(ctx, e, from, until, targetValues) + if err != nil { + return nil, merry.Wrap(err) + } + + for mReq := range values { + SortMetrics(values[mReq], mReq) + } + + return res, nil +} + +func FetchAndEvalExprs(ctx context.Context, eval interfaces.Evaluator, exprs []parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, map[string]merry.Error) { + targetValues, err := eval.Fetch(ctx, exprs, from, until, values) + if err != nil { + return nil, map[string]merry.Error{"*": merry.Wrap(err)} + } + + res := make([]*types.MetricData, 0, len(exprs)) + var errors map[string]merry.Error + for _, exp := range exprs { + evaluationResult, err := eval.Eval(ctx, exp, from, until, targetValues) + if err != nil { + if errors == nil { + errors = make(map[string]merry.Error) + } + errors[exp.Target()] = merry.Wrap(err) + } + res = append(res, evaluationResult...) + } + + for mReq := range values { + SortMetrics(values[mReq], mReq) + } + + return res, errors +} diff --git a/expr/expr_test.go b/expr/expr_test.go index 83a1cbd8f..09b5acf88 100644 --- a/expr/expr_test.go +++ b/expr/expr_test.go @@ -205,7 +205,10 @@ func TestEvalExpr(t *testing.T) { &data, } - _, err = EvalExpr(context.Background(), exp, request.From, request.Until, metricMap) + eval, err := NewEvaluator(nil, th.NewTestZipper(nil)) + if err == nil { + _, err = EvalExpr(context.Background(), eval, exp, request.From, request.Until, metricMap) + } if err != nil { t.Errorf("error='%v'", err) } @@ -357,7 +360,12 @@ func TestEvalExpression(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval, err := NewEvaluator(nil, th.NewTestZipper(nil)) + if err == nil { + th.TestEvalExpr(t, eval, &tt) + } else { + t.Errorf("error='%v'", err) + } }) } } @@ -455,30 +463,35 @@ func TestRewriteExpr(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - rewritten, newTargets, err := RewriteExpr(context.Background(), tt.e, 0, 1, tt.m) + eval, err := NewEvaluator(nil, th.NewTestZipper(nil)) + if err == nil { + rewritten, newTargets, err := RewriteExpr(context.Background(), eval, tt.e, 0, 1, tt.m) - if err != nil { - t.Errorf("failed to rewrite %v: %+v", tt.name, err) - return - } + if err != nil { + t.Errorf("failed to rewrite %v: %+v", tt.name, err) + return + } - if rewritten != tt.rewritten { - t.Errorf("failed to rewrite %v: expected rewritten=%v but was %v", tt.name, tt.rewritten, rewritten) - return - } + if rewritten != tt.rewritten { + t.Errorf("failed to rewrite %v: expected rewritten=%v but was %v", tt.name, tt.rewritten, rewritten) + return + } - var targetsMatch = true - if len(tt.newTargets) != len(newTargets) { - targetsMatch = false - } else { - for i := range tt.newTargets { - targetsMatch = targetsMatch && tt.newTargets[i] == newTargets[i] + var targetsMatch = true + if len(tt.newTargets) != len(newTargets) { + targetsMatch = false + } else { + for i := range tt.newTargets { + targetsMatch = targetsMatch && tt.newTargets[i] == newTargets[i] + } } - } - if !targetsMatch { - t.Errorf("failed to rewrite %v: expected newTargets=%v but was %v", tt.name, tt.newTargets, newTargets) - return + if !targetsMatch { + t.Errorf("failed to rewrite %v: expected newTargets=%v but was %v", tt.name, tt.newTargets, newTargets) + return + } + } else { + t.Errorf("error='%v'", err) } }) } @@ -507,26 +520,31 @@ func TestEvalCustomFromUntil(t *testing.T) { t.Run(tt.name, func(t *testing.T) { originalMetrics := th.DeepClone(tt.m) exp, _, _ := parser.ParseExpr(tt.target) - g, err := EvalExpr(context.Background(), exp, tt.from, tt.until, tt.m) - if err != nil { - t.Errorf("failed to eval %v: %s", tt.name, err) - return - } - if g[0] == nil { - t.Errorf("returned no value %v", tt.target) - return - } + eval, err := NewEvaluator(nil, th.NewTestZipper(nil)) + if err == nil { + g, err := EvalExpr(context.Background(), eval, exp, tt.from, tt.until, tt.m) + if err != nil { + t.Errorf("failed to eval %v: %s", tt.name, err) + return + } + if g[0] == nil { + t.Errorf("returned no value %v", tt.target) + return + } - th.DeepEqual(t, tt.target, originalMetrics, tt.m, false) + th.DeepEqual(t, tt.target, originalMetrics, tt.m, false) - if g[0].StepTime == 0 { - t.Errorf("missing step for %+v", g) - } - if !compare.NearlyEqual(g[0].Values, tt.w) { - t.Errorf("failed: %s: got %+v, want %+v", g[0].Name, g[0].Values, tt.w) - } - if g[0].Name != tt.name { - t.Errorf("bad name for %+v: got %v, want %v", g, g[0].Name, tt.name) + if g[0].StepTime == 0 { + t.Errorf("missing step for %+v", g) + } + if !compare.NearlyEqual(g[0].Values, tt.w) { + t.Errorf("failed: %s: got %+v, want %+v", g[0].Name, g[0].Values, tt.w) + } + if g[0].Name != tt.name { + t.Errorf("bad name for %+v: got %v, want %v", g, g[0].Name, tt.name) + } + } else { + t.Errorf("error='%v'", err) } }) } diff --git a/expr/functions/absolute/function.go b/expr/functions/absolute/function.go index f2e501624..0e916274d 100644 --- a/expr/functions/absolute/function.go +++ b/expr/functions/absolute/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type absolute struct { - interfaces.FunctionBase -} +type absolute struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -27,8 +25,8 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *absolute) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - return helper.ForEachSeriesDo(ctx, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { +func (f *absolute) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + return helper.ForEachSeriesDo(ctx, eval, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { for i, v := range a.Values { if math.IsNaN(a.Values[i]) { r.Values[i] = math.NaN() diff --git a/expr/functions/absolute/function_test.go b/expr/functions/absolute/function_test.go index 73961d78e..36531076e 100644 --- a/expr/functions/absolute/function_test.go +++ b/expr/functions/absolute/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -38,7 +38,8 @@ func TestAbsolute(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/aggregate/function.go b/expr/functions/aggregate/function.go index e2e76354b..59477516b 100644 --- a/expr/functions/aggregate/function.go +++ b/expr/functions/aggregate/function.go @@ -13,9 +13,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type aggregate struct { - interfaces.FunctionBase -} +type aggregate struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -39,7 +37,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // aggregate(*seriesLists) -func (f *aggregate) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *aggregate) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { var args []*types.MetricData var xFilesFactor float64 isAggregateFunc := true @@ -49,7 +47,7 @@ func (f *aggregate) Do(ctx context.Context, e parser.Expr, from, until int64, va if e.Target() == "aggregate" { return nil, err } else { - args, err = helper.GetSeriesArgsAndRemoveNonExisting(ctx, e, from, until, values) + args, err = helper.GetSeriesArgsAndRemoveNonExisting(ctx, eval, e, from, until, values) if err != nil { return nil, err } @@ -61,7 +59,7 @@ func (f *aggregate) Do(ctx context.Context, e parser.Expr, from, until int64, va xFilesFactor = -1 // xFilesFactor is not used by the ...Series functions } } else { - args, err = helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err = helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/aggregate/function_test.go b/expr/functions/aggregate/function_test.go index fa6b0940d..f895da12e 100644 --- a/expr/functions/aggregate/function_test.go +++ b/expr/functions/aggregate/function_test.go @@ -7,7 +7,7 @@ import ( "time" fconfig "github.com/go-graphite/carbonapi/expr/functions/config" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" @@ -15,11 +15,11 @@ import ( "github.com/go-graphite/carbonapi/tests/compare" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -400,7 +400,8 @@ func TestAverageSeries(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -455,7 +456,8 @@ func TestAverageSeriesExtractSeriesByTag(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -498,7 +500,8 @@ func TestAverageSeriesAlign(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprResult(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprResult(t, eval, &tt) }) } @@ -514,7 +517,7 @@ func BenchmarkAverageSeries(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -522,7 +525,7 @@ func BenchmarkAverageSeries(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/aggregateLine/function.go b/expr/functions/aggregateLine/function.go index a5c0f85a5..bf4fe0f1a 100644 --- a/expr/functions/aggregateLine/function.go +++ b/expr/functions/aggregateLine/function.go @@ -13,9 +13,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type aggregateLine struct { - interfaces.FunctionBase -} +type aggregateLine struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,8 +29,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // aggregateLine(*seriesLists) -func (f *aggregateLine) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *aggregateLine) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/aggregateLine/function_test.go b/expr/functions/aggregateLine/function_test.go index 9b78c92b8..f3a3a0855 100644 --- a/expr/functions/aggregateLine/function_test.go +++ b/expr/functions/aggregateLine/function_test.go @@ -6,18 +6,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -60,7 +60,8 @@ func TestConstantLine(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -75,7 +76,7 @@ func BenchmarkAverageSeries(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -83,7 +84,7 @@ func BenchmarkAverageSeries(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/aggregateSeriesLists/function.go b/expr/functions/aggregateSeriesLists/function.go index f9e4649bc..323ead70e 100644 --- a/expr/functions/aggregateSeriesLists/function.go +++ b/expr/functions/aggregateSeriesLists/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type aggregateSeriesLists struct { - interfaces.FunctionBase -} +type aggregateSeriesLists struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,16 +26,16 @@ func New(_ string) []interfaces.FunctionMetadata { return res } -func (f *aggregateSeriesLists) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *aggregateSeriesLists) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 3 { return nil, parser.ErrMissingArgument } - seriesList1, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + seriesList1, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } - seriesList2, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + seriesList2, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/aggregateSeriesLists/function_test.go b/expr/functions/aggregateSeriesLists/function_test.go index 2d24cb52b..6f8eb6d66 100644 --- a/expr/functions/aggregateSeriesLists/function_test.go +++ b/expr/functions/aggregateSeriesLists/function_test.go @@ -1,29 +1,21 @@ package aggregateSeriesLists import ( - "github.com/go-graphite/carbonapi/expr/helper" + "math" + "testing" + "time" + + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" - "math" - "testing" - "time" ) -func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) - for _, m := range md { - metadata.RegisterFunction(m.Name, m.F) - } -} - var ( - now = time.Now().Unix() - shipped = []*types.MetricData{ + md []interfaces.FunctionMetadata = New("") + now = time.Now().Unix() + shipped = []*types.MetricData{ types.MakeMetricData("mining.other.shipped", []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, 1, now), types.MakeMetricData("mining.diamond.shipped", []float64{0, -1, -1, 2, 3, -5, -8, 13, 21, -34, -55, 89, 144, -233, -377}, 1, now), types.MakeMetricData("mining.graphite.shipped", []float64{math.NaN(), 2.3, math.NaN(), -4.5, math.NaN(), 6.7, math.NaN(), -8.9, math.NaN(), 10.111, math.NaN(), -12.13, math.NaN(), 14.15, math.NaN(), -16.17, math.NaN(), 18.19, math.NaN(), -20.21}, 1, now), @@ -37,6 +29,12 @@ var ( } ) +func init() { + for _, m := range md { + metadata.RegisterFunction(m.Name, m.F) + } +} + func TestFunction(t *testing.T) { tests := []th.EvalTestItem{ { @@ -134,7 +132,8 @@ func TestFunction(t *testing.T) { for _, test := range tests { t.Run(test.Target, func(t *testing.T) { - th.TestEvalExpr(t, &test) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &test) }) } } diff --git a/expr/functions/aggregateWithWildcards/function.go b/expr/functions/aggregateWithWildcards/function.go index d3bef0be2..a719a906b 100644 --- a/expr/functions/aggregateWithWildcards/function.go +++ b/expr/functions/aggregateWithWildcards/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type aggregateWithWildcards struct { - interfaces.FunctionBase -} +type aggregateWithWildcards struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *aggregateWithWildcards) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *aggregateWithWildcards) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/aggregateWithWildcards/function_test.go b/expr/functions/aggregateWithWildcards/function_test.go index 1423f6905..ca284c157 100644 --- a/expr/functions/aggregateWithWildcards/function_test.go +++ b/expr/functions/aggregateWithWildcards/function_test.go @@ -6,18 +6,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -178,7 +178,8 @@ func TestAggregateWithWildcards(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -209,7 +210,8 @@ func TestFunctionSumSeriesWithWildcards(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } @@ -241,7 +243,8 @@ func TestAverageSeriesWithWildcards(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } @@ -273,7 +276,8 @@ func TestFunctionMultiplySeriesWithWildcards(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } @@ -293,7 +297,8 @@ func TestEmptyData(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } @@ -403,7 +408,7 @@ func BenchmarkMultiplySeriesWithWildcards(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -415,7 +420,7 @@ func BenchmarkMultiplySeriesWithWildcards(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } @@ -530,7 +535,7 @@ func BenchmarkMultiplyAverageSeriesWithWildcards(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -542,7 +547,7 @@ func BenchmarkMultiplyAverageSeriesWithWildcards(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } @@ -657,8 +662,6 @@ func BenchmarkSumSeriesWithWildcards(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() - for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { exp, _, err := parser.ParseExpr(bm.target) @@ -666,10 +669,12 @@ func BenchmarkSumSeriesWithWildcards(b *testing.B) { b.Fatalf("failed to parse %s: %+v", bm.target, err) } + eval := th.EvaluatorFromFunc(md[0].F) + b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } diff --git a/expr/functions/alias/function.go b/expr/functions/alias/function.go index 2ccce6395..15df246ca 100644 --- a/expr/functions/alias/function.go +++ b/expr/functions/alias/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type alias struct { - interfaces.FunctionBase -} +type alias struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -27,12 +25,12 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *alias) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *alias) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/alias/function_test.go b/expr/functions/alias/function_test.go index c8f0c392f..069e0d3f6 100644 --- a/expr/functions/alias/function_test.go +++ b/expr/functions/alias/function_test.go @@ -5,18 +5,19 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -100,7 +101,8 @@ func TestAlias(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } @@ -112,7 +114,7 @@ func BenchmarkAverageAlias(b *testing.B) { {Metric: "metric2", From: 0, Until: 1}: {types.MakeMetricData("metric2", []float64{1, 2, 3, 4, 5}, 1, 1)}, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -120,7 +122,7 @@ func BenchmarkAverageAlias(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/aliasByBase64/function.go b/expr/functions/aliasByBase64/function.go index 08e581af7..3aab8eb50 100644 --- a/expr/functions/aliasByBase64/function.go +++ b/expr/functions/aliasByBase64/function.go @@ -12,9 +12,7 @@ import ( "github.com/msaf1980/go-stringutils" ) -type aliasByBase64 struct { - interfaces.FunctionBase -} +type aliasByBase64 struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +27,8 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *aliasByBase64) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *aliasByBase64) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/aliasByBase64/function_test.go b/expr/functions/aliasByBase64/function_test.go index 6f2503b6c..5d29371c0 100644 --- a/expr/functions/aliasByBase64/function_test.go +++ b/expr/functions/aliasByBase64/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -75,7 +75,8 @@ func TestAlias(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } @@ -103,7 +104,7 @@ func BenchmarkAliasByMetric(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -115,7 +116,7 @@ func BenchmarkAliasByMetric(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } diff --git a/expr/functions/aliasByMetric/function.go b/expr/functions/aliasByMetric/function.go index a38ada22c..1a8d79552 100644 --- a/expr/functions/aliasByMetric/function.go +++ b/expr/functions/aliasByMetric/function.go @@ -11,9 +11,7 @@ import ( "strings" ) -type aliasByMetric struct { - interfaces.FunctionBase -} +type aliasByMetric struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,8 +26,8 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *aliasByMetric) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - return helper.ForEachSeriesDo1(ctx, e, from, until, values, func(a *types.MetricData) *types.MetricData { +func (f *aliasByMetric) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + return helper.ForEachSeriesDo1(ctx, eval, e, from, until, values, func(a *types.MetricData) *types.MetricData { metric := types.ExtractNameTag(a.Name) part := strings.Split(metric, ".") name := part[len(part)-1] diff --git a/expr/functions/aliasByMetric/function_test.go b/expr/functions/aliasByMetric/function_test.go index 2eaa00f5f..10948fd32 100644 --- a/expr/functions/aliasByMetric/function_test.go +++ b/expr/functions/aliasByMetric/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -38,7 +38,8 @@ func TestAliasByMetric(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -52,7 +53,7 @@ func BenchmarkAliasByMetric(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -60,7 +61,7 @@ func BenchmarkAliasByMetric(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/aliasByNode/function.go b/expr/functions/aliasByNode/function.go index 57a5a1bfb..0c47b0f7d 100644 --- a/expr/functions/aliasByNode/function.go +++ b/expr/functions/aliasByNode/function.go @@ -9,9 +9,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type aliasByNode struct { - interfaces.FunctionBase -} +type aliasByNode struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -26,12 +24,12 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *aliasByNode) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *aliasByNode) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/aliasByNode/function_test.go b/expr/functions/aliasByNode/function_test.go index 24d5b1e17..4d1b03677 100644 --- a/expr/functions/aliasByNode/function_test.go +++ b/expr/functions/aliasByNode/function_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" @@ -18,8 +18,11 @@ import ( "github.com/go-graphite/carbonapi/expr/functions/transformNull" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,10 +42,6 @@ func init() { for _, m := range aggFunc { metadata.RegisterFunction(m.Name, m.F) } - - evaluator := th.EvaluatorFromFuncWithMetadata(metadata.FunctionMD.Functions) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) } func TestAliasByNode(t *testing.T) { @@ -179,7 +178,8 @@ func TestAliasByNode(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFuncWithMetadata(metadata.FunctionMD.Functions) + th.TestEvalExpr(t, eval, &tt) }) } @@ -193,7 +193,7 @@ func BenchmarkAliasByNode(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFuncWithMetadata(metadata.FunctionMD.Functions) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -201,7 +201,7 @@ func BenchmarkAliasByNode(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/aliasByPostgres/function.go b/expr/functions/aliasByPostgres/function.go index 3846d9194..027a1d72c 100644 --- a/expr/functions/aliasByPostgres/function.go +++ b/expr/functions/aliasByPostgres/function.go @@ -20,7 +20,6 @@ import ( ) type aliasByPostgres struct { - interfaces.FunctionBase Enabled bool Database map[string]Database } @@ -149,13 +148,13 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *aliasByPostgres) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *aliasByPostgres) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 4 { return nil, parser.ErrMissingTimeseries } logger := zapwriter.Logger("functionInit").With(zap.String("function", "aliasByPostgres")) - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/aliasByRedis/function.go b/expr/functions/aliasByRedis/function.go index d57f76f9f..3bb6372cf 100644 --- a/expr/functions/aliasByRedis/function.go +++ b/expr/functions/aliasByRedis/function.go @@ -44,8 +44,6 @@ type Database struct { } type aliasByRedis struct { - interfaces.FunctionBase - address string dialOptions []redis.DialOption queryTimeout time.Duration @@ -166,8 +164,8 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *aliasByRedis) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *aliasByRedis) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/aliasByRedis/function_test.go b/expr/functions/aliasByRedis/function_test.go index 200959bb6..3bd7eaf3b 100644 --- a/expr/functions/aliasByRedis/function_test.go +++ b/expr/functions/aliasByRedis/function_test.go @@ -9,14 +9,17 @@ import ( "github.com/alicebob/miniredis/v2" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) -var r *miniredis.Miniredis +var ( + md []interfaces.FunctionMetadata + r *miniredis.Miniredis +) func init() { var err error @@ -43,10 +46,7 @@ enabled: true )) config.Close() - md := New(config.Name()) - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) + md = New(config.Name()) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -142,7 +142,8 @@ func TestAliasByRedis(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/aliasQuery/function.go b/expr/functions/aliasQuery/function.go index 1e43d6e39..a039f5d18 100644 --- a/expr/functions/aliasQuery/function.go +++ b/expr/functions/aliasQuery/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type aliasQuery struct { - interfaces.FunctionBase -} +type aliasQuery struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -25,8 +23,8 @@ func New(_ string) []interfaces.FunctionMetadata { } } -func (f *aliasQuery) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - seriesList, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *aliasQuery) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + seriesList, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -58,7 +56,7 @@ func (f *aliasQuery) Do(ctx context.Context, e parser.Expr, from, until int64, v } fetchTargets[i] = expr } - targetValues, err := f.GetEvaluator().Fetch(ctx, fetchTargets, from, until, values) + targetValues, err := eval.Fetch(ctx, fetchTargets, from, until, values) if err != nil { return nil, err } @@ -66,7 +64,7 @@ func (f *aliasQuery) Do(ctx context.Context, e parser.Expr, from, until int64, v results := make([]*types.MetricData, len(seriesList)) for i, series := range seriesList { - v, err := f.getLastValueOfSeries(ctx, fetchTargets[i], from, until, targetValues) + v, err := f.getLastValueOfSeries(ctx, eval, fetchTargets[i], from, until, targetValues) if err != nil { return nil, err } @@ -87,8 +85,8 @@ func (f *aliasQuery) Do(ctx context.Context, e parser.Expr, from, until int64, v return results, nil } -func (f *aliasQuery) getLastValueOfSeries(ctx context.Context, e parser.Expr, from, until int64, targetValues map[parser.MetricRequest][]*types.MetricData) (float64, error) { - res, err := helper.GetSeriesArg(ctx, e, from, until, targetValues) +func (f *aliasQuery) getLastValueOfSeries(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, targetValues map[parser.MetricRequest][]*types.MetricData) (float64, error) { + res, err := helper.GetSeriesArg(ctx, eval, e, from, until, targetValues) if err != nil { return 0, err } diff --git a/expr/functions/aliasQuery/function_test.go b/expr/functions/aliasQuery/function_test.go index e7d4322cc..15b3e240c 100644 --- a/expr/functions/aliasQuery/function_test.go +++ b/expr/functions/aliasQuery/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -44,7 +44,8 @@ func TestAliasQuery(t *testing.T) { for _, tt := range tests { t.Run(tt.Target, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/aliasSub/function.go b/expr/functions/aliasSub/function.go index fe40d392d..212ae43da 100644 --- a/expr/functions/aliasSub/function.go +++ b/expr/functions/aliasSub/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type aliasSub struct { - interfaces.FunctionBase -} +type aliasSub struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -27,12 +25,12 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *aliasSub) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *aliasSub) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 3 { return nil, parser.ErrMissingTimeseries } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/aliasSub/function_test.go b/expr/functions/aliasSub/function_test.go index 1a9bdc6d8..b41fbf5de 100644 --- a/expr/functions/aliasSub/function_test.go +++ b/expr/functions/aliasSub/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -73,7 +73,8 @@ func TestAliasSub(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -86,7 +87,7 @@ func BenchmarkAverageAlias(b *testing.B) { {"metric1.TCP1024", 0, 1}: {types.MakeMetricData("metric1.TCP1024", []float64{1, 2, 3, 4, 5}, 1, 1)}, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -94,7 +95,7 @@ func BenchmarkAverageAlias(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/asPercent/function.go b/expr/functions/asPercent/function.go index b1ecc7dfd..f9ad8646b 100644 --- a/expr/functions/asPercent/function.go +++ b/expr/functions/asPercent/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type asPercent struct { - interfaces.FunctionBase -} +type asPercent struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -334,8 +332,8 @@ func seriesGroup2AsPercent(arg, total []*types.MetricData, nodesOrTags []parser. } // asPercent(seriesList, total=None, *nodes) -func (f *asPercent) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *asPercent) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -389,7 +387,7 @@ func (f *asPercent) Do(ctx context.Context, e parser.Expr, from, until int64, va return arg, nil } else if e.ArgsLen() == 2 && (e.Arg(1).IsName() || e.Arg(1).IsFunc()) { // asPercent(seriesList, totalList) - total, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + total, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } @@ -414,7 +412,7 @@ func (f *asPercent) Do(ctx context.Context, e parser.Expr, from, until int64, va return seriesGroupAsPercent(arg, nodesOrTags), nil } else { // asPercent(seriesList, totalSeriesList, *nodes) - total, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + total, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/asPercent/function_test.go b/expr/functions/asPercent/function_test.go index 5547c509f..7bd212713 100644 --- a/expr/functions/asPercent/function_test.go +++ b/expr/functions/asPercent/function_test.go @@ -6,18 +6,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -209,7 +209,8 @@ func TestAsPercent(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } @@ -269,7 +270,8 @@ func TestAsPercentAlignment(t *testing.T) { for _, tt := range testAlignments { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } @@ -341,7 +343,8 @@ func TestAsPercentGroup(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } @@ -447,7 +450,7 @@ func BenchmarkAsPercent(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -459,7 +462,7 @@ func BenchmarkAsPercent(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } @@ -500,7 +503,7 @@ func BenchmarkAsPercentGroup(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -512,7 +515,7 @@ func BenchmarkAsPercentGroup(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } diff --git a/expr/functions/averageOutsidePercentile/function.go b/expr/functions/averageOutsidePercentile/function.go index 92fab7359..898fd6149 100644 --- a/expr/functions/averageOutsidePercentile/function.go +++ b/expr/functions/averageOutsidePercentile/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type averageOutsidePercentile struct { - interfaces.FunctionBase -} +type averageOutsidePercentile struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,12 +26,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // averageOutsidePercentile(seriesList, n) -func (f *averageOutsidePercentile) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *averageOutsidePercentile) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/averageOutsidePercentile/function_test.go b/expr/functions/averageOutsidePercentile/function_test.go index 0202d55d3..055f6c35a 100644 --- a/expr/functions/averageOutsidePercentile/function_test.go +++ b/expr/functions/averageOutsidePercentile/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -47,7 +47,8 @@ func TestAverageOutsidePercentile(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/baselines/function.go b/expr/functions/baselines/function.go index 2b560a720..832ded238 100644 --- a/expr/functions/baselines/function.go +++ b/expr/functions/baselines/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type baselines struct { - interfaces.FunctionBase -} +type baselines struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,7 +27,7 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *baselines) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *baselines) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { unit, err := e.GetIntervalArg(1, -1) if err != nil { return nil, err @@ -57,7 +55,7 @@ func (f *baselines) Do(ctx context.Context, e parser.Expr, from, until int64, va } current := make(map[string]*types.MetricData) - arg, _ := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, _ := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) for _, a := range arg { current[a.Name] = a } @@ -68,7 +66,7 @@ func (f *baselines) Do(ctx context.Context, e parser.Expr, from, until int64, va continue } offs := int64(i * unit) - arg, _ := helper.GetSeriesArg(ctx, e.Arg(0), from+offs, until+offs, values) + arg, _ := helper.GetSeriesArg(ctx, eval, e.Arg(0), from+offs, until+offs, values) for _, a := range arg { r := a.CopyLinkTags() if _, ok := current[r.Name]; ok || !isAberration { diff --git a/expr/functions/below/function.go b/expr/functions/below/function.go index dfd0a13bf..d524b7e0a 100644 --- a/expr/functions/below/function.go +++ b/expr/functions/below/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type below struct { - interfaces.FunctionBase -} +type below struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,12 +28,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // averageAbove(seriesList, n), averageBelow(seriesList, n), currentAbove(seriesList, n), currentBelow(seriesList, n), maximumAbove(seriesList, n), maximumBelow(seriesList, n), minimumAbove(seriesList, n), minimumBelow -func (f *below) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *below) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/below/function_test.go b/expr/functions/below/function_test.go index ca919dad8..849ac9966 100644 --- a/expr/functions/below/function_test.go +++ b/expr/functions/below/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -129,7 +129,8 @@ func TestBelow(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/cactiStyle/function.go b/expr/functions/cactiStyle/function.go index 49d487042..4e9ec49fa 100644 --- a/expr/functions/cactiStyle/function.go +++ b/expr/functions/cactiStyle/function.go @@ -13,9 +13,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type cactiStyle struct { - interfaces.FunctionBase -} +type cactiStyle struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -32,9 +30,9 @@ func New(configFile string) []interfaces.FunctionMetadata { } // cactiStyle(seriesList, system=None, units=None) -func (f *cactiStyle) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *cactiStyle) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { // Get the series data - original, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + original, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/cactiStyle/function_test.go b/expr/functions/cactiStyle/function_test.go index e76687f90..1cc0841dd 100644 --- a/expr/functions/cactiStyle/function_test.go +++ b/expr/functions/cactiStyle/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -160,7 +160,8 @@ func TestCactiStyle(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/cairo/cairo_test.go b/expr/functions/cairo/cairo_test.go index 079851dbd..57d4d8c1b 100644 --- a/expr/functions/cairo/cairo_test.go +++ b/expr/functions/cairo/cairo_test.go @@ -6,15 +6,18 @@ package cairo import ( "testing" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - metadata.SetEvaluator(th.EvaluatorFromFunc(md[0].F)) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -73,6 +76,7 @@ func TestEvalExpressionGraph(t *testing.T) { } for _, tt := range tests { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) } } diff --git a/expr/functions/cairo/function.go b/expr/functions/cairo/function.go index c3a2abc9b..e2155cb94 100644 --- a/expr/functions/cairo/function.go +++ b/expr/functions/cairo/function.go @@ -9,9 +9,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type cairo struct { - interfaces.FunctionBase -} +type cairo struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -27,8 +25,8 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *cairo) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - return png.EvalExprGraph(ctx, e, from, until, values) +func (f *cairo) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + return png.EvalExprGraph(ctx, eval, e, from, until, values) } func (f *cairo) Description() map[string]types.FunctionDescription { diff --git a/expr/functions/cairo/png/cairo.go b/expr/functions/cairo/png/cairo.go index 8512c845d..32b595f3f 100644 --- a/expr/functions/cairo/png/cairo.go +++ b/expr/functions/cairo/png/cairo.go @@ -19,11 +19,12 @@ import ( pb "github.com/go-graphite/protocol/carbonapi_v3_pb" "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" - "github.com/tebeka/strftime" "github.com/evmar/gocairo/cairo" + "github.com/tebeka/strftime" ) const HaveGraphSupport = true @@ -671,12 +672,12 @@ func Description() map[string]types.FunctionDescription { } // TODO(civil): Split this into several separate functions. -func EvalExprGraph(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func EvalExprGraph(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { switch e.Target() { case "color": // color(seriesList, theColor) - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -697,7 +698,7 @@ func EvalExprGraph(ctx context.Context, e parser.Expr, from, until int64, values return results, nil case "stacked": // stacked(seriesList, stackname="__DEFAULT__") - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -720,7 +721,7 @@ func EvalExprGraph(ctx context.Context, e parser.Expr, from, until int64, values return results, nil case "areaBetween": - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -751,7 +752,7 @@ func EvalExprGraph(ctx context.Context, e parser.Expr, from, until int64, values return []*types.MetricData{lower, upper}, nil case "alpha": // alpha(seriesList, theAlpha) - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -773,7 +774,7 @@ func EvalExprGraph(ctx context.Context, e parser.Expr, from, until int64, values return results, nil case "dashed", "drawAsInfinite", "secondYAxis": - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -811,7 +812,7 @@ func EvalExprGraph(ctx context.Context, e parser.Expr, from, until int64, values return results, nil case "lineWidth": // lineWidth(seriesList, width) - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/cairo/png/png.go b/expr/functions/cairo/png/png.go index a4a0e77e7..a0f77cd48 100644 --- a/expr/functions/cairo/png/png.go +++ b/expr/functions/cairo/png/png.go @@ -1,3 +1,4 @@ +//go:build !cairo // +build !cairo package png @@ -6,13 +7,14 @@ import ( "context" "net/http" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" ) const HaveGraphSupport = false -func EvalExprGraph(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func EvalExprGraph(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { return nil, nil } diff --git a/expr/functions/changed/function.go b/expr/functions/changed/function.go index b6d24f733..eac086af1 100644 --- a/expr/functions/changed/function.go +++ b/expr/functions/changed/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type changed struct { - interfaces.FunctionBase -} +type changed struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +27,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // changed(SeriesList) -func (f *changed) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *changed) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/changed/function_test.go b/expr/functions/changed/function_test.go index 54792463d..2de83f094 100644 --- a/expr/functions/changed/function_test.go +++ b/expr/functions/changed/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestChanged(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/compressPeriodicGaps/function.go b/expr/functions/compressPeriodicGaps/function.go index 7e0856b31..e96d27aaa 100644 --- a/expr/functions/compressPeriodicGaps/function.go +++ b/expr/functions/compressPeriodicGaps/function.go @@ -2,17 +2,16 @@ package compressPeriodicGaps import ( "context" + "math" + "github.com/go-graphite/carbonapi/expr/consolidations" "github.com/go-graphite/carbonapi/expr/helper" "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" - "math" ) -type compressPeriodicGaps struct { - interfaces.FunctionBase -} +type compressPeriodicGaps struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +28,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // compressPeriodicGaps(seriesList) -func (f *compressPeriodicGaps) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *compressPeriodicGaps) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/compressPeriodicGaps/function_test.go b/expr/functions/compressPeriodicGaps/function_test.go index 65cd2af34..6dd691de2 100644 --- a/expr/functions/compressPeriodicGaps/function_test.go +++ b/expr/functions/compressPeriodicGaps/function_test.go @@ -1,20 +1,21 @@ package compressPeriodicGaps import ( - "github.com/go-graphite/carbonapi/expr/helper" + "math" + "testing" + + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" - "math" - "testing" +) + +var ( + md []interfaces.FunctionMetadata = New("") ) func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -56,7 +57,8 @@ func TestCompressPeriodicGaps(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } diff --git a/expr/functions/consolidateBy/function.go b/expr/functions/consolidateBy/function.go index a44361e6d..99d480da0 100644 --- a/expr/functions/consolidateBy/function.go +++ b/expr/functions/consolidateBy/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type consolidateBy struct { - interfaces.FunctionBase -} +type consolidateBy struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // consolidateBy(seriesList, aggregationMethod) -func (f *consolidateBy) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *consolidateBy) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/consolidateBy/function_test.go b/expr/functions/consolidateBy/function_test.go index c023dd599..9272a2d57 100644 --- a/expr/functions/consolidateBy/function_test.go +++ b/expr/functions/consolidateBy/function_test.go @@ -1,20 +1,21 @@ package consolidateBy import ( - "github.com/go-graphite/carbonapi/expr/helper" + "testing" + "time" + + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" - "testing" - "time" +) + +var ( + md []interfaces.FunctionMetadata = New("") ) func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -77,7 +78,8 @@ func TestConsolidateBy(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/constantLine/function.go b/expr/functions/constantLine/function.go index 23a29f245..3e56059a7 100644 --- a/expr/functions/constantLine/function.go +++ b/expr/functions/constantLine/function.go @@ -10,9 +10,7 @@ import ( pb "github.com/go-graphite/protocol/carbonapi_v3_pb" ) -type constantLine struct { - interfaces.FunctionBase -} +type constantLine struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,7 +26,7 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *constantLine) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *constantLine) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { value, err := e.GetFloatArg(0) if err != nil { diff --git a/expr/functions/constantLine/function_test.go b/expr/functions/constantLine/function_test.go index 6bd5bd244..234004dcf 100644 --- a/expr/functions/constantLine/function_test.go +++ b/expr/functions/constantLine/function_test.go @@ -3,18 +3,18 @@ package constantLine import ( "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestConstantLine(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/cumulative/function.go b/expr/functions/cumulative/function.go index 0e258402e..9ba704a26 100644 --- a/expr/functions/cumulative/function.go +++ b/expr/functions/cumulative/function.go @@ -9,9 +9,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type cumulative struct { - interfaces.FunctionBase -} +type cumulative struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,8 +26,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // cumulative(seriesList) -func (f *cumulative) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *cumulative) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/cumulative/function_test.go b/expr/functions/cumulative/function_test.go index 2415feaf9..dd2446b7b 100644 --- a/expr/functions/cumulative/function_test.go +++ b/expr/functions/cumulative/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -38,7 +38,8 @@ func TestCumulative(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/delay/function.go b/expr/functions/delay/function.go index 9ea7120b7..1fd283475 100644 --- a/expr/functions/delay/function.go +++ b/expr/functions/delay/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type delay struct { - interfaces.FunctionBase -} +type delay struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // delay(seriesList, steps) -func (f *delay) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *delay) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - seriesList, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + seriesList, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/delay/function_test.go b/expr/functions/delay/function_test.go index 584014414..c3ba870e8 100644 --- a/expr/functions/delay/function_test.go +++ b/expr/functions/delay/function_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" @@ -14,11 +14,11 @@ import ( "github.com/go-graphite/carbonapi/tests/compare" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -57,7 +57,8 @@ func TestDelay(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -72,7 +73,7 @@ func BenchmarkDelay(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -80,7 +81,7 @@ func BenchmarkDelay(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } @@ -97,7 +98,7 @@ func BenchmarkDelayReverse(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -105,7 +106,7 @@ func BenchmarkDelayReverse(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/derivative/function.go b/expr/functions/derivative/function.go index 89078ac76..b0d42c0cd 100644 --- a/expr/functions/derivative/function.go +++ b/expr/functions/derivative/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type derivative struct { - interfaces.FunctionBase -} +type derivative struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +27,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // derivative(seriesList) -func (f *derivative) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - return helper.ForEachSeriesDo(ctx, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { +func (f *derivative) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + return helper.ForEachSeriesDo(ctx, eval, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { prev := math.NaN() for i, v := range a.Values { // We don't need to check for special case here. value-NaN == NaN diff --git a/expr/functions/derivative/function_test.go b/expr/functions/derivative/function_test.go index 11ca3e8b2..2acf4d06e 100644 --- a/expr/functions/derivative/function_test.go +++ b/expr/functions/derivative/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -47,7 +47,8 @@ func TestDerivative(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/divideSeries/function.go b/expr/functions/divideSeries/function.go index 0c483c08a..812a693fa 100644 --- a/expr/functions/divideSeries/function.go +++ b/expr/functions/divideSeries/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type divideSeries struct { - interfaces.FunctionBase -} +type divideSeries struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,12 +29,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // divideSeries(dividendSeriesList, divisorSeriesList) -func (f *divideSeries) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *divideSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 1 { return nil, parser.ErrMissingTimeseries } - firstArg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + firstArg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -50,7 +48,7 @@ func (f *divideSeries) Do(ctx context.Context, e parser.Expr, from, until int64, if e.ArgsLen() == 2 { useMetricNames = true numerators = firstArg - denominators, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + denominators, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/divideSeries/function_test.go b/expr/functions/divideSeries/function_test.go index 9caa103a4..3db4f735d 100644 --- a/expr/functions/divideSeries/function_test.go +++ b/expr/functions/divideSeries/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -51,7 +51,8 @@ func TestDivideSeriesMultiReturn(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } } @@ -93,7 +94,8 @@ func TestDivideSeries(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } @@ -149,7 +151,8 @@ func TestDivideSeriesAligned(t *testing.T) { for _, tt := range tests { t.Run(tt.Target, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/ewma/function.go b/expr/functions/ewma/function.go index 17f9f6ccc..3d2753364 100644 --- a/expr/functions/ewma/function.go +++ b/expr/functions/ewma/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type ewma struct { - interfaces.FunctionBase -} +type ewma struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,12 +28,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // ewma(seriesList, alpha) -func (f *ewma) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *ewma) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/ewma/function_test.go b/expr/functions/ewma/function_test.go index c84c39d53..7f858473d 100644 --- a/expr/functions/ewma/function_test.go +++ b/expr/functions/ewma/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -49,7 +49,8 @@ func TestEWMA(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/example/function.go b/expr/functions/example/function.go index cf8169076..a95e18ea2 100644 --- a/expr/functions/example/function.go +++ b/expr/functions/example/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type example struct { - interfaces.FunctionBase -} +type example struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,7 +28,7 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *example) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *example) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { _ = helper.Backref return nil, nil } diff --git a/expr/functions/exclude/function.go b/expr/functions/exclude/function.go index e21e262db..273c4898b 100644 --- a/expr/functions/exclude/function.go +++ b/expr/functions/exclude/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type exclude struct { - interfaces.FunctionBase -} +type exclude struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // exclude(seriesList, pattern) -func (f *exclude) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *exclude) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/exclude/function_test.go b/expr/functions/exclude/function_test.go index ac6a5d93d..6b1864fdf 100644 --- a/expr/functions/exclude/function_test.go +++ b/expr/functions/exclude/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -42,7 +42,8 @@ func TestExclude(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/exp/function.go b/expr/functions/exp/function.go index c0603d33b..11bfeb5d4 100644 --- a/expr/functions/exp/function.go +++ b/expr/functions/exp/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type exp struct { - interfaces.FunctionBase -} +type exp struct{} // offset(seriesList,factor) func GetOrder() interfaces.Order { @@ -28,8 +26,8 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *exp) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *exp) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/exp/function_test.go b/expr/functions/exp/function_test.go index 5e37e33cb..45859796b 100644 --- a/expr/functions/exp/function_test.go +++ b/expr/functions/exp/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestExp(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/exponentialMovingAverage/function.go b/expr/functions/exponentialMovingAverage/function.go index 7a43e1108..d782c26a0 100644 --- a/expr/functions/exponentialMovingAverage/function.go +++ b/expr/functions/exponentialMovingAverage/function.go @@ -13,9 +13,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type exponentialMovingAverage struct { - interfaces.FunctionBase -} +type exponentialMovingAverage struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,7 +29,7 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *exponentialMovingAverage) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *exponentialMovingAverage) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { var ( windowPoints int previewSeconds int @@ -59,7 +57,7 @@ func (f *exponentialMovingAverage) Do(ctx context.Context, e parser.Expr, from, // data. The already fetched values are discarded. refetch = true var maxStep int64 - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil || len(arg) == 0 { return arg, err } @@ -95,9 +93,9 @@ func (f *exponentialMovingAverage) Do(ctx context.Context, e parser.Expr, from, } from = from - int64(previewSeconds) if refetch { - f.GetEvaluator().Fetch(ctx, []parser.Expr{e.Arg(0)}, from, until, values) + eval.Fetch(ctx, []parser.Expr{e.Arg(0)}, from, until, values) } - previewList, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + previewList, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/exponentialMovingAverage/function_test.go b/expr/functions/exponentialMovingAverage/function_test.go index 6b5452c0f..989a2d1df 100644 --- a/expr/functions/exponentialMovingAverage/function_test.go +++ b/expr/functions/exponentialMovingAverage/function_test.go @@ -5,18 +5,18 @@ import ( "math" "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -97,7 +97,8 @@ func TestExponentialMovingAverage(t *testing.T) { tt := tt testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } @@ -124,7 +125,7 @@ func BenchmarkExponentialMovingAverage(b *testing.B) { {"metric[1234]", 0, 1}: {types.MakeMetricData("metric1", []float64{2, 4, 6, 8, 12, 14, 16, 18, 20}, 1, 0)}, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -132,7 +133,7 @@ func BenchmarkExponentialMovingAverage(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } @@ -146,7 +147,7 @@ func BenchmarkExponentialMovingAverageStr(b *testing.B) { {"metric[1234]", 0, 1}: {types.MakeMetricData("metric1", []float64{2, 4, 6, 8, 12, 14, 16, 18, 20}, 1, 0)}, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -154,7 +155,7 @@ func BenchmarkExponentialMovingAverageStr(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/fallbackSeries/function.go b/expr/functions/fallbackSeries/function.go index 2a33bccec..13b55d7b3 100644 --- a/expr/functions/fallbackSeries/function.go +++ b/expr/functions/fallbackSeries/function.go @@ -9,9 +9,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type fallbackSeries struct { - interfaces.FunctionBase -} +type fallbackSeries struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,7 +26,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // fallbackSeries( seriesList, fallback ) -func (f *fallbackSeries) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *fallbackSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { /* Takes a wildcard seriesList, and a second fallback metric. If the wildcard does not match any series, draws the fallback metric. @@ -37,8 +35,8 @@ func (f *fallbackSeries) Do(ctx context.Context, e parser.Expr, from, until int6 return nil, parser.ErrMissingTimeseries } - seriesList, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) - fallback, errFallback := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + seriesList, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) + fallback, errFallback := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if errFallback != nil && err != nil { return nil, errFallback } diff --git a/expr/functions/fallbackSeries/function_test.go b/expr/functions/fallbackSeries/function_test.go index fcd9c3ba2..59efbdb51 100644 --- a/expr/functions/fallbackSeries/function_test.go +++ b/expr/functions/fallbackSeries/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -69,7 +69,8 @@ func TestFallbackSeries(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -96,7 +97,8 @@ func TestErrorMissingTimeSeriesFunction(t *testing.T) { for _, testCase := range tests { testName := testCase.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithError(t, &testCase) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithError(t, eval, &testCase) }) } } diff --git a/expr/functions/fft/function.go b/expr/functions/fft/function.go index 6fddfaac4..8b4a00dbf 100644 --- a/expr/functions/fft/function.go +++ b/expr/functions/fft/function.go @@ -11,9 +11,7 @@ import ( realFFT "github.com/mjibson/go-dsp/fft" ) -type fft struct { - interfaces.FunctionBase -} +type fft struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -40,8 +38,8 @@ func extractComponent(m *types.MetricData, values []complex128, t string, f func // fft(seriesList, mode) // mode: "", abs, phase. Empty string means "both" -func (f *fft) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *fft) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/filter/function.go b/expr/functions/filter/function.go index 8ab422197..dbf8230b8 100644 --- a/expr/functions/filter/function.go +++ b/expr/functions/filter/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type filterSeries struct { - interfaces.FunctionBase -} +type filterSeries struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -38,12 +36,12 @@ var supportedOperators = map[string]struct{}{ } // filterSeries(*seriesLists) -func (f *filterSeries) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *filterSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 4 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/filter/function_test.go b/expr/functions/filter/function_test.go index 372a8da32..fecf4316a 100644 --- a/expr/functions/filter/function_test.go +++ b/expr/functions/filter/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -112,7 +112,8 @@ func TestConstantLine(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/graphiteWeb/function.go b/expr/functions/graphiteWeb/function.go index 104986861..ccc2b4efc 100644 --- a/expr/functions/graphiteWeb/function.go +++ b/expr/functions/graphiteWeb/function.go @@ -25,8 +25,6 @@ import ( ) type graphiteWeb struct { - interfaces.FunctionBase - working bool strict bool maxTries int @@ -325,7 +323,7 @@ type graphiteError struct { err error } -func (f *graphiteWeb) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *graphiteWeb) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { f.logger.Info("received request", zap.Bool("working", f.working), ) diff --git a/expr/functions/grep/function.go b/expr/functions/grep/function.go index 99935ec6d..a5ae17817 100644 --- a/expr/functions/grep/function.go +++ b/expr/functions/grep/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type grep struct { - interfaces.FunctionBase -} +type grep struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // grep(seriesList, pattern) -func (f *grep) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *grep) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/grep/function_test.go b/expr/functions/grep/function_test.go index 4ec6c4679..3b057c209 100644 --- a/expr/functions/grep/function_test.go +++ b/expr/functions/grep/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -42,7 +42,8 @@ func TestGrep(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/group/function.go b/expr/functions/group/function.go index 748e508af..54274bdb1 100644 --- a/expr/functions/group/function.go +++ b/expr/functions/group/function.go @@ -9,9 +9,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type group struct { - interfaces.FunctionBase -} +type group struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,8 +26,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // group(*seriesLists) -func (f *group) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArgsAndRemoveNonExisting(ctx, e, from, until, values) +func (f *group) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArgsAndRemoveNonExisting(ctx, eval, e, from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/groupByNode/function.go b/expr/functions/groupByNode/function.go index a92adf312..3b1c849e5 100644 --- a/expr/functions/groupByNode/function.go +++ b/expr/functions/groupByNode/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type groupByNode struct { - interfaces.FunctionBase -} +type groupByNode struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -32,12 +30,12 @@ func New(configFile string) []interfaces.FunctionMetadata { // groupByNode(seriesList, nodeNum, callback) // groupByNodes(seriesList, callback, *nodes) -func (f *groupByNode) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *groupByNode) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -108,7 +106,7 @@ func (f *groupByNode) Do(ctx context.Context, e parser.Expr, from, until int64, } } - r, _ := f.Evaluator.Eval(ctx, nexpr, from, until, nvalues) + r, _ := eval.Eval(ctx, nexpr, from, until, nvalues) if r != nil { var res []*types.MetricData if len(r) > 0 { diff --git a/expr/functions/groupByNode/function_test.go b/expr/functions/groupByNode/function_test.go index b4e1144db..e2f700fd0 100644 --- a/expr/functions/groupByNode/function_test.go +++ b/expr/functions/groupByNode/function_test.go @@ -6,26 +6,25 @@ import ( "time" "github.com/go-graphite/carbonapi/expr/functions/aggregate" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") + s []interfaces.FunctionMetadata = aggregate.New("") +) + func init() { - s := aggregate.New("") for _, m := range s { metadata.RegisterFunction(m.Name, m.F) } - md := New("") for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } - - evaluator := th.EvaluatorFromFuncWithMetadata(metadata.FunctionMD.Functions) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) } // Note: some of these tests are influenced by the testcases for groupByNode and groupByNodes functions @@ -250,7 +249,8 @@ func TestGroupByNode(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFuncWithMetadata(metadata.FunctionMD.Functions) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } @@ -279,7 +279,8 @@ func TestGroupByNodeError(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithError(t, &tt) + eval := th.EvaluatorFromFuncWithMetadata(metadata.FunctionMD.Functions) + th.TestEvalExprWithError(t, eval, &tt) }) } @@ -296,7 +297,7 @@ func BenchmarkGroupByNode(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFuncWithMetadata(metadata.FunctionMD.Functions) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -304,7 +305,7 @@ func BenchmarkGroupByNode(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/groupByTags/function.go b/expr/functions/groupByTags/function.go index 208073f48..5f1f1bd54 100644 --- a/expr/functions/groupByTags/function.go +++ b/expr/functions/groupByTags/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type groupByTags struct { - interfaces.FunctionBase -} +type groupByTags struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,12 +29,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // seriesByTag("name=cpu")|groupByTags("average","dc","os") -func (f *groupByTags) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *groupByTags) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 3 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -126,7 +124,7 @@ func (f *groupByTags) Do(ctx context.Context, e parser.Expr, from, until int64, {Metric: "stub", From: from, Until: until}: v, } - r, err := f.Evaluator.Eval(ctx, nexpr, from, until, nvalues) + r, err := eval.Eval(ctx, nexpr, from, until, nvalues) if err != nil { return nil, err } diff --git a/expr/functions/groupByTags/function_test.go b/expr/functions/groupByTags/function_test.go index 785947748..2e42f272e 100644 --- a/expr/functions/groupByTags/function_test.go +++ b/expr/functions/groupByTags/function_test.go @@ -2,36 +2,51 @@ package groupByTags import ( "context" + "math" "testing" "time" "github.com/go-graphite/carbonapi/expr/functions/aggregate" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") + s []interfaces.FunctionMetadata = aggregate.New("") +) + func init() { - s := aggregate.New("") for _, m := range s { metadata.RegisterFunction(m.Name, m.F) } - md := New("") for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } - - evaluator := th.EvaluatorFromFuncWithMetadata(metadata.FunctionMD.Functions) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) } func TestGroupByTags(t *testing.T) { now32 := int64(time.Now().Unix()) tests := []th.MultiReturnEvalTestItem{ + { + `groupByTags(metric1.foo.*, "avg", "dc")`, + map[parser.MetricRequest][]*types.MetricData{ + {"metric1.foo.*", 0, 1}: { + types.MakeMetricData("metric1.foo;cpu=cpu1;dc=dc1", []float64{1, math.NaN(), 3, 4, math.NaN()}, 1, now32), + types.MakeMetricData("metric1.foo;cpu=cpu2;dc=dc1", []float64{6, 7, 8, 9, math.NaN()}, 1, now32), + types.MakeMetricData("metric1.foo;cpu=cpu3;dc=dc1", []float64{11, 12, 13, 14, math.NaN()}, 1, now32), + types.MakeMetricData("metric1.foo;cpu=cpu4;dc=dc1", []float64{7, 8, 9, 10, math.NaN()}, 1, now32), + }, + }, + "groupByTags", + map[string][]*types.MetricData{ + "avg;dc=dc1": {types.MakeMetricData("avg;dc=dc1", []float64{6.25, 9, 8.25, 9.25, math.NaN()}, 1, now32)}, + }, + }, { `groupByTags(metric1.foo.*, "sum", "dc")`, map[parser.MetricRequest][]*types.MetricData{ @@ -99,13 +114,14 @@ func TestGroupByTags(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFuncWithMetadata(metadata.FunctionMD.Functions) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } } -func BenchmarkGroupByNode(b *testing.B) { +func BenchmarkGroupByTags(b *testing.B) { target := `groupByTags(metric1.foo.*, "sum", "dc", "cpu", "rack")` metrics := map[parser.MetricRequest][]*types.MetricData{ {Metric: "metric1.foo.*", From: 0, Until: 1}: { @@ -116,7 +132,7 @@ func BenchmarkGroupByNode(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFuncWithMetadata(metadata.FunctionMD.Functions) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -124,7 +140,7 @@ func BenchmarkGroupByNode(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/heatMap/function.go b/expr/functions/heatMap/function.go index 159db7510..c1f86cce2 100644 --- a/expr/functions/heatMap/function.go +++ b/expr/functions/heatMap/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type heatMap struct { - interfaces.FunctionBase -} +type heatMap struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -27,8 +25,8 @@ func New(_ string) []interfaces.FunctionMetadata { }} } -func (f *heatMap) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - series, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *heatMap) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + series, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/heatMap/function_test.go b/expr/functions/heatMap/function_test.go index bee2a363a..3309cfb75 100644 --- a/expr/functions/heatMap/function_test.go +++ b/expr/functions/heatMap/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -45,7 +45,8 @@ func TestHeatMap(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/highestLowest/function.go b/expr/functions/highestLowest/function.go index fb0a1f755..93e8cb7d7 100644 --- a/expr/functions/highestLowest/function.go +++ b/expr/functions/highestLowest/function.go @@ -14,9 +14,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type highest struct { - interfaces.FunctionBase -} +type highest struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -33,8 +31,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // highestAverage(seriesList, n) , highestCurrent(seriesList, n), highestMax(seriesList, n) -func (f *highest) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *highest) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/highestLowest/function_test.go b/expr/functions/highestLowest/function_test.go index b0bfeda55..139702bc8 100644 --- a/expr/functions/highestLowest/function_test.go +++ b/expr/functions/highestLowest/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -153,7 +153,8 @@ func TestHighestMultiReturn(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } } @@ -272,7 +273,8 @@ func TestHighest(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/hitcount/function.go b/expr/functions/hitcount/function.go index 6a87740ba..10977b204 100644 --- a/expr/functions/hitcount/function.go +++ b/expr/functions/hitcount/function.go @@ -2,19 +2,18 @@ package hitcount import ( "context" + "math" + "strconv" + "strings" + "github.com/go-graphite/carbonapi/expr/helper" "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" pb "github.com/go-graphite/protocol/carbonapi_v3_pb" - "math" - "strconv" - "strings" ) -type hitcount struct { - interfaces.FunctionBase -} +type hitcount struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,7 +30,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // hitcount(seriesList, intervalString, alignToInterval=False) -func (f *hitcount) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *hitcount) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { // TODO(dgryski): make sure the arrays are all the same 'size' if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument @@ -53,7 +52,7 @@ func (f *hitcount) Do(ctx context.Context, e parser.Expr, from, until int64, val from = helper.AlignStartToInterval(from, until, interval) } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/hitcount/function_test.go b/expr/functions/hitcount/function_test.go index 2c6e6cc72..1dc204ce2 100644 --- a/expr/functions/hitcount/function_test.go +++ b/expr/functions/hitcount/function_test.go @@ -4,18 +4,18 @@ import ( "math" "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -34,7 +34,8 @@ func TestHitcountEmptyData(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } @@ -130,7 +131,8 @@ func TestHitcount(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/holtWintersAberration/function.go b/expr/functions/holtWintersAberration/function.go index c0082a188..2a6023187 100644 --- a/expr/functions/holtWintersAberration/function.go +++ b/expr/functions/holtWintersAberration/function.go @@ -12,9 +12,7 @@ import ( pb "github.com/go-graphite/protocol/carbonapi_v3_pb" ) -type holtWintersAberration struct { - interfaces.FunctionBase -} +type holtWintersAberration struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,13 +28,13 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *holtWintersAberration) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *holtWintersAberration) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { bootstrapInterval, err := e.GetIntervalNamedOrPosArgDefault("bootstrapInterval", 2, 1, holtwinters.DefaultBootstrapInterval) if err != nil { return nil, err } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -44,7 +42,7 @@ func (f *holtWintersAberration) Do(ctx context.Context, e parser.Expr, from, unt // Note: additional fetch requests are added with an adjusted start time in expr.Metrics() (in // pkg/parser/parser.go) so that the appropriate data corresponding to the adjusted start time // can be pre-fetched. - adjustedStartArgs, err := helper.GetSeriesArg(ctx, e.Arg(0), from-bootstrapInterval, until, values) + adjustedStartArgs, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from-bootstrapInterval, until, values) if err != nil { return nil, err } diff --git a/expr/functions/holtWintersAberration/function_test.go b/expr/functions/holtWintersAberration/function_test.go index ed4849866..8dfdc0ba0 100644 --- a/expr/functions/holtWintersAberration/function_test.go +++ b/expr/functions/holtWintersAberration/function_test.go @@ -1,21 +1,22 @@ package holtWintersAberration import ( - "github.com/go-graphite/carbonapi/expr/holtwinters" "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/holtwinters" + "github.com/go-graphite/carbonapi/expr/interfaces" + "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -110,7 +111,8 @@ func TestHoltWintersAberration(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/holtWintersConfidenceArea/function.go b/expr/functions/holtWintersConfidenceArea/function.go index 9a20a8dd4..6d4b261dd 100644 --- a/expr/functions/holtWintersConfidenceArea/function.go +++ b/expr/functions/holtWintersConfidenceArea/function.go @@ -14,9 +14,7 @@ import ( var UnsupportedError = fmt.Errorf("must build w/ cairo support") -type holtWintersConfidenceArea struct { - interfaces.FunctionBase -} +type holtWintersConfidenceArea struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -34,7 +32,7 @@ func New(_ string) []interfaces.FunctionMetadata { return res } -func (f *holtWintersConfidenceArea) Do(_ context.Context, _ parser.Expr, _, _ int64, _ map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *holtWintersConfidenceArea) Do(_ context.Context, _ interfaces.Evaluator, _ parser.Expr, _, _ int64, _ map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { return nil, UnsupportedError } diff --git a/expr/functions/holtWintersConfidenceArea/function_cairo.go b/expr/functions/holtWintersConfidenceArea/function_cairo.go index 95b0fa5f9..506d0dc57 100644 --- a/expr/functions/holtWintersConfidenceArea/function_cairo.go +++ b/expr/functions/holtWintersConfidenceArea/function_cairo.go @@ -15,9 +15,7 @@ import ( pb "github.com/go-graphite/protocol/carbonapi_v3_pb" ) -type holtWintersConfidenceArea struct { - interfaces.FunctionBase -} +type holtWintersConfidenceArea struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -33,13 +31,13 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *holtWintersConfidenceArea) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *holtWintersConfidenceArea) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { bootstrapInterval, err := e.GetIntervalNamedOrPosArgDefault("bootstrapInterval", 2, 1, holtwinters.DefaultBootstrapInterval) if err != nil { return nil, err } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from-bootstrapInterval, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from-bootstrapInterval, until, values) if err != nil { return nil, err } diff --git a/expr/functions/holtWintersConfidenceArea/function_test.go b/expr/functions/holtWintersConfidenceArea/function_test.go index 90a4c896b..c288c4a6a 100644 --- a/expr/functions/holtWintersConfidenceArea/function_test.go +++ b/expr/functions/holtWintersConfidenceArea/function_test.go @@ -4,21 +4,22 @@ package holtWintersConfidenceArea import ( - "github.com/go-graphite/carbonapi/expr/holtwinters" "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/holtwinters" + "github.com/go-graphite/carbonapi/expr/interfaces" + "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -71,7 +72,8 @@ func TestHoltWintersConfidenceArea(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/holtWintersConfidenceBands/function.go b/expr/functions/holtWintersConfidenceBands/function.go index efc7fc22d..258429d0b 100644 --- a/expr/functions/holtWintersConfidenceBands/function.go +++ b/expr/functions/holtWintersConfidenceBands/function.go @@ -2,6 +2,7 @@ package holtWintersConfidenceBands import ( "context" + "github.com/go-graphite/carbonapi/expr/helper" "github.com/go-graphite/carbonapi/expr/holtwinters" "github.com/go-graphite/carbonapi/expr/interfaces" @@ -10,9 +11,7 @@ import ( pb "github.com/go-graphite/protocol/carbonapi_v3_pb" ) -type holtWintersConfidenceBands struct { - interfaces.FunctionBase -} +type holtWintersConfidenceBands struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,13 +27,13 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *holtWintersConfidenceBands) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *holtWintersConfidenceBands) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { bootstrapInterval, err := e.GetIntervalNamedOrPosArgDefault("bootstrapInterval", 2, 1, holtwinters.DefaultBootstrapInterval) if err != nil { return nil, err } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from-bootstrapInterval, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from-bootstrapInterval, until, values) if err != nil { return nil, err } diff --git a/expr/functions/holtWintersConfidenceBands/function_test.go b/expr/functions/holtWintersConfidenceBands/function_test.go index c48d7c60c..88adb3ed3 100644 --- a/expr/functions/holtWintersConfidenceBands/function_test.go +++ b/expr/functions/holtWintersConfidenceBands/function_test.go @@ -1,21 +1,22 @@ package holtWintersConfidenceBands import ( - "github.com/go-graphite/carbonapi/expr/holtwinters" "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/holtwinters" + "github.com/go-graphite/carbonapi/expr/interfaces" + "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -68,7 +69,8 @@ func TestHoltWintersConfidenceBands(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } @@ -87,7 +89,8 @@ func TestNoPanicOnBigStep(t *testing.T) { }, } - th.TestEvalExpr(t, &test) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &test) } diff --git a/expr/functions/holtWintersForecast/function.go b/expr/functions/holtWintersForecast/function.go index 2195fc953..c7e6619b3 100644 --- a/expr/functions/holtWintersForecast/function.go +++ b/expr/functions/holtWintersForecast/function.go @@ -11,9 +11,7 @@ import ( pb "github.com/go-graphite/protocol/carbonapi_v3_pb" ) -type holtWintersForecast struct { - interfaces.FunctionBase -} +type holtWintersForecast struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,13 +27,13 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *holtWintersForecast) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *holtWintersForecast) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { bootstrapInterval, err := e.GetIntervalNamedOrPosArgDefault("bootstrapInterval", 1, 1, holtwinters.DefaultBootstrapInterval) if err != nil { return nil, err } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from-bootstrapInterval, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from-bootstrapInterval, until, values) if err != nil { return nil, err } diff --git a/expr/functions/holtWintersForecast/function_test.go b/expr/functions/holtWintersForecast/function_test.go index 6283df4c3..56ef5dd44 100644 --- a/expr/functions/holtWintersForecast/function_test.go +++ b/expr/functions/holtWintersForecast/function_test.go @@ -3,18 +3,18 @@ package holtWintersForecast import ( "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -65,7 +65,8 @@ func TestHoltWintersForecast(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/identity/function.go b/expr/functions/identity/function.go index 2cdff51b7..810f69f2f 100644 --- a/expr/functions/identity/function.go +++ b/expr/functions/identity/function.go @@ -9,9 +9,7 @@ import ( pb "github.com/go-graphite/protocol/carbonapi_v3_pb" ) -type identity struct { - interfaces.FunctionBase -} +type identity struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,7 +26,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // identity(name) -func (f *identity) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *identity) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { name, err := e.GetStringArg(0) if err != nil { return nil, err diff --git a/expr/functions/identity/function_test.go b/expr/functions/identity/function_test.go index 7311e0aea..d966dc94e 100644 --- a/expr/functions/identity/function_test.go +++ b/expr/functions/identity/function_test.go @@ -3,18 +3,18 @@ package identity import ( "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestIdentityFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/ifft/function.go b/expr/functions/ifft/function.go index bb8fe54ff..51127837e 100644 --- a/expr/functions/ifft/function.go +++ b/expr/functions/ifft/function.go @@ -12,9 +12,7 @@ import ( realFFT "github.com/mjibson/go-dsp/fft" ) -type ifft struct { - interfaces.FunctionBase -} +type ifft struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,15 +29,15 @@ func New(configFile string) []interfaces.FunctionMetadata { } // ifft(absSeriesList, phaseSeriesList) -func (f *ifft) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - absSeriesList, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *ifft) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + absSeriesList, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } var phaseSeriesList []*types.MetricData if e.ArgsLen() > 1 { - phaseSeriesList, err = helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + phaseSeriesList, err = helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/integral/function.go b/expr/functions/integral/function.go index 25caf5727..9a792750c 100644 --- a/expr/functions/integral/function.go +++ b/expr/functions/integral/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type integral struct { - interfaces.FunctionBase -} +type integral struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +27,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // integral(seriesList) -func (f *integral) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - return helper.ForEachSeriesDo(ctx, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { +func (f *integral) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + return helper.ForEachSeriesDo(ctx, eval, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { current := 0.0 for i, v := range a.Values { if math.IsNaN(v) { diff --git a/expr/functions/integral/function_test.go b/expr/functions/integral/function_test.go index be9e3c01b..7357acbf7 100644 --- a/expr/functions/integral/function_test.go +++ b/expr/functions/integral/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/integralByInterval/function.go b/expr/functions/integralByInterval/function.go index 718cf6ec6..da4b543d4 100644 --- a/expr/functions/integralByInterval/function.go +++ b/expr/functions/integralByInterval/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type integralByInterval struct { - interfaces.FunctionBase -} +type integralByInterval struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // integralByInterval(seriesList, intervalString) -func (f *integralByInterval) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *integralByInterval) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/integralByInterval/function_test.go b/expr/functions/integralByInterval/function_test.go index 8a7f4dc11..de76e09ee 100644 --- a/expr/functions/integralByInterval/function_test.go +++ b/expr/functions/integralByInterval/function_test.go @@ -3,18 +3,18 @@ package integralByInterval import ( "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/integralWithReset/function.go b/expr/functions/integralWithReset/function.go index b3d01544d..760a6a85f 100644 --- a/expr/functions/integralWithReset/function.go +++ b/expr/functions/integralWithReset/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type integralWithReset struct { - interfaces.FunctionBase -} +type integralWithReset struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,12 +29,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // integralWithReset(seriesList, resettingSeries) -func (f *integralWithReset) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *integralWithReset) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } - resettingSeriesList, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + resettingSeriesList, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/integralWithReset/function_test.go b/expr/functions/integralWithReset/function_test.go index 0cca883f0..040485816 100644 --- a/expr/functions/integralWithReset/function_test.go +++ b/expr/functions/integralWithReset/function_test.go @@ -4,19 +4,20 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "math" + + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" - "math" +) + +var ( + md []interfaces.FunctionMetadata = New("") ) func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -56,7 +57,8 @@ func TestIntegralWithResetMultiReturn(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } @@ -80,7 +82,8 @@ func TestIntegralWithReset(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/interpolate/function.go b/expr/functions/interpolate/function.go index 0b71de30f..ab440f85e 100644 --- a/expr/functions/interpolate/function.go +++ b/expr/functions/interpolate/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type interpolate struct { - interfaces.FunctionBase -} +type interpolate struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -25,8 +23,8 @@ func New(configFile string) []interfaces.FunctionMetadata { }} } -func (f *interpolate) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (resultData []*types.MetricData, resultError error) { - seriesList, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *interpolate) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (resultData []*types.MetricData, resultError error) { + seriesList, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/interpolate/function_test.go b/expr/functions/interpolate/function_test.go index 7a714107f..c55b43cb2 100644 --- a/expr/functions/interpolate/function_test.go +++ b/expr/functions/interpolate/function_test.go @@ -7,17 +7,17 @@ import ( th "github.com/go-graphite/carbonapi/tests" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -158,7 +158,8 @@ func TestInterpolate_Do(t *testing.T) { for _, testCase := range testCases { testName := testCase.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &testCase) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &testCase) }) } } diff --git a/expr/functions/invert/function.go b/expr/functions/invert/function.go index 350b9dbc0..2f7f9542b 100644 --- a/expr/functions/invert/function.go +++ b/expr/functions/invert/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type invert struct { - interfaces.FunctionBase -} +type invert struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +27,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // invert(seriesList) -func (f *invert) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - return helper.ForEachSeriesDo(ctx, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { +func (f *invert) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + return helper.ForEachSeriesDo(ctx, eval, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { for i, v := range a.Values { if v == 0 { r.Values[i] = math.NaN() diff --git a/expr/functions/invert/function_test.go b/expr/functions/invert/function_test.go index 0a582a7f1..c82c78735 100644 --- a/expr/functions/invert/function_test.go +++ b/expr/functions/invert/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/isNotNull/function.go b/expr/functions/isNotNull/function.go index d71c1f42a..2d5ca75aa 100644 --- a/expr/functions/isNotNull/function.go +++ b/expr/functions/isNotNull/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type isNotNull struct { - interfaces.FunctionBase -} +type isNotNull struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,10 +28,10 @@ func New(configFile string) []interfaces.FunctionMetadata { // isNonNull(seriesList) // alias: isNotNull(seriesList) -func (f *isNotNull) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *isNotNull) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { e.SetTarget("isNonNull") - return helper.ForEachSeriesDo(ctx, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { + return helper.ForEachSeriesDo(ctx, eval, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { for i, v := range a.Values { if math.IsNaN(v) { r.Values[i] = 0 diff --git a/expr/functions/isNotNull/function_test.go b/expr/functions/isNotNull/function_test.go index 4828d8f74..f2161c0ba 100644 --- a/expr/functions/isNotNull/function_test.go +++ b/expr/functions/isNotNull/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -52,7 +52,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/join/function.go b/expr/functions/join/function.go index fef291e17..55634f61c 100644 --- a/expr/functions/join/function.go +++ b/expr/functions/join/function.go @@ -18,9 +18,7 @@ const ( sub = "SUB" ) -type join struct { - interfaces.FunctionBase -} +type join struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -32,7 +30,7 @@ func New(_ string) []interfaces.FunctionMetadata { } } -func (_ *join) Description() map[string]types.FunctionDescription { +func (f *join) Description() map[string]types.FunctionDescription { return map[string]types.FunctionDescription{ "join": { Description: `Performs set operations on 'seriesA' and 'seriesB'. Following options are available: @@ -77,12 +75,12 @@ Example: } } -func (_ *join) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (results []*types.MetricData, err error) { - seriesA, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *join) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (results []*types.MetricData, err error) { + seriesA, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } - seriesB, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + seriesB, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/join/function_test.go b/expr/functions/join/function_test.go index 7e341aac1..fc586310b 100644 --- a/expr/functions/join/function_test.go +++ b/expr/functions/join/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -71,7 +71,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/keepLastValue/function.go b/expr/functions/keepLastValue/function.go index 5772033cf..7ab3c0c30 100644 --- a/expr/functions/keepLastValue/function.go +++ b/expr/functions/keepLastValue/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type keepLastValue struct { - interfaces.FunctionBase -} +type keepLastValue struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,9 +28,9 @@ func New(configFile string) []interfaces.FunctionMetadata { } // keepLastValue(seriesList, limit=inf) -func (f *keepLastValue) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *keepLastValue) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/keepLastValue/function_test.go b/expr/functions/keepLastValue/function_test.go index 8c80d1f19..414cf9b66 100644 --- a/expr/functions/keepLastValue/function_test.go +++ b/expr/functions/keepLastValue/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -75,7 +75,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/kolmogorovSmirnovTest2/function.go b/expr/functions/kolmogorovSmirnovTest2/function.go index 1588713cc..7fb5febb2 100644 --- a/expr/functions/kolmogorovSmirnovTest2/function.go +++ b/expr/functions/kolmogorovSmirnovTest2/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type kolmogorovSmirnovTest2 struct { - interfaces.FunctionBase -} +type kolmogorovSmirnovTest2 struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,13 +29,13 @@ func New(configFile string) []interfaces.FunctionMetadata { // ksTest2(series, series, points|"interval") // https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test -func (f *kolmogorovSmirnovTest2) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg1, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *kolmogorovSmirnovTest2) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg1, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } - arg2, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + arg2, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/legendValue/function.go b/expr/functions/legendValue/function.go index 2670979bf..6ff860f2c 100644 --- a/expr/functions/legendValue/function.go +++ b/expr/functions/legendValue/function.go @@ -13,9 +13,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type legendValue struct { - interfaces.FunctionBase -} +type legendValue struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -32,12 +30,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // legendValue(seriesList, newName) -func (f *legendValue) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *legendValue) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/legendValue/function_test.go b/expr/functions/legendValue/function_test.go index 19373d66a..3d07624d3 100644 --- a/expr/functions/legendValue/function_test.go +++ b/expr/functions/legendValue/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -94,7 +94,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/limit/function.go b/expr/functions/limit/function.go index 153ebcfee..72619d2fa 100644 --- a/expr/functions/limit/function.go +++ b/expr/functions/limit/function.go @@ -9,9 +9,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type limit struct { - interfaces.FunctionBase -} +type limit struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,12 +26,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // limit(seriesList, n) -func (f *limit) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *limit) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/limit/function_test.go b/expr/functions/limit/function_test.go index 7926c2b4e..8cbee9b0e 100644 --- a/expr/functions/limit/function_test.go +++ b/expr/functions/limit/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -67,7 +67,8 @@ func TestLimit(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/linearRegression/function.go b/expr/functions/linearRegression/function.go index c6b7433c0..fcad364a3 100644 --- a/expr/functions/linearRegression/function.go +++ b/expr/functions/linearRegression/function.go @@ -13,9 +13,7 @@ import ( "gonum.org/v1/gonum/mat" ) -type linearRegression struct { - interfaces.FunctionBase -} +type linearRegression struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -32,8 +30,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // linearRegression(seriesList, startSourceAt=None, endSourceAt=None) -func (f *linearRegression) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *linearRegression) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/linearRegression/function_test.go b/expr/functions/linearRegression/function_test.go index 670d50850..87e9945ba 100644 --- a/expr/functions/linearRegression/function_test.go +++ b/expr/functions/linearRegression/function_test.go @@ -5,18 +5,18 @@ import ( "math" "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -42,7 +42,8 @@ func TestLinearRegression(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -54,7 +55,7 @@ func BenchmarkLinearRegression(b *testing.B) { {"metric1", 0, 1}: {types.MakeMetricData("metric1", []float64{1, 2, math.NaN(), math.NaN(), 5, 6}, 1, 1)}, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(target) if err != nil { b.Fatalf("failed to parse %s: %+v", target, err) @@ -62,7 +63,7 @@ func BenchmarkLinearRegression(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, metrics) + g, err := eval.Eval(context.Background(), exp, 0, 1, metrics) if err != nil { b.Fatalf("failed to eval %s: %+v", target, err) } diff --git a/expr/functions/logarithm/function.go b/expr/functions/logarithm/function.go index 31b2fe131..e1d4330b4 100644 --- a/expr/functions/logarithm/function.go +++ b/expr/functions/logarithm/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type logarithm struct { - interfaces.FunctionBase -} +type logarithm struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,8 +29,8 @@ func New(configFile string) []interfaces.FunctionMetadata { // logarithm(seriesList, base=10) // Alias: log -func (f *logarithm) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *logarithm) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/logarithm/function_test.go b/expr/functions/logarithm/function_test.go index 31b65dad6..82e6be09d 100644 --- a/expr/functions/logarithm/function_test.go +++ b/expr/functions/logarithm/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -47,7 +47,8 @@ func TestLogarithm(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -72,7 +73,7 @@ func BenchmarkLogarithm(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -84,7 +85,7 @@ func BenchmarkLogarithm(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } diff --git a/expr/functions/logit/function.go b/expr/functions/logit/function.go index e55ec6e03..c6520251f 100644 --- a/expr/functions/logit/function.go +++ b/expr/functions/logit/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type logit struct { - interfaces.FunctionBase -} +type logit struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,8 +29,8 @@ func New(configFile string) []interfaces.FunctionMetadata { // logarithm(seriesList, base=10) // Alias: log -func (f *logit) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *logit) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/logit/function_test.go b/expr/functions/logit/function_test.go index 86451255b..37ce99293 100644 --- a/expr/functions/logit/function_test.go +++ b/expr/functions/logit/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -40,7 +40,8 @@ func TestFunction(t *testing.T) { tt := tt testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/lowPass/function.go b/expr/functions/lowPass/function.go index 4945b2921..0c2812aaf 100644 --- a/expr/functions/lowPass/function.go +++ b/expr/functions/lowPass/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type lowPass struct { - interfaces.FunctionBase -} +type lowPass struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,8 +28,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // lowPass(seriesList, cutPercent) -func (f *lowPass) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *lowPass) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/lowPass/function_test.go b/expr/functions/lowPass/function_test.go index c39ae7f62..5b2991efc 100644 --- a/expr/functions/lowPass/function_test.go +++ b/expr/functions/lowPass/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -38,7 +38,8 @@ func TestLowPass(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/mapSeries/function.go b/expr/functions/mapSeries/function.go index 86faad471..4fe08fe25 100644 --- a/expr/functions/mapSeries/function.go +++ b/expr/functions/mapSeries/function.go @@ -9,9 +9,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type mapSeries struct { - interfaces.FunctionBase -} +type mapSeries struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(configFile string) []interfaces.FunctionMetadata { // mapSeries(seriesList, *mapNodes) // Alias: map -func (f *mapSeries) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *mapSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/mapSeries/function_test.go b/expr/functions/mapSeries/function_test.go index 995263622..a13018743 100644 --- a/expr/functions/mapSeries/function_test.go +++ b/expr/functions/mapSeries/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -55,7 +55,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/minMax/function.go b/expr/functions/minMax/function.go index c2a278c4d..d4645d3b8 100644 --- a/expr/functions/minMax/function.go +++ b/expr/functions/minMax/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type minMax struct { - interfaces.FunctionBase -} +type minMax struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,8 +29,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // highestAverage(seriesList, n) , highestCurrent(seriesList, n), highestMax(seriesList, n) -func (f *minMax) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *minMax) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/minMax/function_test.go b/expr/functions/minMax/function_test.go index d934e694d..d7db251d8 100644 --- a/expr/functions/minMax/function_test.go +++ b/expr/functions/minMax/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -47,7 +47,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/mostDeviant/function.go b/expr/functions/mostDeviant/function.go index f244c1dfb..e85f79664 100644 --- a/expr/functions/mostDeviant/function.go +++ b/expr/functions/mostDeviant/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type mostDeviant struct { - interfaces.FunctionBase -} +type mostDeviant struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,7 +29,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // mostDeviant(seriesList, n) -or- mostDeviant(n, seriesList) -func (f *mostDeviant) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *mostDeviant) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } @@ -48,7 +46,7 @@ func (f *mostDeviant) Do(ctx context.Context, e parser.Expr, from, until int64, return nil, err } - args, err := helper.GetSeriesArg(ctx, e.Arg(seriesArg), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(seriesArg), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/mostDeviant/function_test.go b/expr/functions/mostDeviant/function_test.go index 09f33c782..75dae5000 100644 --- a/expr/functions/mostDeviant/function_test.go +++ b/expr/functions/mostDeviant/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -64,7 +64,8 @@ func TestFunctionMultiReturn(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/moving/function.go b/expr/functions/moving/function.go index 562be68b0..290f53fbd 100644 --- a/expr/functions/moving/function.go +++ b/expr/functions/moving/function.go @@ -16,8 +16,6 @@ import ( ) type moving struct { - interfaces.FunctionBase - config movingConfig } @@ -65,7 +63,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // movingXyz(seriesList, windowSize) -func (f *moving) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *moving) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { var n int var err error @@ -88,7 +86,7 @@ func (f *moving) Do(ctx context.Context, e parser.Expr, from, until int64, value n, err = e.GetIntArg(1) argstr = strconv.Itoa(n) - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -106,7 +104,9 @@ func (f *moving) Do(ctx context.Context, e parser.Expr, from, until int64, value preview = maxStep * int64(n) adjustedStart -= maxStep * int64(n) windowPoints = n - refetch = true + if adjustedStart != from { + refetch = true + } case parser.EtString: var n32 int32 n32, err = e.GetIntervalArg(1, 1) @@ -122,7 +122,7 @@ func (f *moving) Do(ctx context.Context, e parser.Expr, from, until int64, value var targetValues map[parser.MetricRequest][]*types.MetricData if refetch { - targetValues, err = f.GetEvaluator().Fetch(ctx, []parser.Expr{e.Arg(0)}, adjustedStart, until, values) + targetValues, err = eval.Fetch(ctx, []parser.Expr{e.Arg(0)}, adjustedStart, until, values) if err != nil { return nil, err } @@ -130,7 +130,7 @@ func (f *moving) Do(ctx context.Context, e parser.Expr, from, until int64, value targetValues = values } - adjustedArgs, err := helper.GetSeriesArg(ctx, e.Arg(0), adjustedStart, until, targetValues) + adjustedArgs, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), adjustedStart, until, targetValues) if err != nil { return nil, err } diff --git a/expr/functions/moving/function_test.go b/expr/functions/moving/function_test.go index b096af734..00ace1da7 100644 --- a/expr/functions/moving/function_test.go +++ b/expr/functions/moving/function_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" @@ -15,11 +15,11 @@ import ( "github.com/go-graphite/carbonapi/tests/compare" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -32,7 +32,7 @@ func TestMoving(t *testing.T) { { Target: "movingAverage(metric1,10)", M: map[parser.MetricRequest][]*types.MetricData{ - {"metric1", 20, 25}: {types.MakeMetricData("metric1", generateValues(10, 25, 1), 1, 20)}, + {"metric1", 20, 25}: {types.MakeMetricData("metric1", th.GenerateValues(10, 25, 1), 1, 20)}, {"metric1", 10, 25}: {types.MakeMetricData("metric1", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, 10)}, }, Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,10)`, @@ -43,7 +43,7 @@ func TestMoving(t *testing.T) { { Target: "movingAverage(metric1,10)", M: map[parser.MetricRequest][]*types.MetricData{ - {"metric1", 20, 30}: {types.MakeMetricData("metric1", generateValues(10, 110, 1), 1, 20)}, + {"metric1", 20, 30}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 20)}, {"metric1", 10, 30}: {types.MakeMetricData("metric1", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 1, 10)}, }, Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,10)`, @@ -54,8 +54,8 @@ func TestMoving(t *testing.T) { { Target: "movingAverage(metric1,60)", M: map[parser.MetricRequest][]*types.MetricData{ - {"metric1", 610, 710}: {types.MakeMetricData("metric1", generateValues(10, 110, 1), 1, 610)}, - {"metric1", 550, 710}: {types.MakeMetricData("metric1", generateValues(0, 100, 1), 1, 600)}, + {"metric1", 610, 710}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 610)}, + {"metric1", 550, 710}: {types.MakeMetricData("metric1", th.GenerateValues(0, 100, 1), 1, 600)}, }, Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,60)`, []float64{30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5}, 1, 660).SetTag("movingAverage", "60").SetNameTag(`movingAverage(metric1,60)`)}, @@ -65,8 +65,8 @@ func TestMoving(t *testing.T) { { Target: "movingAverage(metric1,'-1min')", M: map[parser.MetricRequest][]*types.MetricData{ - {"metric1", 610, 710}: {types.MakeMetricData("metric1", generateValues(10, 110, 1), 1, 610)}, - {"metric1", 550, 710}: {types.MakeMetricData("metric1", generateValues(0, 100, 1), 1, 600)}, + {"metric1", 610, 710}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 610)}, + {"metric1", 550, 710}: {types.MakeMetricData("metric1", th.GenerateValues(0, 100, 1), 1, 600)}, }, Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,'-1min')`, []float64{30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5}, 1, 660).SetTag("movingAverage", "'-1min'").SetNameTag(`movingAverage(metric1,'-1min')`)}, @@ -76,7 +76,7 @@ func TestMoving(t *testing.T) { { Target: "movingMedian(metric1,10)", M: map[parser.MetricRequest][]*types.MetricData{ - {"metric1", 20, 30}: {types.MakeMetricData("metric1", generateValues(10, 110, 1), 1, 20)}, + {"metric1", 20, 30}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 20)}, {"metric1", 10, 30}: {types.MakeMetricData("metric1", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 1, 10)}, }, Want: []*types.MetricData{types.MakeMetricData(`movingMedian(metric1,10)`, @@ -87,7 +87,7 @@ func TestMoving(t *testing.T) { { Target: "movingMedian(metric1,10)", M: map[parser.MetricRequest][]*types.MetricData{ - {"metric1", 20, 25}: {types.MakeMetricData("metric1", generateValues(10, 25, 1), 1, 20)}, + {"metric1", 20, 25}: {types.MakeMetricData("metric1", th.GenerateValues(10, 25, 1), 1, 20)}, {"metric1", 10, 25}: {types.MakeMetricData("metric1", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, 10)}, }, Want: []*types.MetricData{types.MakeMetricData(`movingMedian(metric1,10)`, @@ -98,8 +98,8 @@ func TestMoving(t *testing.T) { { Target: "movingMedian(metric1,60)", M: map[parser.MetricRequest][]*types.MetricData{ - {"metric1", 610, 710}: {types.MakeMetricData("metric1", generateValues(10, 110, 1), 1, 610)}, - {"metric1", 550, 710}: {types.MakeMetricData("metric1", generateValues(0, 100, 1), 1, 600)}, + {"metric1", 610, 710}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 610)}, + {"metric1", 550, 710}: {types.MakeMetricData("metric1", th.GenerateValues(0, 100, 1), 1, 600)}, }, Want: []*types.MetricData{types.MakeMetricData(`movingMedian(metric1,60)`, []float64{30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5}, 1, 660).SetTag("movingMedian", "60").SetNameTag(`movingMedian(metric1,60)`)}, @@ -109,8 +109,8 @@ func TestMoving(t *testing.T) { { Target: "movingMedian(metric1,'1min')", M: map[parser.MetricRequest][]*types.MetricData{ - {"metric1", 610, 710}: {types.MakeMetricData("metric1", generateValues(10, 110, 1), 1, 610)}, - {"metric1", 550, 710}: {types.MakeMetricData("metric1", generateValues(0, 100, 1), 1, 600)}, + {"metric1", 610, 710}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 610)}, + {"metric1", 550, 710}: {types.MakeMetricData("metric1", th.GenerateValues(0, 100, 1), 1, 600)}, }, Want: []*types.MetricData{types.MakeMetricData(`movingMedian(metric1,'1min')`, []float64{30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5}, 1, 660).SetTag("movingMedian", "'1min'").SetNameTag(`movingMedian(metric1,'1min')`)}, @@ -120,8 +120,8 @@ func TestMoving(t *testing.T) { { Target: "movingMedian(metric1,'-1min')", M: map[parser.MetricRequest][]*types.MetricData{ - {"metric1", 610, 710}: {types.MakeMetricData("metric1", generateValues(10, 110, 1), 1, 610)}, - {"metric1", 550, 710}: {types.MakeMetricData("metric1", generateValues(0, 100, 1), 1, 600)}, + {"metric1", 610, 710}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 610)}, + {"metric1", 550, 710}: {types.MakeMetricData("metric1", th.GenerateValues(0, 100, 1), 1, 600)}, }, Want: []*types.MetricData{types.MakeMetricData(`movingMedian(metric1,'-1min')`, []float64{30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5}, 1, 660).SetTag("movingMedian", "'-1min'").SetNameTag(`movingMedian(metric1,'-1min')`)}, @@ -254,7 +254,8 @@ func TestMoving(t *testing.T) { for n, tt := range tests { testName := tt.Target t.Run(testName+"#"+strconv.Itoa(n), func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } @@ -299,7 +300,8 @@ func TestMovingXFilesFactor(t *testing.T) { for n, tt := range tests { testName := tt.Target t.Run(testName+"#"+strconv.Itoa(n), func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } @@ -341,7 +343,8 @@ func TestMovingError(t *testing.T) { for n, tt := range tests { testName := tt.Target t.Run(testName+"#"+strconv.Itoa(n), func(t *testing.T) { - th.TestEvalExprWithError(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithError(t, eval, &tt) }) } @@ -414,7 +417,7 @@ func BenchmarkMoving(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -426,7 +429,7 @@ func BenchmarkMoving(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } @@ -435,10 +438,3 @@ func BenchmarkMoving(b *testing.B) { }) } } - -func generateValues(start, stop, step int64) (values []float64) { - for i := start; i < stop; i += step { - values = append(values, float64(i)) - } - return -} diff --git a/expr/functions/moving/moving_refetch/function_test.go b/expr/functions/moving/moving_refetch/function_test.go new file mode 100644 index 000000000..b79edcc84 --- /dev/null +++ b/expr/functions/moving/moving_refetch/function_test.go @@ -0,0 +1,76 @@ +package moving_refetch + +import ( + "math" + "strconv" + "testing" + + "github.com/go-graphite/carbonapi/expr" + "github.com/go-graphite/carbonapi/expr/functions/moving" + "github.com/go-graphite/carbonapi/expr/interfaces" + "github.com/go-graphite/carbonapi/expr/metadata" + "github.com/go-graphite/carbonapi/expr/types" + "github.com/go-graphite/carbonapi/pkg/parser" + th "github.com/go-graphite/carbonapi/tests" +) + +var ( + md []interfaces.FunctionMetadata = moving.New("") + + M = map[parser.MetricRequest][]*types.MetricData{ + // for refetch + {"metric*", 10, 25}: { + types.MakeMetricData("metric1", []float64{math.NaN(), math.NaN(), 2, math.NaN(), 4, math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, 10). + SetNameTag(`movingAverage(metric1,10)`).SetPathExpression("metric*"), + }, + {"metric1", 10, 25}: { + types.MakeMetricData("metric1", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, 10). + SetNameTag(`movingAverage(metric1,10)`).SetPathExpression("metric1"), + }, + } +) + +func init() { + for _, m := range md { + metadata.RegisterFunction(m.Name, m.F) + } +} + +func TestMovingRefetch(t *testing.T) { + tests := []th.EvalTestItemWithRange{ + { + Target: "movingAverage(metric*,10)", + M: map[parser.MetricRequest][]*types.MetricData{ + {"metric*", 20, 25}: {types.MakeMetricData("metric1", th.GenerateValues(10, 25, 1), 1, 20).SetPathExpression("metric*")}, + }, + Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,10)`, + []float64{3, 3, 4, 4, math.NaN()}, 1, 20).SetTag("movingAverage", "10"). + SetNameTag(`movingAverage(metric1,10)`).SetPathExpression("metric*"), + }, + From: 20, + Until: 25, + }, + { + Target: "movingAverage(metric1,10)", + M: map[parser.MetricRequest][]*types.MetricData{ + {"metric1", 20, 25}: {types.MakeMetricData("metric1", th.GenerateValues(10, 25, 1), 1, 20).SetPathExpression("metric1")}, + }, + Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,10)`, + []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, 20).SetTag("movingAverage", "10").SetNameTag(`movingAverage(metric1,10)`)}, + From: 20, + Until: 25, + }, + } + + for n, tt := range tests { + testName := tt.Target + t.Run(testName+"#"+strconv.Itoa(n), func(t *testing.T) { + eval, err := expr.NewEvaluator(nil, th.NewTestZipper(M)) + if err == nil { + th.TestEvalExprWithRange(t, eval, &tt) + } else { + t.Errorf("error='%v'", err) + } + }) + } +} diff --git a/expr/functions/movingMedian/function.go b/expr/functions/movingMedian/function.go index 9423fde93..e60881bae 100644 --- a/expr/functions/movingMedian/function.go +++ b/expr/functions/movingMedian/function.go @@ -17,8 +17,6 @@ import ( ) type movingMedian struct { - interfaces.FunctionBase - config movingMedianConfig } @@ -66,7 +64,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // movingMedian(seriesList, windowSize) -func (f *movingMedian) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *movingMedian) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } @@ -102,7 +100,7 @@ func (f *movingMedian) Do(ctx context.Context, e parser.Expr, from, until int64, start -= int64(n) } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), start, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), start, until, values) if err != nil { return nil, err } diff --git a/expr/functions/movingMedian/function_test.go b/expr/functions/movingMedian/function_test.go index 67de1ccdc..50e229a56 100644 --- a/expr/functions/movingMedian/function_test.go +++ b/expr/functions/movingMedian/function_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" @@ -14,11 +14,11 @@ import ( "github.com/go-graphite/carbonapi/tests/compare" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -73,7 +73,8 @@ func TestMovingMedian(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -110,7 +111,7 @@ func BenchmarkMovingMedian(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -122,7 +123,7 @@ func BenchmarkMovingMedian(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } diff --git a/expr/functions/nPercentile/function.go b/expr/functions/nPercentile/function.go index 729ab63c2..15ca641b1 100644 --- a/expr/functions/nPercentile/function.go +++ b/expr/functions/nPercentile/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type nPercentile struct { - interfaces.FunctionBase -} +type nPercentile struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,12 +29,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // nPercentile(seriesList, n) -func (f *nPercentile) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *nPercentile) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/nPercentile/function_test.go b/expr/functions/nPercentile/function_test.go index 695e5e798..f2101d532 100644 --- a/expr/functions/nPercentile/function_test.go +++ b/expr/functions/nPercentile/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -38,7 +38,8 @@ func TestNPercentile(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/nonNegativeDerivative/function.go b/expr/functions/nonNegativeDerivative/function.go index 288dbab18..fbe00d7d2 100644 --- a/expr/functions/nonNegativeDerivative/function.go +++ b/expr/functions/nonNegativeDerivative/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type nonNegativeDerivative struct { - interfaces.FunctionBase -} +type nonNegativeDerivative struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,8 +28,8 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *nonNegativeDerivative) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *nonNegativeDerivative) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/nonNegativeDerivative/function_test.go b/expr/functions/nonNegativeDerivative/function_test.go index e5efd3015..38dfc5b93 100644 --- a/expr/functions/nonNegativeDerivative/function_test.go +++ b/expr/functions/nonNegativeDerivative/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -66,7 +66,8 @@ func TestNonNegativeDerivative(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/offset/function.go b/expr/functions/offset/function.go index a4c14f764..b63a4d854 100644 --- a/expr/functions/offset/function.go +++ b/expr/functions/offset/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type offset struct { - interfaces.FunctionBase -} +type offset struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // offset(seriesList,factor) -func (f *offset) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *offset) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/offset/function_test.go b/expr/functions/offset/function_test.go index 4a209ac7b..a8c8c5e1e 100644 --- a/expr/functions/offset/function_test.go +++ b/expr/functions/offset/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -73,7 +73,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/offsetToZero/function.go b/expr/functions/offsetToZero/function.go index 4484406a9..47c4ab70b 100644 --- a/expr/functions/offsetToZero/function.go +++ b/expr/functions/offsetToZero/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type offsetToZero struct { - interfaces.FunctionBase -} +type offsetToZero struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,8 +28,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // offsetToZero(seriesList) -func (f *offsetToZero) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - return helper.ForEachSeriesDo(ctx, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { +func (f *offsetToZero) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + return helper.ForEachSeriesDo(ctx, eval, e, from, until, values, func(a *types.MetricData, r *types.MetricData) *types.MetricData { minimum := math.Inf(1) for _, v := range a.Values { // NaN < val is always false diff --git a/expr/functions/offsetToZero/function_test.go b/expr/functions/offsetToZero/function_test.go index 1f92f9da8..6918bd4a4 100644 --- a/expr/functions/offsetToZero/function_test.go +++ b/expr/functions/offsetToZero/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/pearson/function.go b/expr/functions/pearson/function.go index 395f76021..5a238ca66 100644 --- a/expr/functions/pearson/function.go +++ b/expr/functions/pearson/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type pearson struct { - interfaces.FunctionBase -} +type pearson struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,13 +28,13 @@ func New(configFile string) []interfaces.FunctionMetadata { } // pearson(series, series, windowSize) -func (f *pearson) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg1, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *pearson) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg1, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } - arg2, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + arg2, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/pearson/function_test.go b/expr/functions/pearson/function_test.go index c805ab474..079b1de1a 100644 --- a/expr/functions/pearson/function_test.go +++ b/expr/functions/pearson/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/pearsonClosest/function.go b/expr/functions/pearsonClosest/function.go index 614eefcaf..537bb88f0 100644 --- a/expr/functions/pearsonClosest/function.go +++ b/expr/functions/pearsonClosest/function.go @@ -13,9 +13,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type pearsonClosest struct { - interfaces.FunctionBase -} +type pearsonClosest struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -32,12 +30,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // pearsonClosest(series, seriesList, n, direction=abs) -func (f *pearsonClosest) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *pearsonClosest) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() > 3 { return nil, types.ErrTooManyArguments } - ref, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + ref, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -46,7 +44,7 @@ func (f *pearsonClosest) Do(ctx context.Context, e parser.Expr, from, until int6 return nil, types.ErrWildcardNotAllowed } - compare, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + compare, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/pearsonClosest/function_test.go b/expr/functions/pearsonClosest/function_test.go index 8558b9d79..ed61c18de 100644 --- a/expr/functions/pearsonClosest/function_test.go +++ b/expr/functions/pearsonClosest/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -46,7 +46,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -102,7 +103,8 @@ func TestFunctionMultiReturn(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/perSecond/function.go b/expr/functions/perSecond/function.go index fa50da970..d3a1271bd 100644 --- a/expr/functions/perSecond/function.go +++ b/expr/functions/perSecond/function.go @@ -13,9 +13,7 @@ import ( ) // TODO(civil): See if it's possible to merge it with NonNegativeDerivative -type perSecond struct { - interfaces.FunctionBase -} +type perSecond struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -32,8 +30,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // perSecond(seriesList, maxValue=None) -func (f *perSecond) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *perSecond) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/perSecond/function_test.go b/expr/functions/perSecond/function_test.go index b1272d652..a8268a994 100644 --- a/expr/functions/perSecond/function_test.go +++ b/expr/functions/perSecond/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -59,7 +59,8 @@ func TestPerSecond(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/percentileOfSeries/function.go b/expr/functions/percentileOfSeries/function.go index 7010c329b..9f272de13 100644 --- a/expr/functions/percentileOfSeries/function.go +++ b/expr/functions/percentileOfSeries/function.go @@ -16,8 +16,6 @@ type Config struct { } type percentileOfSeries struct { - interfaces.FunctionBase - extractTagsFromArgs bool } @@ -36,13 +34,13 @@ func New(configFile string) []interfaces.FunctionMetadata { } // percentileOfSeries(seriesList, n, interpolate=False) -func (f *percentileOfSeries) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *percentileOfSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { // TODO(dgryski): make sure the arrays are all the same 'size' if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/percentileOfSeries/function_test.go b/expr/functions/percentileOfSeries/function_test.go index 8e6958c29..64cd816b1 100644 --- a/expr/functions/percentileOfSeries/function_test.go +++ b/expr/functions/percentileOfSeries/function_test.go @@ -6,18 +6,18 @@ import ( "time" fconfig "github.com/go-graphite/carbonapi/expr/functions/config" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -100,7 +100,8 @@ func TestPercentileOfSeries(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -131,7 +132,8 @@ func TestPercentileOfSeriesExtractSeriesByTag(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/polyfit/function.go b/expr/functions/polyfit/function.go index 8ec678ddd..c465fb301 100644 --- a/expr/functions/polyfit/function.go +++ b/expr/functions/polyfit/function.go @@ -14,9 +14,7 @@ import ( "gonum.org/v1/gonum/mat" ) -type polyfit struct { - interfaces.FunctionBase -} +type polyfit struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -33,10 +31,10 @@ func New(configFile string) []interfaces.FunctionMetadata { } // polyfit(seriesList, degree=1, offset="0d") -func (f *polyfit) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *polyfit) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { // Fitting Nth degree polynom to the dataset // https://en.wikipedia.org/wiki/Polynomial_regression#Matrix_form_and_calculation_of_estimates - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/polyfit/function_test.go b/expr/functions/polyfit/function_test.go index e423f5d1b..98bb414c8 100644 --- a/expr/functions/polyfit/function_test.go +++ b/expr/functions/polyfit/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -87,7 +87,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/pow/function.go b/expr/functions/pow/function.go index c4ac5e114..8b618139b 100644 --- a/expr/functions/pow/function.go +++ b/expr/functions/pow/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type pow struct { - interfaces.FunctionBase -} +type pow struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,12 +28,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // pow(seriesList,factor) -func (f *pow) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *pow) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/pow/function_test.go b/expr/functions/pow/function_test.go index 98bf41010..a2adf3c5a 100644 --- a/expr/functions/pow/function_test.go +++ b/expr/functions/pow/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -45,7 +45,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/powSeries/function.go b/expr/functions/powSeries/function.go index 5db4cb7ce..4a8345931 100644 --- a/expr/functions/powSeries/function.go +++ b/expr/functions/powSeries/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type powSeries struct { - interfaces.FunctionBase -} +type powSeries struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,8 +28,8 @@ func New(_ string) []interfaces.FunctionMetadata { return res } -func (f *powSeries) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - series, err := helper.GetSeriesArgs(ctx, e.Args(), from, until, values) +func (f *powSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + series, err := helper.GetSeriesArgs(ctx, eval, e.Args(), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/powSeries/function_test.go b/expr/functions/powSeries/function_test.go index d7947006b..2ec2dcef5 100644 --- a/expr/functions/powSeries/function_test.go +++ b/expr/functions/powSeries/function_test.go @@ -6,18 +6,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -59,7 +59,8 @@ var ( func TestFunction(t *testing.T) { for _, test := range tests { t.Run(test.Target, func(t *testing.T) { - th.TestEvalExpr(t, &test) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &test) }) } } @@ -68,14 +69,14 @@ func BenchmarkFunction(b *testing.B) { for _, test := range tests { for i := 0; i < b.N; i++ { b.Run(test.Target, func(b *testing.B) { - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) exp, _, err := parser.ParseExpr(test.Target) if err != nil { b.Fatalf("could not parse target expression %s", test.Target) } - _, err = evaluator.Eval(context.Background(), exp, 0, 1, test.M) + _, err = eval.Eval(context.Background(), exp, 0, 1, test.M) if err != nil { b.Fatalf("could not evaluate expression %s", test.Target) } diff --git a/expr/functions/randomWalk/function.go b/expr/functions/randomWalk/function.go index 94bc66ee4..8d226911d 100644 --- a/expr/functions/randomWalk/function.go +++ b/expr/functions/randomWalk/function.go @@ -10,9 +10,7 @@ import ( pb "github.com/go-graphite/protocol/carbonapi_v3_pb" ) -type randomWalk struct { - interfaces.FunctionBase -} +type randomWalk struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,7 +27,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // randomWalk(name, step=60) -func (f *randomWalk) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *randomWalk) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { name, err := e.GetStringArg(0) if err != nil { name = "randomWalk" diff --git a/expr/functions/randomWalk/function_test.go b/expr/functions/randomWalk/function_test.go index 4de779661..dda331e90 100644 --- a/expr/functions/randomWalk/function_test.go +++ b/expr/functions/randomWalk/function_test.go @@ -3,7 +3,7 @@ package randomWalk import ( "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" @@ -11,11 +11,11 @@ import ( "github.com/stretchr/testify/assert" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -81,7 +81,8 @@ func TestRandomWalk(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithCustomValidation(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithCustomValidation(t, eval, &tt) }) } } diff --git a/expr/functions/rangeOfSeries/function.go b/expr/functions/rangeOfSeries/function.go index ded6ea926..81f748639 100644 --- a/expr/functions/rangeOfSeries/function.go +++ b/expr/functions/rangeOfSeries/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type rangeOfSeries struct { - interfaces.FunctionBase -} +type rangeOfSeries struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +27,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // rangeOfSeries(*seriesLists) -func (f *rangeOfSeries) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - series, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *rangeOfSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + series, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/rangeOfSeries/function_test.go b/expr/functions/rangeOfSeries/function_test.go index 5251034ee..c591d4753 100644 --- a/expr/functions/rangeOfSeries/function_test.go +++ b/expr/functions/rangeOfSeries/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -50,7 +50,8 @@ func TestRangeOfSeries(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/reduce/function.go b/expr/functions/reduce/function.go index 7f71175a3..776a5775b 100644 --- a/expr/functions/reduce/function.go +++ b/expr/functions/reduce/function.go @@ -11,9 +11,7 @@ import ( "strings" ) -type reduce struct { - interfaces.FunctionBase -} +type reduce struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,14 +27,14 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *reduce) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *reduce) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { const matchersStartIndex = 3 if e.ArgsLen() < matchersStartIndex+1 { return nil, parser.ErrMissingArgument } - seriesList, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + seriesList, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -97,7 +95,7 @@ AliasLoop: reducedNodes[i] = parser.NewTargetExpr(matched.Name) } - result, err := f.Evaluator.Eval(ctx, parser.NewExprTyped("alias", []parser.Expr{ + result, err := eval.Eval(ctx, parser.NewExprTyped("alias", []parser.Expr{ parser.NewExprTyped(reduceFunction, reducedNodes), parser.NewValueExpr(aliasName), }), from, until, reducedValues) diff --git a/expr/functions/removeBelowSeries/function.go b/expr/functions/removeBelowSeries/function.go index 20f8d7927..8cb10d640 100644 --- a/expr/functions/removeBelowSeries/function.go +++ b/expr/functions/removeBelowSeries/function.go @@ -13,9 +13,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type removeBelowSeries struct { - interfaces.FunctionBase -} +type removeBelowSeries struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -32,8 +30,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // removeBelowValue(seriesLists, n), removeAboveValue(seriesLists, n), removeBelowPercentile(seriesLists, percent), removeAbovePercentile(seriesLists, percent) -func (f *removeBelowSeries) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *removeBelowSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/removeBelowSeries/function_test.go b/expr/functions/removeBelowSeries/function_test.go index 546dbff4a..daf26e49f 100644 --- a/expr/functions/removeBelowSeries/function_test.go +++ b/expr/functions/removeBelowSeries/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -63,7 +63,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/removeBetweenPercentile/function.go b/expr/functions/removeBetweenPercentile/function.go index 698557fe4..5e479c6fb 100644 --- a/expr/functions/removeBetweenPercentile/function.go +++ b/expr/functions/removeBetweenPercentile/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type removeBetweenPercentile struct { - interfaces.FunctionBase -} +type removeBetweenPercentile struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,12 +29,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // removeBetweenPercentile(seriesLists, percent) -func (f *removeBetweenPercentile) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *removeBetweenPercentile) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/removeBetweenPercentile/function_test.go b/expr/functions/removeBetweenPercentile/function_test.go index b2570b7d9..d5fbcd82d 100644 --- a/expr/functions/removeBetweenPercentile/function_test.go +++ b/expr/functions/removeBetweenPercentile/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -46,7 +46,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/removeEmptySeries/function.go b/expr/functions/removeEmptySeries/function.go index 611fded1f..e9e00e170 100644 --- a/expr/functions/removeEmptySeries/function.go +++ b/expr/functions/removeEmptySeries/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type removeEmptySeries struct { - interfaces.FunctionBase -} +type removeEmptySeries struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,10 +28,10 @@ func New(configFile string) []interfaces.FunctionMetadata { } // removeEmptySeries(seriesLists, n), removeZeroSeries(seriesLists, n) -func (f *removeEmptySeries) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *removeEmptySeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { var xFilesFactor float64 - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/removeEmptySeries/function_test.go b/expr/functions/removeEmptySeries/function_test.go index ef1150d3f..1a68a777c 100644 --- a/expr/functions/removeEmptySeries/function_test.go +++ b/expr/functions/removeEmptySeries/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -152,7 +152,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/round/function.go b/expr/functions/round/function.go index 1dae20c0b..4350caac8 100644 --- a/expr/functions/round/function.go +++ b/expr/functions/round/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type round struct { - interfaces.FunctionBase -} +type round struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +27,8 @@ func New(_ string) []interfaces.FunctionMetadata { } // round(seriesList,precision) -func (f *round) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *round) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/round/function_test.go b/expr/functions/round/function_test.go index e541b8f08..3d95ea425 100644 --- a/expr/functions/round/function_test.go +++ b/expr/functions/round/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -73,7 +73,8 @@ func TestRound(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/scale/function.go b/expr/functions/scale/function.go index 6e0888be0..af8d045c8 100644 --- a/expr/functions/scale/function.go +++ b/expr/functions/scale/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type scale struct { - interfaces.FunctionBase -} +type scale struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // scale(seriesList, factor) -func (f *scale) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *scale) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/scale/function_test.go b/expr/functions/scale/function_test.go index ea6986b2b..7fff89d3d 100644 --- a/expr/functions/scale/function_test.go +++ b/expr/functions/scale/function_test.go @@ -6,18 +6,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -64,7 +64,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/scaleToSeconds/function.go b/expr/functions/scaleToSeconds/function.go index 3da706902..d6f2edcc7 100644 --- a/expr/functions/scaleToSeconds/function.go +++ b/expr/functions/scaleToSeconds/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type scaleToSeconds struct { - interfaces.FunctionBase -} +type scaleToSeconds struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(configFile string) []interfaces.FunctionMetadata { } // scaleToSeconds(seriesList, seconds) -func (f *scaleToSeconds) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *scaleToSeconds) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/scaleToSeconds/function_test.go b/expr/functions/scaleToSeconds/function_test.go index 752fecd44..75d39453d 100644 --- a/expr/functions/scaleToSeconds/function_test.go +++ b/expr/functions/scaleToSeconds/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -38,7 +38,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/seriesByTag/function.go b/expr/functions/seriesByTag/function.go index 0c311b920..9200db79e 100644 --- a/expr/functions/seriesByTag/function.go +++ b/expr/functions/seriesByTag/function.go @@ -8,9 +8,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type seriesByTag struct { - interfaces.FunctionBase -} +type seriesByTag struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -25,7 +23,7 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *seriesByTag) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *seriesByTag) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { var results []*types.MetricData key := parser.MetricRequest{Metric: e.ToString(), From: from, Until: until} data, ok := values[key] diff --git a/expr/functions/seriesList/function.go b/expr/functions/seriesList/function.go index 7af9e7630..60cbc2fe4 100644 --- a/expr/functions/seriesList/function.go +++ b/expr/functions/seriesList/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type seriesList struct { - interfaces.FunctionBase -} +type seriesList struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,7 +28,7 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *seriesList) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *seriesList) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } @@ -43,7 +41,7 @@ func (f *seriesList) Do(ctx context.Context, e parser.Expr, from, until int64, v return nil, err } - numerators, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + numerators, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -56,7 +54,7 @@ func (f *seriesList) Do(ctx context.Context, e parser.Expr, from, until int64, v } } - denominators, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + denominators, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/seriesList/function_test.go b/expr/functions/seriesList/function_test.go index 0e8b4082a..1f5765870 100644 --- a/expr/functions/seriesList/function_test.go +++ b/expr/functions/seriesList/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -49,7 +49,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } @@ -137,7 +138,8 @@ func TestSeriesListMultiReturn(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } @@ -196,7 +198,8 @@ func TestDivideSeriesMismatchedData(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/setXFilesFactor/function.go b/expr/functions/setXFilesFactor/function.go index e95148a94..1e193eb77 100644 --- a/expr/functions/setXFilesFactor/function.go +++ b/expr/functions/setXFilesFactor/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type setXFilesFactor struct { - interfaces.FunctionBase -} +type setXFilesFactor struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,12 +27,12 @@ func New(_ string) []interfaces.FunctionMetadata { } // setXFilesFactor(seriesList, xFilesFactor) -func (f *setXFilesFactor) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *setXFilesFactor) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/setXFilesFactor/function_test.go b/expr/functions/setXFilesFactor/function_test.go index 45152fb86..0cfd7ac9f 100644 --- a/expr/functions/setXFilesFactor/function_test.go +++ b/expr/functions/setXFilesFactor/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -38,7 +38,8 @@ func TestSetXFilesFactor(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/sigmoid/function.go b/expr/functions/sigmoid/function.go index 950d7679b..861897ed4 100644 --- a/expr/functions/sigmoid/function.go +++ b/expr/functions/sigmoid/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type sigmoid struct { - interfaces.FunctionBase -} +type sigmoid struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +27,8 @@ func New(_ string) []interfaces.FunctionMetadata { } // sigmoid(seriesList) -func (f *sigmoid) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *sigmoid) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/sigmoid/function_test.go b/expr/functions/sigmoid/function_test.go index 1ca0c0187..0da51afb8 100644 --- a/expr/functions/sigmoid/function_test.go +++ b/expr/functions/sigmoid/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/sinFunction/function.go b/expr/functions/sinFunction/function.go index dfc7a8576..7010e4eb7 100644 --- a/expr/functions/sinFunction/function.go +++ b/expr/functions/sinFunction/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type sinFunction struct { - interfaces.FunctionBase -} +type sinFunction struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,7 +28,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // sinFunction(name, amplitude, step) -func (f *sinFunction) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *sinFunction) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { name, err := e.GetStringArg(0) if err != nil { return nil, err diff --git a/expr/functions/sinFunction/function_test.go b/expr/functions/sinFunction/function_test.go index 8c7b4dfc8..d3bef1efe 100644 --- a/expr/functions/sinFunction/function_test.go +++ b/expr/functions/sinFunction/function_test.go @@ -3,18 +3,18 @@ package sinFunction import ( "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -49,7 +49,8 @@ func TestSinFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/slo/function.go b/expr/functions/slo/function.go index 729b9b818..605c3bcd4 100644 --- a/expr/functions/slo/function.go +++ b/expr/functions/slo/function.go @@ -13,9 +13,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type slo struct { - interfaces.FunctionBase -} +type slo struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,7 +26,7 @@ func New(string) []interfaces.FunctionMetadata { } } -func (f *slo) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *slo) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { var ( argsExtended, argsWindowed []*types.MetricData bucketSize32 int32 @@ -38,7 +36,7 @@ func (f *slo) Do(ctx context.Context, e parser.Expr, from, until int64, values m ) // requested data points' window - argsWindowed, err = helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + argsWindowed, err = helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if len(argsWindowed) == 0 || err != nil { return nil, err } @@ -59,7 +57,7 @@ func (f *slo) Do(ctx context.Context, e parser.Expr, from, until int64, values m windowSize = until - from if bucketSize > windowSize && !(from == 0 && until == 1) { delta = bucketSize - windowSize - argsExtended, err = helper.GetSeriesArg(ctx, e.Arg(0), from-delta, until, values) + argsExtended, err = helper.GetSeriesArg(ctx, eval, e.Arg(0), from-delta, until, values) if err != nil { return nil, err diff --git a/expr/functions/slo/function_test.go b/expr/functions/slo/function_test.go index b297cb15c..3c71b32a1 100644 --- a/expr/functions/slo/function_test.go +++ b/expr/functions/slo/function_test.go @@ -6,17 +6,17 @@ import ( th "github.com/go-graphite/carbonapi/tests" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -89,7 +89,8 @@ func TestSlo(t *testing.T) { for _, testCase := range testCases { testName := testCase.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &testCase) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &testCase) }) } } @@ -174,7 +175,8 @@ func TestSloErrorBudget(t *testing.T) { for _, testCase := range testCases { testName := testCase.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &testCase) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &testCase) }) } } diff --git a/expr/functions/smartSummarize/function.go b/expr/functions/smartSummarize/function.go index 53cf5d8a9..948367677 100644 --- a/expr/functions/smartSummarize/function.go +++ b/expr/functions/smartSummarize/function.go @@ -12,9 +12,7 @@ import ( pb "github.com/go-graphite/protocol/carbonapi_v3_pb" ) -type smartSummarize struct { - interfaces.FunctionBase -} +type smartSummarize struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,7 +29,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // smartSummarize(seriesList, intervalString, func='sum', alignTo=None) -func (f *smartSummarize) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *smartSummarize) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { // TODO(dgryski): make sure the arrays are all the same 'size' if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument @@ -51,7 +49,7 @@ func (f *smartSummarize) Do(ctx context.Context, e parser.Expr, from, until int6 } from = newStart } - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/smartSummarize/function_test.go b/expr/functions/smartSummarize/function_test.go index d04b848a2..b94b029bf 100644 --- a/expr/functions/smartSummarize/function_test.go +++ b/expr/functions/smartSummarize/function_test.go @@ -5,18 +5,18 @@ import ( "strconv" "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -36,7 +36,8 @@ func TestSummarizeEmptyData(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -232,7 +233,8 @@ func TestEvalSummarize(t *testing.T) { } for _, tt := range tests { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) } } @@ -306,7 +308,8 @@ func TestSmartSummarizeAlignTo1Year(t *testing.T) { } for _, tt := range tests { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) } } @@ -380,7 +383,8 @@ func TestSmartSummarizeAlignToMonths(t *testing.T) { } for _, tt := range tests { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) } } @@ -454,7 +458,8 @@ func TestSmartSummarizeAlignToWeeksThursday(t *testing.T) { } for _, tt := range tests { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) } } @@ -528,7 +533,8 @@ func TestSmartSummarizeAlignToDays(t *testing.T) { } for _, tt := range tests { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) } } @@ -602,7 +608,8 @@ func TestSmartSummarizeAlignToHours(t *testing.T) { } for _, tt := range tests { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) } } @@ -676,7 +683,8 @@ func TestSmartSummarizeAlignToMinutes(t *testing.T) { } for _, tt := range tests { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) } } @@ -750,7 +758,8 @@ func TestSmartSummarizeAlignToSeconds(t *testing.T) { } for _, tt := range tests { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) } } @@ -777,7 +786,8 @@ func TestFunctionUseNameWithWildcards(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } } @@ -796,7 +806,8 @@ func TestSmartSummarizeErrors(t *testing.T) { for n, tt := range tests { testName := tt.Target t.Run(testName+"#"+strconv.Itoa(n), func(t *testing.T) { - th.TestEvalExprWithError(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithError(t, eval, &tt) }) } } diff --git a/expr/functions/sortBy/function.go b/expr/functions/sortBy/function.go index a4808ef40..b731d414c 100644 --- a/expr/functions/sortBy/function.go +++ b/expr/functions/sortBy/function.go @@ -12,9 +12,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type sortBy struct { - interfaces.FunctionBase -} +type sortBy struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,8 +29,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // sortByMaxima(seriesList), sortByMinima(seriesList), sortByTotal(seriesList) -func (f *sortBy) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - original, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *sortBy) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + original, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/sortBy/function_test.go b/expr/functions/sortBy/function_test.go index d846b9d4e..ddf0416ff 100644 --- a/expr/functions/sortBy/function_test.go +++ b/expr/functions/sortBy/function_test.go @@ -1,22 +1,23 @@ package sortBy import ( - "github.com/go-graphite/carbonapi/expr/consolidations" "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/consolidations" + "github.com/go-graphite/carbonapi/expr/interfaces" + "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -122,7 +123,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -149,7 +151,8 @@ func TestErrorInvalidConsolidationFunction(t *testing.T) { for _, testCase := range tests { testName := testCase.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithError(t, &testCase) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithError(t, eval, &testCase) }) } } diff --git a/expr/functions/sortByName/function.go b/expr/functions/sortByName/function.go index 39f0f4f88..bc50b3aea 100644 --- a/expr/functions/sortByName/function.go +++ b/expr/functions/sortByName/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type sortByName struct { - interfaces.FunctionBase -} +type sortByName struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +27,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // sortByName(seriesList, natural=false) -func (f *sortByName) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - original, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *sortByName) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + original, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/sortByName/function_test.go b/expr/functions/sortByName/function_test.go index 98e3a4db3..770ed690b 100644 --- a/expr/functions/sortByName/function_test.go +++ b/expr/functions/sortByName/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -153,7 +153,8 @@ func TestSortByName(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -226,7 +227,7 @@ func BenchmarkSortByName(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -238,7 +239,7 @@ func BenchmarkSortByName(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } diff --git a/expr/functions/squareRoot/function.go b/expr/functions/squareRoot/function.go index 90211683a..dbb94578e 100644 --- a/expr/functions/squareRoot/function.go +++ b/expr/functions/squareRoot/function.go @@ -10,9 +10,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type squareRoot struct { - interfaces.FunctionBase -} +type squareRoot struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,8 +27,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // squareRoot(seriesList) -func (f *squareRoot) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *squareRoot) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/squareRoot/function_test.go b/expr/functions/squareRoot/function_test.go index 955d6f528..ded85477c 100644 --- a/expr/functions/squareRoot/function_test.go +++ b/expr/functions/squareRoot/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/stdev/function.go b/expr/functions/stdev/function.go index d0672436d..d19e6eb75 100644 --- a/expr/functions/stdev/function.go +++ b/expr/functions/stdev/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type stdev struct { - interfaces.FunctionBase -} +type stdev struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,12 +26,12 @@ func New(configFile string) []interfaces.FunctionMetadata { // stdev(seriesList, points, missingThreshold=0.1) // Alias: stddev -func (f *stdev) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *stdev) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/stdev/function_test.go b/expr/functions/stdev/function_test.go index 4ffcadc34..01e282a02 100644 --- a/expr/functions/stdev/function_test.go +++ b/expr/functions/stdev/function_test.go @@ -1,21 +1,22 @@ package stdev import ( - "github.com/go-graphite/carbonapi/expr/helper" + "math" + "testing" + "time" + + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" - "math" - "testing" - "time" +) + +var ( + md []interfaces.FunctionMetadata = New("") ) func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -46,7 +47,8 @@ func TestStdev(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/substr/function.go b/expr/functions/substr/function.go index b87f7bcf8..4427bbe96 100644 --- a/expr/functions/substr/function.go +++ b/expr/functions/substr/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type substr struct { - interfaces.FunctionBase -} +type substr struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,9 +28,9 @@ func New(configFile string) []interfaces.FunctionMetadata { } // aliasSub(seriesList, start, stop) -func (f *substr) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *substr) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { // BUG: affected by the same positional arg issue as 'threshold'. - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/substr/function_test.go b/expr/functions/substr/function_test.go index d24edb056..ed8315bdf 100644 --- a/expr/functions/substr/function_test.go +++ b/expr/functions/substr/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -118,7 +118,8 @@ func TestSubstr(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/summarize/function.go b/expr/functions/summarize/function.go index 02f9fa28d..cdfe35748 100644 --- a/expr/functions/summarize/function.go +++ b/expr/functions/summarize/function.go @@ -3,18 +3,17 @@ package summarize import ( "context" "fmt" + "math" + "github.com/go-graphite/carbonapi/expr/consolidations" "github.com/go-graphite/carbonapi/expr/helper" "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" pb "github.com/go-graphite/protocol/carbonapi_v3_pb" - "math" ) -type summarize struct { - interfaces.FunctionBase -} +type summarize struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -31,9 +30,9 @@ func New(configFile string) []interfaces.FunctionMetadata { } // summarize(seriesList, intervalString, func='sum', alignToFrom=False) -func (f *summarize) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *summarize) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { // TODO(dgryski): make sure the arrays are all the same 'size' - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/summarize/function_test.go b/expr/functions/summarize/function_test.go index f0a126e2c..611da3d17 100644 --- a/expr/functions/summarize/function_test.go +++ b/expr/functions/summarize/function_test.go @@ -4,18 +4,18 @@ import ( "math" "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -227,7 +227,8 @@ func TestEvalSummarize(t *testing.T) { } for _, tt := range tests { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) } } @@ -366,7 +367,8 @@ func TestEvalSummarize1Minute(t *testing.T) { } for _, tt := range tests { - th.TestSummarizeEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestSummarizeEvalExpr(t, eval, &tt) } } diff --git a/expr/functions/timeFunction/function.go b/expr/functions/timeFunction/function.go index 7f2384c82..50813182a 100644 --- a/expr/functions/timeFunction/function.go +++ b/expr/functions/timeFunction/function.go @@ -10,9 +10,7 @@ import ( pb "github.com/go-graphite/protocol/carbonapi_v3_pb" ) -type timeFunction struct { - interfaces.FunctionBase -} +type timeFunction struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,7 +26,7 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *timeFunction) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *timeFunction) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { name, err := e.GetStringArg(0) if err != nil { return nil, err diff --git a/expr/functions/timeFunction/function_test.go b/expr/functions/timeFunction/function_test.go index fce86b07f..fba602557 100644 --- a/expr/functions/timeFunction/function_test.go +++ b/expr/functions/timeFunction/function_test.go @@ -3,18 +3,18 @@ package timeFunction import ( "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -39,7 +39,8 @@ func TestTimeFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/timeShift/function.go b/expr/functions/timeShift/function.go index bbe715279..5a006b634 100644 --- a/expr/functions/timeShift/function.go +++ b/expr/functions/timeShift/function.go @@ -16,8 +16,6 @@ import ( ) type timeShift struct { - interfaces.FunctionBase - config timeShiftConfig } @@ -73,7 +71,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // timeShift(seriesList, timeShift, resetEnd=True) -func (f *timeShift) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *timeShift) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { // FIXME(civil): support alignDst if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument @@ -91,7 +89,7 @@ func (f *timeShift) Do(ctx context.Context, e parser.Expr, from, until int64, va } resetEndStr := strconv.FormatBool(resetEnd) - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from+int64(offs), until+int64(offs), values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from+int64(offs), until+int64(offs), values) if err != nil { return nil, err } diff --git a/expr/functions/timeShift/function_test.go b/expr/functions/timeShift/function_test.go index d864ad957..34a0e2684 100644 --- a/expr/functions/timeShift/function_test.go +++ b/expr/functions/timeShift/function_test.go @@ -3,18 +3,18 @@ package timeShift import ( "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -100,7 +100,8 @@ func TestTimeShift(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/timeShiftByMetric/function.go b/expr/functions/timeShiftByMetric/function.go index 21b23e120..3e6a39527 100644 --- a/expr/functions/timeShiftByMetric/function.go +++ b/expr/functions/timeShiftByMetric/function.go @@ -16,9 +16,7 @@ import ( type offsetByVersion map[string]int64 -type timeShiftByMetric struct { - interfaces.FunctionBase -} +type timeShiftByMetric struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -32,8 +30,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // timeShiftByMetric(seriesList, markSource, versionRankIndex) -func (f *timeShiftByMetric) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (resultData []*types.MetricData, resultError error) { - params, err := f.extractCallParams(ctx, e, from, until, values) +func (f *timeShiftByMetric) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (resultData []*types.MetricData, resultError error) { + params, err := f.extractCallParams(ctx, eval, e, from, until, values) if err != nil { return nil, err } @@ -106,13 +104,13 @@ func (f *timeShiftByMetric) calculateOffsets(params *callParams, versions versio } // extractCallParams (preliminarily) validates and extracts parameters of timeShiftByMetric's call as structure -func (f *timeShiftByMetric) extractCallParams(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (*callParams, error) { - metrics, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *timeShiftByMetric) extractCallParams(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (*callParams, error) { + metrics, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } - marks, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + marks, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/timeShiftByMetric/function_test.go b/expr/functions/timeShiftByMetric/function_test.go index 6f876e0c6..7f539a574 100644 --- a/expr/functions/timeShiftByMetric/function_test.go +++ b/expr/functions/timeShiftByMetric/function_test.go @@ -6,18 +6,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -87,7 +87,8 @@ func TestTimeShift(t *testing.T) { for _, testCase := range testCases { testName := testCase.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &testCase) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &testCase) }) } } @@ -120,7 +121,8 @@ func TestBadMarks(t *testing.T) { for _, testCase := range testCases { testName := testCase.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithError(t, &testCase) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithError(t, eval, &testCase) }) } } @@ -179,7 +181,8 @@ func TestNotEnoughSeries(t *testing.T) { for _, testCase := range testCases { testName := testCase.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithError(t, &testCase) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithError(t, eval, &testCase) }) } } @@ -239,7 +242,7 @@ func BenchmarkTimeShift(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -251,7 +254,7 @@ func BenchmarkTimeShift(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } diff --git a/expr/functions/timeSlice/function.go b/expr/functions/timeSlice/function.go index 504e6c4dc..3a101a186 100644 --- a/expr/functions/timeSlice/function.go +++ b/expr/functions/timeSlice/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type timeSlice struct { - interfaces.FunctionBase -} +type timeSlice struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -29,7 +27,7 @@ func New(configFile string) []interfaces.FunctionMetadata { return res } -func (f *timeSlice) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *timeSlice) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } @@ -48,7 +46,7 @@ func (f *timeSlice) Do(ctx context.Context, e parser.Expr, from, until int64, va startStr := strconv.FormatInt(start, 10) endStr := strconv.FormatInt(end, 10) - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/timeSlice/function_test.go b/expr/functions/timeSlice/function_test.go index 003dae45e..b297dbd49 100644 --- a/expr/functions/timeSlice/function_test.go +++ b/expr/functions/timeSlice/function_test.go @@ -4,18 +4,18 @@ import ( "math" "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -40,7 +40,8 @@ func TestTimeSlice(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/timeStack/function.go b/expr/functions/timeStack/function.go index 4f0111a91..5f127631f 100644 --- a/expr/functions/timeStack/function.go +++ b/expr/functions/timeStack/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type timeStack struct { - interfaces.FunctionBase -} +type timeStack struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,7 +28,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // timeStack(seriesList, timeShiftUnit, timeShiftStart, timeShiftEnd) -func (f *timeStack) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *timeStack) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { unit, err := e.GetIntervalArg(1, -1) if err != nil { return nil, err @@ -52,7 +50,7 @@ func (f *timeStack) Do(ctx context.Context, e parser.Expr, from, until int64, va offs := i * int64(unit) fromNew := from + offs untilNew := until + offs - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), fromNew, untilNew, values) + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), fromNew, untilNew, values) if err != nil { return nil, err } diff --git a/expr/functions/timeStack/function_test.go b/expr/functions/timeStack/function_test.go index e6eee06d4..9643c70ab 100644 --- a/expr/functions/timeStack/function_test.go +++ b/expr/functions/timeStack/function_test.go @@ -4,18 +4,18 @@ import ( "math" "testing" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -41,7 +41,8 @@ func TestTimeStack(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExprWithRange(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &tt) }) } } diff --git a/expr/functions/toLowerCase/function.go b/expr/functions/toLowerCase/function.go index 6298ed030..20491c664 100644 --- a/expr/functions/toLowerCase/function.go +++ b/expr/functions/toLowerCase/function.go @@ -5,15 +5,12 @@ import ( "strings" "github.com/go-graphite/carbonapi/expr/helper" - "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" ) -type toLowerCase struct { - interfaces.FunctionBase -} +type toLowerCase struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,8 +27,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // toLowerCase(seriesList, *pos) -func (f *toLowerCase) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *toLowerCase) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/toLowerCase/function_test.go b/expr/functions/toLowerCase/function_test.go index 2e7d8c0a9..a4f94127c 100644 --- a/expr/functions/toLowerCase/function_test.go +++ b/expr/functions/toLowerCase/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -71,7 +71,8 @@ func TestToLowerCaseFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/toUpperCase/function.go b/expr/functions/toUpperCase/function.go index fb39e401a..6b56b5456 100644 --- a/expr/functions/toUpperCase/function.go +++ b/expr/functions/toUpperCase/function.go @@ -5,15 +5,12 @@ import ( "strings" "github.com/go-graphite/carbonapi/expr/helper" - "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" ) -type toUpperCase struct { - interfaces.FunctionBase -} +type toUpperCase struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,8 +27,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // toUpperCase(seriesList, *pos) -func (f *toUpperCase) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *toUpperCase) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/toUpperCase/function_test.go b/expr/functions/toUpperCase/function_test.go index efdcf43c4..2f7b1ab76 100644 --- a/expr/functions/toUpperCase/function_test.go +++ b/expr/functions/toUpperCase/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -71,7 +71,8 @@ func TestToUpperCaseFunction(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/transformNull/function.go b/expr/functions/transformNull/function.go index 678151d98..5849a7bdf 100644 --- a/expr/functions/transformNull/function.go +++ b/expr/functions/transformNull/function.go @@ -15,9 +15,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type transformNull struct { - interfaces.FunctionBase -} +type transformNull struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -34,8 +32,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // transformNull(seriesList, default=0) -func (f *transformNull) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *transformNull) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -57,7 +55,7 @@ func (f *transformNull) Do(ctx context.Context, e parser.Expr, from, until int64 var valMap []bool referenceSeriesExpr := e.GetNamedArg("referenceSeries") if !referenceSeriesExpr.IsInterfaceNil() { - referenceSeries, err := helper.GetSeriesArg(ctx, referenceSeriesExpr, from, until, values) + referenceSeries, err := helper.GetSeriesArg(ctx, eval, referenceSeriesExpr, from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/transformNull/function_test.go b/expr/functions/transformNull/function_test.go index d548b5a7f..038557670 100644 --- a/expr/functions/transformNull/function_test.go +++ b/expr/functions/transformNull/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -73,7 +73,8 @@ func TestTransformNull(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/tukey/function.go b/expr/functions/tukey/function.go index 11041476a..0f03826dc 100644 --- a/expr/functions/tukey/function.go +++ b/expr/functions/tukey/function.go @@ -14,9 +14,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type tukey struct { - interfaces.FunctionBase -} +type tukey struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -33,8 +31,8 @@ func New(configFile string) []interfaces.FunctionMetadata { } // tukeyAbove(seriesList,basis,n,interval=0) , tukeyBelow(seriesList,basis,n,interval=0) -func (f *tukey) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *tukey) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/tukey/function_test.go b/expr/functions/tukey/function_test.go index 4690880c5..1fdaa7a90 100644 --- a/expr/functions/tukey/function_test.go +++ b/expr/functions/tukey/function_test.go @@ -4,18 +4,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -175,7 +175,8 @@ func TestFunctionMultiReturn(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestMultiReturnEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestMultiReturnEvalExpr(t, eval, &tt) }) } diff --git a/expr/functions/unique/function.go b/expr/functions/unique/function.go index d0418868d..c1e083d60 100644 --- a/expr/functions/unique/function.go +++ b/expr/functions/unique/function.go @@ -9,9 +9,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type unique struct { - interfaces.FunctionBase -} +type unique struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -28,8 +26,8 @@ func New(_ string) []interfaces.FunctionMetadata { } // unique(seriesList) -func (f *unique) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - arg, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *unique) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + arg, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/unique/function_test.go b/expr/functions/unique/function_test.go index fff4087fe..789e112da 100644 --- a/expr/functions/unique/function_test.go +++ b/expr/functions/unique/function_test.go @@ -5,18 +5,18 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" th "github.com/go-graphite/carbonapi/tests" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -47,7 +47,8 @@ func TestUnique(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } } diff --git a/expr/functions/verticalLine/function.go b/expr/functions/verticalLine/function.go index 9d1bfd218..865a30c18 100644 --- a/expr/functions/verticalLine/function.go +++ b/expr/functions/verticalLine/function.go @@ -6,6 +6,7 @@ package verticalLine import ( "context" "fmt" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" @@ -13,9 +14,7 @@ import ( var UnsupportedError = fmt.Errorf("must build w/ cairo support") -type verticalLine struct { - interfaces.FunctionBase -} +type verticalLine struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -33,7 +32,7 @@ func New(_ string) []interfaces.FunctionMetadata { return res } -func (f *verticalLine) Do(_ context.Context, _ parser.Expr, _, _ int64, _ map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *verticalLine) Do(_ context.Context, _ interfaces.Evaluator, _ parser.Expr, _, _ int64, _ map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { return nil, UnsupportedError } diff --git a/expr/functions/verticalLine/function_cairo.go b/expr/functions/verticalLine/function_cairo.go index 3a39f007f..ef870ea21 100644 --- a/expr/functions/verticalLine/function_cairo.go +++ b/expr/functions/verticalLine/function_cairo.go @@ -17,9 +17,7 @@ import ( var TsOutOfRangeError = fmt.Errorf("timestamp out of range") -type verticalLine struct { - interfaces.FunctionBase -} +type verticalLine struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -37,7 +35,7 @@ func New(_ string) []interfaces.FunctionMetadata { return res } -func (f *verticalLine) Do(_ context.Context, e parser.Expr, from, until int64, _ map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *verticalLine) Do(_ context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, _ map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { start, err := e.GetIntervalArg(0, -1) if err != nil { return nil, err diff --git a/expr/functions/verticalLine/function_test.go b/expr/functions/verticalLine/function_test.go index 0fb31101f..c68beaf9c 100644 --- a/expr/functions/verticalLine/function_test.go +++ b/expr/functions/verticalLine/function_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/tags" "github.com/go-graphite/carbonapi/expr/types" @@ -17,11 +17,11 @@ import ( "github.com/stretchr/testify/assert" ) +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -66,7 +66,8 @@ func TestFunction(t *testing.T) { for _, test := range tests { t.Run(test.Target, func(t *testing.T) { - th.TestEvalExprWithRange(t, &test) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithRange(t, eval, &test) }) } } @@ -102,7 +103,8 @@ func TestFunctionErrors(t *testing.T) { for _, test := range tests { t.Run(test.Target, func(t *testing.T) { - th.TestEvalExprWithError(t, &test) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExprWithError(t, eval, &test) }) } } diff --git a/expr/functions/weightedAverage/function.go b/expr/functions/weightedAverage/function.go index 6d55a728e..7203f3a87 100644 --- a/expr/functions/weightedAverage/function.go +++ b/expr/functions/weightedAverage/function.go @@ -11,9 +11,7 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -type weightedAverage struct { - interfaces.FunctionBase -} +type weightedAverage struct{} func GetOrder() interfaces.Order { return interfaces.Any @@ -30,7 +28,7 @@ func New(configFile string) []interfaces.FunctionMetadata { } // weightedAverage(seriesListAvg, seriesListWeight, *nodes) -func (f *weightedAverage) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func (f *weightedAverage) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if e.ArgsLen() < 2 { return nil, parser.ErrMissingArgument } @@ -38,12 +36,12 @@ func (f *weightedAverage) Do(ctx context.Context, e parser.Expr, from, until int aggKeyPairs := make(map[string]map[string]*types.MetricData) var productList []*types.MetricData - avgs, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) + avgs, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } - weights, err := helper.GetSeriesArg(ctx, e.Arg(1), from, until, values) + weights, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) if err != nil { return nil, err } diff --git a/expr/functions/weightedAverage/function_test.go b/expr/functions/weightedAverage/function_test.go index 6f5bbde6e..f906f4d72 100644 --- a/expr/functions/weightedAverage/function_test.go +++ b/expr/functions/weightedAverage/function_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" + "github.com/go-graphite/carbonapi/expr/interfaces" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" @@ -15,11 +15,11 @@ import ( var None = math.NaN() +var ( + md []interfaces.FunctionMetadata = New("") +) + func init() { - md := New("") - evaluator := th.EvaluatorFromFunc(md[0].F) - metadata.SetEvaluator(evaluator) - helper.SetEvaluator(evaluator) for _, m := range md { metadata.RegisterFunction(m.Name, m.F) } @@ -90,7 +90,8 @@ func TestWeightedAverage(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestEvalExpr(t, &tt) + eval := th.EvaluatorFromFunc(md[0].F) + th.TestEvalExpr(t, eval, &tt) }) } @@ -146,7 +147,7 @@ func BenchmarkWeightedAverage(b *testing.B) { }, } - evaluator := metadata.GetEvaluator() + eval := th.EvaluatorFromFunc(md[0].F) for _, bm := range benchmarks { b.Run(bm.target, func(b *testing.B) { @@ -158,7 +159,7 @@ func BenchmarkWeightedAverage(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - g, err := evaluator.Eval(context.Background(), exp, 0, 1, bm.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) if err != nil { b.Fatalf("failed to eval %s: %+v", bm.target, err) } diff --git a/expr/helper/helper.go b/expr/helper/helper.go index 925c9f2c9..af7444425 100644 --- a/expr/helper/helper.go +++ b/expr/helper/helper.go @@ -12,8 +12,6 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -var evaluator interfaces.Evaluator - // Backref is a pre-compiled expression for backref var Backref = regexp.MustCompile(`\\(\d+)`) @@ -24,18 +22,13 @@ func (e ErrUnknownFunction) Error() string { return fmt.Sprintf("unknown function in evalExpr: %q", string(e)) } -// SetEvaluator sets evaluator for all helper functions -func SetEvaluator(e interfaces.Evaluator) { - evaluator = e -} - // GetSeriesArg returns argument from series. -func GetSeriesArg(ctx context.Context, arg parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func GetSeriesArg(ctx context.Context, eval interfaces.Evaluator, arg parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if !arg.IsName() && !arg.IsFunc() { return nil, parser.ErrMissingTimeseries } - a, err := evaluator.Eval(ctx, arg, from, until, values) + a, err := eval.Eval(ctx, arg, from, until, values) if err != nil { return nil, err } @@ -54,11 +47,11 @@ func RemoveEmptySeriesFromName(args []*types.MetricData) string { } // GetSeriesArgs returns arguments of series -func GetSeriesArgs(ctx context.Context, e []parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { +func GetSeriesArgs(ctx context.Context, eval interfaces.Evaluator, e []parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { var args []*types.MetricData for _, arg := range e { - a, err := GetSeriesArg(ctx, arg, from, until, values) + a, err := GetSeriesArg(ctx, eval, arg, from, until, values) if err != nil { return nil, err } @@ -74,8 +67,8 @@ func GetSeriesArgs(ctx context.Context, e []parser.Expr, from, until int64, valu // GetSeriesArgsAndRemoveNonExisting will fetch all required arguments, but will also filter out non existing Series // This is needed to be graphite-web compatible in cases when you pass non-existing Series to, for example, sumSeries -func GetSeriesArgsAndRemoveNonExisting(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { - args, err := GetSeriesArgs(ctx, e.Args(), from, until, values) +func GetSeriesArgsAndRemoveNonExisting(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + args, err := GetSeriesArgs(ctx, eval, e.Args(), from, until, values) if err != nil { return nil, err } @@ -118,8 +111,8 @@ func AggKey(arg *types.MetricData, nodesOrTags []parser.NodeOrTag) string { type seriesFunc1 func(*types.MetricData) *types.MetricData // ForEachSeriesDo do action for each serie in list. -func ForEachSeriesDo1(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData, function seriesFunc1) ([]*types.MetricData, error) { - arg, err := GetSeriesArg(ctx, e.Arg(0), from, until, values) +func ForEachSeriesDo1(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData, function seriesFunc1) ([]*types.MetricData, error) { + arg, err := GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } @@ -135,8 +128,8 @@ func ForEachSeriesDo1(ctx context.Context, e parser.Expr, from, until int64, val type seriesFunc func(*types.MetricData, *types.MetricData) *types.MetricData // ForEachSeriesDo do action for each serie in list. -func ForEachSeriesDo(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData, function seriesFunc) ([]*types.MetricData, error) { - arg, err := GetSeriesArg(ctx, e.Arg(0), from, until, values) +func ForEachSeriesDo(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData, function seriesFunc) ([]*types.MetricData, error) { + arg, err := GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return nil, err } diff --git a/expr/interfaces/interface.go b/expr/interfaces/interface.go index ef03f6dbc..0eb8cf84b 100644 --- a/expr/interfaces/interface.go +++ b/expr/interfaces/interface.go @@ -7,21 +7,6 @@ import ( "github.com/go-graphite/carbonapi/pkg/parser" ) -// FunctionBase is a set of base methods that partly satisfy Function interface and most probably nobody will modify -type FunctionBase struct { - Evaluator Evaluator -} - -// SetEvaluator sets evaluator -func (b *FunctionBase) SetEvaluator(evaluator Evaluator) { - b.Evaluator = evaluator -} - -// GetEvaluator returns evaluator -func (b *FunctionBase) GetEvaluator() Evaluator { - return b.Evaluator -} - // Evaluator is an interface for any existing expression parser. type Evaluator interface { // Fetch populates the values map being passed into it by translating input expressions into a series of @@ -56,16 +41,12 @@ type FunctionMetadata struct { // Function is interface that all graphite functions should follow type Function interface { - SetEvaluator(evaluator Evaluator) - GetEvaluator() Evaluator - Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) + Do(ctx context.Context, evaluator Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) Description() map[string]types.FunctionDescription } // RewriteFunction is interface that graphite functions that rewrite expressions should follow type RewriteFunction interface { - SetEvaluator(evaluator Evaluator) - GetEvaluator() Evaluator - Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (bool, []string, error) + Do(ctx context.Context, evaluator Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (bool, []string, error) Description() map[string]types.FunctionDescription } diff --git a/expr/metadata/metadata.go b/expr/metadata/metadata.go index 5c62bc092..fe9780331 100644 --- a/expr/metadata/metadata.go +++ b/expr/metadata/metadata.go @@ -13,7 +13,7 @@ import ( func RegisterRewriteFunctionWithFilename(name, filename string, function interfaces.RewriteFunction) { FunctionMD.Lock() defer FunctionMD.Unlock() - function.SetEvaluator(FunctionMD.evaluator) + if _, ok := FunctionMD.RewriteFunctions[name]; ok { n := FunctionMD.RewriteFunctionsFilenames[name] logger := zapwriter.Logger("registerRewriteFunction") @@ -58,7 +58,6 @@ func RegisterRewriteFunction(name string, function interfaces.RewriteFunction) { func RegisterFunctionWithFilename(name, filename string, function interfaces.Function) { FunctionMD.Lock() defer FunctionMD.Unlock() - function.SetEvaluator(FunctionMD.evaluator) if _, ok := FunctionMD.Functions[name]; ok { n := FunctionMD.FunctionsFilenames[name] @@ -100,29 +99,6 @@ func RegisterFunction(name string, function interfaces.Function) { RegisterFunctionWithFilename(name, "", function) } -// SetEvaluator sets new evaluator function to be default for everything that needs it -func SetEvaluator(evaluator interfaces.Evaluator) { - FunctionMD.Lock() - defer FunctionMD.Unlock() - - FunctionMD.evaluator = evaluator - for _, v := range FunctionMD.Functions { - v.SetEvaluator(evaluator) - } - - for _, v := range FunctionMD.RewriteFunctions { - v.SetEvaluator(evaluator) - } -} - -// GetEvaluator returns evaluator -func GetEvaluator() interfaces.Evaluator { - FunctionMD.RLock() - defer FunctionMD.RUnlock() - - return FunctionMD.evaluator -} - // Metadata is a type to store global function metadata type Metadata struct { sync.RWMutex diff --git a/expr/rewrite/aboveSeries/function.go b/expr/rewrite/aboveSeries/function.go index c197656ab..656c4688a 100644 --- a/expr/rewrite/aboveSeries/function.go +++ b/expr/rewrite/aboveSeries/function.go @@ -13,7 +13,7 @@ import ( ) type aboveSeries struct { - interfaces.FunctionBase + interfaces.Function } func GetOrder() interfaces.Order { @@ -30,8 +30,8 @@ func New(configFile string) []interfaces.RewriteFunctionMetadata { return res } -func (f *aboveSeries) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (bool, []string, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *aboveSeries) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (bool, []string, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return false, nil, err } diff --git a/expr/rewrite/aboveSeries/function_test.go b/expr/rewrite/aboveSeries/function_test.go index d61f105d7..b0b1426d3 100644 --- a/expr/rewrite/aboveSeries/function_test.go +++ b/expr/rewrite/aboveSeries/function_test.go @@ -4,8 +4,7 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" - + "github.com/go-graphite/carbonapi/expr" "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" @@ -13,10 +12,6 @@ import ( ) func init() { - evaluator := th.DummyEvaluator() - helper.SetEvaluator(evaluator) - metadata.SetEvaluator(evaluator) - md := New("") for _, m := range md { metadata.RegisterRewriteFunction(m.Name, m.F) @@ -76,7 +71,12 @@ func TestDiffSeries(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestRewriteExpr(t, &tt) + eval, err := expr.NewEvaluator(nil, th.NewTestZipper(nil)) + if err == nil { + th.TestRewriteExpr(t, eval, &tt) + } else { + t.Errorf("error='%v'", err) + } }) } diff --git a/expr/rewrite/applyByNode/function.go b/expr/rewrite/applyByNode/function.go index 73c0acc04..2b4379935 100644 --- a/expr/rewrite/applyByNode/function.go +++ b/expr/rewrite/applyByNode/function.go @@ -16,7 +16,7 @@ func GetOrder() interfaces.Order { } type applyByNode struct { - interfaces.FunctionBase + interfaces.Function } func New(configFile string) []interfaces.RewriteFunctionMetadata { @@ -28,8 +28,8 @@ func New(configFile string) []interfaces.RewriteFunctionMetadata { return res } -func (f *applyByNode) Do(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (bool, []string, error) { - args, err := helper.GetSeriesArg(ctx, e.Arg(0), from, until, values) +func (f *applyByNode) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (bool, []string, error) { + args, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) if err != nil { return false, nil, err } diff --git a/expr/rewrite/applyByNode/function_test.go b/expr/rewrite/applyByNode/function_test.go index f60ee5819..842a44179 100644 --- a/expr/rewrite/applyByNode/function_test.go +++ b/expr/rewrite/applyByNode/function_test.go @@ -4,8 +4,6 @@ import ( "testing" "time" - "github.com/go-graphite/carbonapi/expr/helper" - "github.com/go-graphite/carbonapi/expr/metadata" "github.com/go-graphite/carbonapi/expr/types" "github.com/go-graphite/carbonapi/pkg/parser" @@ -13,10 +11,6 @@ import ( ) func init() { - evaluator := th.DummyEvaluator() - helper.SetEvaluator(evaluator) - metadata.SetEvaluator(evaluator) - md := New("") for _, m := range md { metadata.RegisterRewriteFunction(m.Name, m.F) @@ -61,7 +55,8 @@ func TestApplyByNode(t *testing.T) { for _, tt := range tests { testName := tt.Target t.Run(testName, func(t *testing.T) { - th.TestRewriteExpr(t, &tt) + eval := th.DummyEvaluator() + th.TestRewriteExpr(t, eval, &tt) }) } diff --git a/expr/types/types.go b/expr/types/types.go index 3f5fb764c..ca30bea52 100644 --- a/expr/types/types.go +++ b/expr/types/types.go @@ -690,6 +690,12 @@ func (r *MetricData) SetTags(tags map[string]string) *MetricData { return r } +// SetPathExpression set path expression +func (r *MetricData) SetPathExpression(path string) *MetricData { + r.PathExpression = path + return r +} + // RecalcStopTime recalc StopTime with StartTime and Values length func (r *MetricData) RecalcStopTime() *MetricData { stop := r.StartTime + int64(len(r.Values))*r.StepTime diff --git a/tests/helper.go b/tests/helper.go index f398be550..e4b062738 100644 --- a/tests/helper.go +++ b/tests/helper.go @@ -3,11 +3,11 @@ package tests import ( "context" "fmt" - "reflect" "testing" "time" "github.com/ansel1/merry" + zipperTypes "github.com/go-graphite/carbonapi/zipper/types" pb "github.com/go-graphite/protocol/carbonapi_v3_pb" "github.com/go-graphite/carbonapi/expr/helper" @@ -19,7 +19,7 @@ import ( ) type FuncEvaluator struct { - eval func(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) + eval func(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) } func (evaluator *FuncEvaluator) Fetch(_ context.Context, _ []parser.Expr, _, _ int64, values map[parser.MetricRequest][]*types.MetricData) (map[parser.MetricRequest][]*types.MetricData, error) { @@ -47,7 +47,7 @@ func (evaluator *FuncEvaluator) Eval(ctx context.Context, e parser.Expr, from, u } if evaluator.eval != nil { - return evaluator.eval(context.Background(), e, from, until, values) + return evaluator.eval(context.Background(), evaluator, e, from, until, values) } return nil, helper.ErrUnknownFunction(e.Target()) @@ -71,9 +71,9 @@ func EvaluatorFromFunc(function interfaces.Function) interfaces.Evaluator { func EvaluatorFromFuncWithMetadata(metadata map[string]interfaces.Function) interfaces.Evaluator { e := &FuncEvaluator{ - eval: func(ctx context.Context, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { + eval: func(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { if f, ok := metadata[e.Target()]; ok { - return f.Do(context.Background(), e, from, until, values) + return f.Do(context.Background(), eval, e, from, until, values) } return nil, fmt.Errorf("unknown function: %v", e.Target()) }, @@ -185,13 +185,11 @@ func InitTestSummarize() (int64, int64, int64) { return tenThirtyTwo, tenFiftyNine, tenThirty } -func TestSummarizeEvalExpr(t *testing.T, tt *SummarizeEvalTestItem) { - evaluator := metadata.GetEvaluator() - +func TestSummarizeEvalExpr(t *testing.T, eval interfaces.Evaluator, tt *SummarizeEvalTestItem) { t.Run(tt.Name, func(t *testing.T) { originalMetrics := DeepClone(tt.M) exp, _, _ := parser.ParseExpr(tt.Target) - g, err := evaluator.Eval(context.Background(), exp, tt.From, tt.Until, tt.M) + g, err := eval.Eval(context.Background(), exp, tt.From, tt.Until, tt.M) if err != nil { t.Errorf("failed to eval %v: %+v", tt.Name, err) return @@ -226,16 +224,14 @@ type MultiReturnEvalTestItem struct { Results map[string][]*types.MetricData } -func TestMultiReturnEvalExpr(t *testing.T, tt *MultiReturnEvalTestItem) { - evaluator := metadata.GetEvaluator() - +func TestMultiReturnEvalExpr(t *testing.T, eval interfaces.Evaluator, tt *MultiReturnEvalTestItem) { originalMetrics := DeepClone(tt.M) exp, _, err := parser.ParseExpr(tt.Target) if err != nil { t.Errorf("failed to parse %v: %+v", tt.Target, err) return } - g, err := evaluator.Eval(context.Background(), exp, 0, 1, tt.M) + g, err := eval.Eval(context.Background(), exp, 0, 1, tt.M) if err != nil { t.Errorf("failed to eval %v: %+v", tt.Name, err) return @@ -286,7 +282,7 @@ func TestMultiReturnEvalExpr(t *testing.T, tt *MultiReturnEvalTestItem) { } } - if !reflect.DeepEqual(wants[0].Values, actual.Values) || + if !compare.NearlyEqual(wants[0].Values, actual.Values) || wants[0].StartTime != actual.StartTime || wants[0].StopTime != actual.StopTime || wants[0].StepTime != actual.StepTime { @@ -315,19 +311,19 @@ type RewriteTestError struct { Want error } -func rewriteExpr(e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (bool, []string, error) { +func rewriteExpr(e parser.Expr, eval interfaces.Evaluator, from, until int64, values map[parser.MetricRequest][]*types.MetricData) (bool, []string, error) { if e.IsFunc() { metadata.FunctionMD.RLock() f, ok := metadata.FunctionMD.RewriteFunctions[e.Target()] metadata.FunctionMD.RUnlock() if ok { - return f.Do(context.Background(), e, from, until, values) + return f.Do(context.Background(), eval, e, from, until, values) } } return false, nil, nil } -func TestRewriteExpr(t *testing.T, tt *RewriteTestItem) { +func TestRewriteExpr(t *testing.T, eval interfaces.Evaluator, tt *RewriteTestItem) { originalMetrics := DeepClone(tt.M) testName := tt.Target exp, _, err := parser.ParseExpr(tt.Target) @@ -335,7 +331,7 @@ func TestRewriteExpr(t *testing.T, tt *RewriteTestItem) { t.Fatalf("failed to parse %s: %+v", tt.Target, err) } - rewritten, targets, err := rewriteExpr(exp, 0, 1, tt.M) + rewritten, targets, err := rewriteExpr(exp, eval, 0, 1, tt.M) if err != tt.Want.Err { if err == nil || tt.Want.Err == nil || !merry.Is(err, tt.Want.Err) { t.Fatalf("unexpected error while calling rewrite for '%s': got '%+v', expected '%+v'", testName, err, tt.Want.Err) @@ -396,28 +392,26 @@ func (r *EvalTestItemWithRange) TestItem() *EvalTestItem { } } -func TestEvalExprWithCustomValidation(t *testing.T, tt *EvalTestItemWithCustomValidation) { - evaluator := metadata.GetEvaluator() +func TestEvalExprWithCustomValidation(t *testing.T, eval interfaces.Evaluator, tt *EvalTestItemWithCustomValidation) { exp, _, err := parser.ParseExpr(tt.Target) if err != nil { t.Errorf("failed to parse %s: %+v", tt.Target, err) } - g, err := evaluator.Eval(context.Background(), exp, tt.From, tt.Until, tt.M) + g, err := eval.Eval(context.Background(), exp, tt.From, tt.Until, tt.M) if err != nil { t.Errorf("failed to eval %s: %+v", tt.Target, err) } tt.Validator(t, g) } -func TestEvalExprModifiedOrigin(t *testing.T, tt *EvalTestItem, from, until int64, strictOrder, compareTags bool) error { - evaluator := metadata.GetEvaluator() +func TestEvalExprModifiedOrigin(t *testing.T, eval interfaces.Evaluator, tt *EvalTestItem, from, until int64, strictOrder, compareTags bool) error { testName := tt.Target exp, _, err := parser.ParseExpr(tt.Target) if err != nil { t.Errorf("failed to parse %s: %+v", tt.Target, err) return nil } - g, err := evaluator.Eval(context.Background(), exp, from, until, tt.M) + g, err := eval.Eval(context.Background(), exp, from, until, tt.M) if err != nil { return err } @@ -475,13 +469,13 @@ func TestEvalExprModifiedOrigin(t *testing.T, tt *EvalTestItem, from, until int6 return nil } -func TestEvalExpr(t *testing.T, tt *EvalTestItem) { - TestEvalExprWithOptions(t, tt, true) +func TestEvalExpr(t *testing.T, eval interfaces.Evaluator, tt *EvalTestItem) { + TestEvalExprWithOptions(t, eval, tt, true) } -func TestEvalExprWithOptions(t *testing.T, tt *EvalTestItem, compareTags bool) { +func TestEvalExprWithOptions(t *testing.T, eval interfaces.Evaluator, tt *EvalTestItem, compareTags bool) { originalMetrics := DeepClone(tt.M) - err := TestEvalExprModifiedOrigin(t, tt, 0, 1, false, compareTags) + err := TestEvalExprModifiedOrigin(t, eval, tt, 0, 1, false, compareTags) if err != nil { t.Errorf("unexpected error while evaluating %s: got `%+v`", tt.Target, err) return @@ -489,8 +483,8 @@ func TestEvalExprWithOptions(t *testing.T, tt *EvalTestItem, compareTags bool) { DeepEqual(t, tt.Target, originalMetrics, tt.M, true) } -func TestEvalExprResult(t *testing.T, tt *EvalTestItem) { - err := TestEvalExprModifiedOrigin(t, tt, 0, 1, false, true) +func TestEvalExprResult(t *testing.T, eval interfaces.Evaluator, tt *EvalTestItem) { + err := TestEvalExprModifiedOrigin(t, eval, tt, 0, 1, false, true) if err != nil { t.Errorf("unexpected error while evaluating %s: got `%+v`", tt.Target, err) return @@ -498,10 +492,10 @@ func TestEvalExprResult(t *testing.T, tt *EvalTestItem) { // } -func TestEvalExprWithRange(t *testing.T, tt *EvalTestItemWithRange) { +func TestEvalExprWithRange(t *testing.T, eval interfaces.Evaluator, tt *EvalTestItemWithRange) { originalMetrics := DeepClone(tt.M) tt2 := tt.TestItem() - err := TestEvalExprModifiedOrigin(t, tt2, tt.From, tt.Until, false, true) + err := TestEvalExprModifiedOrigin(t, eval, tt2, tt.From, tt.Until, false, true) if err != nil { t.Errorf("unexpected error while evaluating %s: got `%+v`", tt.Target, err) return @@ -509,14 +503,14 @@ func TestEvalExprWithRange(t *testing.T, tt *EvalTestItemWithRange) { DeepEqual(t, tt.Target, originalMetrics, tt.M, true) } -func TestEvalExprWithError(t *testing.T, tt *EvalTestItemWithError) { +func TestEvalExprWithError(t *testing.T, eval interfaces.Evaluator, tt *EvalTestItemWithError) { originalMetrics := DeepClone(tt.M) tt2 := &EvalTestItem{ Target: tt.Target, M: tt.M, Want: tt.Want, } - err := TestEvalExprModifiedOrigin(t, tt2, 0, 1, false, true) + err := TestEvalExprModifiedOrigin(t, eval, tt2, 0, 1, false, true) if !merry.Is(err, tt.Error) { t.Errorf("unexpected error while evaluating %s: got `%+v`, expected `%+v`", tt.Target, err, tt.Error) return @@ -524,12 +518,62 @@ func TestEvalExprWithError(t *testing.T, tt *EvalTestItemWithError) { DeepEqual(t, tt.Target, originalMetrics, tt.M, true) } -func TestEvalExprOrdered(t *testing.T, tt *EvalTestItem) { +func TestEvalExprOrdered(t *testing.T, eval interfaces.Evaluator, tt *EvalTestItem) { originalMetrics := DeepClone(tt.M) - err := TestEvalExprModifiedOrigin(t, tt, 0, 1, true, true) + err := TestEvalExprModifiedOrigin(t, eval, tt, 0, 1, true, true) if err != nil { t.Errorf("unexpected error while evaluating %s: got `%+v`", tt.Target, err) return } DeepEqual(t, tt.Target, originalMetrics, tt.M, true) } + +type TestZipper struct { + M map[parser.MetricRequest][]*types.MetricData +} + +func NewTestZipper(m map[parser.MetricRequest][]*types.MetricData) TestZipper { + return TestZipper{M: m} +} + +func (zp TestZipper) Find(ctx context.Context, request pb.MultiGlobRequest) (*pb.MultiGlobResponse, *zipperTypes.Stats, merry.Error) { + return nil, nil, zipperTypes.ErrNotImplementedYet +} + +func (zp TestZipper) Info(ctx context.Context, metrics []string) (*pb.ZipperInfoResponse, *zipperTypes.Stats, merry.Error) { + return nil, nil, zipperTypes.ErrNotImplementedYet +} + +func (zp TestZipper) RenderCompat(ctx context.Context, metrics []string, from, until int64) ([]*types.MetricData, *zipperTypes.Stats, merry.Error) { + return nil, nil, zipperTypes.ErrNotImplementedYet +} + +func (zp TestZipper) Render(ctx context.Context, request pb.MultiFetchRequest) ([]*types.MetricData, *zipperTypes.Stats, merry.Error) { + var resp []*types.MetricData + for _, r := range request.Metrics { + metricRequest := parser.MetricRequest{Metric: r.PathExpression, From: r.StartTime, Until: r.StopTime} + if v, ok := zp.M[metricRequest]; ok { + resp = append(resp, v...) + } + } + return resp, nil, nil +} + +func (zp TestZipper) TagNames(ctx context.Context, query string, limit int64) ([]string, merry.Error) { + return nil, zipperTypes.ErrNotImplementedYet +} + +func (zp TestZipper) TagValues(ctx context.Context, query string, limit int64) ([]string, merry.Error) { + return nil, zipperTypes.ErrNotImplementedYet +} + +func (zp TestZipper) ScaleToCommonStep() bool { + return false +} + +func GenerateValues(start, stop, step int64) (values []float64) { + for i := start; i < stop; i += step { + values = append(values, float64(i)) + } + return +} diff --git a/cmd/carbonapi/interfaces/zipper.go b/zipper/interfaces/zipper.go similarity index 100% rename from cmd/carbonapi/interfaces/zipper.go rename to zipper/interfaces/zipper.go