github.com/influxdata/influxdb/v2@v2.7.6/influxql/query/functions.gen.go.tmpl (about) 1 package query 2 3 import ( 4 "encoding/binary" 5 "bytes" 6 "sort" 7 "time" 8 "math/rand" 9 10 "github.com/influxdata/influxdb/v2/pkg/estimator/hll" 11 ) 12 13 {{with $types := .}}{{range $k := $types}} 14 15 // {{$k.Name}}PointAggregator aggregates points to produce a single point. 16 type {{$k.Name}}PointAggregator interface { 17 Aggregate{{$k.Name}}(p *{{$k.Name}}Point) 18 } 19 20 // {{$k.Name}}BulkPointAggregator aggregates multiple points at a time. 21 type {{$k.Name}}BulkPointAggregator interface { 22 Aggregate{{$k.Name}}Bulk(points []{{$k.Name}}Point) 23 } 24 25 // {{$k.Name}}PointEmitter produces a single point from an aggregate. 26 type {{$k.Name}}PointEmitter interface { 27 Emit() []{{$k.Name}}Point 28 } 29 30 {{range $v := $types}} 31 32 // {{$k.Name}}Reduce{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Func is the function called by a {{$k.Name}}Point reducer. 33 type {{$k.Name}}Reduce{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Func func(prev *{{$v.Name}}Point, curr *{{$k.Name}}Point) (t int64, v {{$v.Type}}, aux []interface{}) 34 35 // {{$k.Name}}Func{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer is a reducer that reduces 36 // the passed in points to a single point using a reduce function. 37 type {{$k.Name}}Func{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer struct { 38 prev *{{$v.Name}}Point 39 fn {{$k.Name}}Reduce{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Func 40 } 41 42 // New{{$k.Name}}Func{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer creates a new {{$k.Name}}Func{{$v.Name}}Reducer. 43 func New{{$k.Name}}Func{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer(fn {{$k.Name}}Reduce{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Func, prev *{{$v.Name}}Point) *{{$k.Name}}Func{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer { 44 return &{{$k.Name}}Func{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer{fn: fn, prev: prev} 45 } 46 47 // Aggregate{{$k.Name}} takes a {{$k.Name}}Point and invokes the reduce function with the 48 // current and new point to modify the current point. 49 func (r *{{$k.Name}}Func{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer) Aggregate{{$k.Name}}(p *{{$k.Name}}Point) { 50 t, v, aux := r.fn(r.prev, p) 51 if r.prev == nil { 52 r.prev = &{{$v.Name}}Point{} 53 } 54 r.prev.Time = t 55 r.prev.Value = v 56 r.prev.Aux = aux 57 if p.Aggregated > 1 { 58 r.prev.Aggregated += p.Aggregated 59 } else { 60 r.prev.Aggregated++ 61 } 62 } 63 64 // Emit emits the point that was generated when reducing the points fed in with Aggregate{{$k.Name}}. 65 func (r *{{$k.Name}}Func{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer) Emit() []{{$v.Name}}Point { 66 return []{{$v.Name}}Point{*r.prev} 67 } 68 69 // {{$k.Name}}Reduce{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}SliceFunc is the function called by a {{$k.Name}}Point reducer. 70 type {{$k.Name}}Reduce{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}SliceFunc func(a []{{$k.Name}}Point) []{{$v.Name}}Point 71 72 // {{$k.Name}}SliceFunc{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer is a reducer that aggregates 73 // the passed in points and then invokes the function to reduce the points when they are emitted. 74 type {{$k.Name}}SliceFunc{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer struct { 75 points []{{$k.Name}}Point 76 fn {{$k.Name}}Reduce{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}SliceFunc 77 } 78 79 // New{{$k.Name}}SliceFunc{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer creates a new {{$k.Name}}SliceFunc{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer. 80 func New{{$k.Name}}SliceFunc{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer(fn {{$k.Name}}Reduce{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}SliceFunc) *{{$k.Name}}SliceFunc{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer { 81 return &{{$k.Name}}SliceFunc{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer{fn: fn} 82 } 83 84 // Aggregate{{$k.Name}} copies the {{$k.Name}}Point into the internal slice to be passed 85 // to the reduce function when Emit is called. 86 func (r *{{$k.Name}}SliceFunc{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer) Aggregate{{$k.Name}}(p *{{$k.Name}}Point) { 87 r.points = append(r.points, *p.Clone()) 88 } 89 90 // Aggregate{{$k.Name}}Bulk performs a bulk copy of {{$k.Name}}Points into the internal slice. 91 // This is a more efficient version of calling Aggregate{{$k.Name}} on each point. 92 func (r *{{$k.Name}}SliceFunc{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer) Aggregate{{$k.Name}}Bulk(points []{{$k.Name}}Point) { 93 r.points = append(r.points, points...) 94 } 95 96 // Emit invokes the reduce function on the aggregated points to generate the aggregated points. 97 // This method does not clear the points from the internal slice. 98 func (r *{{$k.Name}}SliceFunc{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}Reducer) Emit() []{{$v.Name}}Point { 99 return r.fn(r.points) 100 } 101 {{end}} 102 103 // {{$k.Name}}SumHllReducer returns the HLL sketch for a series, in string form 104 type {{$k.Name}}SumHllReducer struct { 105 plus *hll.Plus 106 } 107 108 // func New{{$k.Name}}SumHllReducer creates a new {{$k.Name}}SumHllReducer 109 func New{{$k.Name}}SumHllReducer() *{{$k.Name}}SumHllReducer { 110 return &{{$k.Name}}SumHllReducer{plus:hll.NewDefaultPlus()} 111 } 112 113 // Aggregate{{$k.Name}} aggregates a point into the reducer. 114 func (r *{{$k.Name}}SumHllReducer) Aggregate{{$k.Name}}(p *{{$k.Name}}Point) { 115 {{if eq $k.Type "string"}} 116 b := []byte(p.Value) 117 {{else}} 118 buf := new(bytes.Buffer) 119 binary.Write(buf, binary.BigEndian, p.Value) 120 b := buf.Bytes() 121 {{end}} 122 r.plus.Add(b) 123 } 124 125 // Emit emits the distinct points that have been aggregated into the reducer. 126 func (r *{{$k.Name}}SumHllReducer) Emit() []StringPoint { 127 return []StringPoint{ 128 marshalPlus(r.plus, nil), 129 } 130 } 131 132 // {{$k.Name}}DistinctReducer returns the distinct points in a series. 133 type {{$k.Name}}DistinctReducer struct { 134 m map[{{$k.Type}}]{{$k.Name}}Point 135 } 136 137 // New{{$k.Name}}DistinctReducer creates a new {{$k.Name}}DistinctReducer. 138 func New{{$k.Name}}DistinctReducer() *{{$k.Name}}DistinctReducer { 139 return &{{$k.Name}}DistinctReducer{m: make(map[{{$k.Type}}]{{$k.Name}}Point)} 140 } 141 142 // Aggregate{{$k.Name}} aggregates a point into the reducer. 143 func (r *{{$k.Name}}DistinctReducer) Aggregate{{$k.Name}}(p *{{$k.Name}}Point) { 144 if _, ok := r.m[p.Value]; !ok { 145 r.m[p.Value] = *p 146 } 147 } 148 149 // Emit emits the distinct points that have been aggregated into the reducer. 150 func (r *{{$k.Name}}DistinctReducer) Emit() []{{$k.Name}}Point { 151 points := make([]{{$k.Name}}Point, 0, len(r.m)) 152 for _, p := range r.m { 153 points = append(points, {{$k.Name}}Point{Time: p.Time, Value: p.Value}) 154 } 155 sort.Sort({{$k.name}}Points(points)) 156 return points 157 } 158 159 // {{$k.Name}}ElapsedReducer calculates the elapsed of the aggregated points. 160 type {{$k.Name}}ElapsedReducer struct { 161 unitConversion int64 162 prev {{$k.Name}}Point 163 curr {{$k.Name}}Point 164 } 165 166 // New{{$k.Name}}ElapsedReducer creates a new {{$k.Name}}ElapsedReducer. 167 func New{{$k.Name}}ElapsedReducer(interval Interval) *{{$k.Name}}ElapsedReducer { 168 return &{{$k.Name}}ElapsedReducer{ 169 unitConversion: int64(interval.Duration), 170 prev: {{$k.Name}}Point{Nil: true}, 171 curr: {{$k.Name}}Point{Nil: true}, 172 } 173 } 174 175 // Aggregate{{$k.Name}} aggregates a point into the reducer and updates the current window. 176 func (r *{{$k.Name}}ElapsedReducer) Aggregate{{$k.Name}}(p *{{$k.Name}}Point) { 177 r.prev = r.curr 178 r.curr = *p 179 } 180 181 // Emit emits the elapsed of the reducer at the current point. 182 func (r *{{$k.Name}}ElapsedReducer) Emit() []IntegerPoint { 183 if !r.prev.Nil { 184 elapsed := (r.curr.Time - r.prev.Time) / r.unitConversion 185 return []IntegerPoint{ 186 {Time: r.curr.Time, Value: elapsed}, 187 } 188 } 189 return nil 190 } 191 192 // {{$k.Name}}SampleReducer implements a reservoir sampling to calculate a random subset of points 193 type {{$k.Name}}SampleReducer struct { 194 count int // how many points we've iterated over 195 rng *rand.Rand // random number generator for each reducer 196 197 points {{$k.name}}Points // the reservoir 198 } 199 200 // New{{$k.Name}}SampleReducer creates a new {{$k.Name}}SampleReducer 201 func New{{$k.Name}}SampleReducer(size int) *{{$k.Name}}SampleReducer { 202 return &{{$k.Name}}SampleReducer{ 203 rng: rand.New(rand.NewSource(time.Now().UnixNano())), // seed with current time as suggested by https://golang.org/pkg/math/rand/ 204 points: make({{$k.name}}Points, size), 205 } 206 } 207 208 // Aggregate{{$k.Name}} aggregates a point into the reducer. 209 func (r *{{$k.Name}}SampleReducer) Aggregate{{$k.Name}}(p *{{$k.Name}}Point) { 210 r.count++ 211 // Fill the reservoir with the first n points 212 if r.count-1 < len(r.points) { 213 p.CopyTo(&r.points[r.count-1]) 214 return 215 } 216 217 // Generate a random integer between 1 and the count and 218 // if that number is less than the length of the slice 219 // replace the point at that index rnd with p. 220 rnd := r.rng.Intn(r.count) 221 if rnd < len(r.points) { 222 p.CopyTo(&r.points[rnd]) 223 } 224 } 225 226 // Emit emits the reservoir sample as many points. 227 func (r *{{$k.Name}}SampleReducer) Emit() []{{$k.Name}}Point { 228 min := len(r.points) 229 if r.count < min { 230 min = r.count 231 } 232 pts := r.points[:min] 233 sort.Sort(pts) 234 return pts 235 } 236 237 238 {{end}}{{end}}