func (r *IntegerFuncFloatReducer) AggregateInteger(p *IntegerPoint) {
	t, v, aux := r.fn(r.prev, p)
	if r.prev == nil {
		r.prev = &FloatPoint{}
	}
	r.prev.Time = t
	r.prev.Value = v
	r.prev.Aux = aux
	if p.Aggregated > 1 {
		r.prev.Aggregated += p.Aggregated
	} else {
		r.prev.Aggregated++
	}
}
AggregateInteger takes a IntegerPoint and invokes the reduce function with the
current and new point to modify the current point.
package query
import (
	"math/rand"
	"sort"
	"time"
)
type FloatPointAggregator interface {
	AggregateFloat(p *FloatPoint)
}
type FloatBulkPointAggregator interface {
	AggregateFloatBulk(points []FloatPoint)
}
func AggregateFloatPoints(a FloatPointAggregator, points []FloatPoint) {
	switch a := a.(type) {
	case FloatBulkPointAggregator:
		a.AggregateFloatBulk(points)
	default:
		for _, p := range points {
			a.AggregateFloat(&p)
		}
	}
}
type FloatPointEmitter interface {
	Emit() []FloatPoint
}
type FloatReduceFunc func(prev *FloatPoint, curr *FloatPoint) (t int64, v float64, aux []interface{})
type FloatFuncReducer struct {
	prev *FloatPoint
	fn   FloatReduceFunc
}
func NewFloatFuncReducer(fn FloatReduceFunc, prev *FloatPoint) *FloatFuncReducer {
	return &FloatFuncReducer{fn: fn, prev: prev}
}
func (r *FloatFuncReducer) AggregateFloat(p *FloatPoint) {
	t, v, aux := r.fn(r.prev, p)
	if r.prev == nil {
		r.prev = &FloatPoint{}
	}
	r.prev.Time = t
	r.prev.Value = v
	r.prev.Aux = aux
	if p.Aggregated > 1 {
		r.prev.Aggregated += p.Aggregated
	} else {
		r.prev.Aggregated++
	}
}
func (r *FloatFuncReducer) Emit() []FloatPoint {
	return []FloatPoint{*r.prev}
}
type FloatReduceSliceFunc func(a []FloatPoint) []FloatPoint
type FloatSliceFuncReducer struct {
	points []FloatPoint
	fn     FloatReduceSliceFunc
}
func NewFloatSliceFuncReducer(fn FloatReduceSliceFunc) *FloatSliceFuncReducer {
	return &FloatSliceFuncReducer{fn: fn}
}
func (r *FloatSliceFuncReducer) AggregateFloat(p *FloatPoint) {
	r.points = append(r.points, *p.Clone())
}
func (r *FloatSliceFuncReducer) AggregateFloatBulk(points []FloatPoint) {
	r.points = append(r.points, points...)
}
func (r *FloatSliceFuncReducer) Emit() []FloatPoint {
	return r.fn(r.points)
}
type FloatReduceIntegerFunc func(prev *IntegerPoint, curr *FloatPoint) (t int64, v int64, aux []interface{})
type FloatFuncIntegerReducer struct {
	prev *IntegerPoint
	fn   FloatReduceIntegerFunc
}
func NewFloatFuncIntegerReducer(fn FloatReduceIntegerFunc, prev *IntegerPoint) *FloatFuncIntegerReducer {
	return &FloatFuncIntegerReducer{fn: fn, prev: prev}
}
func (r *FloatFuncIntegerReducer) AggregateFloat(p *FloatPoint) {
	t, v, aux := r.fn(r.prev, p)
	if r.prev == nil {
		r.prev = &IntegerPoint{}
	}
	r.prev.Time = t
	r.prev.Value = v
	r.prev.Aux = aux
	if p.Aggregated > 1 {
		r.prev.Aggregated += p.Aggregated
	} else {
		r.prev.Aggregated++
	}
}
func (r *FloatFuncIntegerReducer) Emit() []IntegerPoint {
	return []IntegerPoint{*r.prev}
}
type FloatReduceIntegerSliceFunc func(a []FloatPoint) []IntegerPoint
type FloatSliceFuncIntegerReducer struct {
	points []FloatPoint
	fn     FloatReduceIntegerSliceFunc
}
func NewFloatSliceFuncIntegerReducer(fn FloatReduceIntegerSliceFunc) *FloatSliceFuncIntegerReducer {
	return &FloatSliceFuncIntegerReducer{fn: fn}
}
func (r *FloatSliceFuncIntegerReducer) AggregateFloat(p *FloatPoint) {
	r.points = append(r.points, *p.Clone())
}
func (r *FloatSliceFuncIntegerReducer) AggregateFloatBulk(points []FloatPoint) {
	r.points = append(r.points, points...)
}
func (r *FloatSliceFuncIntegerReducer) Emit() []IntegerPoint {
	return r.fn(r.points)
}
type FloatReduceUnsignedFunc func(prev *UnsignedPoint, curr *FloatPoint) (t int64, v uint64, aux []interface{})
type FloatFuncUnsignedReducer struct {
	prev *UnsignedPoint
	fn   FloatReduceUnsignedFunc
}
func NewFloatFuncUnsignedReducer(fn FloatReduceUnsignedFunc, prev *UnsignedPoint) *FloatFuncUnsignedReducer {
	return &FloatFuncUnsignedReducer{fn: fn, prev: prev}
}
func (r *FloatFuncUnsignedReducer) AggregateFloat(p *FloatPoint) {
	t, v, aux := r.fn(r.prev, p)
	if r.prev == nil {
		r.prev = &UnsignedPoint{}
	}
	r.prev.Time = t
	r.prev.Value = v
	r.prev.Aux = aux
	if p.Aggregated > 1 {
		r.prev.Aggregated += p.Aggregated
	} else {
		r.prev.Aggregated++
	}
}
func (r *FloatFuncUnsignedReducer) Emit() []UnsignedPoint {
	return []UnsignedPoint{*r.prev}
}
type FloatReduceUnsignedSliceFunc func(a []FloatPoint) []UnsignedPoint
type FloatSliceFuncUnsignedReducer struct {
	points []FloatPoint
	fn     FloatReduceUnsignedSliceFunc
}
func NewFloatSliceFuncUnsignedReducer(fn FloatReduceUnsignedSliceFunc) *FloatSliceFuncUnsignedReducer {
	return &FloatSliceFuncUnsignedReducer{fn: fn}
}
func (r *FloatSliceFuncUnsignedReducer) AggregateFloat(p *FloatPoint) {
	r.points = append(r.points, *p.Clone())
}
func (r *FloatSliceFuncUnsignedReducer) AggregateFloatBulk(points []FloatPoint) {
	r.points = append(r.points, points...)
}
func (r *FloatSliceFuncUnsignedReducer) Emit() []UnsignedPoint {
	return r.fn(r.points)
}
type FloatReduceStringFunc func(prev *StringPoint, curr *FloatPoint) (t int64, v string, aux []interface{})
type FloatFuncStringReducer struct {
	prev *StringPoint
	fn   FloatReduceStringFunc
}
func NewFloatFuncStringReducer(fn FloatReduceStringFunc, prev *StringPoint) *FloatFuncStringReducer {
	return &FloatFuncStringReducer{fn: fn, prev: prev}
}
func (r *FloatFuncStringReducer) AggregateFloat(p *FloatPoint) {
	t, v, aux := r.fn(r.prev, p)
	if r.prev == nil {
		r.prev = &StringPoint{}
	}
	r.prev.Time = t
	r.prev.Value = v
	r.prev.Aux = aux
	if p.Aggregated > 1 {
		r.prev.Aggregated += p.Aggregated
	} else {
		r.prev.Aggregated++
	}
}
func (r *FloatFuncStringReducer) Emit() []StringPoint {
	return []StringPoint{*r.prev}
}
type FloatReduceStringSliceFunc func(a []FloatPoint) []StringPoint
type FloatSliceFuncStringReducer struct {
	points []FloatPoint
	fn     FloatReduceStringSliceFunc
}
func NewFloatSliceFuncStringReducer(fn FloatReduceStringSliceFunc) *FloatSliceFuncStringReducer {
	return &FloatSliceFuncStringReducer{fn: fn}
}
func (r *FloatSliceFuncStringReducer) AggregateFloat(p *FloatPoint) {
	r.points = append(r.points, *p.Clone())
}
func (r *FloatSliceFuncStringReducer) AggregateFloatBulk(points []FloatPoint) {
	r.points = append(r.points, points...)
}
func (r *FloatSliceFuncStringReducer) Emit() []StringPoint {
	return r.fn(r.points)
}
type FloatReduceBooleanFunc func(prev *BooleanPoint, curr *FloatPoint) (t int64, v bool, aux []interface{})
type FloatFuncBooleanReducer struct {
	prev *BooleanPoint
	fn   FloatReduceBooleanFunc
}
func NewFloatFuncBooleanReducer(fn FloatReduceBooleanFunc, prev *BooleanPoint) *FloatFuncBooleanReducer {
	return &FloatFuncBooleanReducer{fn: fn, prev: prev}
}
func (r *FloatFuncBooleanReducer) AggregateFloat(p *FloatPoint) {
	t, v, aux := r.fn(r.prev, p)
	if r.prev == nil {
		r.prev = &BooleanPoint{}
	}
	r.prev.Time = t
	r.prev.Value = v
	r.prev.Aux = aux
	if p.Aggregated > 1 {
		r.prev.Aggregated += p.Aggregated
	} else {
		r.prev.Aggregated++
	}
}
func (r *FloatFuncBooleanReducer) Emit() []BooleanPoint {
	return []BooleanPoint{*r.prev}
}
type FloatReduceBooleanSliceFunc func(a []FloatPoint) []BooleanPoint
type FloatSliceFuncBooleanReducer struct {
	points []FloatPoint
	fn     FloatReduceBooleanSliceFunc
}
func NewFloatSliceFuncBooleanReducer(fn FloatReduceBooleanSliceFunc) *FloatSliceFuncBooleanReducer {
	return &FloatSliceFuncBooleanReducer{fn: fn}
}
func (r *FloatSliceFuncBooleanReducer) AggregateFloat(p *FloatPoint) {
	r.points = append(r.points, *p.Clone())
}
func (r *FloatSliceFuncBooleanReducer) AggregateFloatBulk(points []FloatPoint) {
	r.points = append(r.points, points...)
}
func (r *FloatSliceFuncBooleanReducer) Emit() []BooleanPoint {
	return r.fn(r.points)
}
type FloatDistinctReducer struct {
	m map[float64]FloatPoint
}
func NewFloatDistinctReducer() *FloatDistinctReducer {
	return &FloatDistinctReducer{m: make(map[float64]FloatPoint)}
}
func (r *FloatDistinctReducer) AggregateFloat(p *FloatPoint) {
	if _, ok := r.m[p.Value]; !ok {
		r.m[p.Value] = *p
	}
}
func (r *FloatDistinctReducer) Emit() []FloatPoint {
	points := make([]FloatPoint, 0, len(r.m))
	for _, p := range r.m {
		points = append(points, FloatPoint{Time: p.Time, Value: p.Value})
	}
	sort.Sort(floatPoints(points))
	return points
}
type FloatElapsedReducer struct {
	unitConversion int64
	prev           FloatPoint
	curr           FloatPoint
}
func NewFloatElapsedReducer(interval Interval) *FloatElapsedReducer {
	return &FloatElapsedReducer{
		unitConversion: int64(interval.Duration),
		prev:           FloatPoint{Nil: true},
		curr:           FloatPoint{Nil: true},
	}
}
func (r *FloatElapsedReducer) AggregateFloat(p *FloatPoint) {
	r.prev = r.curr
	r.curr = *p
}
func (r *FloatElapsedReducer) Emit() []IntegerPoint {
	if !r.prev.Nil {
		elapsed := (r.curr.Time - r.prev.Time) / r.unitConversion
		return []IntegerPoint{
			{Time: r.curr.Time, Value: elapsed},
		}
	}
	return nil
}
type FloatSampleReducer struct {
	count int         
	rng   *rand.Rand  
	points floatPoints  
}
func NewFloatSampleReducer(size int) *FloatSampleReducer {
	return &FloatSampleReducer{
		rng:    rand.New(rand.NewSource(time.Now().UnixNano())),  
		points: make(floatPoints, size),
	}
}
func (r *FloatSampleReducer) AggregateFloat(p *FloatPoint) {
	r.count++
	if r.count-1 < len(r.points) {
		p.CopyTo(&r.points[r.count-1])
		return
	}
	rnd := r.rng.Intn(r.count)
	if rnd < len(r.points) {
		p.CopyTo(&r.points[rnd])
	}
}
func (r *FloatSampleReducer) Emit() []FloatPoint {
	min := len(r.points)
	if r.count < min {
		min = r.count
	}
	pts := r.points[:min]
	sort.Sort(pts)
	return pts
}
type IntegerPointAggregator interface {
	AggregateInteger(p *IntegerPoint)
}
type IntegerBulkPointAggregator interface {
	AggregateIntegerBulk(points []IntegerPoint)
}
func AggregateIntegerPoints(a IntegerPointAggregator, points []IntegerPoint) {
	switch a := a.(type) {
	case IntegerBulkPointAggregator:
		a.AggregateIntegerBulk(points)
	default:
		for _, p := range points {
			a.AggregateInteger(&p)
		}
	}
}
type IntegerPointEmitter interface {
	Emit() []IntegerPoint
}
type IntegerReduceFloatFunc func(prev *FloatPoint, curr *IntegerPoint) (t int64, v float64, aux []interface{})
type IntegerFuncFloatReducer struct {
	prev *FloatPoint
	fn   IntegerReduceFloatFunc
}
func NewIntegerFuncFloatReducer(fn IntegerReduceFloatFunc, prev *FloatPoint) *IntegerFuncFloatReducer {
	return &IntegerFuncFloatReducer{fn: fn, prev: prev}
}