github.com/go-graphite/carbonapi@v0.17.0/expr/functions/delay/function.go (about) 1 package delay 2 3 import ( 4 "context" 5 "math" 6 7 "github.com/go-graphite/carbonapi/expr/helper" 8 "github.com/go-graphite/carbonapi/expr/interfaces" 9 "github.com/go-graphite/carbonapi/expr/types" 10 "github.com/go-graphite/carbonapi/pkg/parser" 11 ) 12 13 type delay struct{} 14 15 func GetOrder() interfaces.Order { 16 return interfaces.Any 17 } 18 19 func New(configFile string) []interfaces.FunctionMetadata { 20 res := make([]interfaces.FunctionMetadata, 0) 21 f := &delay{} 22 functions := []string{"delay"} 23 for _, n := range functions { 24 res = append(res, interfaces.FunctionMetadata{Name: n, F: f}) 25 } 26 return res 27 } 28 29 // delay(seriesList, steps) 30 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) { 31 if e.ArgsLen() < 2 { 32 return nil, parser.ErrMissingArgument 33 } 34 35 seriesList, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) 36 if err != nil { 37 return nil, err 38 } 39 40 steps, err := e.GetIntArg(1) 41 if err != nil { 42 return nil, err 43 } 44 stepsStr := e.Arg(1).StringValue() 45 46 results := make([]*types.MetricData, len(seriesList)) 47 48 for i, series := range seriesList { 49 length := len(series.Values) 50 51 result := series.CopyLink() 52 result.Name = "delay(" + series.Name + "," + stepsStr + ")" 53 result.Tags["delay"] = stepsStr 54 55 var newValues []float64 56 if steps < 0 { 57 newValues = make([]float64, length) 58 copy(newValues, series.Values[-steps:]) 59 for i := -steps; i < length; i++ { 60 newValues[i] = math.NaN() 61 } 62 result.Values = newValues 63 } else if steps != 0 { 64 newValues = make([]float64, length) 65 for i := 0; i < steps; i++ { 66 newValues[i] = math.NaN() 67 } 68 copy(newValues[steps:], series.Values[:length-steps]) 69 result.Values = newValues 70 } 71 72 results[i] = result 73 } 74 75 return results, nil 76 } 77 78 // Description is auto-generated description, based on output of https://github.com/graphite-project/graphite-web 79 func (f *delay) Description() map[string]types.FunctionDescription { 80 return map[string]types.FunctionDescription{ 81 "delay": { 82 Description: "This shifts all samples later by an integer number of steps. This can be\nused for custom derivative calculations, among other things. Note: this\nwill pad the early end of the data with None for every step shifted.\n\nThis complements other time-displacement functions such as timeShift and\ntimeSlice, in that this function is indifferent about the step intervals\nbeing shifted.\n\nExample:\n\n.. code-block:: none\n\n &target=divideSeries(server.FreeSpace,delay(server.FreeSpace,1))\n\nThis computes the change in server free space as a percentage of the previous\nfree space.", 83 Function: "delay(seriesList, steps)", 84 Group: "Transform", 85 Module: "graphite.render.functions", 86 Name: "delay", 87 Params: []types.FunctionParam{ 88 { 89 Name: "seriesList", 90 Required: true, 91 Type: types.SeriesList, 92 }, 93 { 94 Name: "steps", 95 Required: true, 96 Type: types.Integer, 97 }, 98 }, 99 NameChange: true, // name changed 100 ValuesChange: true, // values changed 101 }, 102 } 103 }