github.com/influxdata/influxdb/v2@v2.7.6/influxql/query/functions.gen.go (about)

     1  // Generated by tmpl
     2  // https://github.com/benbjohnson/tmpl
     3  //
     4  // DO NOT EDIT!
     5  // Source: functions.gen.go.tmpl
     6  
     7  package query
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/binary"
    12  	"math/rand"
    13  	"sort"
    14  	"time"
    15  
    16  	"github.com/influxdata/influxdb/v2/pkg/estimator/hll"
    17  )
    18  
    19  // FloatPointAggregator aggregates points to produce a single point.
    20  type FloatPointAggregator interface {
    21  	AggregateFloat(p *FloatPoint)
    22  }
    23  
    24  // FloatBulkPointAggregator aggregates multiple points at a time.
    25  type FloatBulkPointAggregator interface {
    26  	AggregateFloatBulk(points []FloatPoint)
    27  }
    28  
    29  // FloatPointEmitter produces a single point from an aggregate.
    30  type FloatPointEmitter interface {
    31  	Emit() []FloatPoint
    32  }
    33  
    34  // FloatReduceFunc is the function called by a FloatPoint reducer.
    35  type FloatReduceFunc func(prev *FloatPoint, curr *FloatPoint) (t int64, v float64, aux []interface{})
    36  
    37  // FloatFuncReducer is a reducer that reduces
    38  // the passed in points to a single point using a reduce function.
    39  type FloatFuncReducer struct {
    40  	prev *FloatPoint
    41  	fn   FloatReduceFunc
    42  }
    43  
    44  // NewFloatFuncReducer creates a new FloatFuncFloatReducer.
    45  func NewFloatFuncReducer(fn FloatReduceFunc, prev *FloatPoint) *FloatFuncReducer {
    46  	return &FloatFuncReducer{fn: fn, prev: prev}
    47  }
    48  
    49  // AggregateFloat takes a FloatPoint and invokes the reduce function with the
    50  // current and new point to modify the current point.
    51  func (r *FloatFuncReducer) AggregateFloat(p *FloatPoint) {
    52  	t, v, aux := r.fn(r.prev, p)
    53  	if r.prev == nil {
    54  		r.prev = &FloatPoint{}
    55  	}
    56  	r.prev.Time = t
    57  	r.prev.Value = v
    58  	r.prev.Aux = aux
    59  	if p.Aggregated > 1 {
    60  		r.prev.Aggregated += p.Aggregated
    61  	} else {
    62  		r.prev.Aggregated++
    63  	}
    64  }
    65  
    66  // Emit emits the point that was generated when reducing the points fed in with AggregateFloat.
    67  func (r *FloatFuncReducer) Emit() []FloatPoint {
    68  	return []FloatPoint{*r.prev}
    69  }
    70  
    71  // FloatReduceSliceFunc is the function called by a FloatPoint reducer.
    72  type FloatReduceSliceFunc func(a []FloatPoint) []FloatPoint
    73  
    74  // FloatSliceFuncReducer is a reducer that aggregates
    75  // the passed in points and then invokes the function to reduce the points when they are emitted.
    76  type FloatSliceFuncReducer struct {
    77  	points []FloatPoint
    78  	fn     FloatReduceSliceFunc
    79  }
    80  
    81  // NewFloatSliceFuncReducer creates a new FloatSliceFuncReducer.
    82  func NewFloatSliceFuncReducer(fn FloatReduceSliceFunc) *FloatSliceFuncReducer {
    83  	return &FloatSliceFuncReducer{fn: fn}
    84  }
    85  
    86  // AggregateFloat copies the FloatPoint into the internal slice to be passed
    87  // to the reduce function when Emit is called.
    88  func (r *FloatSliceFuncReducer) AggregateFloat(p *FloatPoint) {
    89  	r.points = append(r.points, *p.Clone())
    90  }
    91  
    92  // AggregateFloatBulk performs a bulk copy of FloatPoints into the internal slice.
    93  // This is a more efficient version of calling AggregateFloat on each point.
    94  func (r *FloatSliceFuncReducer) AggregateFloatBulk(points []FloatPoint) {
    95  	r.points = append(r.points, points...)
    96  }
    97  
    98  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
    99  // This method does not clear the points from the internal slice.
   100  func (r *FloatSliceFuncReducer) Emit() []FloatPoint {
   101  	return r.fn(r.points)
   102  }
   103  
   104  // FloatReduceIntegerFunc is the function called by a FloatPoint reducer.
   105  type FloatReduceIntegerFunc func(prev *IntegerPoint, curr *FloatPoint) (t int64, v int64, aux []interface{})
   106  
   107  // FloatFuncIntegerReducer is a reducer that reduces
   108  // the passed in points to a single point using a reduce function.
   109  type FloatFuncIntegerReducer struct {
   110  	prev *IntegerPoint
   111  	fn   FloatReduceIntegerFunc
   112  }
   113  
   114  // NewFloatFuncIntegerReducer creates a new FloatFuncIntegerReducer.
   115  func NewFloatFuncIntegerReducer(fn FloatReduceIntegerFunc, prev *IntegerPoint) *FloatFuncIntegerReducer {
   116  	return &FloatFuncIntegerReducer{fn: fn, prev: prev}
   117  }
   118  
   119  // AggregateFloat takes a FloatPoint and invokes the reduce function with the
   120  // current and new point to modify the current point.
   121  func (r *FloatFuncIntegerReducer) AggregateFloat(p *FloatPoint) {
   122  	t, v, aux := r.fn(r.prev, p)
   123  	if r.prev == nil {
   124  		r.prev = &IntegerPoint{}
   125  	}
   126  	r.prev.Time = t
   127  	r.prev.Value = v
   128  	r.prev.Aux = aux
   129  	if p.Aggregated > 1 {
   130  		r.prev.Aggregated += p.Aggregated
   131  	} else {
   132  		r.prev.Aggregated++
   133  	}
   134  }
   135  
   136  // Emit emits the point that was generated when reducing the points fed in with AggregateFloat.
   137  func (r *FloatFuncIntegerReducer) Emit() []IntegerPoint {
   138  	return []IntegerPoint{*r.prev}
   139  }
   140  
   141  // FloatReduceIntegerSliceFunc is the function called by a FloatPoint reducer.
   142  type FloatReduceIntegerSliceFunc func(a []FloatPoint) []IntegerPoint
   143  
   144  // FloatSliceFuncIntegerReducer is a reducer that aggregates
   145  // the passed in points and then invokes the function to reduce the points when they are emitted.
   146  type FloatSliceFuncIntegerReducer struct {
   147  	points []FloatPoint
   148  	fn     FloatReduceIntegerSliceFunc
   149  }
   150  
   151  // NewFloatSliceFuncIntegerReducer creates a new FloatSliceFuncIntegerReducer.
   152  func NewFloatSliceFuncIntegerReducer(fn FloatReduceIntegerSliceFunc) *FloatSliceFuncIntegerReducer {
   153  	return &FloatSliceFuncIntegerReducer{fn: fn}
   154  }
   155  
   156  // AggregateFloat copies the FloatPoint into the internal slice to be passed
   157  // to the reduce function when Emit is called.
   158  func (r *FloatSliceFuncIntegerReducer) AggregateFloat(p *FloatPoint) {
   159  	r.points = append(r.points, *p.Clone())
   160  }
   161  
   162  // AggregateFloatBulk performs a bulk copy of FloatPoints into the internal slice.
   163  // This is a more efficient version of calling AggregateFloat on each point.
   164  func (r *FloatSliceFuncIntegerReducer) AggregateFloatBulk(points []FloatPoint) {
   165  	r.points = append(r.points, points...)
   166  }
   167  
   168  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
   169  // This method does not clear the points from the internal slice.
   170  func (r *FloatSliceFuncIntegerReducer) Emit() []IntegerPoint {
   171  	return r.fn(r.points)
   172  }
   173  
   174  // FloatReduceUnsignedFunc is the function called by a FloatPoint reducer.
   175  type FloatReduceUnsignedFunc func(prev *UnsignedPoint, curr *FloatPoint) (t int64, v uint64, aux []interface{})
   176  
   177  // FloatFuncUnsignedReducer is a reducer that reduces
   178  // the passed in points to a single point using a reduce function.
   179  type FloatFuncUnsignedReducer struct {
   180  	prev *UnsignedPoint
   181  	fn   FloatReduceUnsignedFunc
   182  }
   183  
   184  // NewFloatFuncUnsignedReducer creates a new FloatFuncUnsignedReducer.
   185  func NewFloatFuncUnsignedReducer(fn FloatReduceUnsignedFunc, prev *UnsignedPoint) *FloatFuncUnsignedReducer {
   186  	return &FloatFuncUnsignedReducer{fn: fn, prev: prev}
   187  }
   188  
   189  // AggregateFloat takes a FloatPoint and invokes the reduce function with the
   190  // current and new point to modify the current point.
   191  func (r *FloatFuncUnsignedReducer) AggregateFloat(p *FloatPoint) {
   192  	t, v, aux := r.fn(r.prev, p)
   193  	if r.prev == nil {
   194  		r.prev = &UnsignedPoint{}
   195  	}
   196  	r.prev.Time = t
   197  	r.prev.Value = v
   198  	r.prev.Aux = aux
   199  	if p.Aggregated > 1 {
   200  		r.prev.Aggregated += p.Aggregated
   201  	} else {
   202  		r.prev.Aggregated++
   203  	}
   204  }
   205  
   206  // Emit emits the point that was generated when reducing the points fed in with AggregateFloat.
   207  func (r *FloatFuncUnsignedReducer) Emit() []UnsignedPoint {
   208  	return []UnsignedPoint{*r.prev}
   209  }
   210  
   211  // FloatReduceUnsignedSliceFunc is the function called by a FloatPoint reducer.
   212  type FloatReduceUnsignedSliceFunc func(a []FloatPoint) []UnsignedPoint
   213  
   214  // FloatSliceFuncUnsignedReducer is a reducer that aggregates
   215  // the passed in points and then invokes the function to reduce the points when they are emitted.
   216  type FloatSliceFuncUnsignedReducer struct {
   217  	points []FloatPoint
   218  	fn     FloatReduceUnsignedSliceFunc
   219  }
   220  
   221  // NewFloatSliceFuncUnsignedReducer creates a new FloatSliceFuncUnsignedReducer.
   222  func NewFloatSliceFuncUnsignedReducer(fn FloatReduceUnsignedSliceFunc) *FloatSliceFuncUnsignedReducer {
   223  	return &FloatSliceFuncUnsignedReducer{fn: fn}
   224  }
   225  
   226  // AggregateFloat copies the FloatPoint into the internal slice to be passed
   227  // to the reduce function when Emit is called.
   228  func (r *FloatSliceFuncUnsignedReducer) AggregateFloat(p *FloatPoint) {
   229  	r.points = append(r.points, *p.Clone())
   230  }
   231  
   232  // AggregateFloatBulk performs a bulk copy of FloatPoints into the internal slice.
   233  // This is a more efficient version of calling AggregateFloat on each point.
   234  func (r *FloatSliceFuncUnsignedReducer) AggregateFloatBulk(points []FloatPoint) {
   235  	r.points = append(r.points, points...)
   236  }
   237  
   238  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
   239  // This method does not clear the points from the internal slice.
   240  func (r *FloatSliceFuncUnsignedReducer) Emit() []UnsignedPoint {
   241  	return r.fn(r.points)
   242  }
   243  
   244  // FloatReduceStringFunc is the function called by a FloatPoint reducer.
   245  type FloatReduceStringFunc func(prev *StringPoint, curr *FloatPoint) (t int64, v string, aux []interface{})
   246  
   247  // FloatFuncStringReducer is a reducer that reduces
   248  // the passed in points to a single point using a reduce function.
   249  type FloatFuncStringReducer struct {
   250  	prev *StringPoint
   251  	fn   FloatReduceStringFunc
   252  }
   253  
   254  // NewFloatFuncStringReducer creates a new FloatFuncStringReducer.
   255  func NewFloatFuncStringReducer(fn FloatReduceStringFunc, prev *StringPoint) *FloatFuncStringReducer {
   256  	return &FloatFuncStringReducer{fn: fn, prev: prev}
   257  }
   258  
   259  // AggregateFloat takes a FloatPoint and invokes the reduce function with the
   260  // current and new point to modify the current point.
   261  func (r *FloatFuncStringReducer) AggregateFloat(p *FloatPoint) {
   262  	t, v, aux := r.fn(r.prev, p)
   263  	if r.prev == nil {
   264  		r.prev = &StringPoint{}
   265  	}
   266  	r.prev.Time = t
   267  	r.prev.Value = v
   268  	r.prev.Aux = aux
   269  	if p.Aggregated > 1 {
   270  		r.prev.Aggregated += p.Aggregated
   271  	} else {
   272  		r.prev.Aggregated++
   273  	}
   274  }
   275  
   276  // Emit emits the point that was generated when reducing the points fed in with AggregateFloat.
   277  func (r *FloatFuncStringReducer) Emit() []StringPoint {
   278  	return []StringPoint{*r.prev}
   279  }
   280  
   281  // FloatReduceStringSliceFunc is the function called by a FloatPoint reducer.
   282  type FloatReduceStringSliceFunc func(a []FloatPoint) []StringPoint
   283  
   284  // FloatSliceFuncStringReducer is a reducer that aggregates
   285  // the passed in points and then invokes the function to reduce the points when they are emitted.
   286  type FloatSliceFuncStringReducer struct {
   287  	points []FloatPoint
   288  	fn     FloatReduceStringSliceFunc
   289  }
   290  
   291  // NewFloatSliceFuncStringReducer creates a new FloatSliceFuncStringReducer.
   292  func NewFloatSliceFuncStringReducer(fn FloatReduceStringSliceFunc) *FloatSliceFuncStringReducer {
   293  	return &FloatSliceFuncStringReducer{fn: fn}
   294  }
   295  
   296  // AggregateFloat copies the FloatPoint into the internal slice to be passed
   297  // to the reduce function when Emit is called.
   298  func (r *FloatSliceFuncStringReducer) AggregateFloat(p *FloatPoint) {
   299  	r.points = append(r.points, *p.Clone())
   300  }
   301  
   302  // AggregateFloatBulk performs a bulk copy of FloatPoints into the internal slice.
   303  // This is a more efficient version of calling AggregateFloat on each point.
   304  func (r *FloatSliceFuncStringReducer) AggregateFloatBulk(points []FloatPoint) {
   305  	r.points = append(r.points, points...)
   306  }
   307  
   308  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
   309  // This method does not clear the points from the internal slice.
   310  func (r *FloatSliceFuncStringReducer) Emit() []StringPoint {
   311  	return r.fn(r.points)
   312  }
   313  
   314  // FloatReduceBooleanFunc is the function called by a FloatPoint reducer.
   315  type FloatReduceBooleanFunc func(prev *BooleanPoint, curr *FloatPoint) (t int64, v bool, aux []interface{})
   316  
   317  // FloatFuncBooleanReducer is a reducer that reduces
   318  // the passed in points to a single point using a reduce function.
   319  type FloatFuncBooleanReducer struct {
   320  	prev *BooleanPoint
   321  	fn   FloatReduceBooleanFunc
   322  }
   323  
   324  // NewFloatFuncBooleanReducer creates a new FloatFuncBooleanReducer.
   325  func NewFloatFuncBooleanReducer(fn FloatReduceBooleanFunc, prev *BooleanPoint) *FloatFuncBooleanReducer {
   326  	return &FloatFuncBooleanReducer{fn: fn, prev: prev}
   327  }
   328  
   329  // AggregateFloat takes a FloatPoint and invokes the reduce function with the
   330  // current and new point to modify the current point.
   331  func (r *FloatFuncBooleanReducer) AggregateFloat(p *FloatPoint) {
   332  	t, v, aux := r.fn(r.prev, p)
   333  	if r.prev == nil {
   334  		r.prev = &BooleanPoint{}
   335  	}
   336  	r.prev.Time = t
   337  	r.prev.Value = v
   338  	r.prev.Aux = aux
   339  	if p.Aggregated > 1 {
   340  		r.prev.Aggregated += p.Aggregated
   341  	} else {
   342  		r.prev.Aggregated++
   343  	}
   344  }
   345  
   346  // Emit emits the point that was generated when reducing the points fed in with AggregateFloat.
   347  func (r *FloatFuncBooleanReducer) Emit() []BooleanPoint {
   348  	return []BooleanPoint{*r.prev}
   349  }
   350  
   351  // FloatReduceBooleanSliceFunc is the function called by a FloatPoint reducer.
   352  type FloatReduceBooleanSliceFunc func(a []FloatPoint) []BooleanPoint
   353  
   354  // FloatSliceFuncBooleanReducer is a reducer that aggregates
   355  // the passed in points and then invokes the function to reduce the points when they are emitted.
   356  type FloatSliceFuncBooleanReducer struct {
   357  	points []FloatPoint
   358  	fn     FloatReduceBooleanSliceFunc
   359  }
   360  
   361  // NewFloatSliceFuncBooleanReducer creates a new FloatSliceFuncBooleanReducer.
   362  func NewFloatSliceFuncBooleanReducer(fn FloatReduceBooleanSliceFunc) *FloatSliceFuncBooleanReducer {
   363  	return &FloatSliceFuncBooleanReducer{fn: fn}
   364  }
   365  
   366  // AggregateFloat copies the FloatPoint into the internal slice to be passed
   367  // to the reduce function when Emit is called.
   368  func (r *FloatSliceFuncBooleanReducer) AggregateFloat(p *FloatPoint) {
   369  	r.points = append(r.points, *p.Clone())
   370  }
   371  
   372  // AggregateFloatBulk performs a bulk copy of FloatPoints into the internal slice.
   373  // This is a more efficient version of calling AggregateFloat on each point.
   374  func (r *FloatSliceFuncBooleanReducer) AggregateFloatBulk(points []FloatPoint) {
   375  	r.points = append(r.points, points...)
   376  }
   377  
   378  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
   379  // This method does not clear the points from the internal slice.
   380  func (r *FloatSliceFuncBooleanReducer) Emit() []BooleanPoint {
   381  	return r.fn(r.points)
   382  }
   383  
   384  // FloatSumHllReducer returns the HLL sketch for a series, in string form
   385  type FloatSumHllReducer struct {
   386  	plus *hll.Plus
   387  }
   388  
   389  // func NewFloatSumHllReducer creates a new FloatSumHllReducer
   390  func NewFloatSumHllReducer() *FloatSumHllReducer {
   391  	return &FloatSumHllReducer{plus: hll.NewDefaultPlus()}
   392  }
   393  
   394  // AggregateFloat aggregates a point into the reducer.
   395  func (r *FloatSumHllReducer) AggregateFloat(p *FloatPoint) {
   396  
   397  	buf := new(bytes.Buffer)
   398  	binary.Write(buf, binary.BigEndian, p.Value)
   399  	b := buf.Bytes()
   400  
   401  	r.plus.Add(b)
   402  }
   403  
   404  // Emit emits the distinct points that have been aggregated into the reducer.
   405  func (r *FloatSumHllReducer) Emit() []StringPoint {
   406  	return []StringPoint{
   407  		marshalPlus(r.plus, nil),
   408  	}
   409  }
   410  
   411  // FloatDistinctReducer returns the distinct points in a series.
   412  type FloatDistinctReducer struct {
   413  	m map[float64]FloatPoint
   414  }
   415  
   416  // NewFloatDistinctReducer creates a new FloatDistinctReducer.
   417  func NewFloatDistinctReducer() *FloatDistinctReducer {
   418  	return &FloatDistinctReducer{m: make(map[float64]FloatPoint)}
   419  }
   420  
   421  // AggregateFloat aggregates a point into the reducer.
   422  func (r *FloatDistinctReducer) AggregateFloat(p *FloatPoint) {
   423  	if _, ok := r.m[p.Value]; !ok {
   424  		r.m[p.Value] = *p
   425  	}
   426  }
   427  
   428  // Emit emits the distinct points that have been aggregated into the reducer.
   429  func (r *FloatDistinctReducer) Emit() []FloatPoint {
   430  	points := make([]FloatPoint, 0, len(r.m))
   431  	for _, p := range r.m {
   432  		points = append(points, FloatPoint{Time: p.Time, Value: p.Value})
   433  	}
   434  	sort.Sort(floatPoints(points))
   435  	return points
   436  }
   437  
   438  // FloatElapsedReducer calculates the elapsed of the aggregated points.
   439  type FloatElapsedReducer struct {
   440  	unitConversion int64
   441  	prev           FloatPoint
   442  	curr           FloatPoint
   443  }
   444  
   445  // NewFloatElapsedReducer creates a new FloatElapsedReducer.
   446  func NewFloatElapsedReducer(interval Interval) *FloatElapsedReducer {
   447  	return &FloatElapsedReducer{
   448  		unitConversion: int64(interval.Duration),
   449  		prev:           FloatPoint{Nil: true},
   450  		curr:           FloatPoint{Nil: true},
   451  	}
   452  }
   453  
   454  // AggregateFloat aggregates a point into the reducer and updates the current window.
   455  func (r *FloatElapsedReducer) AggregateFloat(p *FloatPoint) {
   456  	r.prev = r.curr
   457  	r.curr = *p
   458  }
   459  
   460  // Emit emits the elapsed of the reducer at the current point.
   461  func (r *FloatElapsedReducer) Emit() []IntegerPoint {
   462  	if !r.prev.Nil {
   463  		elapsed := (r.curr.Time - r.prev.Time) / r.unitConversion
   464  		return []IntegerPoint{
   465  			{Time: r.curr.Time, Value: elapsed},
   466  		}
   467  	}
   468  	return nil
   469  }
   470  
   471  // FloatSampleReducer implements a reservoir sampling to calculate a random subset of points
   472  type FloatSampleReducer struct {
   473  	count int        // how many points we've iterated over
   474  	rng   *rand.Rand // random number generator for each reducer
   475  
   476  	points floatPoints // the reservoir
   477  }
   478  
   479  // NewFloatSampleReducer creates a new FloatSampleReducer
   480  func NewFloatSampleReducer(size int) *FloatSampleReducer {
   481  	return &FloatSampleReducer{
   482  		rng:    rand.New(rand.NewSource(time.Now().UnixNano())), // seed with current time as suggested by https://golang.org/pkg/math/rand/
   483  		points: make(floatPoints, size),
   484  	}
   485  }
   486  
   487  // AggregateFloat aggregates a point into the reducer.
   488  func (r *FloatSampleReducer) AggregateFloat(p *FloatPoint) {
   489  	r.count++
   490  	// Fill the reservoir with the first n points
   491  	if r.count-1 < len(r.points) {
   492  		p.CopyTo(&r.points[r.count-1])
   493  		return
   494  	}
   495  
   496  	// Generate a random integer between 1 and the count and
   497  	// if that number is less than the length of the slice
   498  	// replace the point at that index rnd with p.
   499  	rnd := r.rng.Intn(r.count)
   500  	if rnd < len(r.points) {
   501  		p.CopyTo(&r.points[rnd])
   502  	}
   503  }
   504  
   505  // Emit emits the reservoir sample as many points.
   506  func (r *FloatSampleReducer) Emit() []FloatPoint {
   507  	min := len(r.points)
   508  	if r.count < min {
   509  		min = r.count
   510  	}
   511  	pts := r.points[:min]
   512  	sort.Sort(pts)
   513  	return pts
   514  }
   515  
   516  // IntegerPointAggregator aggregates points to produce a single point.
   517  type IntegerPointAggregator interface {
   518  	AggregateInteger(p *IntegerPoint)
   519  }
   520  
   521  // IntegerBulkPointAggregator aggregates multiple points at a time.
   522  type IntegerBulkPointAggregator interface {
   523  	AggregateIntegerBulk(points []IntegerPoint)
   524  }
   525  
   526  // IntegerPointEmitter produces a single point from an aggregate.
   527  type IntegerPointEmitter interface {
   528  	Emit() []IntegerPoint
   529  }
   530  
   531  // IntegerReduceFloatFunc is the function called by a IntegerPoint reducer.
   532  type IntegerReduceFloatFunc func(prev *FloatPoint, curr *IntegerPoint) (t int64, v float64, aux []interface{})
   533  
   534  // IntegerFuncFloatReducer is a reducer that reduces
   535  // the passed in points to a single point using a reduce function.
   536  type IntegerFuncFloatReducer struct {
   537  	prev *FloatPoint
   538  	fn   IntegerReduceFloatFunc
   539  }
   540  
   541  // NewIntegerFuncFloatReducer creates a new IntegerFuncFloatReducer.
   542  func NewIntegerFuncFloatReducer(fn IntegerReduceFloatFunc, prev *FloatPoint) *IntegerFuncFloatReducer {
   543  	return &IntegerFuncFloatReducer{fn: fn, prev: prev}
   544  }
   545  
   546  // AggregateInteger takes a IntegerPoint and invokes the reduce function with the
   547  // current and new point to modify the current point.
   548  func (r *IntegerFuncFloatReducer) AggregateInteger(p *IntegerPoint) {
   549  	t, v, aux := r.fn(r.prev, p)
   550  	if r.prev == nil {
   551  		r.prev = &FloatPoint{}
   552  	}
   553  	r.prev.Time = t
   554  	r.prev.Value = v
   555  	r.prev.Aux = aux
   556  	if p.Aggregated > 1 {
   557  		r.prev.Aggregated += p.Aggregated
   558  	} else {
   559  		r.prev.Aggregated++
   560  	}
   561  }
   562  
   563  // Emit emits the point that was generated when reducing the points fed in with AggregateInteger.
   564  func (r *IntegerFuncFloatReducer) Emit() []FloatPoint {
   565  	return []FloatPoint{*r.prev}
   566  }
   567  
   568  // IntegerReduceFloatSliceFunc is the function called by a IntegerPoint reducer.
   569  type IntegerReduceFloatSliceFunc func(a []IntegerPoint) []FloatPoint
   570  
   571  // IntegerSliceFuncFloatReducer is a reducer that aggregates
   572  // the passed in points and then invokes the function to reduce the points when they are emitted.
   573  type IntegerSliceFuncFloatReducer struct {
   574  	points []IntegerPoint
   575  	fn     IntegerReduceFloatSliceFunc
   576  }
   577  
   578  // NewIntegerSliceFuncFloatReducer creates a new IntegerSliceFuncFloatReducer.
   579  func NewIntegerSliceFuncFloatReducer(fn IntegerReduceFloatSliceFunc) *IntegerSliceFuncFloatReducer {
   580  	return &IntegerSliceFuncFloatReducer{fn: fn}
   581  }
   582  
   583  // AggregateInteger copies the IntegerPoint into the internal slice to be passed
   584  // to the reduce function when Emit is called.
   585  func (r *IntegerSliceFuncFloatReducer) AggregateInteger(p *IntegerPoint) {
   586  	r.points = append(r.points, *p.Clone())
   587  }
   588  
   589  // AggregateIntegerBulk performs a bulk copy of IntegerPoints into the internal slice.
   590  // This is a more efficient version of calling AggregateInteger on each point.
   591  func (r *IntegerSliceFuncFloatReducer) AggregateIntegerBulk(points []IntegerPoint) {
   592  	r.points = append(r.points, points...)
   593  }
   594  
   595  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
   596  // This method does not clear the points from the internal slice.
   597  func (r *IntegerSliceFuncFloatReducer) Emit() []FloatPoint {
   598  	return r.fn(r.points)
   599  }
   600  
   601  // IntegerReduceFunc is the function called by a IntegerPoint reducer.
   602  type IntegerReduceFunc func(prev *IntegerPoint, curr *IntegerPoint) (t int64, v int64, aux []interface{})
   603  
   604  // IntegerFuncReducer is a reducer that reduces
   605  // the passed in points to a single point using a reduce function.
   606  type IntegerFuncReducer struct {
   607  	prev *IntegerPoint
   608  	fn   IntegerReduceFunc
   609  }
   610  
   611  // NewIntegerFuncReducer creates a new IntegerFuncIntegerReducer.
   612  func NewIntegerFuncReducer(fn IntegerReduceFunc, prev *IntegerPoint) *IntegerFuncReducer {
   613  	return &IntegerFuncReducer{fn: fn, prev: prev}
   614  }
   615  
   616  // AggregateInteger takes a IntegerPoint and invokes the reduce function with the
   617  // current and new point to modify the current point.
   618  func (r *IntegerFuncReducer) AggregateInteger(p *IntegerPoint) {
   619  	t, v, aux := r.fn(r.prev, p)
   620  	if r.prev == nil {
   621  		r.prev = &IntegerPoint{}
   622  	}
   623  	r.prev.Time = t
   624  	r.prev.Value = v
   625  	r.prev.Aux = aux
   626  	if p.Aggregated > 1 {
   627  		r.prev.Aggregated += p.Aggregated
   628  	} else {
   629  		r.prev.Aggregated++
   630  	}
   631  }
   632  
   633  // Emit emits the point that was generated when reducing the points fed in with AggregateInteger.
   634  func (r *IntegerFuncReducer) Emit() []IntegerPoint {
   635  	return []IntegerPoint{*r.prev}
   636  }
   637  
   638  // IntegerReduceSliceFunc is the function called by a IntegerPoint reducer.
   639  type IntegerReduceSliceFunc func(a []IntegerPoint) []IntegerPoint
   640  
   641  // IntegerSliceFuncReducer is a reducer that aggregates
   642  // the passed in points and then invokes the function to reduce the points when they are emitted.
   643  type IntegerSliceFuncReducer struct {
   644  	points []IntegerPoint
   645  	fn     IntegerReduceSliceFunc
   646  }
   647  
   648  // NewIntegerSliceFuncReducer creates a new IntegerSliceFuncReducer.
   649  func NewIntegerSliceFuncReducer(fn IntegerReduceSliceFunc) *IntegerSliceFuncReducer {
   650  	return &IntegerSliceFuncReducer{fn: fn}
   651  }
   652  
   653  // AggregateInteger copies the IntegerPoint into the internal slice to be passed
   654  // to the reduce function when Emit is called.
   655  func (r *IntegerSliceFuncReducer) AggregateInteger(p *IntegerPoint) {
   656  	r.points = append(r.points, *p.Clone())
   657  }
   658  
   659  // AggregateIntegerBulk performs a bulk copy of IntegerPoints into the internal slice.
   660  // This is a more efficient version of calling AggregateInteger on each point.
   661  func (r *IntegerSliceFuncReducer) AggregateIntegerBulk(points []IntegerPoint) {
   662  	r.points = append(r.points, points...)
   663  }
   664  
   665  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
   666  // This method does not clear the points from the internal slice.
   667  func (r *IntegerSliceFuncReducer) Emit() []IntegerPoint {
   668  	return r.fn(r.points)
   669  }
   670  
   671  // IntegerReduceUnsignedFunc is the function called by a IntegerPoint reducer.
   672  type IntegerReduceUnsignedFunc func(prev *UnsignedPoint, curr *IntegerPoint) (t int64, v uint64, aux []interface{})
   673  
   674  // IntegerFuncUnsignedReducer is a reducer that reduces
   675  // the passed in points to a single point using a reduce function.
   676  type IntegerFuncUnsignedReducer struct {
   677  	prev *UnsignedPoint
   678  	fn   IntegerReduceUnsignedFunc
   679  }
   680  
   681  // NewIntegerFuncUnsignedReducer creates a new IntegerFuncUnsignedReducer.
   682  func NewIntegerFuncUnsignedReducer(fn IntegerReduceUnsignedFunc, prev *UnsignedPoint) *IntegerFuncUnsignedReducer {
   683  	return &IntegerFuncUnsignedReducer{fn: fn, prev: prev}
   684  }
   685  
   686  // AggregateInteger takes a IntegerPoint and invokes the reduce function with the
   687  // current and new point to modify the current point.
   688  func (r *IntegerFuncUnsignedReducer) AggregateInteger(p *IntegerPoint) {
   689  	t, v, aux := r.fn(r.prev, p)
   690  	if r.prev == nil {
   691  		r.prev = &UnsignedPoint{}
   692  	}
   693  	r.prev.Time = t
   694  	r.prev.Value = v
   695  	r.prev.Aux = aux
   696  	if p.Aggregated > 1 {
   697  		r.prev.Aggregated += p.Aggregated
   698  	} else {
   699  		r.prev.Aggregated++
   700  	}
   701  }
   702  
   703  // Emit emits the point that was generated when reducing the points fed in with AggregateInteger.
   704  func (r *IntegerFuncUnsignedReducer) Emit() []UnsignedPoint {
   705  	return []UnsignedPoint{*r.prev}
   706  }
   707  
   708  // IntegerReduceUnsignedSliceFunc is the function called by a IntegerPoint reducer.
   709  type IntegerReduceUnsignedSliceFunc func(a []IntegerPoint) []UnsignedPoint
   710  
   711  // IntegerSliceFuncUnsignedReducer is a reducer that aggregates
   712  // the passed in points and then invokes the function to reduce the points when they are emitted.
   713  type IntegerSliceFuncUnsignedReducer struct {
   714  	points []IntegerPoint
   715  	fn     IntegerReduceUnsignedSliceFunc
   716  }
   717  
   718  // NewIntegerSliceFuncUnsignedReducer creates a new IntegerSliceFuncUnsignedReducer.
   719  func NewIntegerSliceFuncUnsignedReducer(fn IntegerReduceUnsignedSliceFunc) *IntegerSliceFuncUnsignedReducer {
   720  	return &IntegerSliceFuncUnsignedReducer{fn: fn}
   721  }
   722  
   723  // AggregateInteger copies the IntegerPoint into the internal slice to be passed
   724  // to the reduce function when Emit is called.
   725  func (r *IntegerSliceFuncUnsignedReducer) AggregateInteger(p *IntegerPoint) {
   726  	r.points = append(r.points, *p.Clone())
   727  }
   728  
   729  // AggregateIntegerBulk performs a bulk copy of IntegerPoints into the internal slice.
   730  // This is a more efficient version of calling AggregateInteger on each point.
   731  func (r *IntegerSliceFuncUnsignedReducer) AggregateIntegerBulk(points []IntegerPoint) {
   732  	r.points = append(r.points, points...)
   733  }
   734  
   735  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
   736  // This method does not clear the points from the internal slice.
   737  func (r *IntegerSliceFuncUnsignedReducer) Emit() []UnsignedPoint {
   738  	return r.fn(r.points)
   739  }
   740  
   741  // IntegerReduceStringFunc is the function called by a IntegerPoint reducer.
   742  type IntegerReduceStringFunc func(prev *StringPoint, curr *IntegerPoint) (t int64, v string, aux []interface{})
   743  
   744  // IntegerFuncStringReducer is a reducer that reduces
   745  // the passed in points to a single point using a reduce function.
   746  type IntegerFuncStringReducer struct {
   747  	prev *StringPoint
   748  	fn   IntegerReduceStringFunc
   749  }
   750  
   751  // NewIntegerFuncStringReducer creates a new IntegerFuncStringReducer.
   752  func NewIntegerFuncStringReducer(fn IntegerReduceStringFunc, prev *StringPoint) *IntegerFuncStringReducer {
   753  	return &IntegerFuncStringReducer{fn: fn, prev: prev}
   754  }
   755  
   756  // AggregateInteger takes a IntegerPoint and invokes the reduce function with the
   757  // current and new point to modify the current point.
   758  func (r *IntegerFuncStringReducer) AggregateInteger(p *IntegerPoint) {
   759  	t, v, aux := r.fn(r.prev, p)
   760  	if r.prev == nil {
   761  		r.prev = &StringPoint{}
   762  	}
   763  	r.prev.Time = t
   764  	r.prev.Value = v
   765  	r.prev.Aux = aux
   766  	if p.Aggregated > 1 {
   767  		r.prev.Aggregated += p.Aggregated
   768  	} else {
   769  		r.prev.Aggregated++
   770  	}
   771  }
   772  
   773  // Emit emits the point that was generated when reducing the points fed in with AggregateInteger.
   774  func (r *IntegerFuncStringReducer) Emit() []StringPoint {
   775  	return []StringPoint{*r.prev}
   776  }
   777  
   778  // IntegerReduceStringSliceFunc is the function called by a IntegerPoint reducer.
   779  type IntegerReduceStringSliceFunc func(a []IntegerPoint) []StringPoint
   780  
   781  // IntegerSliceFuncStringReducer is a reducer that aggregates
   782  // the passed in points and then invokes the function to reduce the points when they are emitted.
   783  type IntegerSliceFuncStringReducer struct {
   784  	points []IntegerPoint
   785  	fn     IntegerReduceStringSliceFunc
   786  }
   787  
   788  // NewIntegerSliceFuncStringReducer creates a new IntegerSliceFuncStringReducer.
   789  func NewIntegerSliceFuncStringReducer(fn IntegerReduceStringSliceFunc) *IntegerSliceFuncStringReducer {
   790  	return &IntegerSliceFuncStringReducer{fn: fn}
   791  }
   792  
   793  // AggregateInteger copies the IntegerPoint into the internal slice to be passed
   794  // to the reduce function when Emit is called.
   795  func (r *IntegerSliceFuncStringReducer) AggregateInteger(p *IntegerPoint) {
   796  	r.points = append(r.points, *p.Clone())
   797  }
   798  
   799  // AggregateIntegerBulk performs a bulk copy of IntegerPoints into the internal slice.
   800  // This is a more efficient version of calling AggregateInteger on each point.
   801  func (r *IntegerSliceFuncStringReducer) AggregateIntegerBulk(points []IntegerPoint) {
   802  	r.points = append(r.points, points...)
   803  }
   804  
   805  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
   806  // This method does not clear the points from the internal slice.
   807  func (r *IntegerSliceFuncStringReducer) Emit() []StringPoint {
   808  	return r.fn(r.points)
   809  }
   810  
   811  // IntegerReduceBooleanFunc is the function called by a IntegerPoint reducer.
   812  type IntegerReduceBooleanFunc func(prev *BooleanPoint, curr *IntegerPoint) (t int64, v bool, aux []interface{})
   813  
   814  // IntegerFuncBooleanReducer is a reducer that reduces
   815  // the passed in points to a single point using a reduce function.
   816  type IntegerFuncBooleanReducer struct {
   817  	prev *BooleanPoint
   818  	fn   IntegerReduceBooleanFunc
   819  }
   820  
   821  // NewIntegerFuncBooleanReducer creates a new IntegerFuncBooleanReducer.
   822  func NewIntegerFuncBooleanReducer(fn IntegerReduceBooleanFunc, prev *BooleanPoint) *IntegerFuncBooleanReducer {
   823  	return &IntegerFuncBooleanReducer{fn: fn, prev: prev}
   824  }
   825  
   826  // AggregateInteger takes a IntegerPoint and invokes the reduce function with the
   827  // current and new point to modify the current point.
   828  func (r *IntegerFuncBooleanReducer) AggregateInteger(p *IntegerPoint) {
   829  	t, v, aux := r.fn(r.prev, p)
   830  	if r.prev == nil {
   831  		r.prev = &BooleanPoint{}
   832  	}
   833  	r.prev.Time = t
   834  	r.prev.Value = v
   835  	r.prev.Aux = aux
   836  	if p.Aggregated > 1 {
   837  		r.prev.Aggregated += p.Aggregated
   838  	} else {
   839  		r.prev.Aggregated++
   840  	}
   841  }
   842  
   843  // Emit emits the point that was generated when reducing the points fed in with AggregateInteger.
   844  func (r *IntegerFuncBooleanReducer) Emit() []BooleanPoint {
   845  	return []BooleanPoint{*r.prev}
   846  }
   847  
   848  // IntegerReduceBooleanSliceFunc is the function called by a IntegerPoint reducer.
   849  type IntegerReduceBooleanSliceFunc func(a []IntegerPoint) []BooleanPoint
   850  
   851  // IntegerSliceFuncBooleanReducer is a reducer that aggregates
   852  // the passed in points and then invokes the function to reduce the points when they are emitted.
   853  type IntegerSliceFuncBooleanReducer struct {
   854  	points []IntegerPoint
   855  	fn     IntegerReduceBooleanSliceFunc
   856  }
   857  
   858  // NewIntegerSliceFuncBooleanReducer creates a new IntegerSliceFuncBooleanReducer.
   859  func NewIntegerSliceFuncBooleanReducer(fn IntegerReduceBooleanSliceFunc) *IntegerSliceFuncBooleanReducer {
   860  	return &IntegerSliceFuncBooleanReducer{fn: fn}
   861  }
   862  
   863  // AggregateInteger copies the IntegerPoint into the internal slice to be passed
   864  // to the reduce function when Emit is called.
   865  func (r *IntegerSliceFuncBooleanReducer) AggregateInteger(p *IntegerPoint) {
   866  	r.points = append(r.points, *p.Clone())
   867  }
   868  
   869  // AggregateIntegerBulk performs a bulk copy of IntegerPoints into the internal slice.
   870  // This is a more efficient version of calling AggregateInteger on each point.
   871  func (r *IntegerSliceFuncBooleanReducer) AggregateIntegerBulk(points []IntegerPoint) {
   872  	r.points = append(r.points, points...)
   873  }
   874  
   875  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
   876  // This method does not clear the points from the internal slice.
   877  func (r *IntegerSliceFuncBooleanReducer) Emit() []BooleanPoint {
   878  	return r.fn(r.points)
   879  }
   880  
   881  // IntegerSumHllReducer returns the HLL sketch for a series, in string form
   882  type IntegerSumHllReducer struct {
   883  	plus *hll.Plus
   884  }
   885  
   886  // func NewIntegerSumHllReducer creates a new IntegerSumHllReducer
   887  func NewIntegerSumHllReducer() *IntegerSumHllReducer {
   888  	return &IntegerSumHllReducer{plus: hll.NewDefaultPlus()}
   889  }
   890  
   891  // AggregateInteger aggregates a point into the reducer.
   892  func (r *IntegerSumHllReducer) AggregateInteger(p *IntegerPoint) {
   893  
   894  	buf := new(bytes.Buffer)
   895  	binary.Write(buf, binary.BigEndian, p.Value)
   896  	b := buf.Bytes()
   897  
   898  	r.plus.Add(b)
   899  }
   900  
   901  // Emit emits the distinct points that have been aggregated into the reducer.
   902  func (r *IntegerSumHllReducer) Emit() []StringPoint {
   903  	return []StringPoint{
   904  		marshalPlus(r.plus, nil),
   905  	}
   906  }
   907  
   908  // IntegerDistinctReducer returns the distinct points in a series.
   909  type IntegerDistinctReducer struct {
   910  	m map[int64]IntegerPoint
   911  }
   912  
   913  // NewIntegerDistinctReducer creates a new IntegerDistinctReducer.
   914  func NewIntegerDistinctReducer() *IntegerDistinctReducer {
   915  	return &IntegerDistinctReducer{m: make(map[int64]IntegerPoint)}
   916  }
   917  
   918  // AggregateInteger aggregates a point into the reducer.
   919  func (r *IntegerDistinctReducer) AggregateInteger(p *IntegerPoint) {
   920  	if _, ok := r.m[p.Value]; !ok {
   921  		r.m[p.Value] = *p
   922  	}
   923  }
   924  
   925  // Emit emits the distinct points that have been aggregated into the reducer.
   926  func (r *IntegerDistinctReducer) Emit() []IntegerPoint {
   927  	points := make([]IntegerPoint, 0, len(r.m))
   928  	for _, p := range r.m {
   929  		points = append(points, IntegerPoint{Time: p.Time, Value: p.Value})
   930  	}
   931  	sort.Sort(integerPoints(points))
   932  	return points
   933  }
   934  
   935  // IntegerElapsedReducer calculates the elapsed of the aggregated points.
   936  type IntegerElapsedReducer struct {
   937  	unitConversion int64
   938  	prev           IntegerPoint
   939  	curr           IntegerPoint
   940  }
   941  
   942  // NewIntegerElapsedReducer creates a new IntegerElapsedReducer.
   943  func NewIntegerElapsedReducer(interval Interval) *IntegerElapsedReducer {
   944  	return &IntegerElapsedReducer{
   945  		unitConversion: int64(interval.Duration),
   946  		prev:           IntegerPoint{Nil: true},
   947  		curr:           IntegerPoint{Nil: true},
   948  	}
   949  }
   950  
   951  // AggregateInteger aggregates a point into the reducer and updates the current window.
   952  func (r *IntegerElapsedReducer) AggregateInteger(p *IntegerPoint) {
   953  	r.prev = r.curr
   954  	r.curr = *p
   955  }
   956  
   957  // Emit emits the elapsed of the reducer at the current point.
   958  func (r *IntegerElapsedReducer) Emit() []IntegerPoint {
   959  	if !r.prev.Nil {
   960  		elapsed := (r.curr.Time - r.prev.Time) / r.unitConversion
   961  		return []IntegerPoint{
   962  			{Time: r.curr.Time, Value: elapsed},
   963  		}
   964  	}
   965  	return nil
   966  }
   967  
   968  // IntegerSampleReducer implements a reservoir sampling to calculate a random subset of points
   969  type IntegerSampleReducer struct {
   970  	count int        // how many points we've iterated over
   971  	rng   *rand.Rand // random number generator for each reducer
   972  
   973  	points integerPoints // the reservoir
   974  }
   975  
   976  // NewIntegerSampleReducer creates a new IntegerSampleReducer
   977  func NewIntegerSampleReducer(size int) *IntegerSampleReducer {
   978  	return &IntegerSampleReducer{
   979  		rng:    rand.New(rand.NewSource(time.Now().UnixNano())), // seed with current time as suggested by https://golang.org/pkg/math/rand/
   980  		points: make(integerPoints, size),
   981  	}
   982  }
   983  
   984  // AggregateInteger aggregates a point into the reducer.
   985  func (r *IntegerSampleReducer) AggregateInteger(p *IntegerPoint) {
   986  	r.count++
   987  	// Fill the reservoir with the first n points
   988  	if r.count-1 < len(r.points) {
   989  		p.CopyTo(&r.points[r.count-1])
   990  		return
   991  	}
   992  
   993  	// Generate a random integer between 1 and the count and
   994  	// if that number is less than the length of the slice
   995  	// replace the point at that index rnd with p.
   996  	rnd := r.rng.Intn(r.count)
   997  	if rnd < len(r.points) {
   998  		p.CopyTo(&r.points[rnd])
   999  	}
  1000  }
  1001  
  1002  // Emit emits the reservoir sample as many points.
  1003  func (r *IntegerSampleReducer) Emit() []IntegerPoint {
  1004  	min := len(r.points)
  1005  	if r.count < min {
  1006  		min = r.count
  1007  	}
  1008  	pts := r.points[:min]
  1009  	sort.Sort(pts)
  1010  	return pts
  1011  }
  1012  
  1013  // UnsignedPointAggregator aggregates points to produce a single point.
  1014  type UnsignedPointAggregator interface {
  1015  	AggregateUnsigned(p *UnsignedPoint)
  1016  }
  1017  
  1018  // UnsignedBulkPointAggregator aggregates multiple points at a time.
  1019  type UnsignedBulkPointAggregator interface {
  1020  	AggregateUnsignedBulk(points []UnsignedPoint)
  1021  }
  1022  
  1023  // UnsignedPointEmitter produces a single point from an aggregate.
  1024  type UnsignedPointEmitter interface {
  1025  	Emit() []UnsignedPoint
  1026  }
  1027  
  1028  // UnsignedReduceFloatFunc is the function called by a UnsignedPoint reducer.
  1029  type UnsignedReduceFloatFunc func(prev *FloatPoint, curr *UnsignedPoint) (t int64, v float64, aux []interface{})
  1030  
  1031  // UnsignedFuncFloatReducer is a reducer that reduces
  1032  // the passed in points to a single point using a reduce function.
  1033  type UnsignedFuncFloatReducer struct {
  1034  	prev *FloatPoint
  1035  	fn   UnsignedReduceFloatFunc
  1036  }
  1037  
  1038  // NewUnsignedFuncFloatReducer creates a new UnsignedFuncFloatReducer.
  1039  func NewUnsignedFuncFloatReducer(fn UnsignedReduceFloatFunc, prev *FloatPoint) *UnsignedFuncFloatReducer {
  1040  	return &UnsignedFuncFloatReducer{fn: fn, prev: prev}
  1041  }
  1042  
  1043  // AggregateUnsigned takes a UnsignedPoint and invokes the reduce function with the
  1044  // current and new point to modify the current point.
  1045  func (r *UnsignedFuncFloatReducer) AggregateUnsigned(p *UnsignedPoint) {
  1046  	t, v, aux := r.fn(r.prev, p)
  1047  	if r.prev == nil {
  1048  		r.prev = &FloatPoint{}
  1049  	}
  1050  	r.prev.Time = t
  1051  	r.prev.Value = v
  1052  	r.prev.Aux = aux
  1053  	if p.Aggregated > 1 {
  1054  		r.prev.Aggregated += p.Aggregated
  1055  	} else {
  1056  		r.prev.Aggregated++
  1057  	}
  1058  }
  1059  
  1060  // Emit emits the point that was generated when reducing the points fed in with AggregateUnsigned.
  1061  func (r *UnsignedFuncFloatReducer) Emit() []FloatPoint {
  1062  	return []FloatPoint{*r.prev}
  1063  }
  1064  
  1065  // UnsignedReduceFloatSliceFunc is the function called by a UnsignedPoint reducer.
  1066  type UnsignedReduceFloatSliceFunc func(a []UnsignedPoint) []FloatPoint
  1067  
  1068  // UnsignedSliceFuncFloatReducer is a reducer that aggregates
  1069  // the passed in points and then invokes the function to reduce the points when they are emitted.
  1070  type UnsignedSliceFuncFloatReducer struct {
  1071  	points []UnsignedPoint
  1072  	fn     UnsignedReduceFloatSliceFunc
  1073  }
  1074  
  1075  // NewUnsignedSliceFuncFloatReducer creates a new UnsignedSliceFuncFloatReducer.
  1076  func NewUnsignedSliceFuncFloatReducer(fn UnsignedReduceFloatSliceFunc) *UnsignedSliceFuncFloatReducer {
  1077  	return &UnsignedSliceFuncFloatReducer{fn: fn}
  1078  }
  1079  
  1080  // AggregateUnsigned copies the UnsignedPoint into the internal slice to be passed
  1081  // to the reduce function when Emit is called.
  1082  func (r *UnsignedSliceFuncFloatReducer) AggregateUnsigned(p *UnsignedPoint) {
  1083  	r.points = append(r.points, *p.Clone())
  1084  }
  1085  
  1086  // AggregateUnsignedBulk performs a bulk copy of UnsignedPoints into the internal slice.
  1087  // This is a more efficient version of calling AggregateUnsigned on each point.
  1088  func (r *UnsignedSliceFuncFloatReducer) AggregateUnsignedBulk(points []UnsignedPoint) {
  1089  	r.points = append(r.points, points...)
  1090  }
  1091  
  1092  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  1093  // This method does not clear the points from the internal slice.
  1094  func (r *UnsignedSliceFuncFloatReducer) Emit() []FloatPoint {
  1095  	return r.fn(r.points)
  1096  }
  1097  
  1098  // UnsignedReduceIntegerFunc is the function called by a UnsignedPoint reducer.
  1099  type UnsignedReduceIntegerFunc func(prev *IntegerPoint, curr *UnsignedPoint) (t int64, v int64, aux []interface{})
  1100  
  1101  // UnsignedFuncIntegerReducer is a reducer that reduces
  1102  // the passed in points to a single point using a reduce function.
  1103  type UnsignedFuncIntegerReducer struct {
  1104  	prev *IntegerPoint
  1105  	fn   UnsignedReduceIntegerFunc
  1106  }
  1107  
  1108  // NewUnsignedFuncIntegerReducer creates a new UnsignedFuncIntegerReducer.
  1109  func NewUnsignedFuncIntegerReducer(fn UnsignedReduceIntegerFunc, prev *IntegerPoint) *UnsignedFuncIntegerReducer {
  1110  	return &UnsignedFuncIntegerReducer{fn: fn, prev: prev}
  1111  }
  1112  
  1113  // AggregateUnsigned takes a UnsignedPoint and invokes the reduce function with the
  1114  // current and new point to modify the current point.
  1115  func (r *UnsignedFuncIntegerReducer) AggregateUnsigned(p *UnsignedPoint) {
  1116  	t, v, aux := r.fn(r.prev, p)
  1117  	if r.prev == nil {
  1118  		r.prev = &IntegerPoint{}
  1119  	}
  1120  	r.prev.Time = t
  1121  	r.prev.Value = v
  1122  	r.prev.Aux = aux
  1123  	if p.Aggregated > 1 {
  1124  		r.prev.Aggregated += p.Aggregated
  1125  	} else {
  1126  		r.prev.Aggregated++
  1127  	}
  1128  }
  1129  
  1130  // Emit emits the point that was generated when reducing the points fed in with AggregateUnsigned.
  1131  func (r *UnsignedFuncIntegerReducer) Emit() []IntegerPoint {
  1132  	return []IntegerPoint{*r.prev}
  1133  }
  1134  
  1135  // UnsignedReduceIntegerSliceFunc is the function called by a UnsignedPoint reducer.
  1136  type UnsignedReduceIntegerSliceFunc func(a []UnsignedPoint) []IntegerPoint
  1137  
  1138  // UnsignedSliceFuncIntegerReducer is a reducer that aggregates
  1139  // the passed in points and then invokes the function to reduce the points when they are emitted.
  1140  type UnsignedSliceFuncIntegerReducer struct {
  1141  	points []UnsignedPoint
  1142  	fn     UnsignedReduceIntegerSliceFunc
  1143  }
  1144  
  1145  // NewUnsignedSliceFuncIntegerReducer creates a new UnsignedSliceFuncIntegerReducer.
  1146  func NewUnsignedSliceFuncIntegerReducer(fn UnsignedReduceIntegerSliceFunc) *UnsignedSliceFuncIntegerReducer {
  1147  	return &UnsignedSliceFuncIntegerReducer{fn: fn}
  1148  }
  1149  
  1150  // AggregateUnsigned copies the UnsignedPoint into the internal slice to be passed
  1151  // to the reduce function when Emit is called.
  1152  func (r *UnsignedSliceFuncIntegerReducer) AggregateUnsigned(p *UnsignedPoint) {
  1153  	r.points = append(r.points, *p.Clone())
  1154  }
  1155  
  1156  // AggregateUnsignedBulk performs a bulk copy of UnsignedPoints into the internal slice.
  1157  // This is a more efficient version of calling AggregateUnsigned on each point.
  1158  func (r *UnsignedSliceFuncIntegerReducer) AggregateUnsignedBulk(points []UnsignedPoint) {
  1159  	r.points = append(r.points, points...)
  1160  }
  1161  
  1162  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  1163  // This method does not clear the points from the internal slice.
  1164  func (r *UnsignedSliceFuncIntegerReducer) Emit() []IntegerPoint {
  1165  	return r.fn(r.points)
  1166  }
  1167  
  1168  // UnsignedReduceFunc is the function called by a UnsignedPoint reducer.
  1169  type UnsignedReduceFunc func(prev *UnsignedPoint, curr *UnsignedPoint) (t int64, v uint64, aux []interface{})
  1170  
  1171  // UnsignedFuncReducer is a reducer that reduces
  1172  // the passed in points to a single point using a reduce function.
  1173  type UnsignedFuncReducer struct {
  1174  	prev *UnsignedPoint
  1175  	fn   UnsignedReduceFunc
  1176  }
  1177  
  1178  // NewUnsignedFuncReducer creates a new UnsignedFuncUnsignedReducer.
  1179  func NewUnsignedFuncReducer(fn UnsignedReduceFunc, prev *UnsignedPoint) *UnsignedFuncReducer {
  1180  	return &UnsignedFuncReducer{fn: fn, prev: prev}
  1181  }
  1182  
  1183  // AggregateUnsigned takes a UnsignedPoint and invokes the reduce function with the
  1184  // current and new point to modify the current point.
  1185  func (r *UnsignedFuncReducer) AggregateUnsigned(p *UnsignedPoint) {
  1186  	t, v, aux := r.fn(r.prev, p)
  1187  	if r.prev == nil {
  1188  		r.prev = &UnsignedPoint{}
  1189  	}
  1190  	r.prev.Time = t
  1191  	r.prev.Value = v
  1192  	r.prev.Aux = aux
  1193  	if p.Aggregated > 1 {
  1194  		r.prev.Aggregated += p.Aggregated
  1195  	} else {
  1196  		r.prev.Aggregated++
  1197  	}
  1198  }
  1199  
  1200  // Emit emits the point that was generated when reducing the points fed in with AggregateUnsigned.
  1201  func (r *UnsignedFuncReducer) Emit() []UnsignedPoint {
  1202  	return []UnsignedPoint{*r.prev}
  1203  }
  1204  
  1205  // UnsignedReduceSliceFunc is the function called by a UnsignedPoint reducer.
  1206  type UnsignedReduceSliceFunc func(a []UnsignedPoint) []UnsignedPoint
  1207  
  1208  // UnsignedSliceFuncReducer is a reducer that aggregates
  1209  // the passed in points and then invokes the function to reduce the points when they are emitted.
  1210  type UnsignedSliceFuncReducer struct {
  1211  	points []UnsignedPoint
  1212  	fn     UnsignedReduceSliceFunc
  1213  }
  1214  
  1215  // NewUnsignedSliceFuncReducer creates a new UnsignedSliceFuncReducer.
  1216  func NewUnsignedSliceFuncReducer(fn UnsignedReduceSliceFunc) *UnsignedSliceFuncReducer {
  1217  	return &UnsignedSliceFuncReducer{fn: fn}
  1218  }
  1219  
  1220  // AggregateUnsigned copies the UnsignedPoint into the internal slice to be passed
  1221  // to the reduce function when Emit is called.
  1222  func (r *UnsignedSliceFuncReducer) AggregateUnsigned(p *UnsignedPoint) {
  1223  	r.points = append(r.points, *p.Clone())
  1224  }
  1225  
  1226  // AggregateUnsignedBulk performs a bulk copy of UnsignedPoints into the internal slice.
  1227  // This is a more efficient version of calling AggregateUnsigned on each point.
  1228  func (r *UnsignedSliceFuncReducer) AggregateUnsignedBulk(points []UnsignedPoint) {
  1229  	r.points = append(r.points, points...)
  1230  }
  1231  
  1232  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  1233  // This method does not clear the points from the internal slice.
  1234  func (r *UnsignedSliceFuncReducer) Emit() []UnsignedPoint {
  1235  	return r.fn(r.points)
  1236  }
  1237  
  1238  // UnsignedReduceStringFunc is the function called by a UnsignedPoint reducer.
  1239  type UnsignedReduceStringFunc func(prev *StringPoint, curr *UnsignedPoint) (t int64, v string, aux []interface{})
  1240  
  1241  // UnsignedFuncStringReducer is a reducer that reduces
  1242  // the passed in points to a single point using a reduce function.
  1243  type UnsignedFuncStringReducer struct {
  1244  	prev *StringPoint
  1245  	fn   UnsignedReduceStringFunc
  1246  }
  1247  
  1248  // NewUnsignedFuncStringReducer creates a new UnsignedFuncStringReducer.
  1249  func NewUnsignedFuncStringReducer(fn UnsignedReduceStringFunc, prev *StringPoint) *UnsignedFuncStringReducer {
  1250  	return &UnsignedFuncStringReducer{fn: fn, prev: prev}
  1251  }
  1252  
  1253  // AggregateUnsigned takes a UnsignedPoint and invokes the reduce function with the
  1254  // current and new point to modify the current point.
  1255  func (r *UnsignedFuncStringReducer) AggregateUnsigned(p *UnsignedPoint) {
  1256  	t, v, aux := r.fn(r.prev, p)
  1257  	if r.prev == nil {
  1258  		r.prev = &StringPoint{}
  1259  	}
  1260  	r.prev.Time = t
  1261  	r.prev.Value = v
  1262  	r.prev.Aux = aux
  1263  	if p.Aggregated > 1 {
  1264  		r.prev.Aggregated += p.Aggregated
  1265  	} else {
  1266  		r.prev.Aggregated++
  1267  	}
  1268  }
  1269  
  1270  // Emit emits the point that was generated when reducing the points fed in with AggregateUnsigned.
  1271  func (r *UnsignedFuncStringReducer) Emit() []StringPoint {
  1272  	return []StringPoint{*r.prev}
  1273  }
  1274  
  1275  // UnsignedReduceStringSliceFunc is the function called by a UnsignedPoint reducer.
  1276  type UnsignedReduceStringSliceFunc func(a []UnsignedPoint) []StringPoint
  1277  
  1278  // UnsignedSliceFuncStringReducer is a reducer that aggregates
  1279  // the passed in points and then invokes the function to reduce the points when they are emitted.
  1280  type UnsignedSliceFuncStringReducer struct {
  1281  	points []UnsignedPoint
  1282  	fn     UnsignedReduceStringSliceFunc
  1283  }
  1284  
  1285  // NewUnsignedSliceFuncStringReducer creates a new UnsignedSliceFuncStringReducer.
  1286  func NewUnsignedSliceFuncStringReducer(fn UnsignedReduceStringSliceFunc) *UnsignedSliceFuncStringReducer {
  1287  	return &UnsignedSliceFuncStringReducer{fn: fn}
  1288  }
  1289  
  1290  // AggregateUnsigned copies the UnsignedPoint into the internal slice to be passed
  1291  // to the reduce function when Emit is called.
  1292  func (r *UnsignedSliceFuncStringReducer) AggregateUnsigned(p *UnsignedPoint) {
  1293  	r.points = append(r.points, *p.Clone())
  1294  }
  1295  
  1296  // AggregateUnsignedBulk performs a bulk copy of UnsignedPoints into the internal slice.
  1297  // This is a more efficient version of calling AggregateUnsigned on each point.
  1298  func (r *UnsignedSliceFuncStringReducer) AggregateUnsignedBulk(points []UnsignedPoint) {
  1299  	r.points = append(r.points, points...)
  1300  }
  1301  
  1302  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  1303  // This method does not clear the points from the internal slice.
  1304  func (r *UnsignedSliceFuncStringReducer) Emit() []StringPoint {
  1305  	return r.fn(r.points)
  1306  }
  1307  
  1308  // UnsignedReduceBooleanFunc is the function called by a UnsignedPoint reducer.
  1309  type UnsignedReduceBooleanFunc func(prev *BooleanPoint, curr *UnsignedPoint) (t int64, v bool, aux []interface{})
  1310  
  1311  // UnsignedFuncBooleanReducer is a reducer that reduces
  1312  // the passed in points to a single point using a reduce function.
  1313  type UnsignedFuncBooleanReducer struct {
  1314  	prev *BooleanPoint
  1315  	fn   UnsignedReduceBooleanFunc
  1316  }
  1317  
  1318  // NewUnsignedFuncBooleanReducer creates a new UnsignedFuncBooleanReducer.
  1319  func NewUnsignedFuncBooleanReducer(fn UnsignedReduceBooleanFunc, prev *BooleanPoint) *UnsignedFuncBooleanReducer {
  1320  	return &UnsignedFuncBooleanReducer{fn: fn, prev: prev}
  1321  }
  1322  
  1323  // AggregateUnsigned takes a UnsignedPoint and invokes the reduce function with the
  1324  // current and new point to modify the current point.
  1325  func (r *UnsignedFuncBooleanReducer) AggregateUnsigned(p *UnsignedPoint) {
  1326  	t, v, aux := r.fn(r.prev, p)
  1327  	if r.prev == nil {
  1328  		r.prev = &BooleanPoint{}
  1329  	}
  1330  	r.prev.Time = t
  1331  	r.prev.Value = v
  1332  	r.prev.Aux = aux
  1333  	if p.Aggregated > 1 {
  1334  		r.prev.Aggregated += p.Aggregated
  1335  	} else {
  1336  		r.prev.Aggregated++
  1337  	}
  1338  }
  1339  
  1340  // Emit emits the point that was generated when reducing the points fed in with AggregateUnsigned.
  1341  func (r *UnsignedFuncBooleanReducer) Emit() []BooleanPoint {
  1342  	return []BooleanPoint{*r.prev}
  1343  }
  1344  
  1345  // UnsignedReduceBooleanSliceFunc is the function called by a UnsignedPoint reducer.
  1346  type UnsignedReduceBooleanSliceFunc func(a []UnsignedPoint) []BooleanPoint
  1347  
  1348  // UnsignedSliceFuncBooleanReducer is a reducer that aggregates
  1349  // the passed in points and then invokes the function to reduce the points when they are emitted.
  1350  type UnsignedSliceFuncBooleanReducer struct {
  1351  	points []UnsignedPoint
  1352  	fn     UnsignedReduceBooleanSliceFunc
  1353  }
  1354  
  1355  // NewUnsignedSliceFuncBooleanReducer creates a new UnsignedSliceFuncBooleanReducer.
  1356  func NewUnsignedSliceFuncBooleanReducer(fn UnsignedReduceBooleanSliceFunc) *UnsignedSliceFuncBooleanReducer {
  1357  	return &UnsignedSliceFuncBooleanReducer{fn: fn}
  1358  }
  1359  
  1360  // AggregateUnsigned copies the UnsignedPoint into the internal slice to be passed
  1361  // to the reduce function when Emit is called.
  1362  func (r *UnsignedSliceFuncBooleanReducer) AggregateUnsigned(p *UnsignedPoint) {
  1363  	r.points = append(r.points, *p.Clone())
  1364  }
  1365  
  1366  // AggregateUnsignedBulk performs a bulk copy of UnsignedPoints into the internal slice.
  1367  // This is a more efficient version of calling AggregateUnsigned on each point.
  1368  func (r *UnsignedSliceFuncBooleanReducer) AggregateUnsignedBulk(points []UnsignedPoint) {
  1369  	r.points = append(r.points, points...)
  1370  }
  1371  
  1372  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  1373  // This method does not clear the points from the internal slice.
  1374  func (r *UnsignedSliceFuncBooleanReducer) Emit() []BooleanPoint {
  1375  	return r.fn(r.points)
  1376  }
  1377  
  1378  // UnsignedSumHllReducer returns the HLL sketch for a series, in string form
  1379  type UnsignedSumHllReducer struct {
  1380  	plus *hll.Plus
  1381  }
  1382  
  1383  // func NewUnsignedSumHllReducer creates a new UnsignedSumHllReducer
  1384  func NewUnsignedSumHllReducer() *UnsignedSumHllReducer {
  1385  	return &UnsignedSumHllReducer{plus: hll.NewDefaultPlus()}
  1386  }
  1387  
  1388  // AggregateUnsigned aggregates a point into the reducer.
  1389  func (r *UnsignedSumHllReducer) AggregateUnsigned(p *UnsignedPoint) {
  1390  
  1391  	buf := new(bytes.Buffer)
  1392  	binary.Write(buf, binary.BigEndian, p.Value)
  1393  	b := buf.Bytes()
  1394  
  1395  	r.plus.Add(b)
  1396  }
  1397  
  1398  // Emit emits the distinct points that have been aggregated into the reducer.
  1399  func (r *UnsignedSumHllReducer) Emit() []StringPoint {
  1400  	return []StringPoint{
  1401  		marshalPlus(r.plus, nil),
  1402  	}
  1403  }
  1404  
  1405  // UnsignedDistinctReducer returns the distinct points in a series.
  1406  type UnsignedDistinctReducer struct {
  1407  	m map[uint64]UnsignedPoint
  1408  }
  1409  
  1410  // NewUnsignedDistinctReducer creates a new UnsignedDistinctReducer.
  1411  func NewUnsignedDistinctReducer() *UnsignedDistinctReducer {
  1412  	return &UnsignedDistinctReducer{m: make(map[uint64]UnsignedPoint)}
  1413  }
  1414  
  1415  // AggregateUnsigned aggregates a point into the reducer.
  1416  func (r *UnsignedDistinctReducer) AggregateUnsigned(p *UnsignedPoint) {
  1417  	if _, ok := r.m[p.Value]; !ok {
  1418  		r.m[p.Value] = *p
  1419  	}
  1420  }
  1421  
  1422  // Emit emits the distinct points that have been aggregated into the reducer.
  1423  func (r *UnsignedDistinctReducer) Emit() []UnsignedPoint {
  1424  	points := make([]UnsignedPoint, 0, len(r.m))
  1425  	for _, p := range r.m {
  1426  		points = append(points, UnsignedPoint{Time: p.Time, Value: p.Value})
  1427  	}
  1428  	sort.Sort(unsignedPoints(points))
  1429  	return points
  1430  }
  1431  
  1432  // UnsignedElapsedReducer calculates the elapsed of the aggregated points.
  1433  type UnsignedElapsedReducer struct {
  1434  	unitConversion int64
  1435  	prev           UnsignedPoint
  1436  	curr           UnsignedPoint
  1437  }
  1438  
  1439  // NewUnsignedElapsedReducer creates a new UnsignedElapsedReducer.
  1440  func NewUnsignedElapsedReducer(interval Interval) *UnsignedElapsedReducer {
  1441  	return &UnsignedElapsedReducer{
  1442  		unitConversion: int64(interval.Duration),
  1443  		prev:           UnsignedPoint{Nil: true},
  1444  		curr:           UnsignedPoint{Nil: true},
  1445  	}
  1446  }
  1447  
  1448  // AggregateUnsigned aggregates a point into the reducer and updates the current window.
  1449  func (r *UnsignedElapsedReducer) AggregateUnsigned(p *UnsignedPoint) {
  1450  	r.prev = r.curr
  1451  	r.curr = *p
  1452  }
  1453  
  1454  // Emit emits the elapsed of the reducer at the current point.
  1455  func (r *UnsignedElapsedReducer) Emit() []IntegerPoint {
  1456  	if !r.prev.Nil {
  1457  		elapsed := (r.curr.Time - r.prev.Time) / r.unitConversion
  1458  		return []IntegerPoint{
  1459  			{Time: r.curr.Time, Value: elapsed},
  1460  		}
  1461  	}
  1462  	return nil
  1463  }
  1464  
  1465  // UnsignedSampleReducer implements a reservoir sampling to calculate a random subset of points
  1466  type UnsignedSampleReducer struct {
  1467  	count int        // how many points we've iterated over
  1468  	rng   *rand.Rand // random number generator for each reducer
  1469  
  1470  	points unsignedPoints // the reservoir
  1471  }
  1472  
  1473  // NewUnsignedSampleReducer creates a new UnsignedSampleReducer
  1474  func NewUnsignedSampleReducer(size int) *UnsignedSampleReducer {
  1475  	return &UnsignedSampleReducer{
  1476  		rng:    rand.New(rand.NewSource(time.Now().UnixNano())), // seed with current time as suggested by https://golang.org/pkg/math/rand/
  1477  		points: make(unsignedPoints, size),
  1478  	}
  1479  }
  1480  
  1481  // AggregateUnsigned aggregates a point into the reducer.
  1482  func (r *UnsignedSampleReducer) AggregateUnsigned(p *UnsignedPoint) {
  1483  	r.count++
  1484  	// Fill the reservoir with the first n points
  1485  	if r.count-1 < len(r.points) {
  1486  		p.CopyTo(&r.points[r.count-1])
  1487  		return
  1488  	}
  1489  
  1490  	// Generate a random integer between 1 and the count and
  1491  	// if that number is less than the length of the slice
  1492  	// replace the point at that index rnd with p.
  1493  	rnd := r.rng.Intn(r.count)
  1494  	if rnd < len(r.points) {
  1495  		p.CopyTo(&r.points[rnd])
  1496  	}
  1497  }
  1498  
  1499  // Emit emits the reservoir sample as many points.
  1500  func (r *UnsignedSampleReducer) Emit() []UnsignedPoint {
  1501  	min := len(r.points)
  1502  	if r.count < min {
  1503  		min = r.count
  1504  	}
  1505  	pts := r.points[:min]
  1506  	sort.Sort(pts)
  1507  	return pts
  1508  }
  1509  
  1510  // StringPointAggregator aggregates points to produce a single point.
  1511  type StringPointAggregator interface {
  1512  	AggregateString(p *StringPoint)
  1513  }
  1514  
  1515  // StringBulkPointAggregator aggregates multiple points at a time.
  1516  type StringBulkPointAggregator interface {
  1517  	AggregateStringBulk(points []StringPoint)
  1518  }
  1519  
  1520  // StringPointEmitter produces a single point from an aggregate.
  1521  type StringPointEmitter interface {
  1522  	Emit() []StringPoint
  1523  }
  1524  
  1525  // StringReduceFloatFunc is the function called by a StringPoint reducer.
  1526  type StringReduceFloatFunc func(prev *FloatPoint, curr *StringPoint) (t int64, v float64, aux []interface{})
  1527  
  1528  // StringFuncFloatReducer is a reducer that reduces
  1529  // the passed in points to a single point using a reduce function.
  1530  type StringFuncFloatReducer struct {
  1531  	prev *FloatPoint
  1532  	fn   StringReduceFloatFunc
  1533  }
  1534  
  1535  // NewStringFuncFloatReducer creates a new StringFuncFloatReducer.
  1536  func NewStringFuncFloatReducer(fn StringReduceFloatFunc, prev *FloatPoint) *StringFuncFloatReducer {
  1537  	return &StringFuncFloatReducer{fn: fn, prev: prev}
  1538  }
  1539  
  1540  // AggregateString takes a StringPoint and invokes the reduce function with the
  1541  // current and new point to modify the current point.
  1542  func (r *StringFuncFloatReducer) AggregateString(p *StringPoint) {
  1543  	t, v, aux := r.fn(r.prev, p)
  1544  	if r.prev == nil {
  1545  		r.prev = &FloatPoint{}
  1546  	}
  1547  	r.prev.Time = t
  1548  	r.prev.Value = v
  1549  	r.prev.Aux = aux
  1550  	if p.Aggregated > 1 {
  1551  		r.prev.Aggregated += p.Aggregated
  1552  	} else {
  1553  		r.prev.Aggregated++
  1554  	}
  1555  }
  1556  
  1557  // Emit emits the point that was generated when reducing the points fed in with AggregateString.
  1558  func (r *StringFuncFloatReducer) Emit() []FloatPoint {
  1559  	return []FloatPoint{*r.prev}
  1560  }
  1561  
  1562  // StringReduceFloatSliceFunc is the function called by a StringPoint reducer.
  1563  type StringReduceFloatSliceFunc func(a []StringPoint) []FloatPoint
  1564  
  1565  // StringSliceFuncFloatReducer is a reducer that aggregates
  1566  // the passed in points and then invokes the function to reduce the points when they are emitted.
  1567  type StringSliceFuncFloatReducer struct {
  1568  	points []StringPoint
  1569  	fn     StringReduceFloatSliceFunc
  1570  }
  1571  
  1572  // NewStringSliceFuncFloatReducer creates a new StringSliceFuncFloatReducer.
  1573  func NewStringSliceFuncFloatReducer(fn StringReduceFloatSliceFunc) *StringSliceFuncFloatReducer {
  1574  	return &StringSliceFuncFloatReducer{fn: fn}
  1575  }
  1576  
  1577  // AggregateString copies the StringPoint into the internal slice to be passed
  1578  // to the reduce function when Emit is called.
  1579  func (r *StringSliceFuncFloatReducer) AggregateString(p *StringPoint) {
  1580  	r.points = append(r.points, *p.Clone())
  1581  }
  1582  
  1583  // AggregateStringBulk performs a bulk copy of StringPoints into the internal slice.
  1584  // This is a more efficient version of calling AggregateString on each point.
  1585  func (r *StringSliceFuncFloatReducer) AggregateStringBulk(points []StringPoint) {
  1586  	r.points = append(r.points, points...)
  1587  }
  1588  
  1589  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  1590  // This method does not clear the points from the internal slice.
  1591  func (r *StringSliceFuncFloatReducer) Emit() []FloatPoint {
  1592  	return r.fn(r.points)
  1593  }
  1594  
  1595  // StringReduceIntegerFunc is the function called by a StringPoint reducer.
  1596  type StringReduceIntegerFunc func(prev *IntegerPoint, curr *StringPoint) (t int64, v int64, aux []interface{})
  1597  
  1598  // StringFuncIntegerReducer is a reducer that reduces
  1599  // the passed in points to a single point using a reduce function.
  1600  type StringFuncIntegerReducer struct {
  1601  	prev *IntegerPoint
  1602  	fn   StringReduceIntegerFunc
  1603  }
  1604  
  1605  // NewStringFuncIntegerReducer creates a new StringFuncIntegerReducer.
  1606  func NewStringFuncIntegerReducer(fn StringReduceIntegerFunc, prev *IntegerPoint) *StringFuncIntegerReducer {
  1607  	return &StringFuncIntegerReducer{fn: fn, prev: prev}
  1608  }
  1609  
  1610  // AggregateString takes a StringPoint and invokes the reduce function with the
  1611  // current and new point to modify the current point.
  1612  func (r *StringFuncIntegerReducer) AggregateString(p *StringPoint) {
  1613  	t, v, aux := r.fn(r.prev, p)
  1614  	if r.prev == nil {
  1615  		r.prev = &IntegerPoint{}
  1616  	}
  1617  	r.prev.Time = t
  1618  	r.prev.Value = v
  1619  	r.prev.Aux = aux
  1620  	if p.Aggregated > 1 {
  1621  		r.prev.Aggregated += p.Aggregated
  1622  	} else {
  1623  		r.prev.Aggregated++
  1624  	}
  1625  }
  1626  
  1627  // Emit emits the point that was generated when reducing the points fed in with AggregateString.
  1628  func (r *StringFuncIntegerReducer) Emit() []IntegerPoint {
  1629  	return []IntegerPoint{*r.prev}
  1630  }
  1631  
  1632  // StringReduceIntegerSliceFunc is the function called by a StringPoint reducer.
  1633  type StringReduceIntegerSliceFunc func(a []StringPoint) []IntegerPoint
  1634  
  1635  // StringSliceFuncIntegerReducer is a reducer that aggregates
  1636  // the passed in points and then invokes the function to reduce the points when they are emitted.
  1637  type StringSliceFuncIntegerReducer struct {
  1638  	points []StringPoint
  1639  	fn     StringReduceIntegerSliceFunc
  1640  }
  1641  
  1642  // NewStringSliceFuncIntegerReducer creates a new StringSliceFuncIntegerReducer.
  1643  func NewStringSliceFuncIntegerReducer(fn StringReduceIntegerSliceFunc) *StringSliceFuncIntegerReducer {
  1644  	return &StringSliceFuncIntegerReducer{fn: fn}
  1645  }
  1646  
  1647  // AggregateString copies the StringPoint into the internal slice to be passed
  1648  // to the reduce function when Emit is called.
  1649  func (r *StringSliceFuncIntegerReducer) AggregateString(p *StringPoint) {
  1650  	r.points = append(r.points, *p.Clone())
  1651  }
  1652  
  1653  // AggregateStringBulk performs a bulk copy of StringPoints into the internal slice.
  1654  // This is a more efficient version of calling AggregateString on each point.
  1655  func (r *StringSliceFuncIntegerReducer) AggregateStringBulk(points []StringPoint) {
  1656  	r.points = append(r.points, points...)
  1657  }
  1658  
  1659  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  1660  // This method does not clear the points from the internal slice.
  1661  func (r *StringSliceFuncIntegerReducer) Emit() []IntegerPoint {
  1662  	return r.fn(r.points)
  1663  }
  1664  
  1665  // StringReduceUnsignedFunc is the function called by a StringPoint reducer.
  1666  type StringReduceUnsignedFunc func(prev *UnsignedPoint, curr *StringPoint) (t int64, v uint64, aux []interface{})
  1667  
  1668  // StringFuncUnsignedReducer is a reducer that reduces
  1669  // the passed in points to a single point using a reduce function.
  1670  type StringFuncUnsignedReducer struct {
  1671  	prev *UnsignedPoint
  1672  	fn   StringReduceUnsignedFunc
  1673  }
  1674  
  1675  // NewStringFuncUnsignedReducer creates a new StringFuncUnsignedReducer.
  1676  func NewStringFuncUnsignedReducer(fn StringReduceUnsignedFunc, prev *UnsignedPoint) *StringFuncUnsignedReducer {
  1677  	return &StringFuncUnsignedReducer{fn: fn, prev: prev}
  1678  }
  1679  
  1680  // AggregateString takes a StringPoint and invokes the reduce function with the
  1681  // current and new point to modify the current point.
  1682  func (r *StringFuncUnsignedReducer) AggregateString(p *StringPoint) {
  1683  	t, v, aux := r.fn(r.prev, p)
  1684  	if r.prev == nil {
  1685  		r.prev = &UnsignedPoint{}
  1686  	}
  1687  	r.prev.Time = t
  1688  	r.prev.Value = v
  1689  	r.prev.Aux = aux
  1690  	if p.Aggregated > 1 {
  1691  		r.prev.Aggregated += p.Aggregated
  1692  	} else {
  1693  		r.prev.Aggregated++
  1694  	}
  1695  }
  1696  
  1697  // Emit emits the point that was generated when reducing the points fed in with AggregateString.
  1698  func (r *StringFuncUnsignedReducer) Emit() []UnsignedPoint {
  1699  	return []UnsignedPoint{*r.prev}
  1700  }
  1701  
  1702  // StringReduceUnsignedSliceFunc is the function called by a StringPoint reducer.
  1703  type StringReduceUnsignedSliceFunc func(a []StringPoint) []UnsignedPoint
  1704  
  1705  // StringSliceFuncUnsignedReducer is a reducer that aggregates
  1706  // the passed in points and then invokes the function to reduce the points when they are emitted.
  1707  type StringSliceFuncUnsignedReducer struct {
  1708  	points []StringPoint
  1709  	fn     StringReduceUnsignedSliceFunc
  1710  }
  1711  
  1712  // NewStringSliceFuncUnsignedReducer creates a new StringSliceFuncUnsignedReducer.
  1713  func NewStringSliceFuncUnsignedReducer(fn StringReduceUnsignedSliceFunc) *StringSliceFuncUnsignedReducer {
  1714  	return &StringSliceFuncUnsignedReducer{fn: fn}
  1715  }
  1716  
  1717  // AggregateString copies the StringPoint into the internal slice to be passed
  1718  // to the reduce function when Emit is called.
  1719  func (r *StringSliceFuncUnsignedReducer) AggregateString(p *StringPoint) {
  1720  	r.points = append(r.points, *p.Clone())
  1721  }
  1722  
  1723  // AggregateStringBulk performs a bulk copy of StringPoints into the internal slice.
  1724  // This is a more efficient version of calling AggregateString on each point.
  1725  func (r *StringSliceFuncUnsignedReducer) AggregateStringBulk(points []StringPoint) {
  1726  	r.points = append(r.points, points...)
  1727  }
  1728  
  1729  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  1730  // This method does not clear the points from the internal slice.
  1731  func (r *StringSliceFuncUnsignedReducer) Emit() []UnsignedPoint {
  1732  	return r.fn(r.points)
  1733  }
  1734  
  1735  // StringReduceFunc is the function called by a StringPoint reducer.
  1736  type StringReduceFunc func(prev *StringPoint, curr *StringPoint) (t int64, v string, aux []interface{})
  1737  
  1738  // StringFuncReducer is a reducer that reduces
  1739  // the passed in points to a single point using a reduce function.
  1740  type StringFuncReducer struct {
  1741  	prev *StringPoint
  1742  	fn   StringReduceFunc
  1743  }
  1744  
  1745  // NewStringFuncReducer creates a new StringFuncStringReducer.
  1746  func NewStringFuncReducer(fn StringReduceFunc, prev *StringPoint) *StringFuncReducer {
  1747  	return &StringFuncReducer{fn: fn, prev: prev}
  1748  }
  1749  
  1750  // AggregateString takes a StringPoint and invokes the reduce function with the
  1751  // current and new point to modify the current point.
  1752  func (r *StringFuncReducer) AggregateString(p *StringPoint) {
  1753  	t, v, aux := r.fn(r.prev, p)
  1754  	if r.prev == nil {
  1755  		r.prev = &StringPoint{}
  1756  	}
  1757  	r.prev.Time = t
  1758  	r.prev.Value = v
  1759  	r.prev.Aux = aux
  1760  	if p.Aggregated > 1 {
  1761  		r.prev.Aggregated += p.Aggregated
  1762  	} else {
  1763  		r.prev.Aggregated++
  1764  	}
  1765  }
  1766  
  1767  // Emit emits the point that was generated when reducing the points fed in with AggregateString.
  1768  func (r *StringFuncReducer) Emit() []StringPoint {
  1769  	return []StringPoint{*r.prev}
  1770  }
  1771  
  1772  // StringReduceSliceFunc is the function called by a StringPoint reducer.
  1773  type StringReduceSliceFunc func(a []StringPoint) []StringPoint
  1774  
  1775  // StringSliceFuncReducer is a reducer that aggregates
  1776  // the passed in points and then invokes the function to reduce the points when they are emitted.
  1777  type StringSliceFuncReducer struct {
  1778  	points []StringPoint
  1779  	fn     StringReduceSliceFunc
  1780  }
  1781  
  1782  // NewStringSliceFuncReducer creates a new StringSliceFuncReducer.
  1783  func NewStringSliceFuncReducer(fn StringReduceSliceFunc) *StringSliceFuncReducer {
  1784  	return &StringSliceFuncReducer{fn: fn}
  1785  }
  1786  
  1787  // AggregateString copies the StringPoint into the internal slice to be passed
  1788  // to the reduce function when Emit is called.
  1789  func (r *StringSliceFuncReducer) AggregateString(p *StringPoint) {
  1790  	r.points = append(r.points, *p.Clone())
  1791  }
  1792  
  1793  // AggregateStringBulk performs a bulk copy of StringPoints into the internal slice.
  1794  // This is a more efficient version of calling AggregateString on each point.
  1795  func (r *StringSliceFuncReducer) AggregateStringBulk(points []StringPoint) {
  1796  	r.points = append(r.points, points...)
  1797  }
  1798  
  1799  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  1800  // This method does not clear the points from the internal slice.
  1801  func (r *StringSliceFuncReducer) Emit() []StringPoint {
  1802  	return r.fn(r.points)
  1803  }
  1804  
  1805  // StringReduceBooleanFunc is the function called by a StringPoint reducer.
  1806  type StringReduceBooleanFunc func(prev *BooleanPoint, curr *StringPoint) (t int64, v bool, aux []interface{})
  1807  
  1808  // StringFuncBooleanReducer is a reducer that reduces
  1809  // the passed in points to a single point using a reduce function.
  1810  type StringFuncBooleanReducer struct {
  1811  	prev *BooleanPoint
  1812  	fn   StringReduceBooleanFunc
  1813  }
  1814  
  1815  // NewStringFuncBooleanReducer creates a new StringFuncBooleanReducer.
  1816  func NewStringFuncBooleanReducer(fn StringReduceBooleanFunc, prev *BooleanPoint) *StringFuncBooleanReducer {
  1817  	return &StringFuncBooleanReducer{fn: fn, prev: prev}
  1818  }
  1819  
  1820  // AggregateString takes a StringPoint and invokes the reduce function with the
  1821  // current and new point to modify the current point.
  1822  func (r *StringFuncBooleanReducer) AggregateString(p *StringPoint) {
  1823  	t, v, aux := r.fn(r.prev, p)
  1824  	if r.prev == nil {
  1825  		r.prev = &BooleanPoint{}
  1826  	}
  1827  	r.prev.Time = t
  1828  	r.prev.Value = v
  1829  	r.prev.Aux = aux
  1830  	if p.Aggregated > 1 {
  1831  		r.prev.Aggregated += p.Aggregated
  1832  	} else {
  1833  		r.prev.Aggregated++
  1834  	}
  1835  }
  1836  
  1837  // Emit emits the point that was generated when reducing the points fed in with AggregateString.
  1838  func (r *StringFuncBooleanReducer) Emit() []BooleanPoint {
  1839  	return []BooleanPoint{*r.prev}
  1840  }
  1841  
  1842  // StringReduceBooleanSliceFunc is the function called by a StringPoint reducer.
  1843  type StringReduceBooleanSliceFunc func(a []StringPoint) []BooleanPoint
  1844  
  1845  // StringSliceFuncBooleanReducer is a reducer that aggregates
  1846  // the passed in points and then invokes the function to reduce the points when they are emitted.
  1847  type StringSliceFuncBooleanReducer struct {
  1848  	points []StringPoint
  1849  	fn     StringReduceBooleanSliceFunc
  1850  }
  1851  
  1852  // NewStringSliceFuncBooleanReducer creates a new StringSliceFuncBooleanReducer.
  1853  func NewStringSliceFuncBooleanReducer(fn StringReduceBooleanSliceFunc) *StringSliceFuncBooleanReducer {
  1854  	return &StringSliceFuncBooleanReducer{fn: fn}
  1855  }
  1856  
  1857  // AggregateString copies the StringPoint into the internal slice to be passed
  1858  // to the reduce function when Emit is called.
  1859  func (r *StringSliceFuncBooleanReducer) AggregateString(p *StringPoint) {
  1860  	r.points = append(r.points, *p.Clone())
  1861  }
  1862  
  1863  // AggregateStringBulk performs a bulk copy of StringPoints into the internal slice.
  1864  // This is a more efficient version of calling AggregateString on each point.
  1865  func (r *StringSliceFuncBooleanReducer) AggregateStringBulk(points []StringPoint) {
  1866  	r.points = append(r.points, points...)
  1867  }
  1868  
  1869  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  1870  // This method does not clear the points from the internal slice.
  1871  func (r *StringSliceFuncBooleanReducer) Emit() []BooleanPoint {
  1872  	return r.fn(r.points)
  1873  }
  1874  
  1875  // StringSumHllReducer returns the HLL sketch for a series, in string form
  1876  type StringSumHllReducer struct {
  1877  	plus *hll.Plus
  1878  }
  1879  
  1880  // func NewStringSumHllReducer creates a new StringSumHllReducer
  1881  func NewStringSumHllReducer() *StringSumHllReducer {
  1882  	return &StringSumHllReducer{plus: hll.NewDefaultPlus()}
  1883  }
  1884  
  1885  // AggregateString aggregates a point into the reducer.
  1886  func (r *StringSumHllReducer) AggregateString(p *StringPoint) {
  1887  
  1888  	b := []byte(p.Value)
  1889  
  1890  	r.plus.Add(b)
  1891  }
  1892  
  1893  // Emit emits the distinct points that have been aggregated into the reducer.
  1894  func (r *StringSumHllReducer) Emit() []StringPoint {
  1895  	return []StringPoint{
  1896  		marshalPlus(r.plus, nil),
  1897  	}
  1898  }
  1899  
  1900  // StringDistinctReducer returns the distinct points in a series.
  1901  type StringDistinctReducer struct {
  1902  	m map[string]StringPoint
  1903  }
  1904  
  1905  // NewStringDistinctReducer creates a new StringDistinctReducer.
  1906  func NewStringDistinctReducer() *StringDistinctReducer {
  1907  	return &StringDistinctReducer{m: make(map[string]StringPoint)}
  1908  }
  1909  
  1910  // AggregateString aggregates a point into the reducer.
  1911  func (r *StringDistinctReducer) AggregateString(p *StringPoint) {
  1912  	if _, ok := r.m[p.Value]; !ok {
  1913  		r.m[p.Value] = *p
  1914  	}
  1915  }
  1916  
  1917  // Emit emits the distinct points that have been aggregated into the reducer.
  1918  func (r *StringDistinctReducer) Emit() []StringPoint {
  1919  	points := make([]StringPoint, 0, len(r.m))
  1920  	for _, p := range r.m {
  1921  		points = append(points, StringPoint{Time: p.Time, Value: p.Value})
  1922  	}
  1923  	sort.Sort(stringPoints(points))
  1924  	return points
  1925  }
  1926  
  1927  // StringElapsedReducer calculates the elapsed of the aggregated points.
  1928  type StringElapsedReducer struct {
  1929  	unitConversion int64
  1930  	prev           StringPoint
  1931  	curr           StringPoint
  1932  }
  1933  
  1934  // NewStringElapsedReducer creates a new StringElapsedReducer.
  1935  func NewStringElapsedReducer(interval Interval) *StringElapsedReducer {
  1936  	return &StringElapsedReducer{
  1937  		unitConversion: int64(interval.Duration),
  1938  		prev:           StringPoint{Nil: true},
  1939  		curr:           StringPoint{Nil: true},
  1940  	}
  1941  }
  1942  
  1943  // AggregateString aggregates a point into the reducer and updates the current window.
  1944  func (r *StringElapsedReducer) AggregateString(p *StringPoint) {
  1945  	r.prev = r.curr
  1946  	r.curr = *p
  1947  }
  1948  
  1949  // Emit emits the elapsed of the reducer at the current point.
  1950  func (r *StringElapsedReducer) Emit() []IntegerPoint {
  1951  	if !r.prev.Nil {
  1952  		elapsed := (r.curr.Time - r.prev.Time) / r.unitConversion
  1953  		return []IntegerPoint{
  1954  			{Time: r.curr.Time, Value: elapsed},
  1955  		}
  1956  	}
  1957  	return nil
  1958  }
  1959  
  1960  // StringSampleReducer implements a reservoir sampling to calculate a random subset of points
  1961  type StringSampleReducer struct {
  1962  	count int        // how many points we've iterated over
  1963  	rng   *rand.Rand // random number generator for each reducer
  1964  
  1965  	points stringPoints // the reservoir
  1966  }
  1967  
  1968  // NewStringSampleReducer creates a new StringSampleReducer
  1969  func NewStringSampleReducer(size int) *StringSampleReducer {
  1970  	return &StringSampleReducer{
  1971  		rng:    rand.New(rand.NewSource(time.Now().UnixNano())), // seed with current time as suggested by https://golang.org/pkg/math/rand/
  1972  		points: make(stringPoints, size),
  1973  	}
  1974  }
  1975  
  1976  // AggregateString aggregates a point into the reducer.
  1977  func (r *StringSampleReducer) AggregateString(p *StringPoint) {
  1978  	r.count++
  1979  	// Fill the reservoir with the first n points
  1980  	if r.count-1 < len(r.points) {
  1981  		p.CopyTo(&r.points[r.count-1])
  1982  		return
  1983  	}
  1984  
  1985  	// Generate a random integer between 1 and the count and
  1986  	// if that number is less than the length of the slice
  1987  	// replace the point at that index rnd with p.
  1988  	rnd := r.rng.Intn(r.count)
  1989  	if rnd < len(r.points) {
  1990  		p.CopyTo(&r.points[rnd])
  1991  	}
  1992  }
  1993  
  1994  // Emit emits the reservoir sample as many points.
  1995  func (r *StringSampleReducer) Emit() []StringPoint {
  1996  	min := len(r.points)
  1997  	if r.count < min {
  1998  		min = r.count
  1999  	}
  2000  	pts := r.points[:min]
  2001  	sort.Sort(pts)
  2002  	return pts
  2003  }
  2004  
  2005  // BooleanPointAggregator aggregates points to produce a single point.
  2006  type BooleanPointAggregator interface {
  2007  	AggregateBoolean(p *BooleanPoint)
  2008  }
  2009  
  2010  // BooleanBulkPointAggregator aggregates multiple points at a time.
  2011  type BooleanBulkPointAggregator interface {
  2012  	AggregateBooleanBulk(points []BooleanPoint)
  2013  }
  2014  
  2015  // BooleanPointEmitter produces a single point from an aggregate.
  2016  type BooleanPointEmitter interface {
  2017  	Emit() []BooleanPoint
  2018  }
  2019  
  2020  // BooleanReduceFloatFunc is the function called by a BooleanPoint reducer.
  2021  type BooleanReduceFloatFunc func(prev *FloatPoint, curr *BooleanPoint) (t int64, v float64, aux []interface{})
  2022  
  2023  // BooleanFuncFloatReducer is a reducer that reduces
  2024  // the passed in points to a single point using a reduce function.
  2025  type BooleanFuncFloatReducer struct {
  2026  	prev *FloatPoint
  2027  	fn   BooleanReduceFloatFunc
  2028  }
  2029  
  2030  // NewBooleanFuncFloatReducer creates a new BooleanFuncFloatReducer.
  2031  func NewBooleanFuncFloatReducer(fn BooleanReduceFloatFunc, prev *FloatPoint) *BooleanFuncFloatReducer {
  2032  	return &BooleanFuncFloatReducer{fn: fn, prev: prev}
  2033  }
  2034  
  2035  // AggregateBoolean takes a BooleanPoint and invokes the reduce function with the
  2036  // current and new point to modify the current point.
  2037  func (r *BooleanFuncFloatReducer) AggregateBoolean(p *BooleanPoint) {
  2038  	t, v, aux := r.fn(r.prev, p)
  2039  	if r.prev == nil {
  2040  		r.prev = &FloatPoint{}
  2041  	}
  2042  	r.prev.Time = t
  2043  	r.prev.Value = v
  2044  	r.prev.Aux = aux
  2045  	if p.Aggregated > 1 {
  2046  		r.prev.Aggregated += p.Aggregated
  2047  	} else {
  2048  		r.prev.Aggregated++
  2049  	}
  2050  }
  2051  
  2052  // Emit emits the point that was generated when reducing the points fed in with AggregateBoolean.
  2053  func (r *BooleanFuncFloatReducer) Emit() []FloatPoint {
  2054  	return []FloatPoint{*r.prev}
  2055  }
  2056  
  2057  // BooleanReduceFloatSliceFunc is the function called by a BooleanPoint reducer.
  2058  type BooleanReduceFloatSliceFunc func(a []BooleanPoint) []FloatPoint
  2059  
  2060  // BooleanSliceFuncFloatReducer is a reducer that aggregates
  2061  // the passed in points and then invokes the function to reduce the points when they are emitted.
  2062  type BooleanSliceFuncFloatReducer struct {
  2063  	points []BooleanPoint
  2064  	fn     BooleanReduceFloatSliceFunc
  2065  }
  2066  
  2067  // NewBooleanSliceFuncFloatReducer creates a new BooleanSliceFuncFloatReducer.
  2068  func NewBooleanSliceFuncFloatReducer(fn BooleanReduceFloatSliceFunc) *BooleanSliceFuncFloatReducer {
  2069  	return &BooleanSliceFuncFloatReducer{fn: fn}
  2070  }
  2071  
  2072  // AggregateBoolean copies the BooleanPoint into the internal slice to be passed
  2073  // to the reduce function when Emit is called.
  2074  func (r *BooleanSliceFuncFloatReducer) AggregateBoolean(p *BooleanPoint) {
  2075  	r.points = append(r.points, *p.Clone())
  2076  }
  2077  
  2078  // AggregateBooleanBulk performs a bulk copy of BooleanPoints into the internal slice.
  2079  // This is a more efficient version of calling AggregateBoolean on each point.
  2080  func (r *BooleanSliceFuncFloatReducer) AggregateBooleanBulk(points []BooleanPoint) {
  2081  	r.points = append(r.points, points...)
  2082  }
  2083  
  2084  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  2085  // This method does not clear the points from the internal slice.
  2086  func (r *BooleanSliceFuncFloatReducer) Emit() []FloatPoint {
  2087  	return r.fn(r.points)
  2088  }
  2089  
  2090  // BooleanReduceIntegerFunc is the function called by a BooleanPoint reducer.
  2091  type BooleanReduceIntegerFunc func(prev *IntegerPoint, curr *BooleanPoint) (t int64, v int64, aux []interface{})
  2092  
  2093  // BooleanFuncIntegerReducer is a reducer that reduces
  2094  // the passed in points to a single point using a reduce function.
  2095  type BooleanFuncIntegerReducer struct {
  2096  	prev *IntegerPoint
  2097  	fn   BooleanReduceIntegerFunc
  2098  }
  2099  
  2100  // NewBooleanFuncIntegerReducer creates a new BooleanFuncIntegerReducer.
  2101  func NewBooleanFuncIntegerReducer(fn BooleanReduceIntegerFunc, prev *IntegerPoint) *BooleanFuncIntegerReducer {
  2102  	return &BooleanFuncIntegerReducer{fn: fn, prev: prev}
  2103  }
  2104  
  2105  // AggregateBoolean takes a BooleanPoint and invokes the reduce function with the
  2106  // current and new point to modify the current point.
  2107  func (r *BooleanFuncIntegerReducer) AggregateBoolean(p *BooleanPoint) {
  2108  	t, v, aux := r.fn(r.prev, p)
  2109  	if r.prev == nil {
  2110  		r.prev = &IntegerPoint{}
  2111  	}
  2112  	r.prev.Time = t
  2113  	r.prev.Value = v
  2114  	r.prev.Aux = aux
  2115  	if p.Aggregated > 1 {
  2116  		r.prev.Aggregated += p.Aggregated
  2117  	} else {
  2118  		r.prev.Aggregated++
  2119  	}
  2120  }
  2121  
  2122  // Emit emits the point that was generated when reducing the points fed in with AggregateBoolean.
  2123  func (r *BooleanFuncIntegerReducer) Emit() []IntegerPoint {
  2124  	return []IntegerPoint{*r.prev}
  2125  }
  2126  
  2127  // BooleanReduceIntegerSliceFunc is the function called by a BooleanPoint reducer.
  2128  type BooleanReduceIntegerSliceFunc func(a []BooleanPoint) []IntegerPoint
  2129  
  2130  // BooleanSliceFuncIntegerReducer is a reducer that aggregates
  2131  // the passed in points and then invokes the function to reduce the points when they are emitted.
  2132  type BooleanSliceFuncIntegerReducer struct {
  2133  	points []BooleanPoint
  2134  	fn     BooleanReduceIntegerSliceFunc
  2135  }
  2136  
  2137  // NewBooleanSliceFuncIntegerReducer creates a new BooleanSliceFuncIntegerReducer.
  2138  func NewBooleanSliceFuncIntegerReducer(fn BooleanReduceIntegerSliceFunc) *BooleanSliceFuncIntegerReducer {
  2139  	return &BooleanSliceFuncIntegerReducer{fn: fn}
  2140  }
  2141  
  2142  // AggregateBoolean copies the BooleanPoint into the internal slice to be passed
  2143  // to the reduce function when Emit is called.
  2144  func (r *BooleanSliceFuncIntegerReducer) AggregateBoolean(p *BooleanPoint) {
  2145  	r.points = append(r.points, *p.Clone())
  2146  }
  2147  
  2148  // AggregateBooleanBulk performs a bulk copy of BooleanPoints into the internal slice.
  2149  // This is a more efficient version of calling AggregateBoolean on each point.
  2150  func (r *BooleanSliceFuncIntegerReducer) AggregateBooleanBulk(points []BooleanPoint) {
  2151  	r.points = append(r.points, points...)
  2152  }
  2153  
  2154  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  2155  // This method does not clear the points from the internal slice.
  2156  func (r *BooleanSliceFuncIntegerReducer) Emit() []IntegerPoint {
  2157  	return r.fn(r.points)
  2158  }
  2159  
  2160  // BooleanReduceUnsignedFunc is the function called by a BooleanPoint reducer.
  2161  type BooleanReduceUnsignedFunc func(prev *UnsignedPoint, curr *BooleanPoint) (t int64, v uint64, aux []interface{})
  2162  
  2163  // BooleanFuncUnsignedReducer is a reducer that reduces
  2164  // the passed in points to a single point using a reduce function.
  2165  type BooleanFuncUnsignedReducer struct {
  2166  	prev *UnsignedPoint
  2167  	fn   BooleanReduceUnsignedFunc
  2168  }
  2169  
  2170  // NewBooleanFuncUnsignedReducer creates a new BooleanFuncUnsignedReducer.
  2171  func NewBooleanFuncUnsignedReducer(fn BooleanReduceUnsignedFunc, prev *UnsignedPoint) *BooleanFuncUnsignedReducer {
  2172  	return &BooleanFuncUnsignedReducer{fn: fn, prev: prev}
  2173  }
  2174  
  2175  // AggregateBoolean takes a BooleanPoint and invokes the reduce function with the
  2176  // current and new point to modify the current point.
  2177  func (r *BooleanFuncUnsignedReducer) AggregateBoolean(p *BooleanPoint) {
  2178  	t, v, aux := r.fn(r.prev, p)
  2179  	if r.prev == nil {
  2180  		r.prev = &UnsignedPoint{}
  2181  	}
  2182  	r.prev.Time = t
  2183  	r.prev.Value = v
  2184  	r.prev.Aux = aux
  2185  	if p.Aggregated > 1 {
  2186  		r.prev.Aggregated += p.Aggregated
  2187  	} else {
  2188  		r.prev.Aggregated++
  2189  	}
  2190  }
  2191  
  2192  // Emit emits the point that was generated when reducing the points fed in with AggregateBoolean.
  2193  func (r *BooleanFuncUnsignedReducer) Emit() []UnsignedPoint {
  2194  	return []UnsignedPoint{*r.prev}
  2195  }
  2196  
  2197  // BooleanReduceUnsignedSliceFunc is the function called by a BooleanPoint reducer.
  2198  type BooleanReduceUnsignedSliceFunc func(a []BooleanPoint) []UnsignedPoint
  2199  
  2200  // BooleanSliceFuncUnsignedReducer is a reducer that aggregates
  2201  // the passed in points and then invokes the function to reduce the points when they are emitted.
  2202  type BooleanSliceFuncUnsignedReducer struct {
  2203  	points []BooleanPoint
  2204  	fn     BooleanReduceUnsignedSliceFunc
  2205  }
  2206  
  2207  // NewBooleanSliceFuncUnsignedReducer creates a new BooleanSliceFuncUnsignedReducer.
  2208  func NewBooleanSliceFuncUnsignedReducer(fn BooleanReduceUnsignedSliceFunc) *BooleanSliceFuncUnsignedReducer {
  2209  	return &BooleanSliceFuncUnsignedReducer{fn: fn}
  2210  }
  2211  
  2212  // AggregateBoolean copies the BooleanPoint into the internal slice to be passed
  2213  // to the reduce function when Emit is called.
  2214  func (r *BooleanSliceFuncUnsignedReducer) AggregateBoolean(p *BooleanPoint) {
  2215  	r.points = append(r.points, *p.Clone())
  2216  }
  2217  
  2218  // AggregateBooleanBulk performs a bulk copy of BooleanPoints into the internal slice.
  2219  // This is a more efficient version of calling AggregateBoolean on each point.
  2220  func (r *BooleanSliceFuncUnsignedReducer) AggregateBooleanBulk(points []BooleanPoint) {
  2221  	r.points = append(r.points, points...)
  2222  }
  2223  
  2224  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  2225  // This method does not clear the points from the internal slice.
  2226  func (r *BooleanSliceFuncUnsignedReducer) Emit() []UnsignedPoint {
  2227  	return r.fn(r.points)
  2228  }
  2229  
  2230  // BooleanReduceStringFunc is the function called by a BooleanPoint reducer.
  2231  type BooleanReduceStringFunc func(prev *StringPoint, curr *BooleanPoint) (t int64, v string, aux []interface{})
  2232  
  2233  // BooleanFuncStringReducer is a reducer that reduces
  2234  // the passed in points to a single point using a reduce function.
  2235  type BooleanFuncStringReducer struct {
  2236  	prev *StringPoint
  2237  	fn   BooleanReduceStringFunc
  2238  }
  2239  
  2240  // NewBooleanFuncStringReducer creates a new BooleanFuncStringReducer.
  2241  func NewBooleanFuncStringReducer(fn BooleanReduceStringFunc, prev *StringPoint) *BooleanFuncStringReducer {
  2242  	return &BooleanFuncStringReducer{fn: fn, prev: prev}
  2243  }
  2244  
  2245  // AggregateBoolean takes a BooleanPoint and invokes the reduce function with the
  2246  // current and new point to modify the current point.
  2247  func (r *BooleanFuncStringReducer) AggregateBoolean(p *BooleanPoint) {
  2248  	t, v, aux := r.fn(r.prev, p)
  2249  	if r.prev == nil {
  2250  		r.prev = &StringPoint{}
  2251  	}
  2252  	r.prev.Time = t
  2253  	r.prev.Value = v
  2254  	r.prev.Aux = aux
  2255  	if p.Aggregated > 1 {
  2256  		r.prev.Aggregated += p.Aggregated
  2257  	} else {
  2258  		r.prev.Aggregated++
  2259  	}
  2260  }
  2261  
  2262  // Emit emits the point that was generated when reducing the points fed in with AggregateBoolean.
  2263  func (r *BooleanFuncStringReducer) Emit() []StringPoint {
  2264  	return []StringPoint{*r.prev}
  2265  }
  2266  
  2267  // BooleanReduceStringSliceFunc is the function called by a BooleanPoint reducer.
  2268  type BooleanReduceStringSliceFunc func(a []BooleanPoint) []StringPoint
  2269  
  2270  // BooleanSliceFuncStringReducer is a reducer that aggregates
  2271  // the passed in points and then invokes the function to reduce the points when they are emitted.
  2272  type BooleanSliceFuncStringReducer struct {
  2273  	points []BooleanPoint
  2274  	fn     BooleanReduceStringSliceFunc
  2275  }
  2276  
  2277  // NewBooleanSliceFuncStringReducer creates a new BooleanSliceFuncStringReducer.
  2278  func NewBooleanSliceFuncStringReducer(fn BooleanReduceStringSliceFunc) *BooleanSliceFuncStringReducer {
  2279  	return &BooleanSliceFuncStringReducer{fn: fn}
  2280  }
  2281  
  2282  // AggregateBoolean copies the BooleanPoint into the internal slice to be passed
  2283  // to the reduce function when Emit is called.
  2284  func (r *BooleanSliceFuncStringReducer) AggregateBoolean(p *BooleanPoint) {
  2285  	r.points = append(r.points, *p.Clone())
  2286  }
  2287  
  2288  // AggregateBooleanBulk performs a bulk copy of BooleanPoints into the internal slice.
  2289  // This is a more efficient version of calling AggregateBoolean on each point.
  2290  func (r *BooleanSliceFuncStringReducer) AggregateBooleanBulk(points []BooleanPoint) {
  2291  	r.points = append(r.points, points...)
  2292  }
  2293  
  2294  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  2295  // This method does not clear the points from the internal slice.
  2296  func (r *BooleanSliceFuncStringReducer) Emit() []StringPoint {
  2297  	return r.fn(r.points)
  2298  }
  2299  
  2300  // BooleanReduceFunc is the function called by a BooleanPoint reducer.
  2301  type BooleanReduceFunc func(prev *BooleanPoint, curr *BooleanPoint) (t int64, v bool, aux []interface{})
  2302  
  2303  // BooleanFuncReducer is a reducer that reduces
  2304  // the passed in points to a single point using a reduce function.
  2305  type BooleanFuncReducer struct {
  2306  	prev *BooleanPoint
  2307  	fn   BooleanReduceFunc
  2308  }
  2309  
  2310  // NewBooleanFuncReducer creates a new BooleanFuncBooleanReducer.
  2311  func NewBooleanFuncReducer(fn BooleanReduceFunc, prev *BooleanPoint) *BooleanFuncReducer {
  2312  	return &BooleanFuncReducer{fn: fn, prev: prev}
  2313  }
  2314  
  2315  // AggregateBoolean takes a BooleanPoint and invokes the reduce function with the
  2316  // current and new point to modify the current point.
  2317  func (r *BooleanFuncReducer) AggregateBoolean(p *BooleanPoint) {
  2318  	t, v, aux := r.fn(r.prev, p)
  2319  	if r.prev == nil {
  2320  		r.prev = &BooleanPoint{}
  2321  	}
  2322  	r.prev.Time = t
  2323  	r.prev.Value = v
  2324  	r.prev.Aux = aux
  2325  	if p.Aggregated > 1 {
  2326  		r.prev.Aggregated += p.Aggregated
  2327  	} else {
  2328  		r.prev.Aggregated++
  2329  	}
  2330  }
  2331  
  2332  // Emit emits the point that was generated when reducing the points fed in with AggregateBoolean.
  2333  func (r *BooleanFuncReducer) Emit() []BooleanPoint {
  2334  	return []BooleanPoint{*r.prev}
  2335  }
  2336  
  2337  // BooleanReduceSliceFunc is the function called by a BooleanPoint reducer.
  2338  type BooleanReduceSliceFunc func(a []BooleanPoint) []BooleanPoint
  2339  
  2340  // BooleanSliceFuncReducer is a reducer that aggregates
  2341  // the passed in points and then invokes the function to reduce the points when they are emitted.
  2342  type BooleanSliceFuncReducer struct {
  2343  	points []BooleanPoint
  2344  	fn     BooleanReduceSliceFunc
  2345  }
  2346  
  2347  // NewBooleanSliceFuncReducer creates a new BooleanSliceFuncReducer.
  2348  func NewBooleanSliceFuncReducer(fn BooleanReduceSliceFunc) *BooleanSliceFuncReducer {
  2349  	return &BooleanSliceFuncReducer{fn: fn}
  2350  }
  2351  
  2352  // AggregateBoolean copies the BooleanPoint into the internal slice to be passed
  2353  // to the reduce function when Emit is called.
  2354  func (r *BooleanSliceFuncReducer) AggregateBoolean(p *BooleanPoint) {
  2355  	r.points = append(r.points, *p.Clone())
  2356  }
  2357  
  2358  // AggregateBooleanBulk performs a bulk copy of BooleanPoints into the internal slice.
  2359  // This is a more efficient version of calling AggregateBoolean on each point.
  2360  func (r *BooleanSliceFuncReducer) AggregateBooleanBulk(points []BooleanPoint) {
  2361  	r.points = append(r.points, points...)
  2362  }
  2363  
  2364  // Emit invokes the reduce function on the aggregated points to generate the aggregated points.
  2365  // This method does not clear the points from the internal slice.
  2366  func (r *BooleanSliceFuncReducer) Emit() []BooleanPoint {
  2367  	return r.fn(r.points)
  2368  }
  2369  
  2370  // BooleanSumHllReducer returns the HLL sketch for a series, in string form
  2371  type BooleanSumHllReducer struct {
  2372  	plus *hll.Plus
  2373  }
  2374  
  2375  // func NewBooleanSumHllReducer creates a new BooleanSumHllReducer
  2376  func NewBooleanSumHllReducer() *BooleanSumHllReducer {
  2377  	return &BooleanSumHllReducer{plus: hll.NewDefaultPlus()}
  2378  }
  2379  
  2380  // AggregateBoolean aggregates a point into the reducer.
  2381  func (r *BooleanSumHllReducer) AggregateBoolean(p *BooleanPoint) {
  2382  
  2383  	buf := new(bytes.Buffer)
  2384  	binary.Write(buf, binary.BigEndian, p.Value)
  2385  	b := buf.Bytes()
  2386  
  2387  	r.plus.Add(b)
  2388  }
  2389  
  2390  // Emit emits the distinct points that have been aggregated into the reducer.
  2391  func (r *BooleanSumHllReducer) Emit() []StringPoint {
  2392  	return []StringPoint{
  2393  		marshalPlus(r.plus, nil),
  2394  	}
  2395  }
  2396  
  2397  // BooleanDistinctReducer returns the distinct points in a series.
  2398  type BooleanDistinctReducer struct {
  2399  	m map[bool]BooleanPoint
  2400  }
  2401  
  2402  // NewBooleanDistinctReducer creates a new BooleanDistinctReducer.
  2403  func NewBooleanDistinctReducer() *BooleanDistinctReducer {
  2404  	return &BooleanDistinctReducer{m: make(map[bool]BooleanPoint)}
  2405  }
  2406  
  2407  // AggregateBoolean aggregates a point into the reducer.
  2408  func (r *BooleanDistinctReducer) AggregateBoolean(p *BooleanPoint) {
  2409  	if _, ok := r.m[p.Value]; !ok {
  2410  		r.m[p.Value] = *p
  2411  	}
  2412  }
  2413  
  2414  // Emit emits the distinct points that have been aggregated into the reducer.
  2415  func (r *BooleanDistinctReducer) Emit() []BooleanPoint {
  2416  	points := make([]BooleanPoint, 0, len(r.m))
  2417  	for _, p := range r.m {
  2418  		points = append(points, BooleanPoint{Time: p.Time, Value: p.Value})
  2419  	}
  2420  	sort.Sort(booleanPoints(points))
  2421  	return points
  2422  }
  2423  
  2424  // BooleanElapsedReducer calculates the elapsed of the aggregated points.
  2425  type BooleanElapsedReducer struct {
  2426  	unitConversion int64
  2427  	prev           BooleanPoint
  2428  	curr           BooleanPoint
  2429  }
  2430  
  2431  // NewBooleanElapsedReducer creates a new BooleanElapsedReducer.
  2432  func NewBooleanElapsedReducer(interval Interval) *BooleanElapsedReducer {
  2433  	return &BooleanElapsedReducer{
  2434  		unitConversion: int64(interval.Duration),
  2435  		prev:           BooleanPoint{Nil: true},
  2436  		curr:           BooleanPoint{Nil: true},
  2437  	}
  2438  }
  2439  
  2440  // AggregateBoolean aggregates a point into the reducer and updates the current window.
  2441  func (r *BooleanElapsedReducer) AggregateBoolean(p *BooleanPoint) {
  2442  	r.prev = r.curr
  2443  	r.curr = *p
  2444  }
  2445  
  2446  // Emit emits the elapsed of the reducer at the current point.
  2447  func (r *BooleanElapsedReducer) Emit() []IntegerPoint {
  2448  	if !r.prev.Nil {
  2449  		elapsed := (r.curr.Time - r.prev.Time) / r.unitConversion
  2450  		return []IntegerPoint{
  2451  			{Time: r.curr.Time, Value: elapsed},
  2452  		}
  2453  	}
  2454  	return nil
  2455  }
  2456  
  2457  // BooleanSampleReducer implements a reservoir sampling to calculate a random subset of points
  2458  type BooleanSampleReducer struct {
  2459  	count int        // how many points we've iterated over
  2460  	rng   *rand.Rand // random number generator for each reducer
  2461  
  2462  	points booleanPoints // the reservoir
  2463  }
  2464  
  2465  // NewBooleanSampleReducer creates a new BooleanSampleReducer
  2466  func NewBooleanSampleReducer(size int) *BooleanSampleReducer {
  2467  	return &BooleanSampleReducer{
  2468  		rng:    rand.New(rand.NewSource(time.Now().UnixNano())), // seed with current time as suggested by https://golang.org/pkg/math/rand/
  2469  		points: make(booleanPoints, size),
  2470  	}
  2471  }
  2472  
  2473  // AggregateBoolean aggregates a point into the reducer.
  2474  func (r *BooleanSampleReducer) AggregateBoolean(p *BooleanPoint) {
  2475  	r.count++
  2476  	// Fill the reservoir with the first n points
  2477  	if r.count-1 < len(r.points) {
  2478  		p.CopyTo(&r.points[r.count-1])
  2479  		return
  2480  	}
  2481  
  2482  	// Generate a random integer between 1 and the count and
  2483  	// if that number is less than the length of the slice
  2484  	// replace the point at that index rnd with p.
  2485  	rnd := r.rng.Intn(r.count)
  2486  	if rnd < len(r.points) {
  2487  		p.CopyTo(&r.points[rnd])
  2488  	}
  2489  }
  2490  
  2491  // Emit emits the reservoir sample as many points.
  2492  func (r *BooleanSampleReducer) Emit() []BooleanPoint {
  2493  	min := len(r.points)
  2494  	if r.count < min {
  2495  		min = r.count
  2496  	}
  2497  	pts := r.points[:min]
  2498  	sort.Sort(pts)
  2499  	return pts
  2500  }