1// Generated by tmpl
2// https://github.com/benbjohnson/tmpl
3//
4// DO NOT EDIT!
5// Source: iterator.gen.go.tmpl
6
7package query
8
9import (
10	"container/heap"
11	"context"
12	"io"
13	"sort"
14	"sync"
15	"time"
16
17	"github.com/gogo/protobuf/proto"
18	"github.com/influxdata/influxql"
19)
20
21// DefaultStatsInterval is the default value for IteratorEncoder.StatsInterval.
22const DefaultStatsInterval = time.Second
23
24// FloatIterator represents a stream of float points.
25type FloatIterator interface {
26	Iterator
27	Next() (*FloatPoint, error)
28}
29
30// newFloatIterators converts a slice of Iterator to a slice of FloatIterator.
31// Drop and closes any iterator in itrs that is not a FloatIterator and cannot
32// be cast to a FloatIterator.
33func newFloatIterators(itrs []Iterator) []FloatIterator {
34	a := make([]FloatIterator, 0, len(itrs))
35	for _, itr := range itrs {
36		switch itr := itr.(type) {
37		case FloatIterator:
38			a = append(a, itr)
39		default:
40			itr.Close()
41		}
42	}
43	return a
44}
45
46// bufFloatIterator represents a buffered FloatIterator.
47type bufFloatIterator struct {
48	itr FloatIterator
49	buf *FloatPoint
50}
51
52// newBufFloatIterator returns a buffered FloatIterator.
53func newBufFloatIterator(itr FloatIterator) *bufFloatIterator {
54	return &bufFloatIterator{itr: itr}
55}
56
57// Stats returns statistics from the input iterator.
58func (itr *bufFloatIterator) Stats() IteratorStats { return itr.itr.Stats() }
59
60// Close closes the underlying iterator.
61func (itr *bufFloatIterator) Close() error { return itr.itr.Close() }
62
63// peek returns the next point without removing it from the iterator.
64func (itr *bufFloatIterator) peek() (*FloatPoint, error) {
65	p, err := itr.Next()
66	if err != nil {
67		return nil, err
68	}
69	itr.unread(p)
70	return p, nil
71}
72
73// peekTime returns the time of the next point.
74// Returns zero time if no more points available.
75func (itr *bufFloatIterator) peekTime() (int64, error) {
76	p, err := itr.peek()
77	if p == nil || err != nil {
78		return ZeroTime, err
79	}
80	return p.Time, nil
81}
82
83// Next returns the current buffer, if exists, or calls the underlying iterator.
84func (itr *bufFloatIterator) Next() (*FloatPoint, error) {
85	buf := itr.buf
86	if buf != nil {
87		itr.buf = nil
88		return buf, nil
89	}
90	return itr.itr.Next()
91}
92
93// NextInWindow returns the next value if it is between [startTime, endTime).
94// If the next value is outside the range then it is moved to the buffer.
95func (itr *bufFloatIterator) NextInWindow(startTime, endTime int64) (*FloatPoint, error) {
96	v, err := itr.Next()
97	if v == nil || err != nil {
98		return nil, err
99	} else if t := v.Time; t >= endTime || t < startTime {
100		itr.unread(v)
101		return nil, nil
102	}
103	return v, nil
104}
105
106// unread sets v to the buffer. It is read on the next call to Next().
107func (itr *bufFloatIterator) unread(v *FloatPoint) { itr.buf = v }
108
109// floatMergeIterator represents an iterator that combines multiple float iterators.
110type floatMergeIterator struct {
111	inputs []FloatIterator
112	heap   *floatMergeHeap
113	init   bool
114
115	closed bool
116	mu     sync.RWMutex
117
118	// Current iterator and window.
119	curr   *floatMergeHeapItem
120	window struct {
121		name      string
122		tags      string
123		startTime int64
124		endTime   int64
125	}
126}
127
128// newFloatMergeIterator returns a new instance of floatMergeIterator.
129func newFloatMergeIterator(inputs []FloatIterator, opt IteratorOptions) *floatMergeIterator {
130	itr := &floatMergeIterator{
131		inputs: inputs,
132		heap: &floatMergeHeap{
133			items: make([]*floatMergeHeapItem, 0, len(inputs)),
134			opt:   opt,
135		},
136	}
137
138	// Initialize heap items.
139	for _, input := range inputs {
140		// Wrap in buffer, ignore any inputs without anymore points.
141		bufInput := newBufFloatIterator(input)
142
143		// Append to the heap.
144		itr.heap.items = append(itr.heap.items, &floatMergeHeapItem{itr: bufInput})
145	}
146
147	return itr
148}
149
150// Stats returns an aggregation of stats from the underlying iterators.
151func (itr *floatMergeIterator) Stats() IteratorStats {
152	var stats IteratorStats
153	for _, input := range itr.inputs {
154		stats.Add(input.Stats())
155	}
156	return stats
157}
158
159// Close closes the underlying iterators.
160func (itr *floatMergeIterator) Close() error {
161	itr.mu.Lock()
162	defer itr.mu.Unlock()
163
164	for _, input := range itr.inputs {
165		input.Close()
166	}
167	itr.curr = nil
168	itr.inputs = nil
169	itr.heap.items = nil
170	itr.closed = true
171	return nil
172}
173
174// Next returns the next point from the iterator.
175func (itr *floatMergeIterator) Next() (*FloatPoint, error) {
176	itr.mu.RLock()
177	defer itr.mu.RUnlock()
178	if itr.closed {
179		return nil, nil
180	}
181
182	// Initialize the heap. This needs to be done lazily on the first call to this iterator
183	// so that iterator initialization done through the Select() call returns quickly.
184	// Queries can only be interrupted after the Select() call completes so any operations
185	// done during iterator creation cannot be interrupted, which is why we do it here
186	// instead so an interrupt can happen while initializing the heap.
187	if !itr.init {
188		items := itr.heap.items
189		itr.heap.items = make([]*floatMergeHeapItem, 0, len(items))
190		for _, item := range items {
191			if p, err := item.itr.peek(); err != nil {
192				return nil, err
193			} else if p == nil {
194				continue
195			}
196			itr.heap.items = append(itr.heap.items, item)
197		}
198		heap.Init(itr.heap)
199		itr.init = true
200	}
201
202	for {
203		// Retrieve the next iterator if we don't have one.
204		if itr.curr == nil {
205			if len(itr.heap.items) == 0 {
206				return nil, nil
207			}
208			itr.curr = heap.Pop(itr.heap).(*floatMergeHeapItem)
209
210			// Read point and set current window.
211			p, err := itr.curr.itr.Next()
212			if err != nil {
213				return nil, err
214			}
215			tags := p.Tags.Subset(itr.heap.opt.Dimensions)
216			itr.window.name, itr.window.tags = p.Name, tags.ID()
217			itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time)
218			return p, nil
219		}
220
221		// Read the next point from the current iterator.
222		p, err := itr.curr.itr.Next()
223		if err != nil {
224			return nil, err
225		}
226
227		// If there are no more points then remove iterator from heap and find next.
228		if p == nil {
229			itr.curr = nil
230			continue
231		}
232
233		// Check if the point is inside of our current window.
234		inWindow := true
235		if window := itr.window; window.name != p.Name {
236			inWindow = false
237		} else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() {
238			inWindow = false
239		} else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime {
240			inWindow = false
241		} else if !opt.Ascending && p.Time < window.startTime {
242			inWindow = false
243		}
244
245		// If it's outside our window then push iterator back on the heap and find new iterator.
246		if !inWindow {
247			itr.curr.itr.unread(p)
248			heap.Push(itr.heap, itr.curr)
249			itr.curr = nil
250			continue
251		}
252
253		return p, nil
254	}
255}
256
257// floatMergeHeap represents a heap of floatMergeHeapItems.
258// Items are sorted by their next window and then by name/tags.
259type floatMergeHeap struct {
260	opt   IteratorOptions
261	items []*floatMergeHeapItem
262}
263
264func (h *floatMergeHeap) Len() int      { return len(h.items) }
265func (h *floatMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
266func (h *floatMergeHeap) Less(i, j int) bool {
267	x, err := h.items[i].itr.peek()
268	if err != nil {
269		return true
270	}
271	y, err := h.items[j].itr.peek()
272	if err != nil {
273		return false
274	}
275
276	if h.opt.Ascending {
277		if x.Name != y.Name {
278			return x.Name < y.Name
279		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
280			return xTags.ID() < yTags.ID()
281		}
282	} else {
283		if x.Name != y.Name {
284			return x.Name > y.Name
285		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
286			return xTags.ID() > yTags.ID()
287		}
288	}
289
290	xt, _ := h.opt.Window(x.Time)
291	yt, _ := h.opt.Window(y.Time)
292
293	if h.opt.Ascending {
294		return xt < yt
295	}
296	return xt > yt
297}
298
299func (h *floatMergeHeap) Push(x interface{}) {
300	h.items = append(h.items, x.(*floatMergeHeapItem))
301}
302
303func (h *floatMergeHeap) Pop() interface{} {
304	old := h.items
305	n := len(old)
306	item := old[n-1]
307	h.items = old[0 : n-1]
308	return item
309}
310
311type floatMergeHeapItem struct {
312	itr *bufFloatIterator
313}
314
315// floatSortedMergeIterator is an iterator that sorts and merges multiple iterators into one.
316type floatSortedMergeIterator struct {
317	inputs []FloatIterator
318	heap   *floatSortedMergeHeap
319	init   bool
320}
321
322// newFloatSortedMergeIterator returns an instance of floatSortedMergeIterator.
323func newFloatSortedMergeIterator(inputs []FloatIterator, opt IteratorOptions) Iterator {
324	itr := &floatSortedMergeIterator{
325		inputs: inputs,
326		heap: &floatSortedMergeHeap{
327			items: make([]*floatSortedMergeHeapItem, 0, len(inputs)),
328			opt:   opt,
329		},
330	}
331
332	// Initialize heap items.
333	for _, input := range inputs {
334		// Append to the heap.
335		itr.heap.items = append(itr.heap.items, &floatSortedMergeHeapItem{itr: input})
336	}
337
338	return itr
339}
340
341// Stats returns an aggregation of stats from the underlying iterators.
342func (itr *floatSortedMergeIterator) Stats() IteratorStats {
343	var stats IteratorStats
344	for _, input := range itr.inputs {
345		stats.Add(input.Stats())
346	}
347	return stats
348}
349
350// Close closes the underlying iterators.
351func (itr *floatSortedMergeIterator) Close() error {
352	for _, input := range itr.inputs {
353		input.Close()
354	}
355	return nil
356}
357
358// Next returns the next points from the iterator.
359func (itr *floatSortedMergeIterator) Next() (*FloatPoint, error) { return itr.pop() }
360
361// pop returns the next point from the heap.
362// Reads the next point from item's cursor and puts it back on the heap.
363func (itr *floatSortedMergeIterator) pop() (*FloatPoint, error) {
364	// Initialize the heap. See the MergeIterator to see why this has to be done lazily.
365	if !itr.init {
366		items := itr.heap.items
367		itr.heap.items = make([]*floatSortedMergeHeapItem, 0, len(items))
368		for _, item := range items {
369			var err error
370			if item.point, err = item.itr.Next(); err != nil {
371				return nil, err
372			} else if item.point == nil {
373				continue
374			}
375			itr.heap.items = append(itr.heap.items, item)
376		}
377		heap.Init(itr.heap)
378		itr.init = true
379	}
380
381	if len(itr.heap.items) == 0 {
382		return nil, nil
383	}
384
385	// Read the next item from the heap.
386	item := heap.Pop(itr.heap).(*floatSortedMergeHeapItem)
387	if item.err != nil {
388		return nil, item.err
389	} else if item.point == nil {
390		return nil, nil
391	}
392
393	// Copy the point for return.
394	p := item.point.Clone()
395
396	// Read the next item from the cursor. Push back to heap if one exists.
397	if item.point, item.err = item.itr.Next(); item.point != nil {
398		heap.Push(itr.heap, item)
399	}
400
401	return p, nil
402}
403
404// floatSortedMergeHeap represents a heap of floatSortedMergeHeapItems.
405// Items are sorted with the following priority:
406//     - By their measurement name;
407//     - By their tag keys/values;
408//     - By time; or
409//     - By their Aux field values.
410//
411type floatSortedMergeHeap struct {
412	opt   IteratorOptions
413	items []*floatSortedMergeHeapItem
414}
415
416func (h *floatSortedMergeHeap) Len() int      { return len(h.items) }
417func (h *floatSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
418func (h *floatSortedMergeHeap) Less(i, j int) bool {
419	x, y := h.items[i].point, h.items[j].point
420
421	if h.opt.Ascending {
422		if x.Name != y.Name {
423			return x.Name < y.Name
424		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
425			return xTags.ID() < yTags.ID()
426		}
427
428		if x.Time != y.Time {
429			return x.Time < y.Time
430		}
431
432		if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
433			for i := 0; i < len(x.Aux); i++ {
434				v1, ok1 := x.Aux[i].(string)
435				v2, ok2 := y.Aux[i].(string)
436				if !ok1 || !ok2 {
437					// Unsupported types used in Aux fields. Maybe they
438					// need to be added here?
439					return false
440				} else if v1 == v2 {
441					continue
442				}
443				return v1 < v2
444			}
445		}
446		return false // Times and/or Aux fields are equal.
447	}
448
449	if x.Name != y.Name {
450		return x.Name > y.Name
451	} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
452		return xTags.ID() > yTags.ID()
453	}
454
455	if x.Time != y.Time {
456		return x.Time > y.Time
457	}
458
459	if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
460		for i := 0; i < len(x.Aux); i++ {
461			v1, ok1 := x.Aux[i].(string)
462			v2, ok2 := y.Aux[i].(string)
463			if !ok1 || !ok2 {
464				// Unsupported types used in Aux fields. Maybe they
465				// need to be added here?
466				return false
467			} else if v1 == v2 {
468				continue
469			}
470			return v1 > v2
471		}
472	}
473	return false // Times and/or Aux fields are equal.
474}
475
476func (h *floatSortedMergeHeap) Push(x interface{}) {
477	h.items = append(h.items, x.(*floatSortedMergeHeapItem))
478}
479
480func (h *floatSortedMergeHeap) Pop() interface{} {
481	old := h.items
482	n := len(old)
483	item := old[n-1]
484	h.items = old[0 : n-1]
485	return item
486}
487
488type floatSortedMergeHeapItem struct {
489	point *FloatPoint
490	err   error
491	itr   FloatIterator
492}
493
494// floatIteratorScanner scans the results of a FloatIterator into a map.
495type floatIteratorScanner struct {
496	input        *bufFloatIterator
497	err          error
498	keys         []influxql.VarRef
499	defaultValue interface{}
500}
501
502// newFloatIteratorScanner creates a new IteratorScanner.
503func newFloatIteratorScanner(input FloatIterator, keys []influxql.VarRef, defaultValue interface{}) *floatIteratorScanner {
504	return &floatIteratorScanner{
505		input:        newBufFloatIterator(input),
506		keys:         keys,
507		defaultValue: defaultValue,
508	}
509}
510
511func (s *floatIteratorScanner) Peek() (int64, string, Tags) {
512	if s.err != nil {
513		return ZeroTime, "", Tags{}
514	}
515
516	p, err := s.input.peek()
517	if err != nil {
518		s.err = err
519		return ZeroTime, "", Tags{}
520	} else if p == nil {
521		return ZeroTime, "", Tags{}
522	}
523	return p.Time, p.Name, p.Tags
524}
525
526func (s *floatIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) {
527	if s.err != nil {
528		return
529	}
530
531	p, err := s.input.Next()
532	if err != nil {
533		s.err = err
534		return
535	} else if p == nil {
536		s.useDefaults(m)
537		return
538	} else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) {
539		s.useDefaults(m)
540		s.input.unread(p)
541		return
542	}
543
544	if k := s.keys[0]; k.Val != "" {
545		if p.Nil {
546			if s.defaultValue != SkipDefault {
547				m[k.Val] = castToType(s.defaultValue, k.Type)
548			}
549		} else {
550			m[k.Val] = p.Value
551		}
552	}
553	for i, v := range p.Aux {
554		k := s.keys[i+1]
555		switch v.(type) {
556		case float64, int64, uint64, string, bool:
557			m[k.Val] = v
558		default:
559			// Insert the fill value if one was specified.
560			if s.defaultValue != SkipDefault {
561				m[k.Val] = castToType(s.defaultValue, k.Type)
562			}
563		}
564	}
565}
566
567func (s *floatIteratorScanner) useDefaults(m map[string]interface{}) {
568	if s.defaultValue == SkipDefault {
569		return
570	}
571	for _, k := range s.keys {
572		if k.Val == "" {
573			continue
574		}
575		m[k.Val] = castToType(s.defaultValue, k.Type)
576	}
577}
578
579func (s *floatIteratorScanner) Stats() IteratorStats { return s.input.Stats() }
580func (s *floatIteratorScanner) Err() error           { return s.err }
581func (s *floatIteratorScanner) Close() error         { return s.input.Close() }
582
583// floatParallelIterator represents an iterator that pulls data in a separate goroutine.
584type floatParallelIterator struct {
585	input FloatIterator
586	ch    chan floatPointError
587
588	once    sync.Once
589	closing chan struct{}
590	wg      sync.WaitGroup
591}
592
593// newFloatParallelIterator returns a new instance of floatParallelIterator.
594func newFloatParallelIterator(input FloatIterator) *floatParallelIterator {
595	itr := &floatParallelIterator{
596		input:   input,
597		ch:      make(chan floatPointError, 256),
598		closing: make(chan struct{}),
599	}
600	itr.wg.Add(1)
601	go itr.monitor()
602	return itr
603}
604
605// Stats returns stats from the underlying iterator.
606func (itr *floatParallelIterator) Stats() IteratorStats { return itr.input.Stats() }
607
608// Close closes the underlying iterators.
609func (itr *floatParallelIterator) Close() error {
610	itr.once.Do(func() { close(itr.closing) })
611	itr.wg.Wait()
612	return itr.input.Close()
613}
614
615// Next returns the next point from the iterator.
616func (itr *floatParallelIterator) Next() (*FloatPoint, error) {
617	v, ok := <-itr.ch
618	if !ok {
619		return nil, io.EOF
620	}
621	return v.point, v.err
622}
623
624// monitor runs in a separate goroutine and actively pulls the next point.
625func (itr *floatParallelIterator) monitor() {
626	defer close(itr.ch)
627	defer itr.wg.Done()
628
629	for {
630		// Read next point.
631		p, err := itr.input.Next()
632		if p != nil {
633			p = p.Clone()
634		}
635
636		select {
637		case <-itr.closing:
638			return
639		case itr.ch <- floatPointError{point: p, err: err}:
640		}
641	}
642}
643
644type floatPointError struct {
645	point *FloatPoint
646	err   error
647}
648
649// floatLimitIterator represents an iterator that limits points per group.
650type floatLimitIterator struct {
651	input FloatIterator
652	opt   IteratorOptions
653	n     int
654
655	prev struct {
656		name string
657		tags Tags
658	}
659}
660
661// newFloatLimitIterator returns a new instance of floatLimitIterator.
662func newFloatLimitIterator(input FloatIterator, opt IteratorOptions) *floatLimitIterator {
663	return &floatLimitIterator{
664		input: input,
665		opt:   opt,
666	}
667}
668
669// Stats returns stats from the underlying iterator.
670func (itr *floatLimitIterator) Stats() IteratorStats { return itr.input.Stats() }
671
672// Close closes the underlying iterators.
673func (itr *floatLimitIterator) Close() error { return itr.input.Close() }
674
675// Next returns the next point from the iterator.
676func (itr *floatLimitIterator) Next() (*FloatPoint, error) {
677	for {
678		p, err := itr.input.Next()
679		if p == nil || err != nil {
680			return nil, err
681		}
682
683		// Reset window and counter if a new window is encountered.
684		if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) {
685			itr.prev.name = p.Name
686			itr.prev.tags = p.Tags
687			itr.n = 0
688		}
689
690		// Increment counter.
691		itr.n++
692
693		// Read next point if not beyond the offset.
694		if itr.n <= itr.opt.Offset {
695			continue
696		}
697
698		// Read next point if we're beyond the limit.
699		if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit {
700			continue
701		}
702
703		return p, nil
704	}
705}
706
707type floatFillIterator struct {
708	input     *bufFloatIterator
709	prev      FloatPoint
710	startTime int64
711	endTime   int64
712	auxFields []interface{}
713	init      bool
714	opt       IteratorOptions
715
716	window struct {
717		name   string
718		tags   Tags
719		time   int64
720		offset int64
721	}
722}
723
724func newFloatFillIterator(input FloatIterator, expr influxql.Expr, opt IteratorOptions) *floatFillIterator {
725	if opt.Fill == influxql.NullFill {
726		if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" {
727			opt.Fill = influxql.NumberFill
728			opt.FillValue = float64(0)
729		}
730	}
731
732	var startTime, endTime int64
733	if opt.Ascending {
734		startTime, _ = opt.Window(opt.StartTime)
735		endTime, _ = opt.Window(opt.EndTime)
736	} else {
737		startTime, _ = opt.Window(opt.EndTime)
738		endTime, _ = opt.Window(opt.StartTime)
739	}
740
741	var auxFields []interface{}
742	if len(opt.Aux) > 0 {
743		auxFields = make([]interface{}, len(opt.Aux))
744	}
745
746	return &floatFillIterator{
747		input:     newBufFloatIterator(input),
748		prev:      FloatPoint{Nil: true},
749		startTime: startTime,
750		endTime:   endTime,
751		auxFields: auxFields,
752		opt:       opt,
753	}
754}
755
756func (itr *floatFillIterator) Stats() IteratorStats { return itr.input.Stats() }
757func (itr *floatFillIterator) Close() error         { return itr.input.Close() }
758
759func (itr *floatFillIterator) Next() (*FloatPoint, error) {
760	if !itr.init {
761		p, err := itr.input.peek()
762		if p == nil || err != nil {
763			return nil, err
764		}
765		itr.window.name, itr.window.tags = p.Name, p.Tags
766		itr.window.time = itr.startTime
767		if itr.startTime == influxql.MinTime {
768			itr.window.time, _ = itr.opt.Window(p.Time)
769		}
770		if itr.opt.Location != nil {
771			_, itr.window.offset = itr.opt.Zone(itr.window.time)
772		}
773		itr.init = true
774	}
775
776	p, err := itr.input.Next()
777	if err != nil {
778		return nil, err
779	}
780
781	// Check if the next point is outside of our window or is nil.
782	if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() {
783		// If we are inside of an interval, unread the point and continue below to
784		// constructing a new point.
785		if itr.opt.Ascending && itr.window.time <= itr.endTime {
786			itr.input.unread(p)
787			p = nil
788			goto CONSTRUCT
789		} else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime {
790			itr.input.unread(p)
791			p = nil
792			goto CONSTRUCT
793		}
794
795		// We are *not* in a current interval. If there is no next point,
796		// we are at the end of all intervals.
797		if p == nil {
798			return nil, nil
799		}
800
801		// Set the new interval.
802		itr.window.name, itr.window.tags = p.Name, p.Tags
803		itr.window.time = itr.startTime
804		if itr.window.time == influxql.MinTime {
805			itr.window.time, _ = itr.opt.Window(p.Time)
806		}
807		if itr.opt.Location != nil {
808			_, itr.window.offset = itr.opt.Zone(itr.window.time)
809		}
810		itr.prev = FloatPoint{Nil: true}
811	}
812
813	// Check if the point is our next expected point.
814CONSTRUCT:
815	if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) {
816		if p != nil {
817			itr.input.unread(p)
818		}
819
820		p = &FloatPoint{
821			Name: itr.window.name,
822			Tags: itr.window.tags,
823			Time: itr.window.time,
824			Aux:  itr.auxFields,
825		}
826
827		switch itr.opt.Fill {
828		case influxql.LinearFill:
829			if !itr.prev.Nil {
830				next, err := itr.input.peek()
831				if err != nil {
832					return nil, err
833				} else if next != nil && next.Name == itr.window.name && next.Tags.ID() == itr.window.tags.ID() {
834					interval := int64(itr.opt.Interval.Duration)
835					start := itr.window.time / interval
836					p.Value = linearFloat(start, itr.prev.Time/interval, next.Time/interval, itr.prev.Value, next.Value)
837				} else {
838					p.Nil = true
839				}
840			} else {
841				p.Nil = true
842			}
843
844		case influxql.NullFill:
845			p.Nil = true
846		case influxql.NumberFill:
847			p.Value, _ = castToFloat(itr.opt.FillValue)
848		case influxql.PreviousFill:
849			if !itr.prev.Nil {
850				p.Value = itr.prev.Value
851				p.Nil = itr.prev.Nil
852			} else {
853				p.Nil = true
854			}
855		}
856	} else {
857		itr.prev = *p
858	}
859
860	// Advance the expected time. Do not advance to a new window here
861	// as there may be lingering points with the same timestamp in the previous
862	// window.
863	if itr.opt.Ascending {
864		itr.window.time += int64(itr.opt.Interval.Duration)
865	} else {
866		itr.window.time -= int64(itr.opt.Interval.Duration)
867	}
868
869	// Check to see if we have passed over an offset change and adjust the time
870	// to account for this new offset.
871	if itr.opt.Location != nil {
872		if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset {
873			diff := itr.window.offset - offset
874			if abs(diff) < int64(itr.opt.Interval.Duration) {
875				itr.window.time += diff
876			}
877			itr.window.offset = offset
878		}
879	}
880	return p, nil
881}
882
883// floatIntervalIterator represents a float implementation of IntervalIterator.
884type floatIntervalIterator struct {
885	input FloatIterator
886	opt   IteratorOptions
887}
888
889func newFloatIntervalIterator(input FloatIterator, opt IteratorOptions) *floatIntervalIterator {
890	return &floatIntervalIterator{input: input, opt: opt}
891}
892
893func (itr *floatIntervalIterator) Stats() IteratorStats { return itr.input.Stats() }
894func (itr *floatIntervalIterator) Close() error         { return itr.input.Close() }
895
896func (itr *floatIntervalIterator) Next() (*FloatPoint, error) {
897	p, err := itr.input.Next()
898	if p == nil || err != nil {
899		return nil, err
900	}
901	p.Time, _ = itr.opt.Window(p.Time)
902	// If we see the minimum allowable time, set the time to zero so we don't
903	// break the default returned time for aggregate queries without times.
904	if p.Time == influxql.MinTime {
905		p.Time = 0
906	}
907	return p, nil
908}
909
910// floatInterruptIterator represents a float implementation of InterruptIterator.
911type floatInterruptIterator struct {
912	input   FloatIterator
913	closing <-chan struct{}
914	count   int
915}
916
917func newFloatInterruptIterator(input FloatIterator, closing <-chan struct{}) *floatInterruptIterator {
918	return &floatInterruptIterator{input: input, closing: closing}
919}
920
921func (itr *floatInterruptIterator) Stats() IteratorStats { return itr.input.Stats() }
922func (itr *floatInterruptIterator) Close() error         { return itr.input.Close() }
923
924func (itr *floatInterruptIterator) Next() (*FloatPoint, error) {
925	// Only check if the channel is closed every N points. This
926	// intentionally checks on both 0 and N so that if the iterator
927	// has been interrupted before the first point is emitted it will
928	// not emit any points.
929	if itr.count&0xFF == 0xFF {
930		select {
931		case <-itr.closing:
932			return nil, itr.Close()
933		default:
934			// Reset iterator count to zero and fall through to emit the next point.
935			itr.count = 0
936		}
937	}
938
939	// Increment the counter for every point read.
940	itr.count++
941	return itr.input.Next()
942}
943
944// floatCloseInterruptIterator represents a float implementation of CloseInterruptIterator.
945type floatCloseInterruptIterator struct {
946	input   FloatIterator
947	closing <-chan struct{}
948	done    chan struct{}
949	once    sync.Once
950}
951
952func newFloatCloseInterruptIterator(input FloatIterator, closing <-chan struct{}) *floatCloseInterruptIterator {
953	itr := &floatCloseInterruptIterator{
954		input:   input,
955		closing: closing,
956		done:    make(chan struct{}),
957	}
958	go itr.monitor()
959	return itr
960}
961
962func (itr *floatCloseInterruptIterator) monitor() {
963	select {
964	case <-itr.closing:
965		itr.Close()
966	case <-itr.done:
967	}
968}
969
970func (itr *floatCloseInterruptIterator) Stats() IteratorStats {
971	return itr.input.Stats()
972}
973
974func (itr *floatCloseInterruptIterator) Close() error {
975	itr.once.Do(func() {
976		close(itr.done)
977		itr.input.Close()
978	})
979	return nil
980}
981
982func (itr *floatCloseInterruptIterator) Next() (*FloatPoint, error) {
983	p, err := itr.input.Next()
984	if err != nil {
985		// Check if the iterator was closed.
986		select {
987		case <-itr.done:
988			return nil, nil
989		default:
990			return nil, err
991		}
992	}
993	return p, nil
994}
995
996// floatReduceFloatIterator executes a reducer for every interval and buffers the result.
997type floatReduceFloatIterator struct {
998	input    *bufFloatIterator
999	create   func() (FloatPointAggregator, FloatPointEmitter)
1000	dims     []string
1001	opt      IteratorOptions
1002	points   []FloatPoint
1003	keepTags bool
1004}
1005
1006func newFloatReduceFloatIterator(input FloatIterator, opt IteratorOptions, createFn func() (FloatPointAggregator, FloatPointEmitter)) *floatReduceFloatIterator {
1007	return &floatReduceFloatIterator{
1008		input:  newBufFloatIterator(input),
1009		create: createFn,
1010		dims:   opt.GetDimensions(),
1011		opt:    opt,
1012	}
1013}
1014
1015// Stats returns stats from the input iterator.
1016func (itr *floatReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
1017
1018// Close closes the iterator and all child iterators.
1019func (itr *floatReduceFloatIterator) Close() error { return itr.input.Close() }
1020
1021// Next returns the minimum value for the next available interval.
1022func (itr *floatReduceFloatIterator) Next() (*FloatPoint, error) {
1023	// Calculate next window if we have no more points.
1024	if len(itr.points) == 0 {
1025		var err error
1026		itr.points, err = itr.reduce()
1027		if len(itr.points) == 0 {
1028			return nil, err
1029		}
1030	}
1031
1032	// Pop next point off the stack.
1033	p := &itr.points[len(itr.points)-1]
1034	itr.points = itr.points[:len(itr.points)-1]
1035	return p, nil
1036}
1037
1038// floatReduceFloatPoint stores the reduced data for a name/tag combination.
1039type floatReduceFloatPoint struct {
1040	Name       string
1041	Tags       Tags
1042	Aggregator FloatPointAggregator
1043	Emitter    FloatPointEmitter
1044}
1045
1046// reduce executes fn once for every point in the next window.
1047// The previous value for the dimension is passed to fn.
1048func (itr *floatReduceFloatIterator) reduce() ([]FloatPoint, error) {
1049	// Calculate next window.
1050	var (
1051		startTime, endTime int64
1052		window             struct {
1053			name string
1054			tags string
1055		}
1056	)
1057	for {
1058		p, err := itr.input.Next()
1059		if err != nil || p == nil {
1060			return nil, err
1061		} else if p.Nil {
1062			continue
1063		}
1064
1065		// Unread the point so it can be processed.
1066		itr.input.unread(p)
1067		startTime, endTime = itr.opt.Window(p.Time)
1068		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
1069		break
1070	}
1071
1072	// Create points by tags.
1073	m := make(map[string]*floatReduceFloatPoint)
1074	for {
1075		// Read next point.
1076		curr, err := itr.input.NextInWindow(startTime, endTime)
1077		if err != nil {
1078			return nil, err
1079		} else if curr == nil {
1080			break
1081		} else if curr.Nil {
1082			continue
1083		} else if curr.Name != window.name {
1084			itr.input.unread(curr)
1085			break
1086		}
1087
1088		// Ensure this point is within the same final window.
1089		if curr.Name != window.name {
1090			itr.input.unread(curr)
1091			break
1092		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
1093			itr.input.unread(curr)
1094			break
1095		}
1096
1097		// Retrieve the tags on this point for this level of the query.
1098		// This may be different than the bucket dimensions.
1099		tags := curr.Tags.Subset(itr.dims)
1100		id := tags.ID()
1101
1102		// Retrieve the aggregator for this name/tag combination or create one.
1103		rp := m[id]
1104		if rp == nil {
1105			aggregator, emitter := itr.create()
1106			rp = &floatReduceFloatPoint{
1107				Name:       curr.Name,
1108				Tags:       tags,
1109				Aggregator: aggregator,
1110				Emitter:    emitter,
1111			}
1112			m[id] = rp
1113		}
1114		rp.Aggregator.AggregateFloat(curr)
1115	}
1116
1117	keys := make([]string, 0, len(m))
1118	for k := range m {
1119		keys = append(keys, k)
1120	}
1121
1122	// Reverse sort points by name & tag.
1123	// This ensures a consistent order of output.
1124	if len(keys) > 0 {
1125		var sorted sort.Interface = sort.StringSlice(keys)
1126		if itr.opt.Ascending {
1127			sorted = sort.Reverse(sorted)
1128		}
1129		sort.Sort(sorted)
1130	}
1131
1132	// Assume the points are already sorted until proven otherwise.
1133	sortedByTime := true
1134	// Emit the points for each name & tag combination.
1135	a := make([]FloatPoint, 0, len(m))
1136	for _, k := range keys {
1137		rp := m[k]
1138		points := rp.Emitter.Emit()
1139		for i := len(points) - 1; i >= 0; i-- {
1140			points[i].Name = rp.Name
1141			if !itr.keepTags {
1142				points[i].Tags = rp.Tags
1143			}
1144			// Set the points time to the interval time if the reducer didn't provide one.
1145			if points[i].Time == ZeroTime {
1146				points[i].Time = startTime
1147			} else {
1148				sortedByTime = false
1149			}
1150			a = append(a, points[i])
1151		}
1152	}
1153	// Points may be out of order. Perform a stable sort by time if requested.
1154	if !sortedByTime && itr.opt.Ordered {
1155		var sorted sort.Interface = floatPointsByTime(a)
1156		if itr.opt.Ascending {
1157			sorted = sort.Reverse(sorted)
1158		}
1159		sort.Stable(sorted)
1160	}
1161	return a, nil
1162}
1163
1164// floatStreamFloatIterator streams inputs into the iterator and emits points gradually.
1165type floatStreamFloatIterator struct {
1166	input  *bufFloatIterator
1167	create func() (FloatPointAggregator, FloatPointEmitter)
1168	dims   []string
1169	opt    IteratorOptions
1170	m      map[string]*floatReduceFloatPoint
1171	points []FloatPoint
1172}
1173
1174// newFloatStreamFloatIterator returns a new instance of floatStreamFloatIterator.
1175func newFloatStreamFloatIterator(input FloatIterator, createFn func() (FloatPointAggregator, FloatPointEmitter), opt IteratorOptions) *floatStreamFloatIterator {
1176	return &floatStreamFloatIterator{
1177		input:  newBufFloatIterator(input),
1178		create: createFn,
1179		dims:   opt.GetDimensions(),
1180		opt:    opt,
1181		m:      make(map[string]*floatReduceFloatPoint),
1182	}
1183}
1184
1185// Stats returns stats from the input iterator.
1186func (itr *floatStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
1187
1188// Close closes the iterator and all child iterators.
1189func (itr *floatStreamFloatIterator) Close() error { return itr.input.Close() }
1190
1191// Next returns the next value for the stream iterator.
1192func (itr *floatStreamFloatIterator) Next() (*FloatPoint, error) {
1193	// Calculate next window if we have no more points.
1194	if len(itr.points) == 0 {
1195		var err error
1196		itr.points, err = itr.reduce()
1197		if len(itr.points) == 0 {
1198			return nil, err
1199		}
1200	}
1201
1202	// Pop next point off the stack.
1203	p := &itr.points[len(itr.points)-1]
1204	itr.points = itr.points[:len(itr.points)-1]
1205	return p, nil
1206}
1207
1208// reduce creates and manages aggregators for every point from the input.
1209// After aggregating a point, it always tries to emit a value using the emitter.
1210func (itr *floatStreamFloatIterator) reduce() ([]FloatPoint, error) {
1211	// We have already read all of the input points.
1212	if itr.m == nil {
1213		return nil, nil
1214	}
1215
1216	for {
1217		// Read next point.
1218		curr, err := itr.input.Next()
1219		if err != nil {
1220			return nil, err
1221		} else if curr == nil {
1222			// Close all of the aggregators to flush any remaining points to emit.
1223			var points []FloatPoint
1224			for _, rp := range itr.m {
1225				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
1226					if err := aggregator.Close(); err != nil {
1227						return nil, err
1228					}
1229
1230					pts := rp.Emitter.Emit()
1231					if len(pts) == 0 {
1232						continue
1233					}
1234
1235					for i := range pts {
1236						pts[i].Name = rp.Name
1237						pts[i].Tags = rp.Tags
1238					}
1239					points = append(points, pts...)
1240				}
1241			}
1242
1243			// Eliminate the aggregators and emitters.
1244			itr.m = nil
1245			return points, nil
1246		} else if curr.Nil {
1247			continue
1248		}
1249		tags := curr.Tags.Subset(itr.dims)
1250
1251		id := curr.Name
1252		if len(tags.m) > 0 {
1253			id += "\x00" + tags.ID()
1254		}
1255
1256		// Retrieve the aggregator for this name/tag combination or create one.
1257		rp := itr.m[id]
1258		if rp == nil {
1259			aggregator, emitter := itr.create()
1260			rp = &floatReduceFloatPoint{
1261				Name:       curr.Name,
1262				Tags:       tags,
1263				Aggregator: aggregator,
1264				Emitter:    emitter,
1265			}
1266			itr.m[id] = rp
1267		}
1268		rp.Aggregator.AggregateFloat(curr)
1269
1270		// Attempt to emit points from the aggregator.
1271		points := rp.Emitter.Emit()
1272		if len(points) == 0 {
1273			continue
1274		}
1275
1276		for i := range points {
1277			points[i].Name = rp.Name
1278			points[i].Tags = rp.Tags
1279		}
1280		return points, nil
1281	}
1282}
1283
1284// floatReduceIntegerIterator executes a reducer for every interval and buffers the result.
1285type floatReduceIntegerIterator struct {
1286	input    *bufFloatIterator
1287	create   func() (FloatPointAggregator, IntegerPointEmitter)
1288	dims     []string
1289	opt      IteratorOptions
1290	points   []IntegerPoint
1291	keepTags bool
1292}
1293
1294func newFloatReduceIntegerIterator(input FloatIterator, opt IteratorOptions, createFn func() (FloatPointAggregator, IntegerPointEmitter)) *floatReduceIntegerIterator {
1295	return &floatReduceIntegerIterator{
1296		input:  newBufFloatIterator(input),
1297		create: createFn,
1298		dims:   opt.GetDimensions(),
1299		opt:    opt,
1300	}
1301}
1302
1303// Stats returns stats from the input iterator.
1304func (itr *floatReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
1305
1306// Close closes the iterator and all child iterators.
1307func (itr *floatReduceIntegerIterator) Close() error { return itr.input.Close() }
1308
1309// Next returns the minimum value for the next available interval.
1310func (itr *floatReduceIntegerIterator) Next() (*IntegerPoint, error) {
1311	// Calculate next window if we have no more points.
1312	if len(itr.points) == 0 {
1313		var err error
1314		itr.points, err = itr.reduce()
1315		if len(itr.points) == 0 {
1316			return nil, err
1317		}
1318	}
1319
1320	// Pop next point off the stack.
1321	p := &itr.points[len(itr.points)-1]
1322	itr.points = itr.points[:len(itr.points)-1]
1323	return p, nil
1324}
1325
1326// floatReduceIntegerPoint stores the reduced data for a name/tag combination.
1327type floatReduceIntegerPoint struct {
1328	Name       string
1329	Tags       Tags
1330	Aggregator FloatPointAggregator
1331	Emitter    IntegerPointEmitter
1332}
1333
1334// reduce executes fn once for every point in the next window.
1335// The previous value for the dimension is passed to fn.
1336func (itr *floatReduceIntegerIterator) reduce() ([]IntegerPoint, error) {
1337	// Calculate next window.
1338	var (
1339		startTime, endTime int64
1340		window             struct {
1341			name string
1342			tags string
1343		}
1344	)
1345	for {
1346		p, err := itr.input.Next()
1347		if err != nil || p == nil {
1348			return nil, err
1349		} else if p.Nil {
1350			continue
1351		}
1352
1353		// Unread the point so it can be processed.
1354		itr.input.unread(p)
1355		startTime, endTime = itr.opt.Window(p.Time)
1356		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
1357		break
1358	}
1359
1360	// Create points by tags.
1361	m := make(map[string]*floatReduceIntegerPoint)
1362	for {
1363		// Read next point.
1364		curr, err := itr.input.NextInWindow(startTime, endTime)
1365		if err != nil {
1366			return nil, err
1367		} else if curr == nil {
1368			break
1369		} else if curr.Nil {
1370			continue
1371		} else if curr.Name != window.name {
1372			itr.input.unread(curr)
1373			break
1374		}
1375
1376		// Ensure this point is within the same final window.
1377		if curr.Name != window.name {
1378			itr.input.unread(curr)
1379			break
1380		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
1381			itr.input.unread(curr)
1382			break
1383		}
1384
1385		// Retrieve the tags on this point for this level of the query.
1386		// This may be different than the bucket dimensions.
1387		tags := curr.Tags.Subset(itr.dims)
1388		id := tags.ID()
1389
1390		// Retrieve the aggregator for this name/tag combination or create one.
1391		rp := m[id]
1392		if rp == nil {
1393			aggregator, emitter := itr.create()
1394			rp = &floatReduceIntegerPoint{
1395				Name:       curr.Name,
1396				Tags:       tags,
1397				Aggregator: aggregator,
1398				Emitter:    emitter,
1399			}
1400			m[id] = rp
1401		}
1402		rp.Aggregator.AggregateFloat(curr)
1403	}
1404
1405	keys := make([]string, 0, len(m))
1406	for k := range m {
1407		keys = append(keys, k)
1408	}
1409
1410	// Reverse sort points by name & tag.
1411	// This ensures a consistent order of output.
1412	if len(keys) > 0 {
1413		var sorted sort.Interface = sort.StringSlice(keys)
1414		if itr.opt.Ascending {
1415			sorted = sort.Reverse(sorted)
1416		}
1417		sort.Sort(sorted)
1418	}
1419
1420	// Assume the points are already sorted until proven otherwise.
1421	sortedByTime := true
1422	// Emit the points for each name & tag combination.
1423	a := make([]IntegerPoint, 0, len(m))
1424	for _, k := range keys {
1425		rp := m[k]
1426		points := rp.Emitter.Emit()
1427		for i := len(points) - 1; i >= 0; i-- {
1428			points[i].Name = rp.Name
1429			if !itr.keepTags {
1430				points[i].Tags = rp.Tags
1431			}
1432			// Set the points time to the interval time if the reducer didn't provide one.
1433			if points[i].Time == ZeroTime {
1434				points[i].Time = startTime
1435			} else {
1436				sortedByTime = false
1437			}
1438			a = append(a, points[i])
1439		}
1440	}
1441	// Points may be out of order. Perform a stable sort by time if requested.
1442	if !sortedByTime && itr.opt.Ordered {
1443		var sorted sort.Interface = integerPointsByTime(a)
1444		if itr.opt.Ascending {
1445			sorted = sort.Reverse(sorted)
1446		}
1447		sort.Stable(sorted)
1448	}
1449	return a, nil
1450}
1451
1452// floatStreamIntegerIterator streams inputs into the iterator and emits points gradually.
1453type floatStreamIntegerIterator struct {
1454	input  *bufFloatIterator
1455	create func() (FloatPointAggregator, IntegerPointEmitter)
1456	dims   []string
1457	opt    IteratorOptions
1458	m      map[string]*floatReduceIntegerPoint
1459	points []IntegerPoint
1460}
1461
1462// newFloatStreamIntegerIterator returns a new instance of floatStreamIntegerIterator.
1463func newFloatStreamIntegerIterator(input FloatIterator, createFn func() (FloatPointAggregator, IntegerPointEmitter), opt IteratorOptions) *floatStreamIntegerIterator {
1464	return &floatStreamIntegerIterator{
1465		input:  newBufFloatIterator(input),
1466		create: createFn,
1467		dims:   opt.GetDimensions(),
1468		opt:    opt,
1469		m:      make(map[string]*floatReduceIntegerPoint),
1470	}
1471}
1472
1473// Stats returns stats from the input iterator.
1474func (itr *floatStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
1475
1476// Close closes the iterator and all child iterators.
1477func (itr *floatStreamIntegerIterator) Close() error { return itr.input.Close() }
1478
1479// Next returns the next value for the stream iterator.
1480func (itr *floatStreamIntegerIterator) Next() (*IntegerPoint, error) {
1481	// Calculate next window if we have no more points.
1482	if len(itr.points) == 0 {
1483		var err error
1484		itr.points, err = itr.reduce()
1485		if len(itr.points) == 0 {
1486			return nil, err
1487		}
1488	}
1489
1490	// Pop next point off the stack.
1491	p := &itr.points[len(itr.points)-1]
1492	itr.points = itr.points[:len(itr.points)-1]
1493	return p, nil
1494}
1495
1496// reduce creates and manages aggregators for every point from the input.
1497// After aggregating a point, it always tries to emit a value using the emitter.
1498func (itr *floatStreamIntegerIterator) reduce() ([]IntegerPoint, error) {
1499	// We have already read all of the input points.
1500	if itr.m == nil {
1501		return nil, nil
1502	}
1503
1504	for {
1505		// Read next point.
1506		curr, err := itr.input.Next()
1507		if err != nil {
1508			return nil, err
1509		} else if curr == nil {
1510			// Close all of the aggregators to flush any remaining points to emit.
1511			var points []IntegerPoint
1512			for _, rp := range itr.m {
1513				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
1514					if err := aggregator.Close(); err != nil {
1515						return nil, err
1516					}
1517
1518					pts := rp.Emitter.Emit()
1519					if len(pts) == 0 {
1520						continue
1521					}
1522
1523					for i := range pts {
1524						pts[i].Name = rp.Name
1525						pts[i].Tags = rp.Tags
1526					}
1527					points = append(points, pts...)
1528				}
1529			}
1530
1531			// Eliminate the aggregators and emitters.
1532			itr.m = nil
1533			return points, nil
1534		} else if curr.Nil {
1535			continue
1536		}
1537		tags := curr.Tags.Subset(itr.dims)
1538
1539		id := curr.Name
1540		if len(tags.m) > 0 {
1541			id += "\x00" + tags.ID()
1542		}
1543
1544		// Retrieve the aggregator for this name/tag combination or create one.
1545		rp := itr.m[id]
1546		if rp == nil {
1547			aggregator, emitter := itr.create()
1548			rp = &floatReduceIntegerPoint{
1549				Name:       curr.Name,
1550				Tags:       tags,
1551				Aggregator: aggregator,
1552				Emitter:    emitter,
1553			}
1554			itr.m[id] = rp
1555		}
1556		rp.Aggregator.AggregateFloat(curr)
1557
1558		// Attempt to emit points from the aggregator.
1559		points := rp.Emitter.Emit()
1560		if len(points) == 0 {
1561			continue
1562		}
1563
1564		for i := range points {
1565			points[i].Name = rp.Name
1566			points[i].Tags = rp.Tags
1567		}
1568		return points, nil
1569	}
1570}
1571
1572// floatReduceUnsignedIterator executes a reducer for every interval and buffers the result.
1573type floatReduceUnsignedIterator struct {
1574	input    *bufFloatIterator
1575	create   func() (FloatPointAggregator, UnsignedPointEmitter)
1576	dims     []string
1577	opt      IteratorOptions
1578	points   []UnsignedPoint
1579	keepTags bool
1580}
1581
1582func newFloatReduceUnsignedIterator(input FloatIterator, opt IteratorOptions, createFn func() (FloatPointAggregator, UnsignedPointEmitter)) *floatReduceUnsignedIterator {
1583	return &floatReduceUnsignedIterator{
1584		input:  newBufFloatIterator(input),
1585		create: createFn,
1586		dims:   opt.GetDimensions(),
1587		opt:    opt,
1588	}
1589}
1590
1591// Stats returns stats from the input iterator.
1592func (itr *floatReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
1593
1594// Close closes the iterator and all child iterators.
1595func (itr *floatReduceUnsignedIterator) Close() error { return itr.input.Close() }
1596
1597// Next returns the minimum value for the next available interval.
1598func (itr *floatReduceUnsignedIterator) Next() (*UnsignedPoint, error) {
1599	// Calculate next window if we have no more points.
1600	if len(itr.points) == 0 {
1601		var err error
1602		itr.points, err = itr.reduce()
1603		if len(itr.points) == 0 {
1604			return nil, err
1605		}
1606	}
1607
1608	// Pop next point off the stack.
1609	p := &itr.points[len(itr.points)-1]
1610	itr.points = itr.points[:len(itr.points)-1]
1611	return p, nil
1612}
1613
1614// floatReduceUnsignedPoint stores the reduced data for a name/tag combination.
1615type floatReduceUnsignedPoint struct {
1616	Name       string
1617	Tags       Tags
1618	Aggregator FloatPointAggregator
1619	Emitter    UnsignedPointEmitter
1620}
1621
1622// reduce executes fn once for every point in the next window.
1623// The previous value for the dimension is passed to fn.
1624func (itr *floatReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) {
1625	// Calculate next window.
1626	var (
1627		startTime, endTime int64
1628		window             struct {
1629			name string
1630			tags string
1631		}
1632	)
1633	for {
1634		p, err := itr.input.Next()
1635		if err != nil || p == nil {
1636			return nil, err
1637		} else if p.Nil {
1638			continue
1639		}
1640
1641		// Unread the point so it can be processed.
1642		itr.input.unread(p)
1643		startTime, endTime = itr.opt.Window(p.Time)
1644		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
1645		break
1646	}
1647
1648	// Create points by tags.
1649	m := make(map[string]*floatReduceUnsignedPoint)
1650	for {
1651		// Read next point.
1652		curr, err := itr.input.NextInWindow(startTime, endTime)
1653		if err != nil {
1654			return nil, err
1655		} else if curr == nil {
1656			break
1657		} else if curr.Nil {
1658			continue
1659		} else if curr.Name != window.name {
1660			itr.input.unread(curr)
1661			break
1662		}
1663
1664		// Ensure this point is within the same final window.
1665		if curr.Name != window.name {
1666			itr.input.unread(curr)
1667			break
1668		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
1669			itr.input.unread(curr)
1670			break
1671		}
1672
1673		// Retrieve the tags on this point for this level of the query.
1674		// This may be different than the bucket dimensions.
1675		tags := curr.Tags.Subset(itr.dims)
1676		id := tags.ID()
1677
1678		// Retrieve the aggregator for this name/tag combination or create one.
1679		rp := m[id]
1680		if rp == nil {
1681			aggregator, emitter := itr.create()
1682			rp = &floatReduceUnsignedPoint{
1683				Name:       curr.Name,
1684				Tags:       tags,
1685				Aggregator: aggregator,
1686				Emitter:    emitter,
1687			}
1688			m[id] = rp
1689		}
1690		rp.Aggregator.AggregateFloat(curr)
1691	}
1692
1693	keys := make([]string, 0, len(m))
1694	for k := range m {
1695		keys = append(keys, k)
1696	}
1697
1698	// Reverse sort points by name & tag.
1699	// This ensures a consistent order of output.
1700	if len(keys) > 0 {
1701		var sorted sort.Interface = sort.StringSlice(keys)
1702		if itr.opt.Ascending {
1703			sorted = sort.Reverse(sorted)
1704		}
1705		sort.Sort(sorted)
1706	}
1707
1708	// Assume the points are already sorted until proven otherwise.
1709	sortedByTime := true
1710	// Emit the points for each name & tag combination.
1711	a := make([]UnsignedPoint, 0, len(m))
1712	for _, k := range keys {
1713		rp := m[k]
1714		points := rp.Emitter.Emit()
1715		for i := len(points) - 1; i >= 0; i-- {
1716			points[i].Name = rp.Name
1717			if !itr.keepTags {
1718				points[i].Tags = rp.Tags
1719			}
1720			// Set the points time to the interval time if the reducer didn't provide one.
1721			if points[i].Time == ZeroTime {
1722				points[i].Time = startTime
1723			} else {
1724				sortedByTime = false
1725			}
1726			a = append(a, points[i])
1727		}
1728	}
1729	// Points may be out of order. Perform a stable sort by time if requested.
1730	if !sortedByTime && itr.opt.Ordered {
1731		var sorted sort.Interface = unsignedPointsByTime(a)
1732		if itr.opt.Ascending {
1733			sorted = sort.Reverse(sorted)
1734		}
1735		sort.Stable(sorted)
1736	}
1737	return a, nil
1738}
1739
1740// floatStreamUnsignedIterator streams inputs into the iterator and emits points gradually.
1741type floatStreamUnsignedIterator struct {
1742	input  *bufFloatIterator
1743	create func() (FloatPointAggregator, UnsignedPointEmitter)
1744	dims   []string
1745	opt    IteratorOptions
1746	m      map[string]*floatReduceUnsignedPoint
1747	points []UnsignedPoint
1748}
1749
1750// newFloatStreamUnsignedIterator returns a new instance of floatStreamUnsignedIterator.
1751func newFloatStreamUnsignedIterator(input FloatIterator, createFn func() (FloatPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *floatStreamUnsignedIterator {
1752	return &floatStreamUnsignedIterator{
1753		input:  newBufFloatIterator(input),
1754		create: createFn,
1755		dims:   opt.GetDimensions(),
1756		opt:    opt,
1757		m:      make(map[string]*floatReduceUnsignedPoint),
1758	}
1759}
1760
1761// Stats returns stats from the input iterator.
1762func (itr *floatStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
1763
1764// Close closes the iterator and all child iterators.
1765func (itr *floatStreamUnsignedIterator) Close() error { return itr.input.Close() }
1766
1767// Next returns the next value for the stream iterator.
1768func (itr *floatStreamUnsignedIterator) Next() (*UnsignedPoint, error) {
1769	// Calculate next window if we have no more points.
1770	if len(itr.points) == 0 {
1771		var err error
1772		itr.points, err = itr.reduce()
1773		if len(itr.points) == 0 {
1774			return nil, err
1775		}
1776	}
1777
1778	// Pop next point off the stack.
1779	p := &itr.points[len(itr.points)-1]
1780	itr.points = itr.points[:len(itr.points)-1]
1781	return p, nil
1782}
1783
1784// reduce creates and manages aggregators for every point from the input.
1785// After aggregating a point, it always tries to emit a value using the emitter.
1786func (itr *floatStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) {
1787	// We have already read all of the input points.
1788	if itr.m == nil {
1789		return nil, nil
1790	}
1791
1792	for {
1793		// Read next point.
1794		curr, err := itr.input.Next()
1795		if err != nil {
1796			return nil, err
1797		} else if curr == nil {
1798			// Close all of the aggregators to flush any remaining points to emit.
1799			var points []UnsignedPoint
1800			for _, rp := range itr.m {
1801				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
1802					if err := aggregator.Close(); err != nil {
1803						return nil, err
1804					}
1805
1806					pts := rp.Emitter.Emit()
1807					if len(pts) == 0 {
1808						continue
1809					}
1810
1811					for i := range pts {
1812						pts[i].Name = rp.Name
1813						pts[i].Tags = rp.Tags
1814					}
1815					points = append(points, pts...)
1816				}
1817			}
1818
1819			// Eliminate the aggregators and emitters.
1820			itr.m = nil
1821			return points, nil
1822		} else if curr.Nil {
1823			continue
1824		}
1825		tags := curr.Tags.Subset(itr.dims)
1826
1827		id := curr.Name
1828		if len(tags.m) > 0 {
1829			id += "\x00" + tags.ID()
1830		}
1831
1832		// Retrieve the aggregator for this name/tag combination or create one.
1833		rp := itr.m[id]
1834		if rp == nil {
1835			aggregator, emitter := itr.create()
1836			rp = &floatReduceUnsignedPoint{
1837				Name:       curr.Name,
1838				Tags:       tags,
1839				Aggregator: aggregator,
1840				Emitter:    emitter,
1841			}
1842			itr.m[id] = rp
1843		}
1844		rp.Aggregator.AggregateFloat(curr)
1845
1846		// Attempt to emit points from the aggregator.
1847		points := rp.Emitter.Emit()
1848		if len(points) == 0 {
1849			continue
1850		}
1851
1852		for i := range points {
1853			points[i].Name = rp.Name
1854			points[i].Tags = rp.Tags
1855		}
1856		return points, nil
1857	}
1858}
1859
1860// floatReduceStringIterator executes a reducer for every interval and buffers the result.
1861type floatReduceStringIterator struct {
1862	input    *bufFloatIterator
1863	create   func() (FloatPointAggregator, StringPointEmitter)
1864	dims     []string
1865	opt      IteratorOptions
1866	points   []StringPoint
1867	keepTags bool
1868}
1869
1870func newFloatReduceStringIterator(input FloatIterator, opt IteratorOptions, createFn func() (FloatPointAggregator, StringPointEmitter)) *floatReduceStringIterator {
1871	return &floatReduceStringIterator{
1872		input:  newBufFloatIterator(input),
1873		create: createFn,
1874		dims:   opt.GetDimensions(),
1875		opt:    opt,
1876	}
1877}
1878
1879// Stats returns stats from the input iterator.
1880func (itr *floatReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() }
1881
1882// Close closes the iterator and all child iterators.
1883func (itr *floatReduceStringIterator) Close() error { return itr.input.Close() }
1884
1885// Next returns the minimum value for the next available interval.
1886func (itr *floatReduceStringIterator) Next() (*StringPoint, error) {
1887	// Calculate next window if we have no more points.
1888	if len(itr.points) == 0 {
1889		var err error
1890		itr.points, err = itr.reduce()
1891		if len(itr.points) == 0 {
1892			return nil, err
1893		}
1894	}
1895
1896	// Pop next point off the stack.
1897	p := &itr.points[len(itr.points)-1]
1898	itr.points = itr.points[:len(itr.points)-1]
1899	return p, nil
1900}
1901
1902// floatReduceStringPoint stores the reduced data for a name/tag combination.
1903type floatReduceStringPoint struct {
1904	Name       string
1905	Tags       Tags
1906	Aggregator FloatPointAggregator
1907	Emitter    StringPointEmitter
1908}
1909
1910// reduce executes fn once for every point in the next window.
1911// The previous value for the dimension is passed to fn.
1912func (itr *floatReduceStringIterator) reduce() ([]StringPoint, error) {
1913	// Calculate next window.
1914	var (
1915		startTime, endTime int64
1916		window             struct {
1917			name string
1918			tags string
1919		}
1920	)
1921	for {
1922		p, err := itr.input.Next()
1923		if err != nil || p == nil {
1924			return nil, err
1925		} else if p.Nil {
1926			continue
1927		}
1928
1929		// Unread the point so it can be processed.
1930		itr.input.unread(p)
1931		startTime, endTime = itr.opt.Window(p.Time)
1932		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
1933		break
1934	}
1935
1936	// Create points by tags.
1937	m := make(map[string]*floatReduceStringPoint)
1938	for {
1939		// Read next point.
1940		curr, err := itr.input.NextInWindow(startTime, endTime)
1941		if err != nil {
1942			return nil, err
1943		} else if curr == nil {
1944			break
1945		} else if curr.Nil {
1946			continue
1947		} else if curr.Name != window.name {
1948			itr.input.unread(curr)
1949			break
1950		}
1951
1952		// Ensure this point is within the same final window.
1953		if curr.Name != window.name {
1954			itr.input.unread(curr)
1955			break
1956		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
1957			itr.input.unread(curr)
1958			break
1959		}
1960
1961		// Retrieve the tags on this point for this level of the query.
1962		// This may be different than the bucket dimensions.
1963		tags := curr.Tags.Subset(itr.dims)
1964		id := tags.ID()
1965
1966		// Retrieve the aggregator for this name/tag combination or create one.
1967		rp := m[id]
1968		if rp == nil {
1969			aggregator, emitter := itr.create()
1970			rp = &floatReduceStringPoint{
1971				Name:       curr.Name,
1972				Tags:       tags,
1973				Aggregator: aggregator,
1974				Emitter:    emitter,
1975			}
1976			m[id] = rp
1977		}
1978		rp.Aggregator.AggregateFloat(curr)
1979	}
1980
1981	keys := make([]string, 0, len(m))
1982	for k := range m {
1983		keys = append(keys, k)
1984	}
1985
1986	// Reverse sort points by name & tag.
1987	// This ensures a consistent order of output.
1988	if len(keys) > 0 {
1989		var sorted sort.Interface = sort.StringSlice(keys)
1990		if itr.opt.Ascending {
1991			sorted = sort.Reverse(sorted)
1992		}
1993		sort.Sort(sorted)
1994	}
1995
1996	// Assume the points are already sorted until proven otherwise.
1997	sortedByTime := true
1998	// Emit the points for each name & tag combination.
1999	a := make([]StringPoint, 0, len(m))
2000	for _, k := range keys {
2001		rp := m[k]
2002		points := rp.Emitter.Emit()
2003		for i := len(points) - 1; i >= 0; i-- {
2004			points[i].Name = rp.Name
2005			if !itr.keepTags {
2006				points[i].Tags = rp.Tags
2007			}
2008			// Set the points time to the interval time if the reducer didn't provide one.
2009			if points[i].Time == ZeroTime {
2010				points[i].Time = startTime
2011			} else {
2012				sortedByTime = false
2013			}
2014			a = append(a, points[i])
2015		}
2016	}
2017	// Points may be out of order. Perform a stable sort by time if requested.
2018	if !sortedByTime && itr.opt.Ordered {
2019		var sorted sort.Interface = stringPointsByTime(a)
2020		if itr.opt.Ascending {
2021			sorted = sort.Reverse(sorted)
2022		}
2023		sort.Stable(sorted)
2024	}
2025	return a, nil
2026}
2027
2028// floatStreamStringIterator streams inputs into the iterator and emits points gradually.
2029type floatStreamStringIterator struct {
2030	input  *bufFloatIterator
2031	create func() (FloatPointAggregator, StringPointEmitter)
2032	dims   []string
2033	opt    IteratorOptions
2034	m      map[string]*floatReduceStringPoint
2035	points []StringPoint
2036}
2037
2038// newFloatStreamStringIterator returns a new instance of floatStreamStringIterator.
2039func newFloatStreamStringIterator(input FloatIterator, createFn func() (FloatPointAggregator, StringPointEmitter), opt IteratorOptions) *floatStreamStringIterator {
2040	return &floatStreamStringIterator{
2041		input:  newBufFloatIterator(input),
2042		create: createFn,
2043		dims:   opt.GetDimensions(),
2044		opt:    opt,
2045		m:      make(map[string]*floatReduceStringPoint),
2046	}
2047}
2048
2049// Stats returns stats from the input iterator.
2050func (itr *floatStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() }
2051
2052// Close closes the iterator and all child iterators.
2053func (itr *floatStreamStringIterator) Close() error { return itr.input.Close() }
2054
2055// Next returns the next value for the stream iterator.
2056func (itr *floatStreamStringIterator) Next() (*StringPoint, error) {
2057	// Calculate next window if we have no more points.
2058	if len(itr.points) == 0 {
2059		var err error
2060		itr.points, err = itr.reduce()
2061		if len(itr.points) == 0 {
2062			return nil, err
2063		}
2064	}
2065
2066	// Pop next point off the stack.
2067	p := &itr.points[len(itr.points)-1]
2068	itr.points = itr.points[:len(itr.points)-1]
2069	return p, nil
2070}
2071
2072// reduce creates and manages aggregators for every point from the input.
2073// After aggregating a point, it always tries to emit a value using the emitter.
2074func (itr *floatStreamStringIterator) reduce() ([]StringPoint, error) {
2075	// We have already read all of the input points.
2076	if itr.m == nil {
2077		return nil, nil
2078	}
2079
2080	for {
2081		// Read next point.
2082		curr, err := itr.input.Next()
2083		if err != nil {
2084			return nil, err
2085		} else if curr == nil {
2086			// Close all of the aggregators to flush any remaining points to emit.
2087			var points []StringPoint
2088			for _, rp := range itr.m {
2089				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
2090					if err := aggregator.Close(); err != nil {
2091						return nil, err
2092					}
2093
2094					pts := rp.Emitter.Emit()
2095					if len(pts) == 0 {
2096						continue
2097					}
2098
2099					for i := range pts {
2100						pts[i].Name = rp.Name
2101						pts[i].Tags = rp.Tags
2102					}
2103					points = append(points, pts...)
2104				}
2105			}
2106
2107			// Eliminate the aggregators and emitters.
2108			itr.m = nil
2109			return points, nil
2110		} else if curr.Nil {
2111			continue
2112		}
2113		tags := curr.Tags.Subset(itr.dims)
2114
2115		id := curr.Name
2116		if len(tags.m) > 0 {
2117			id += "\x00" + tags.ID()
2118		}
2119
2120		// Retrieve the aggregator for this name/tag combination or create one.
2121		rp := itr.m[id]
2122		if rp == nil {
2123			aggregator, emitter := itr.create()
2124			rp = &floatReduceStringPoint{
2125				Name:       curr.Name,
2126				Tags:       tags,
2127				Aggregator: aggregator,
2128				Emitter:    emitter,
2129			}
2130			itr.m[id] = rp
2131		}
2132		rp.Aggregator.AggregateFloat(curr)
2133
2134		// Attempt to emit points from the aggregator.
2135		points := rp.Emitter.Emit()
2136		if len(points) == 0 {
2137			continue
2138		}
2139
2140		for i := range points {
2141			points[i].Name = rp.Name
2142			points[i].Tags = rp.Tags
2143		}
2144		return points, nil
2145	}
2146}
2147
2148// floatReduceBooleanIterator executes a reducer for every interval and buffers the result.
2149type floatReduceBooleanIterator struct {
2150	input    *bufFloatIterator
2151	create   func() (FloatPointAggregator, BooleanPointEmitter)
2152	dims     []string
2153	opt      IteratorOptions
2154	points   []BooleanPoint
2155	keepTags bool
2156}
2157
2158func newFloatReduceBooleanIterator(input FloatIterator, opt IteratorOptions, createFn func() (FloatPointAggregator, BooleanPointEmitter)) *floatReduceBooleanIterator {
2159	return &floatReduceBooleanIterator{
2160		input:  newBufFloatIterator(input),
2161		create: createFn,
2162		dims:   opt.GetDimensions(),
2163		opt:    opt,
2164	}
2165}
2166
2167// Stats returns stats from the input iterator.
2168func (itr *floatReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
2169
2170// Close closes the iterator and all child iterators.
2171func (itr *floatReduceBooleanIterator) Close() error { return itr.input.Close() }
2172
2173// Next returns the minimum value for the next available interval.
2174func (itr *floatReduceBooleanIterator) Next() (*BooleanPoint, error) {
2175	// Calculate next window if we have no more points.
2176	if len(itr.points) == 0 {
2177		var err error
2178		itr.points, err = itr.reduce()
2179		if len(itr.points) == 0 {
2180			return nil, err
2181		}
2182	}
2183
2184	// Pop next point off the stack.
2185	p := &itr.points[len(itr.points)-1]
2186	itr.points = itr.points[:len(itr.points)-1]
2187	return p, nil
2188}
2189
2190// floatReduceBooleanPoint stores the reduced data for a name/tag combination.
2191type floatReduceBooleanPoint struct {
2192	Name       string
2193	Tags       Tags
2194	Aggregator FloatPointAggregator
2195	Emitter    BooleanPointEmitter
2196}
2197
2198// reduce executes fn once for every point in the next window.
2199// The previous value for the dimension is passed to fn.
2200func (itr *floatReduceBooleanIterator) reduce() ([]BooleanPoint, error) {
2201	// Calculate next window.
2202	var (
2203		startTime, endTime int64
2204		window             struct {
2205			name string
2206			tags string
2207		}
2208	)
2209	for {
2210		p, err := itr.input.Next()
2211		if err != nil || p == nil {
2212			return nil, err
2213		} else if p.Nil {
2214			continue
2215		}
2216
2217		// Unread the point so it can be processed.
2218		itr.input.unread(p)
2219		startTime, endTime = itr.opt.Window(p.Time)
2220		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
2221		break
2222	}
2223
2224	// Create points by tags.
2225	m := make(map[string]*floatReduceBooleanPoint)
2226	for {
2227		// Read next point.
2228		curr, err := itr.input.NextInWindow(startTime, endTime)
2229		if err != nil {
2230			return nil, err
2231		} else if curr == nil {
2232			break
2233		} else if curr.Nil {
2234			continue
2235		} else if curr.Name != window.name {
2236			itr.input.unread(curr)
2237			break
2238		}
2239
2240		// Ensure this point is within the same final window.
2241		if curr.Name != window.name {
2242			itr.input.unread(curr)
2243			break
2244		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
2245			itr.input.unread(curr)
2246			break
2247		}
2248
2249		// Retrieve the tags on this point for this level of the query.
2250		// This may be different than the bucket dimensions.
2251		tags := curr.Tags.Subset(itr.dims)
2252		id := tags.ID()
2253
2254		// Retrieve the aggregator for this name/tag combination or create one.
2255		rp := m[id]
2256		if rp == nil {
2257			aggregator, emitter := itr.create()
2258			rp = &floatReduceBooleanPoint{
2259				Name:       curr.Name,
2260				Tags:       tags,
2261				Aggregator: aggregator,
2262				Emitter:    emitter,
2263			}
2264			m[id] = rp
2265		}
2266		rp.Aggregator.AggregateFloat(curr)
2267	}
2268
2269	keys := make([]string, 0, len(m))
2270	for k := range m {
2271		keys = append(keys, k)
2272	}
2273
2274	// Reverse sort points by name & tag.
2275	// This ensures a consistent order of output.
2276	if len(keys) > 0 {
2277		var sorted sort.Interface = sort.StringSlice(keys)
2278		if itr.opt.Ascending {
2279			sorted = sort.Reverse(sorted)
2280		}
2281		sort.Sort(sorted)
2282	}
2283
2284	// Assume the points are already sorted until proven otherwise.
2285	sortedByTime := true
2286	// Emit the points for each name & tag combination.
2287	a := make([]BooleanPoint, 0, len(m))
2288	for _, k := range keys {
2289		rp := m[k]
2290		points := rp.Emitter.Emit()
2291		for i := len(points) - 1; i >= 0; i-- {
2292			points[i].Name = rp.Name
2293			if !itr.keepTags {
2294				points[i].Tags = rp.Tags
2295			}
2296			// Set the points time to the interval time if the reducer didn't provide one.
2297			if points[i].Time == ZeroTime {
2298				points[i].Time = startTime
2299			} else {
2300				sortedByTime = false
2301			}
2302			a = append(a, points[i])
2303		}
2304	}
2305	// Points may be out of order. Perform a stable sort by time if requested.
2306	if !sortedByTime && itr.opt.Ordered {
2307		var sorted sort.Interface = booleanPointsByTime(a)
2308		if itr.opt.Ascending {
2309			sorted = sort.Reverse(sorted)
2310		}
2311		sort.Stable(sorted)
2312	}
2313	return a, nil
2314}
2315
2316// floatStreamBooleanIterator streams inputs into the iterator and emits points gradually.
2317type floatStreamBooleanIterator struct {
2318	input  *bufFloatIterator
2319	create func() (FloatPointAggregator, BooleanPointEmitter)
2320	dims   []string
2321	opt    IteratorOptions
2322	m      map[string]*floatReduceBooleanPoint
2323	points []BooleanPoint
2324}
2325
2326// newFloatStreamBooleanIterator returns a new instance of floatStreamBooleanIterator.
2327func newFloatStreamBooleanIterator(input FloatIterator, createFn func() (FloatPointAggregator, BooleanPointEmitter), opt IteratorOptions) *floatStreamBooleanIterator {
2328	return &floatStreamBooleanIterator{
2329		input:  newBufFloatIterator(input),
2330		create: createFn,
2331		dims:   opt.GetDimensions(),
2332		opt:    opt,
2333		m:      make(map[string]*floatReduceBooleanPoint),
2334	}
2335}
2336
2337// Stats returns stats from the input iterator.
2338func (itr *floatStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
2339
2340// Close closes the iterator and all child iterators.
2341func (itr *floatStreamBooleanIterator) Close() error { return itr.input.Close() }
2342
2343// Next returns the next value for the stream iterator.
2344func (itr *floatStreamBooleanIterator) Next() (*BooleanPoint, error) {
2345	// Calculate next window if we have no more points.
2346	if len(itr.points) == 0 {
2347		var err error
2348		itr.points, err = itr.reduce()
2349		if len(itr.points) == 0 {
2350			return nil, err
2351		}
2352	}
2353
2354	// Pop next point off the stack.
2355	p := &itr.points[len(itr.points)-1]
2356	itr.points = itr.points[:len(itr.points)-1]
2357	return p, nil
2358}
2359
2360// reduce creates and manages aggregators for every point from the input.
2361// After aggregating a point, it always tries to emit a value using the emitter.
2362func (itr *floatStreamBooleanIterator) reduce() ([]BooleanPoint, error) {
2363	// We have already read all of the input points.
2364	if itr.m == nil {
2365		return nil, nil
2366	}
2367
2368	for {
2369		// Read next point.
2370		curr, err := itr.input.Next()
2371		if err != nil {
2372			return nil, err
2373		} else if curr == nil {
2374			// Close all of the aggregators to flush any remaining points to emit.
2375			var points []BooleanPoint
2376			for _, rp := range itr.m {
2377				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
2378					if err := aggregator.Close(); err != nil {
2379						return nil, err
2380					}
2381
2382					pts := rp.Emitter.Emit()
2383					if len(pts) == 0 {
2384						continue
2385					}
2386
2387					for i := range pts {
2388						pts[i].Name = rp.Name
2389						pts[i].Tags = rp.Tags
2390					}
2391					points = append(points, pts...)
2392				}
2393			}
2394
2395			// Eliminate the aggregators and emitters.
2396			itr.m = nil
2397			return points, nil
2398		} else if curr.Nil {
2399			continue
2400		}
2401		tags := curr.Tags.Subset(itr.dims)
2402
2403		id := curr.Name
2404		if len(tags.m) > 0 {
2405			id += "\x00" + tags.ID()
2406		}
2407
2408		// Retrieve the aggregator for this name/tag combination or create one.
2409		rp := itr.m[id]
2410		if rp == nil {
2411			aggregator, emitter := itr.create()
2412			rp = &floatReduceBooleanPoint{
2413				Name:       curr.Name,
2414				Tags:       tags,
2415				Aggregator: aggregator,
2416				Emitter:    emitter,
2417			}
2418			itr.m[id] = rp
2419		}
2420		rp.Aggregator.AggregateFloat(curr)
2421
2422		// Attempt to emit points from the aggregator.
2423		points := rp.Emitter.Emit()
2424		if len(points) == 0 {
2425			continue
2426		}
2427
2428		for i := range points {
2429			points[i].Name = rp.Name
2430			points[i].Tags = rp.Tags
2431		}
2432		return points, nil
2433	}
2434}
2435
2436// floatDedupeIterator only outputs unique points.
2437// This differs from the DistinctIterator in that it compares all aux fields too.
2438// This iterator is relatively inefficient and should only be used on small
2439// datasets such as meta query results.
2440type floatDedupeIterator struct {
2441	input FloatIterator
2442	m     map[string]struct{} // lookup of points already sent
2443}
2444
2445type floatIteratorMapper struct {
2446	cur    Cursor
2447	row    Row
2448	driver IteratorMap   // which iterator to use for the primary value, can be nil
2449	fields []IteratorMap // which iterator to use for an aux field
2450	point  FloatPoint
2451}
2452
2453func newFloatIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *floatIteratorMapper {
2454	return &floatIteratorMapper{
2455		cur:    cur,
2456		driver: driver,
2457		fields: fields,
2458		point: FloatPoint{
2459			Aux: make([]interface{}, len(fields)),
2460		},
2461	}
2462}
2463
2464func (itr *floatIteratorMapper) Next() (*FloatPoint, error) {
2465	if !itr.cur.Scan(&itr.row) {
2466		if err := itr.cur.Err(); err != nil {
2467			return nil, err
2468		}
2469		return nil, nil
2470	}
2471
2472	itr.point.Time = itr.row.Time
2473	itr.point.Name = itr.row.Series.Name
2474	itr.point.Tags = itr.row.Series.Tags
2475
2476	if itr.driver != nil {
2477		if v := itr.driver.Value(&itr.row); v != nil {
2478			if v, ok := castToFloat(v); ok {
2479				itr.point.Value = v
2480				itr.point.Nil = false
2481			} else {
2482				itr.point.Value = 0
2483				itr.point.Nil = true
2484			}
2485		} else {
2486			itr.point.Value = 0
2487			itr.point.Nil = true
2488		}
2489	}
2490	for i, f := range itr.fields {
2491		itr.point.Aux[i] = f.Value(&itr.row)
2492	}
2493	return &itr.point, nil
2494}
2495
2496func (itr *floatIteratorMapper) Stats() IteratorStats {
2497	return itr.cur.Stats()
2498}
2499
2500func (itr *floatIteratorMapper) Close() error {
2501	return itr.cur.Close()
2502}
2503
2504type floatFilterIterator struct {
2505	input FloatIterator
2506	cond  influxql.Expr
2507	opt   IteratorOptions
2508	m     map[string]interface{}
2509}
2510
2511func newFloatFilterIterator(input FloatIterator, cond influxql.Expr, opt IteratorOptions) FloatIterator {
2512	// Strip out time conditions from the WHERE clause.
2513	// TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct.
2514	n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node {
2515		switch n := n.(type) {
2516		case *influxql.BinaryExpr:
2517			if n.LHS.String() == "time" {
2518				return &influxql.BooleanLiteral{Val: true}
2519			}
2520		}
2521		return n
2522	})
2523
2524	cond, _ = n.(influxql.Expr)
2525	if cond == nil {
2526		return input
2527	} else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val {
2528		return input
2529	}
2530
2531	return &floatFilterIterator{
2532		input: input,
2533		cond:  cond,
2534		opt:   opt,
2535		m:     make(map[string]interface{}),
2536	}
2537}
2538
2539func (itr *floatFilterIterator) Stats() IteratorStats { return itr.input.Stats() }
2540func (itr *floatFilterIterator) Close() error         { return itr.input.Close() }
2541
2542func (itr *floatFilterIterator) Next() (*FloatPoint, error) {
2543	for {
2544		p, err := itr.input.Next()
2545		if err != nil || p == nil {
2546			return nil, err
2547		}
2548
2549		for i, ref := range itr.opt.Aux {
2550			itr.m[ref.Val] = p.Aux[i]
2551		}
2552		for k, v := range p.Tags.KeyValues() {
2553			itr.m[k] = v
2554		}
2555
2556		if !influxql.EvalBool(itr.cond, itr.m) {
2557			continue
2558		}
2559		return p, nil
2560	}
2561}
2562
2563type floatTagSubsetIterator struct {
2564	input      FloatIterator
2565	point      FloatPoint
2566	lastTags   Tags
2567	dimensions []string
2568}
2569
2570func newFloatTagSubsetIterator(input FloatIterator, opt IteratorOptions) *floatTagSubsetIterator {
2571	return &floatTagSubsetIterator{
2572		input:      input,
2573		dimensions: opt.GetDimensions(),
2574	}
2575}
2576
2577func (itr *floatTagSubsetIterator) Next() (*FloatPoint, error) {
2578	p, err := itr.input.Next()
2579	if err != nil {
2580		return nil, err
2581	} else if p == nil {
2582		return nil, nil
2583	}
2584
2585	itr.point.Name = p.Name
2586	if !p.Tags.Equal(itr.lastTags) {
2587		itr.point.Tags = p.Tags.Subset(itr.dimensions)
2588		itr.lastTags = p.Tags
2589	}
2590	itr.point.Time = p.Time
2591	itr.point.Value = p.Value
2592	itr.point.Aux = p.Aux
2593	itr.point.Aggregated = p.Aggregated
2594	itr.point.Nil = p.Nil
2595	return &itr.point, nil
2596}
2597
2598func (itr *floatTagSubsetIterator) Stats() IteratorStats {
2599	return itr.input.Stats()
2600}
2601
2602func (itr *floatTagSubsetIterator) Close() error {
2603	return itr.input.Close()
2604}
2605
2606// newFloatDedupeIterator returns a new instance of floatDedupeIterator.
2607func newFloatDedupeIterator(input FloatIterator) *floatDedupeIterator {
2608	return &floatDedupeIterator{
2609		input: input,
2610		m:     make(map[string]struct{}),
2611	}
2612}
2613
2614// Stats returns stats from the input iterator.
2615func (itr *floatDedupeIterator) Stats() IteratorStats { return itr.input.Stats() }
2616
2617// Close closes the iterator and all child iterators.
2618func (itr *floatDedupeIterator) Close() error { return itr.input.Close() }
2619
2620// Next returns the next unique point from the input iterator.
2621func (itr *floatDedupeIterator) Next() (*FloatPoint, error) {
2622	for {
2623		// Read next point.
2624		p, err := itr.input.Next()
2625		if p == nil || err != nil {
2626			return nil, err
2627		}
2628
2629		// Serialize to bytes to store in lookup.
2630		buf, err := proto.Marshal(encodeFloatPoint(p))
2631		if err != nil {
2632			return nil, err
2633		}
2634
2635		// If the point has already been output then move to the next point.
2636		if _, ok := itr.m[string(buf)]; ok {
2637			continue
2638		}
2639
2640		// Otherwise mark it as emitted and return point.
2641		itr.m[string(buf)] = struct{}{}
2642		return p, nil
2643	}
2644}
2645
2646// floatReaderIterator represents an iterator that streams from a reader.
2647type floatReaderIterator struct {
2648	r   io.Reader
2649	dec *FloatPointDecoder
2650}
2651
2652// newFloatReaderIterator returns a new instance of floatReaderIterator.
2653func newFloatReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *floatReaderIterator {
2654	dec := NewFloatPointDecoder(ctx, r)
2655	dec.stats = stats
2656
2657	return &floatReaderIterator{
2658		r:   r,
2659		dec: dec,
2660	}
2661}
2662
2663// Stats returns stats about points processed.
2664func (itr *floatReaderIterator) Stats() IteratorStats { return itr.dec.stats }
2665
2666// Close closes the underlying reader, if applicable.
2667func (itr *floatReaderIterator) Close() error {
2668	if r, ok := itr.r.(io.ReadCloser); ok {
2669		return r.Close()
2670	}
2671	return nil
2672}
2673
2674// Next returns the next point from the iterator.
2675func (itr *floatReaderIterator) Next() (*FloatPoint, error) {
2676	// OPTIMIZE(benbjohnson): Reuse point on iterator.
2677
2678	// Unmarshal next point.
2679	p := &FloatPoint{}
2680	if err := itr.dec.DecodeFloatPoint(p); err == io.EOF {
2681		return nil, nil
2682	} else if err != nil {
2683		return nil, err
2684	}
2685	return p, nil
2686}
2687
2688// IntegerIterator represents a stream of integer points.
2689type IntegerIterator interface {
2690	Iterator
2691	Next() (*IntegerPoint, error)
2692}
2693
2694// newIntegerIterators converts a slice of Iterator to a slice of IntegerIterator.
2695// Drop and closes any iterator in itrs that is not a IntegerIterator and cannot
2696// be cast to a IntegerIterator.
2697func newIntegerIterators(itrs []Iterator) []IntegerIterator {
2698	a := make([]IntegerIterator, 0, len(itrs))
2699	for _, itr := range itrs {
2700		switch itr := itr.(type) {
2701		case IntegerIterator:
2702			a = append(a, itr)
2703		default:
2704			itr.Close()
2705		}
2706	}
2707	return a
2708}
2709
2710// bufIntegerIterator represents a buffered IntegerIterator.
2711type bufIntegerIterator struct {
2712	itr IntegerIterator
2713	buf *IntegerPoint
2714}
2715
2716// newBufIntegerIterator returns a buffered IntegerIterator.
2717func newBufIntegerIterator(itr IntegerIterator) *bufIntegerIterator {
2718	return &bufIntegerIterator{itr: itr}
2719}
2720
2721// Stats returns statistics from the input iterator.
2722func (itr *bufIntegerIterator) Stats() IteratorStats { return itr.itr.Stats() }
2723
2724// Close closes the underlying iterator.
2725func (itr *bufIntegerIterator) Close() error { return itr.itr.Close() }
2726
2727// peek returns the next point without removing it from the iterator.
2728func (itr *bufIntegerIterator) peek() (*IntegerPoint, error) {
2729	p, err := itr.Next()
2730	if err != nil {
2731		return nil, err
2732	}
2733	itr.unread(p)
2734	return p, nil
2735}
2736
2737// peekTime returns the time of the next point.
2738// Returns zero time if no more points available.
2739func (itr *bufIntegerIterator) peekTime() (int64, error) {
2740	p, err := itr.peek()
2741	if p == nil || err != nil {
2742		return ZeroTime, err
2743	}
2744	return p.Time, nil
2745}
2746
2747// Next returns the current buffer, if exists, or calls the underlying iterator.
2748func (itr *bufIntegerIterator) Next() (*IntegerPoint, error) {
2749	buf := itr.buf
2750	if buf != nil {
2751		itr.buf = nil
2752		return buf, nil
2753	}
2754	return itr.itr.Next()
2755}
2756
2757// NextInWindow returns the next value if it is between [startTime, endTime).
2758// If the next value is outside the range then it is moved to the buffer.
2759func (itr *bufIntegerIterator) NextInWindow(startTime, endTime int64) (*IntegerPoint, error) {
2760	v, err := itr.Next()
2761	if v == nil || err != nil {
2762		return nil, err
2763	} else if t := v.Time; t >= endTime || t < startTime {
2764		itr.unread(v)
2765		return nil, nil
2766	}
2767	return v, nil
2768}
2769
2770// unread sets v to the buffer. It is read on the next call to Next().
2771func (itr *bufIntegerIterator) unread(v *IntegerPoint) { itr.buf = v }
2772
2773// integerMergeIterator represents an iterator that combines multiple integer iterators.
2774type integerMergeIterator struct {
2775	inputs []IntegerIterator
2776	heap   *integerMergeHeap
2777	init   bool
2778
2779	closed bool
2780	mu     sync.RWMutex
2781
2782	// Current iterator and window.
2783	curr   *integerMergeHeapItem
2784	window struct {
2785		name      string
2786		tags      string
2787		startTime int64
2788		endTime   int64
2789	}
2790}
2791
2792// newIntegerMergeIterator returns a new instance of integerMergeIterator.
2793func newIntegerMergeIterator(inputs []IntegerIterator, opt IteratorOptions) *integerMergeIterator {
2794	itr := &integerMergeIterator{
2795		inputs: inputs,
2796		heap: &integerMergeHeap{
2797			items: make([]*integerMergeHeapItem, 0, len(inputs)),
2798			opt:   opt,
2799		},
2800	}
2801
2802	// Initialize heap items.
2803	for _, input := range inputs {
2804		// Wrap in buffer, ignore any inputs without anymore points.
2805		bufInput := newBufIntegerIterator(input)
2806
2807		// Append to the heap.
2808		itr.heap.items = append(itr.heap.items, &integerMergeHeapItem{itr: bufInput})
2809	}
2810
2811	return itr
2812}
2813
2814// Stats returns an aggregation of stats from the underlying iterators.
2815func (itr *integerMergeIterator) Stats() IteratorStats {
2816	var stats IteratorStats
2817	for _, input := range itr.inputs {
2818		stats.Add(input.Stats())
2819	}
2820	return stats
2821}
2822
2823// Close closes the underlying iterators.
2824func (itr *integerMergeIterator) Close() error {
2825	itr.mu.Lock()
2826	defer itr.mu.Unlock()
2827
2828	for _, input := range itr.inputs {
2829		input.Close()
2830	}
2831	itr.curr = nil
2832	itr.inputs = nil
2833	itr.heap.items = nil
2834	itr.closed = true
2835	return nil
2836}
2837
2838// Next returns the next point from the iterator.
2839func (itr *integerMergeIterator) Next() (*IntegerPoint, error) {
2840	itr.mu.RLock()
2841	defer itr.mu.RUnlock()
2842	if itr.closed {
2843		return nil, nil
2844	}
2845
2846	// Initialize the heap. This needs to be done lazily on the first call to this iterator
2847	// so that iterator initialization done through the Select() call returns quickly.
2848	// Queries can only be interrupted after the Select() call completes so any operations
2849	// done during iterator creation cannot be interrupted, which is why we do it here
2850	// instead so an interrupt can happen while initializing the heap.
2851	if !itr.init {
2852		items := itr.heap.items
2853		itr.heap.items = make([]*integerMergeHeapItem, 0, len(items))
2854		for _, item := range items {
2855			if p, err := item.itr.peek(); err != nil {
2856				return nil, err
2857			} else if p == nil {
2858				continue
2859			}
2860			itr.heap.items = append(itr.heap.items, item)
2861		}
2862		heap.Init(itr.heap)
2863		itr.init = true
2864	}
2865
2866	for {
2867		// Retrieve the next iterator if we don't have one.
2868		if itr.curr == nil {
2869			if len(itr.heap.items) == 0 {
2870				return nil, nil
2871			}
2872			itr.curr = heap.Pop(itr.heap).(*integerMergeHeapItem)
2873
2874			// Read point and set current window.
2875			p, err := itr.curr.itr.Next()
2876			if err != nil {
2877				return nil, err
2878			}
2879			tags := p.Tags.Subset(itr.heap.opt.Dimensions)
2880			itr.window.name, itr.window.tags = p.Name, tags.ID()
2881			itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time)
2882			return p, nil
2883		}
2884
2885		// Read the next point from the current iterator.
2886		p, err := itr.curr.itr.Next()
2887		if err != nil {
2888			return nil, err
2889		}
2890
2891		// If there are no more points then remove iterator from heap and find next.
2892		if p == nil {
2893			itr.curr = nil
2894			continue
2895		}
2896
2897		// Check if the point is inside of our current window.
2898		inWindow := true
2899		if window := itr.window; window.name != p.Name {
2900			inWindow = false
2901		} else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() {
2902			inWindow = false
2903		} else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime {
2904			inWindow = false
2905		} else if !opt.Ascending && p.Time < window.startTime {
2906			inWindow = false
2907		}
2908
2909		// If it's outside our window then push iterator back on the heap and find new iterator.
2910		if !inWindow {
2911			itr.curr.itr.unread(p)
2912			heap.Push(itr.heap, itr.curr)
2913			itr.curr = nil
2914			continue
2915		}
2916
2917		return p, nil
2918	}
2919}
2920
2921// integerMergeHeap represents a heap of integerMergeHeapItems.
2922// Items are sorted by their next window and then by name/tags.
2923type integerMergeHeap struct {
2924	opt   IteratorOptions
2925	items []*integerMergeHeapItem
2926}
2927
2928func (h *integerMergeHeap) Len() int      { return len(h.items) }
2929func (h *integerMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
2930func (h *integerMergeHeap) Less(i, j int) bool {
2931	x, err := h.items[i].itr.peek()
2932	if err != nil {
2933		return true
2934	}
2935	y, err := h.items[j].itr.peek()
2936	if err != nil {
2937		return false
2938	}
2939
2940	if h.opt.Ascending {
2941		if x.Name != y.Name {
2942			return x.Name < y.Name
2943		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
2944			return xTags.ID() < yTags.ID()
2945		}
2946	} else {
2947		if x.Name != y.Name {
2948			return x.Name > y.Name
2949		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
2950			return xTags.ID() > yTags.ID()
2951		}
2952	}
2953
2954	xt, _ := h.opt.Window(x.Time)
2955	yt, _ := h.opt.Window(y.Time)
2956
2957	if h.opt.Ascending {
2958		return xt < yt
2959	}
2960	return xt > yt
2961}
2962
2963func (h *integerMergeHeap) Push(x interface{}) {
2964	h.items = append(h.items, x.(*integerMergeHeapItem))
2965}
2966
2967func (h *integerMergeHeap) Pop() interface{} {
2968	old := h.items
2969	n := len(old)
2970	item := old[n-1]
2971	h.items = old[0 : n-1]
2972	return item
2973}
2974
2975type integerMergeHeapItem struct {
2976	itr *bufIntegerIterator
2977}
2978
2979// integerSortedMergeIterator is an iterator that sorts and merges multiple iterators into one.
2980type integerSortedMergeIterator struct {
2981	inputs []IntegerIterator
2982	heap   *integerSortedMergeHeap
2983	init   bool
2984}
2985
2986// newIntegerSortedMergeIterator returns an instance of integerSortedMergeIterator.
2987func newIntegerSortedMergeIterator(inputs []IntegerIterator, opt IteratorOptions) Iterator {
2988	itr := &integerSortedMergeIterator{
2989		inputs: inputs,
2990		heap: &integerSortedMergeHeap{
2991			items: make([]*integerSortedMergeHeapItem, 0, len(inputs)),
2992			opt:   opt,
2993		},
2994	}
2995
2996	// Initialize heap items.
2997	for _, input := range inputs {
2998		// Append to the heap.
2999		itr.heap.items = append(itr.heap.items, &integerSortedMergeHeapItem{itr: input})
3000	}
3001
3002	return itr
3003}
3004
3005// Stats returns an aggregation of stats from the underlying iterators.
3006func (itr *integerSortedMergeIterator) Stats() IteratorStats {
3007	var stats IteratorStats
3008	for _, input := range itr.inputs {
3009		stats.Add(input.Stats())
3010	}
3011	return stats
3012}
3013
3014// Close closes the underlying iterators.
3015func (itr *integerSortedMergeIterator) Close() error {
3016	for _, input := range itr.inputs {
3017		input.Close()
3018	}
3019	return nil
3020}
3021
3022// Next returns the next points from the iterator.
3023func (itr *integerSortedMergeIterator) Next() (*IntegerPoint, error) { return itr.pop() }
3024
3025// pop returns the next point from the heap.
3026// Reads the next point from item's cursor and puts it back on the heap.
3027func (itr *integerSortedMergeIterator) pop() (*IntegerPoint, error) {
3028	// Initialize the heap. See the MergeIterator to see why this has to be done lazily.
3029	if !itr.init {
3030		items := itr.heap.items
3031		itr.heap.items = make([]*integerSortedMergeHeapItem, 0, len(items))
3032		for _, item := range items {
3033			var err error
3034			if item.point, err = item.itr.Next(); err != nil {
3035				return nil, err
3036			} else if item.point == nil {
3037				continue
3038			}
3039			itr.heap.items = append(itr.heap.items, item)
3040		}
3041		heap.Init(itr.heap)
3042		itr.init = true
3043	}
3044
3045	if len(itr.heap.items) == 0 {
3046		return nil, nil
3047	}
3048
3049	// Read the next item from the heap.
3050	item := heap.Pop(itr.heap).(*integerSortedMergeHeapItem)
3051	if item.err != nil {
3052		return nil, item.err
3053	} else if item.point == nil {
3054		return nil, nil
3055	}
3056
3057	// Copy the point for return.
3058	p := item.point.Clone()
3059
3060	// Read the next item from the cursor. Push back to heap if one exists.
3061	if item.point, item.err = item.itr.Next(); item.point != nil {
3062		heap.Push(itr.heap, item)
3063	}
3064
3065	return p, nil
3066}
3067
3068// integerSortedMergeHeap represents a heap of integerSortedMergeHeapItems.
3069// Items are sorted with the following priority:
3070//     - By their measurement name;
3071//     - By their tag keys/values;
3072//     - By time; or
3073//     - By their Aux field values.
3074//
3075type integerSortedMergeHeap struct {
3076	opt   IteratorOptions
3077	items []*integerSortedMergeHeapItem
3078}
3079
3080func (h *integerSortedMergeHeap) Len() int      { return len(h.items) }
3081func (h *integerSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
3082func (h *integerSortedMergeHeap) Less(i, j int) bool {
3083	x, y := h.items[i].point, h.items[j].point
3084
3085	if h.opt.Ascending {
3086		if x.Name != y.Name {
3087			return x.Name < y.Name
3088		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
3089			return xTags.ID() < yTags.ID()
3090		}
3091
3092		if x.Time != y.Time {
3093			return x.Time < y.Time
3094		}
3095
3096		if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
3097			for i := 0; i < len(x.Aux); i++ {
3098				v1, ok1 := x.Aux[i].(string)
3099				v2, ok2 := y.Aux[i].(string)
3100				if !ok1 || !ok2 {
3101					// Unsupported types used in Aux fields. Maybe they
3102					// need to be added here?
3103					return false
3104				} else if v1 == v2 {
3105					continue
3106				}
3107				return v1 < v2
3108			}
3109		}
3110		return false // Times and/or Aux fields are equal.
3111	}
3112
3113	if x.Name != y.Name {
3114		return x.Name > y.Name
3115	} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
3116		return xTags.ID() > yTags.ID()
3117	}
3118
3119	if x.Time != y.Time {
3120		return x.Time > y.Time
3121	}
3122
3123	if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
3124		for i := 0; i < len(x.Aux); i++ {
3125			v1, ok1 := x.Aux[i].(string)
3126			v2, ok2 := y.Aux[i].(string)
3127			if !ok1 || !ok2 {
3128				// Unsupported types used in Aux fields. Maybe they
3129				// need to be added here?
3130				return false
3131			} else if v1 == v2 {
3132				continue
3133			}
3134			return v1 > v2
3135		}
3136	}
3137	return false // Times and/or Aux fields are equal.
3138}
3139
3140func (h *integerSortedMergeHeap) Push(x interface{}) {
3141	h.items = append(h.items, x.(*integerSortedMergeHeapItem))
3142}
3143
3144func (h *integerSortedMergeHeap) Pop() interface{} {
3145	old := h.items
3146	n := len(old)
3147	item := old[n-1]
3148	h.items = old[0 : n-1]
3149	return item
3150}
3151
3152type integerSortedMergeHeapItem struct {
3153	point *IntegerPoint
3154	err   error
3155	itr   IntegerIterator
3156}
3157
3158// integerIteratorScanner scans the results of a IntegerIterator into a map.
3159type integerIteratorScanner struct {
3160	input        *bufIntegerIterator
3161	err          error
3162	keys         []influxql.VarRef
3163	defaultValue interface{}
3164}
3165
3166// newIntegerIteratorScanner creates a new IteratorScanner.
3167func newIntegerIteratorScanner(input IntegerIterator, keys []influxql.VarRef, defaultValue interface{}) *integerIteratorScanner {
3168	return &integerIteratorScanner{
3169		input:        newBufIntegerIterator(input),
3170		keys:         keys,
3171		defaultValue: defaultValue,
3172	}
3173}
3174
3175func (s *integerIteratorScanner) Peek() (int64, string, Tags) {
3176	if s.err != nil {
3177		return ZeroTime, "", Tags{}
3178	}
3179
3180	p, err := s.input.peek()
3181	if err != nil {
3182		s.err = err
3183		return ZeroTime, "", Tags{}
3184	} else if p == nil {
3185		return ZeroTime, "", Tags{}
3186	}
3187	return p.Time, p.Name, p.Tags
3188}
3189
3190func (s *integerIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) {
3191	if s.err != nil {
3192		return
3193	}
3194
3195	p, err := s.input.Next()
3196	if err != nil {
3197		s.err = err
3198		return
3199	} else if p == nil {
3200		s.useDefaults(m)
3201		return
3202	} else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) {
3203		s.useDefaults(m)
3204		s.input.unread(p)
3205		return
3206	}
3207
3208	if k := s.keys[0]; k.Val != "" {
3209		if p.Nil {
3210			if s.defaultValue != SkipDefault {
3211				m[k.Val] = castToType(s.defaultValue, k.Type)
3212			}
3213		} else {
3214			m[k.Val] = p.Value
3215		}
3216	}
3217	for i, v := range p.Aux {
3218		k := s.keys[i+1]
3219		switch v.(type) {
3220		case float64, int64, uint64, string, bool:
3221			m[k.Val] = v
3222		default:
3223			// Insert the fill value if one was specified.
3224			if s.defaultValue != SkipDefault {
3225				m[k.Val] = castToType(s.defaultValue, k.Type)
3226			}
3227		}
3228	}
3229}
3230
3231func (s *integerIteratorScanner) useDefaults(m map[string]interface{}) {
3232	if s.defaultValue == SkipDefault {
3233		return
3234	}
3235	for _, k := range s.keys {
3236		if k.Val == "" {
3237			continue
3238		}
3239		m[k.Val] = castToType(s.defaultValue, k.Type)
3240	}
3241}
3242
3243func (s *integerIteratorScanner) Stats() IteratorStats { return s.input.Stats() }
3244func (s *integerIteratorScanner) Err() error           { return s.err }
3245func (s *integerIteratorScanner) Close() error         { return s.input.Close() }
3246
3247// integerParallelIterator represents an iterator that pulls data in a separate goroutine.
3248type integerParallelIterator struct {
3249	input IntegerIterator
3250	ch    chan integerPointError
3251
3252	once    sync.Once
3253	closing chan struct{}
3254	wg      sync.WaitGroup
3255}
3256
3257// newIntegerParallelIterator returns a new instance of integerParallelIterator.
3258func newIntegerParallelIterator(input IntegerIterator) *integerParallelIterator {
3259	itr := &integerParallelIterator{
3260		input:   input,
3261		ch:      make(chan integerPointError, 256),
3262		closing: make(chan struct{}),
3263	}
3264	itr.wg.Add(1)
3265	go itr.monitor()
3266	return itr
3267}
3268
3269// Stats returns stats from the underlying iterator.
3270func (itr *integerParallelIterator) Stats() IteratorStats { return itr.input.Stats() }
3271
3272// Close closes the underlying iterators.
3273func (itr *integerParallelIterator) Close() error {
3274	itr.once.Do(func() { close(itr.closing) })
3275	itr.wg.Wait()
3276	return itr.input.Close()
3277}
3278
3279// Next returns the next point from the iterator.
3280func (itr *integerParallelIterator) Next() (*IntegerPoint, error) {
3281	v, ok := <-itr.ch
3282	if !ok {
3283		return nil, io.EOF
3284	}
3285	return v.point, v.err
3286}
3287
3288// monitor runs in a separate goroutine and actively pulls the next point.
3289func (itr *integerParallelIterator) monitor() {
3290	defer close(itr.ch)
3291	defer itr.wg.Done()
3292
3293	for {
3294		// Read next point.
3295		p, err := itr.input.Next()
3296		if p != nil {
3297			p = p.Clone()
3298		}
3299
3300		select {
3301		case <-itr.closing:
3302			return
3303		case itr.ch <- integerPointError{point: p, err: err}:
3304		}
3305	}
3306}
3307
3308type integerPointError struct {
3309	point *IntegerPoint
3310	err   error
3311}
3312
3313// integerLimitIterator represents an iterator that limits points per group.
3314type integerLimitIterator struct {
3315	input IntegerIterator
3316	opt   IteratorOptions
3317	n     int
3318
3319	prev struct {
3320		name string
3321		tags Tags
3322	}
3323}
3324
3325// newIntegerLimitIterator returns a new instance of integerLimitIterator.
3326func newIntegerLimitIterator(input IntegerIterator, opt IteratorOptions) *integerLimitIterator {
3327	return &integerLimitIterator{
3328		input: input,
3329		opt:   opt,
3330	}
3331}
3332
3333// Stats returns stats from the underlying iterator.
3334func (itr *integerLimitIterator) Stats() IteratorStats { return itr.input.Stats() }
3335
3336// Close closes the underlying iterators.
3337func (itr *integerLimitIterator) Close() error { return itr.input.Close() }
3338
3339// Next returns the next point from the iterator.
3340func (itr *integerLimitIterator) Next() (*IntegerPoint, error) {
3341	for {
3342		p, err := itr.input.Next()
3343		if p == nil || err != nil {
3344			return nil, err
3345		}
3346
3347		// Reset window and counter if a new window is encountered.
3348		if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) {
3349			itr.prev.name = p.Name
3350			itr.prev.tags = p.Tags
3351			itr.n = 0
3352		}
3353
3354		// Increment counter.
3355		itr.n++
3356
3357		// Read next point if not beyond the offset.
3358		if itr.n <= itr.opt.Offset {
3359			continue
3360		}
3361
3362		// Read next point if we're beyond the limit.
3363		if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit {
3364			continue
3365		}
3366
3367		return p, nil
3368	}
3369}
3370
3371type integerFillIterator struct {
3372	input     *bufIntegerIterator
3373	prev      IntegerPoint
3374	startTime int64
3375	endTime   int64
3376	auxFields []interface{}
3377	init      bool
3378	opt       IteratorOptions
3379
3380	window struct {
3381		name   string
3382		tags   Tags
3383		time   int64
3384		offset int64
3385	}
3386}
3387
3388func newIntegerFillIterator(input IntegerIterator, expr influxql.Expr, opt IteratorOptions) *integerFillIterator {
3389	if opt.Fill == influxql.NullFill {
3390		if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" {
3391			opt.Fill = influxql.NumberFill
3392			opt.FillValue = int64(0)
3393		}
3394	}
3395
3396	var startTime, endTime int64
3397	if opt.Ascending {
3398		startTime, _ = opt.Window(opt.StartTime)
3399		endTime, _ = opt.Window(opt.EndTime)
3400	} else {
3401		startTime, _ = opt.Window(opt.EndTime)
3402		endTime, _ = opt.Window(opt.StartTime)
3403	}
3404
3405	var auxFields []interface{}
3406	if len(opt.Aux) > 0 {
3407		auxFields = make([]interface{}, len(opt.Aux))
3408	}
3409
3410	return &integerFillIterator{
3411		input:     newBufIntegerIterator(input),
3412		prev:      IntegerPoint{Nil: true},
3413		startTime: startTime,
3414		endTime:   endTime,
3415		auxFields: auxFields,
3416		opt:       opt,
3417	}
3418}
3419
3420func (itr *integerFillIterator) Stats() IteratorStats { return itr.input.Stats() }
3421func (itr *integerFillIterator) Close() error         { return itr.input.Close() }
3422
3423func (itr *integerFillIterator) Next() (*IntegerPoint, error) {
3424	if !itr.init {
3425		p, err := itr.input.peek()
3426		if p == nil || err != nil {
3427			return nil, err
3428		}
3429		itr.window.name, itr.window.tags = p.Name, p.Tags
3430		itr.window.time = itr.startTime
3431		if itr.startTime == influxql.MinTime {
3432			itr.window.time, _ = itr.opt.Window(p.Time)
3433		}
3434		if itr.opt.Location != nil {
3435			_, itr.window.offset = itr.opt.Zone(itr.window.time)
3436		}
3437		itr.init = true
3438	}
3439
3440	p, err := itr.input.Next()
3441	if err != nil {
3442		return nil, err
3443	}
3444
3445	// Check if the next point is outside of our window or is nil.
3446	if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() {
3447		// If we are inside of an interval, unread the point and continue below to
3448		// constructing a new point.
3449		if itr.opt.Ascending && itr.window.time <= itr.endTime {
3450			itr.input.unread(p)
3451			p = nil
3452			goto CONSTRUCT
3453		} else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime {
3454			itr.input.unread(p)
3455			p = nil
3456			goto CONSTRUCT
3457		}
3458
3459		// We are *not* in a current interval. If there is no next point,
3460		// we are at the end of all intervals.
3461		if p == nil {
3462			return nil, nil
3463		}
3464
3465		// Set the new interval.
3466		itr.window.name, itr.window.tags = p.Name, p.Tags
3467		itr.window.time = itr.startTime
3468		if itr.window.time == influxql.MinTime {
3469			itr.window.time, _ = itr.opt.Window(p.Time)
3470		}
3471		if itr.opt.Location != nil {
3472			_, itr.window.offset = itr.opt.Zone(itr.window.time)
3473		}
3474		itr.prev = IntegerPoint{Nil: true}
3475	}
3476
3477	// Check if the point is our next expected point.
3478CONSTRUCT:
3479	if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) {
3480		if p != nil {
3481			itr.input.unread(p)
3482		}
3483
3484		p = &IntegerPoint{
3485			Name: itr.window.name,
3486			Tags: itr.window.tags,
3487			Time: itr.window.time,
3488			Aux:  itr.auxFields,
3489		}
3490
3491		switch itr.opt.Fill {
3492		case influxql.LinearFill:
3493			if !itr.prev.Nil {
3494				next, err := itr.input.peek()
3495				if err != nil {
3496					return nil, err
3497				} else if next != nil && next.Name == itr.window.name && next.Tags.ID() == itr.window.tags.ID() {
3498					interval := int64(itr.opt.Interval.Duration)
3499					start := itr.window.time / interval
3500					p.Value = linearInteger(start, itr.prev.Time/interval, next.Time/interval, itr.prev.Value, next.Value)
3501				} else {
3502					p.Nil = true
3503				}
3504			} else {
3505				p.Nil = true
3506			}
3507
3508		case influxql.NullFill:
3509			p.Nil = true
3510		case influxql.NumberFill:
3511			p.Value, _ = castToInteger(itr.opt.FillValue)
3512		case influxql.PreviousFill:
3513			if !itr.prev.Nil {
3514				p.Value = itr.prev.Value
3515				p.Nil = itr.prev.Nil
3516			} else {
3517				p.Nil = true
3518			}
3519		}
3520	} else {
3521		itr.prev = *p
3522	}
3523
3524	// Advance the expected time. Do not advance to a new window here
3525	// as there may be lingering points with the same timestamp in the previous
3526	// window.
3527	if itr.opt.Ascending {
3528		itr.window.time += int64(itr.opt.Interval.Duration)
3529	} else {
3530		itr.window.time -= int64(itr.opt.Interval.Duration)
3531	}
3532
3533	// Check to see if we have passed over an offset change and adjust the time
3534	// to account for this new offset.
3535	if itr.opt.Location != nil {
3536		if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset {
3537			diff := itr.window.offset - offset
3538			if abs(diff) < int64(itr.opt.Interval.Duration) {
3539				itr.window.time += diff
3540			}
3541			itr.window.offset = offset
3542		}
3543	}
3544	return p, nil
3545}
3546
3547// integerIntervalIterator represents a integer implementation of IntervalIterator.
3548type integerIntervalIterator struct {
3549	input IntegerIterator
3550	opt   IteratorOptions
3551}
3552
3553func newIntegerIntervalIterator(input IntegerIterator, opt IteratorOptions) *integerIntervalIterator {
3554	return &integerIntervalIterator{input: input, opt: opt}
3555}
3556
3557func (itr *integerIntervalIterator) Stats() IteratorStats { return itr.input.Stats() }
3558func (itr *integerIntervalIterator) Close() error         { return itr.input.Close() }
3559
3560func (itr *integerIntervalIterator) Next() (*IntegerPoint, error) {
3561	p, err := itr.input.Next()
3562	if p == nil || err != nil {
3563		return nil, err
3564	}
3565	p.Time, _ = itr.opt.Window(p.Time)
3566	// If we see the minimum allowable time, set the time to zero so we don't
3567	// break the default returned time for aggregate queries without times.
3568	if p.Time == influxql.MinTime {
3569		p.Time = 0
3570	}
3571	return p, nil
3572}
3573
3574// integerInterruptIterator represents a integer implementation of InterruptIterator.
3575type integerInterruptIterator struct {
3576	input   IntegerIterator
3577	closing <-chan struct{}
3578	count   int
3579}
3580
3581func newIntegerInterruptIterator(input IntegerIterator, closing <-chan struct{}) *integerInterruptIterator {
3582	return &integerInterruptIterator{input: input, closing: closing}
3583}
3584
3585func (itr *integerInterruptIterator) Stats() IteratorStats { return itr.input.Stats() }
3586func (itr *integerInterruptIterator) Close() error         { return itr.input.Close() }
3587
3588func (itr *integerInterruptIterator) Next() (*IntegerPoint, error) {
3589	// Only check if the channel is closed every N points. This
3590	// intentionally checks on both 0 and N so that if the iterator
3591	// has been interrupted before the first point is emitted it will
3592	// not emit any points.
3593	if itr.count&0xFF == 0xFF {
3594		select {
3595		case <-itr.closing:
3596			return nil, itr.Close()
3597		default:
3598			// Reset iterator count to zero and fall through to emit the next point.
3599			itr.count = 0
3600		}
3601	}
3602
3603	// Increment the counter for every point read.
3604	itr.count++
3605	return itr.input.Next()
3606}
3607
3608// integerCloseInterruptIterator represents a integer implementation of CloseInterruptIterator.
3609type integerCloseInterruptIterator struct {
3610	input   IntegerIterator
3611	closing <-chan struct{}
3612	done    chan struct{}
3613	once    sync.Once
3614}
3615
3616func newIntegerCloseInterruptIterator(input IntegerIterator, closing <-chan struct{}) *integerCloseInterruptIterator {
3617	itr := &integerCloseInterruptIterator{
3618		input:   input,
3619		closing: closing,
3620		done:    make(chan struct{}),
3621	}
3622	go itr.monitor()
3623	return itr
3624}
3625
3626func (itr *integerCloseInterruptIterator) monitor() {
3627	select {
3628	case <-itr.closing:
3629		itr.Close()
3630	case <-itr.done:
3631	}
3632}
3633
3634func (itr *integerCloseInterruptIterator) Stats() IteratorStats {
3635	return itr.input.Stats()
3636}
3637
3638func (itr *integerCloseInterruptIterator) Close() error {
3639	itr.once.Do(func() {
3640		close(itr.done)
3641		itr.input.Close()
3642	})
3643	return nil
3644}
3645
3646func (itr *integerCloseInterruptIterator) Next() (*IntegerPoint, error) {
3647	p, err := itr.input.Next()
3648	if err != nil {
3649		// Check if the iterator was closed.
3650		select {
3651		case <-itr.done:
3652			return nil, nil
3653		default:
3654			return nil, err
3655		}
3656	}
3657	return p, nil
3658}
3659
3660// integerReduceFloatIterator executes a reducer for every interval and buffers the result.
3661type integerReduceFloatIterator struct {
3662	input    *bufIntegerIterator
3663	create   func() (IntegerPointAggregator, FloatPointEmitter)
3664	dims     []string
3665	opt      IteratorOptions
3666	points   []FloatPoint
3667	keepTags bool
3668}
3669
3670func newIntegerReduceFloatIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, FloatPointEmitter)) *integerReduceFloatIterator {
3671	return &integerReduceFloatIterator{
3672		input:  newBufIntegerIterator(input),
3673		create: createFn,
3674		dims:   opt.GetDimensions(),
3675		opt:    opt,
3676	}
3677}
3678
3679// Stats returns stats from the input iterator.
3680func (itr *integerReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
3681
3682// Close closes the iterator and all child iterators.
3683func (itr *integerReduceFloatIterator) Close() error { return itr.input.Close() }
3684
3685// Next returns the minimum value for the next available interval.
3686func (itr *integerReduceFloatIterator) Next() (*FloatPoint, error) {
3687	// Calculate next window if we have no more points.
3688	if len(itr.points) == 0 {
3689		var err error
3690		itr.points, err = itr.reduce()
3691		if len(itr.points) == 0 {
3692			return nil, err
3693		}
3694	}
3695
3696	// Pop next point off the stack.
3697	p := &itr.points[len(itr.points)-1]
3698	itr.points = itr.points[:len(itr.points)-1]
3699	return p, nil
3700}
3701
3702// integerReduceFloatPoint stores the reduced data for a name/tag combination.
3703type integerReduceFloatPoint struct {
3704	Name       string
3705	Tags       Tags
3706	Aggregator IntegerPointAggregator
3707	Emitter    FloatPointEmitter
3708}
3709
3710// reduce executes fn once for every point in the next window.
3711// The previous value for the dimension is passed to fn.
3712func (itr *integerReduceFloatIterator) reduce() ([]FloatPoint, error) {
3713	// Calculate next window.
3714	var (
3715		startTime, endTime int64
3716		window             struct {
3717			name string
3718			tags string
3719		}
3720	)
3721	for {
3722		p, err := itr.input.Next()
3723		if err != nil || p == nil {
3724			return nil, err
3725		} else if p.Nil {
3726			continue
3727		}
3728
3729		// Unread the point so it can be processed.
3730		itr.input.unread(p)
3731		startTime, endTime = itr.opt.Window(p.Time)
3732		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
3733		break
3734	}
3735
3736	// Create points by tags.
3737	m := make(map[string]*integerReduceFloatPoint)
3738	for {
3739		// Read next point.
3740		curr, err := itr.input.NextInWindow(startTime, endTime)
3741		if err != nil {
3742			return nil, err
3743		} else if curr == nil {
3744			break
3745		} else if curr.Nil {
3746			continue
3747		} else if curr.Name != window.name {
3748			itr.input.unread(curr)
3749			break
3750		}
3751
3752		// Ensure this point is within the same final window.
3753		if curr.Name != window.name {
3754			itr.input.unread(curr)
3755			break
3756		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
3757			itr.input.unread(curr)
3758			break
3759		}
3760
3761		// Retrieve the tags on this point for this level of the query.
3762		// This may be different than the bucket dimensions.
3763		tags := curr.Tags.Subset(itr.dims)
3764		id := tags.ID()
3765
3766		// Retrieve the aggregator for this name/tag combination or create one.
3767		rp := m[id]
3768		if rp == nil {
3769			aggregator, emitter := itr.create()
3770			rp = &integerReduceFloatPoint{
3771				Name:       curr.Name,
3772				Tags:       tags,
3773				Aggregator: aggregator,
3774				Emitter:    emitter,
3775			}
3776			m[id] = rp
3777		}
3778		rp.Aggregator.AggregateInteger(curr)
3779	}
3780
3781	keys := make([]string, 0, len(m))
3782	for k := range m {
3783		keys = append(keys, k)
3784	}
3785
3786	// Reverse sort points by name & tag.
3787	// This ensures a consistent order of output.
3788	if len(keys) > 0 {
3789		var sorted sort.Interface = sort.StringSlice(keys)
3790		if itr.opt.Ascending {
3791			sorted = sort.Reverse(sorted)
3792		}
3793		sort.Sort(sorted)
3794	}
3795
3796	// Assume the points are already sorted until proven otherwise.
3797	sortedByTime := true
3798	// Emit the points for each name & tag combination.
3799	a := make([]FloatPoint, 0, len(m))
3800	for _, k := range keys {
3801		rp := m[k]
3802		points := rp.Emitter.Emit()
3803		for i := len(points) - 1; i >= 0; i-- {
3804			points[i].Name = rp.Name
3805			if !itr.keepTags {
3806				points[i].Tags = rp.Tags
3807			}
3808			// Set the points time to the interval time if the reducer didn't provide one.
3809			if points[i].Time == ZeroTime {
3810				points[i].Time = startTime
3811			} else {
3812				sortedByTime = false
3813			}
3814			a = append(a, points[i])
3815		}
3816	}
3817	// Points may be out of order. Perform a stable sort by time if requested.
3818	if !sortedByTime && itr.opt.Ordered {
3819		var sorted sort.Interface = floatPointsByTime(a)
3820		if itr.opt.Ascending {
3821			sorted = sort.Reverse(sorted)
3822		}
3823		sort.Stable(sorted)
3824	}
3825	return a, nil
3826}
3827
3828// integerStreamFloatIterator streams inputs into the iterator and emits points gradually.
3829type integerStreamFloatIterator struct {
3830	input  *bufIntegerIterator
3831	create func() (IntegerPointAggregator, FloatPointEmitter)
3832	dims   []string
3833	opt    IteratorOptions
3834	m      map[string]*integerReduceFloatPoint
3835	points []FloatPoint
3836}
3837
3838// newIntegerStreamFloatIterator returns a new instance of integerStreamFloatIterator.
3839func newIntegerStreamFloatIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, FloatPointEmitter), opt IteratorOptions) *integerStreamFloatIterator {
3840	return &integerStreamFloatIterator{
3841		input:  newBufIntegerIterator(input),
3842		create: createFn,
3843		dims:   opt.GetDimensions(),
3844		opt:    opt,
3845		m:      make(map[string]*integerReduceFloatPoint),
3846	}
3847}
3848
3849// Stats returns stats from the input iterator.
3850func (itr *integerStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
3851
3852// Close closes the iterator and all child iterators.
3853func (itr *integerStreamFloatIterator) Close() error { return itr.input.Close() }
3854
3855// Next returns the next value for the stream iterator.
3856func (itr *integerStreamFloatIterator) Next() (*FloatPoint, error) {
3857	// Calculate next window if we have no more points.
3858	if len(itr.points) == 0 {
3859		var err error
3860		itr.points, err = itr.reduce()
3861		if len(itr.points) == 0 {
3862			return nil, err
3863		}
3864	}
3865
3866	// Pop next point off the stack.
3867	p := &itr.points[len(itr.points)-1]
3868	itr.points = itr.points[:len(itr.points)-1]
3869	return p, nil
3870}
3871
3872// reduce creates and manages aggregators for every point from the input.
3873// After aggregating a point, it always tries to emit a value using the emitter.
3874func (itr *integerStreamFloatIterator) reduce() ([]FloatPoint, error) {
3875	// We have already read all of the input points.
3876	if itr.m == nil {
3877		return nil, nil
3878	}
3879
3880	for {
3881		// Read next point.
3882		curr, err := itr.input.Next()
3883		if err != nil {
3884			return nil, err
3885		} else if curr == nil {
3886			// Close all of the aggregators to flush any remaining points to emit.
3887			var points []FloatPoint
3888			for _, rp := range itr.m {
3889				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
3890					if err := aggregator.Close(); err != nil {
3891						return nil, err
3892					}
3893
3894					pts := rp.Emitter.Emit()
3895					if len(pts) == 0 {
3896						continue
3897					}
3898
3899					for i := range pts {
3900						pts[i].Name = rp.Name
3901						pts[i].Tags = rp.Tags
3902					}
3903					points = append(points, pts...)
3904				}
3905			}
3906
3907			// Eliminate the aggregators and emitters.
3908			itr.m = nil
3909			return points, nil
3910		} else if curr.Nil {
3911			continue
3912		}
3913		tags := curr.Tags.Subset(itr.dims)
3914
3915		id := curr.Name
3916		if len(tags.m) > 0 {
3917			id += "\x00" + tags.ID()
3918		}
3919
3920		// Retrieve the aggregator for this name/tag combination or create one.
3921		rp := itr.m[id]
3922		if rp == nil {
3923			aggregator, emitter := itr.create()
3924			rp = &integerReduceFloatPoint{
3925				Name:       curr.Name,
3926				Tags:       tags,
3927				Aggregator: aggregator,
3928				Emitter:    emitter,
3929			}
3930			itr.m[id] = rp
3931		}
3932		rp.Aggregator.AggregateInteger(curr)
3933
3934		// Attempt to emit points from the aggregator.
3935		points := rp.Emitter.Emit()
3936		if len(points) == 0 {
3937			continue
3938		}
3939
3940		for i := range points {
3941			points[i].Name = rp.Name
3942			points[i].Tags = rp.Tags
3943		}
3944		return points, nil
3945	}
3946}
3947
3948// integerReduceIntegerIterator executes a reducer for every interval and buffers the result.
3949type integerReduceIntegerIterator struct {
3950	input    *bufIntegerIterator
3951	create   func() (IntegerPointAggregator, IntegerPointEmitter)
3952	dims     []string
3953	opt      IteratorOptions
3954	points   []IntegerPoint
3955	keepTags bool
3956}
3957
3958func newIntegerReduceIntegerIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, IntegerPointEmitter)) *integerReduceIntegerIterator {
3959	return &integerReduceIntegerIterator{
3960		input:  newBufIntegerIterator(input),
3961		create: createFn,
3962		dims:   opt.GetDimensions(),
3963		opt:    opt,
3964	}
3965}
3966
3967// Stats returns stats from the input iterator.
3968func (itr *integerReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
3969
3970// Close closes the iterator and all child iterators.
3971func (itr *integerReduceIntegerIterator) Close() error { return itr.input.Close() }
3972
3973// Next returns the minimum value for the next available interval.
3974func (itr *integerReduceIntegerIterator) Next() (*IntegerPoint, error) {
3975	// Calculate next window if we have no more points.
3976	if len(itr.points) == 0 {
3977		var err error
3978		itr.points, err = itr.reduce()
3979		if len(itr.points) == 0 {
3980			return nil, err
3981		}
3982	}
3983
3984	// Pop next point off the stack.
3985	p := &itr.points[len(itr.points)-1]
3986	itr.points = itr.points[:len(itr.points)-1]
3987	return p, nil
3988}
3989
3990// integerReduceIntegerPoint stores the reduced data for a name/tag combination.
3991type integerReduceIntegerPoint struct {
3992	Name       string
3993	Tags       Tags
3994	Aggregator IntegerPointAggregator
3995	Emitter    IntegerPointEmitter
3996}
3997
3998// reduce executes fn once for every point in the next window.
3999// The previous value for the dimension is passed to fn.
4000func (itr *integerReduceIntegerIterator) reduce() ([]IntegerPoint, error) {
4001	// Calculate next window.
4002	var (
4003		startTime, endTime int64
4004		window             struct {
4005			name string
4006			tags string
4007		}
4008	)
4009	for {
4010		p, err := itr.input.Next()
4011		if err != nil || p == nil {
4012			return nil, err
4013		} else if p.Nil {
4014			continue
4015		}
4016
4017		// Unread the point so it can be processed.
4018		itr.input.unread(p)
4019		startTime, endTime = itr.opt.Window(p.Time)
4020		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
4021		break
4022	}
4023
4024	// Create points by tags.
4025	m := make(map[string]*integerReduceIntegerPoint)
4026	for {
4027		// Read next point.
4028		curr, err := itr.input.NextInWindow(startTime, endTime)
4029		if err != nil {
4030			return nil, err
4031		} else if curr == nil {
4032			break
4033		} else if curr.Nil {
4034			continue
4035		} else if curr.Name != window.name {
4036			itr.input.unread(curr)
4037			break
4038		}
4039
4040		// Ensure this point is within the same final window.
4041		if curr.Name != window.name {
4042			itr.input.unread(curr)
4043			break
4044		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
4045			itr.input.unread(curr)
4046			break
4047		}
4048
4049		// Retrieve the tags on this point for this level of the query.
4050		// This may be different than the bucket dimensions.
4051		tags := curr.Tags.Subset(itr.dims)
4052		id := tags.ID()
4053
4054		// Retrieve the aggregator for this name/tag combination or create one.
4055		rp := m[id]
4056		if rp == nil {
4057			aggregator, emitter := itr.create()
4058			rp = &integerReduceIntegerPoint{
4059				Name:       curr.Name,
4060				Tags:       tags,
4061				Aggregator: aggregator,
4062				Emitter:    emitter,
4063			}
4064			m[id] = rp
4065		}
4066		rp.Aggregator.AggregateInteger(curr)
4067	}
4068
4069	keys := make([]string, 0, len(m))
4070	for k := range m {
4071		keys = append(keys, k)
4072	}
4073
4074	// Reverse sort points by name & tag.
4075	// This ensures a consistent order of output.
4076	if len(keys) > 0 {
4077		var sorted sort.Interface = sort.StringSlice(keys)
4078		if itr.opt.Ascending {
4079			sorted = sort.Reverse(sorted)
4080		}
4081		sort.Sort(sorted)
4082	}
4083
4084	// Assume the points are already sorted until proven otherwise.
4085	sortedByTime := true
4086	// Emit the points for each name & tag combination.
4087	a := make([]IntegerPoint, 0, len(m))
4088	for _, k := range keys {
4089		rp := m[k]
4090		points := rp.Emitter.Emit()
4091		for i := len(points) - 1; i >= 0; i-- {
4092			points[i].Name = rp.Name
4093			if !itr.keepTags {
4094				points[i].Tags = rp.Tags
4095			}
4096			// Set the points time to the interval time if the reducer didn't provide one.
4097			if points[i].Time == ZeroTime {
4098				points[i].Time = startTime
4099			} else {
4100				sortedByTime = false
4101			}
4102			a = append(a, points[i])
4103		}
4104	}
4105	// Points may be out of order. Perform a stable sort by time if requested.
4106	if !sortedByTime && itr.opt.Ordered {
4107		var sorted sort.Interface = integerPointsByTime(a)
4108		if itr.opt.Ascending {
4109			sorted = sort.Reverse(sorted)
4110		}
4111		sort.Stable(sorted)
4112	}
4113	return a, nil
4114}
4115
4116// integerStreamIntegerIterator streams inputs into the iterator and emits points gradually.
4117type integerStreamIntegerIterator struct {
4118	input  *bufIntegerIterator
4119	create func() (IntegerPointAggregator, IntegerPointEmitter)
4120	dims   []string
4121	opt    IteratorOptions
4122	m      map[string]*integerReduceIntegerPoint
4123	points []IntegerPoint
4124}
4125
4126// newIntegerStreamIntegerIterator returns a new instance of integerStreamIntegerIterator.
4127func newIntegerStreamIntegerIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, IntegerPointEmitter), opt IteratorOptions) *integerStreamIntegerIterator {
4128	return &integerStreamIntegerIterator{
4129		input:  newBufIntegerIterator(input),
4130		create: createFn,
4131		dims:   opt.GetDimensions(),
4132		opt:    opt,
4133		m:      make(map[string]*integerReduceIntegerPoint),
4134	}
4135}
4136
4137// Stats returns stats from the input iterator.
4138func (itr *integerStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
4139
4140// Close closes the iterator and all child iterators.
4141func (itr *integerStreamIntegerIterator) Close() error { return itr.input.Close() }
4142
4143// Next returns the next value for the stream iterator.
4144func (itr *integerStreamIntegerIterator) Next() (*IntegerPoint, error) {
4145	// Calculate next window if we have no more points.
4146	if len(itr.points) == 0 {
4147		var err error
4148		itr.points, err = itr.reduce()
4149		if len(itr.points) == 0 {
4150			return nil, err
4151		}
4152	}
4153
4154	// Pop next point off the stack.
4155	p := &itr.points[len(itr.points)-1]
4156	itr.points = itr.points[:len(itr.points)-1]
4157	return p, nil
4158}
4159
4160// reduce creates and manages aggregators for every point from the input.
4161// After aggregating a point, it always tries to emit a value using the emitter.
4162func (itr *integerStreamIntegerIterator) reduce() ([]IntegerPoint, error) {
4163	// We have already read all of the input points.
4164	if itr.m == nil {
4165		return nil, nil
4166	}
4167
4168	for {
4169		// Read next point.
4170		curr, err := itr.input.Next()
4171		if err != nil {
4172			return nil, err
4173		} else if curr == nil {
4174			// Close all of the aggregators to flush any remaining points to emit.
4175			var points []IntegerPoint
4176			for _, rp := range itr.m {
4177				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
4178					if err := aggregator.Close(); err != nil {
4179						return nil, err
4180					}
4181
4182					pts := rp.Emitter.Emit()
4183					if len(pts) == 0 {
4184						continue
4185					}
4186
4187					for i := range pts {
4188						pts[i].Name = rp.Name
4189						pts[i].Tags = rp.Tags
4190					}
4191					points = append(points, pts...)
4192				}
4193			}
4194
4195			// Eliminate the aggregators and emitters.
4196			itr.m = nil
4197			return points, nil
4198		} else if curr.Nil {
4199			continue
4200		}
4201		tags := curr.Tags.Subset(itr.dims)
4202
4203		id := curr.Name
4204		if len(tags.m) > 0 {
4205			id += "\x00" + tags.ID()
4206		}
4207
4208		// Retrieve the aggregator for this name/tag combination or create one.
4209		rp := itr.m[id]
4210		if rp == nil {
4211			aggregator, emitter := itr.create()
4212			rp = &integerReduceIntegerPoint{
4213				Name:       curr.Name,
4214				Tags:       tags,
4215				Aggregator: aggregator,
4216				Emitter:    emitter,
4217			}
4218			itr.m[id] = rp
4219		}
4220		rp.Aggregator.AggregateInteger(curr)
4221
4222		// Attempt to emit points from the aggregator.
4223		points := rp.Emitter.Emit()
4224		if len(points) == 0 {
4225			continue
4226		}
4227
4228		for i := range points {
4229			points[i].Name = rp.Name
4230			points[i].Tags = rp.Tags
4231		}
4232		return points, nil
4233	}
4234}
4235
4236// integerReduceUnsignedIterator executes a reducer for every interval and buffers the result.
4237type integerReduceUnsignedIterator struct {
4238	input    *bufIntegerIterator
4239	create   func() (IntegerPointAggregator, UnsignedPointEmitter)
4240	dims     []string
4241	opt      IteratorOptions
4242	points   []UnsignedPoint
4243	keepTags bool
4244}
4245
4246func newIntegerReduceUnsignedIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, UnsignedPointEmitter)) *integerReduceUnsignedIterator {
4247	return &integerReduceUnsignedIterator{
4248		input:  newBufIntegerIterator(input),
4249		create: createFn,
4250		dims:   opt.GetDimensions(),
4251		opt:    opt,
4252	}
4253}
4254
4255// Stats returns stats from the input iterator.
4256func (itr *integerReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
4257
4258// Close closes the iterator and all child iterators.
4259func (itr *integerReduceUnsignedIterator) Close() error { return itr.input.Close() }
4260
4261// Next returns the minimum value for the next available interval.
4262func (itr *integerReduceUnsignedIterator) Next() (*UnsignedPoint, error) {
4263	// Calculate next window if we have no more points.
4264	if len(itr.points) == 0 {
4265		var err error
4266		itr.points, err = itr.reduce()
4267		if len(itr.points) == 0 {
4268			return nil, err
4269		}
4270	}
4271
4272	// Pop next point off the stack.
4273	p := &itr.points[len(itr.points)-1]
4274	itr.points = itr.points[:len(itr.points)-1]
4275	return p, nil
4276}
4277
4278// integerReduceUnsignedPoint stores the reduced data for a name/tag combination.
4279type integerReduceUnsignedPoint struct {
4280	Name       string
4281	Tags       Tags
4282	Aggregator IntegerPointAggregator
4283	Emitter    UnsignedPointEmitter
4284}
4285
4286// reduce executes fn once for every point in the next window.
4287// The previous value for the dimension is passed to fn.
4288func (itr *integerReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) {
4289	// Calculate next window.
4290	var (
4291		startTime, endTime int64
4292		window             struct {
4293			name string
4294			tags string
4295		}
4296	)
4297	for {
4298		p, err := itr.input.Next()
4299		if err != nil || p == nil {
4300			return nil, err
4301		} else if p.Nil {
4302			continue
4303		}
4304
4305		// Unread the point so it can be processed.
4306		itr.input.unread(p)
4307		startTime, endTime = itr.opt.Window(p.Time)
4308		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
4309		break
4310	}
4311
4312	// Create points by tags.
4313	m := make(map[string]*integerReduceUnsignedPoint)
4314	for {
4315		// Read next point.
4316		curr, err := itr.input.NextInWindow(startTime, endTime)
4317		if err != nil {
4318			return nil, err
4319		} else if curr == nil {
4320			break
4321		} else if curr.Nil {
4322			continue
4323		} else if curr.Name != window.name {
4324			itr.input.unread(curr)
4325			break
4326		}
4327
4328		// Ensure this point is within the same final window.
4329		if curr.Name != window.name {
4330			itr.input.unread(curr)
4331			break
4332		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
4333			itr.input.unread(curr)
4334			break
4335		}
4336
4337		// Retrieve the tags on this point for this level of the query.
4338		// This may be different than the bucket dimensions.
4339		tags := curr.Tags.Subset(itr.dims)
4340		id := tags.ID()
4341
4342		// Retrieve the aggregator for this name/tag combination or create one.
4343		rp := m[id]
4344		if rp == nil {
4345			aggregator, emitter := itr.create()
4346			rp = &integerReduceUnsignedPoint{
4347				Name:       curr.Name,
4348				Tags:       tags,
4349				Aggregator: aggregator,
4350				Emitter:    emitter,
4351			}
4352			m[id] = rp
4353		}
4354		rp.Aggregator.AggregateInteger(curr)
4355	}
4356
4357	keys := make([]string, 0, len(m))
4358	for k := range m {
4359		keys = append(keys, k)
4360	}
4361
4362	// Reverse sort points by name & tag.
4363	// This ensures a consistent order of output.
4364	if len(keys) > 0 {
4365		var sorted sort.Interface = sort.StringSlice(keys)
4366		if itr.opt.Ascending {
4367			sorted = sort.Reverse(sorted)
4368		}
4369		sort.Sort(sorted)
4370	}
4371
4372	// Assume the points are already sorted until proven otherwise.
4373	sortedByTime := true
4374	// Emit the points for each name & tag combination.
4375	a := make([]UnsignedPoint, 0, len(m))
4376	for _, k := range keys {
4377		rp := m[k]
4378		points := rp.Emitter.Emit()
4379		for i := len(points) - 1; i >= 0; i-- {
4380			points[i].Name = rp.Name
4381			if !itr.keepTags {
4382				points[i].Tags = rp.Tags
4383			}
4384			// Set the points time to the interval time if the reducer didn't provide one.
4385			if points[i].Time == ZeroTime {
4386				points[i].Time = startTime
4387			} else {
4388				sortedByTime = false
4389			}
4390			a = append(a, points[i])
4391		}
4392	}
4393	// Points may be out of order. Perform a stable sort by time if requested.
4394	if !sortedByTime && itr.opt.Ordered {
4395		var sorted sort.Interface = unsignedPointsByTime(a)
4396		if itr.opt.Ascending {
4397			sorted = sort.Reverse(sorted)
4398		}
4399		sort.Stable(sorted)
4400	}
4401	return a, nil
4402}
4403
4404// integerStreamUnsignedIterator streams inputs into the iterator and emits points gradually.
4405type integerStreamUnsignedIterator struct {
4406	input  *bufIntegerIterator
4407	create func() (IntegerPointAggregator, UnsignedPointEmitter)
4408	dims   []string
4409	opt    IteratorOptions
4410	m      map[string]*integerReduceUnsignedPoint
4411	points []UnsignedPoint
4412}
4413
4414// newIntegerStreamUnsignedIterator returns a new instance of integerStreamUnsignedIterator.
4415func newIntegerStreamUnsignedIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *integerStreamUnsignedIterator {
4416	return &integerStreamUnsignedIterator{
4417		input:  newBufIntegerIterator(input),
4418		create: createFn,
4419		dims:   opt.GetDimensions(),
4420		opt:    opt,
4421		m:      make(map[string]*integerReduceUnsignedPoint),
4422	}
4423}
4424
4425// Stats returns stats from the input iterator.
4426func (itr *integerStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
4427
4428// Close closes the iterator and all child iterators.
4429func (itr *integerStreamUnsignedIterator) Close() error { return itr.input.Close() }
4430
4431// Next returns the next value for the stream iterator.
4432func (itr *integerStreamUnsignedIterator) Next() (*UnsignedPoint, error) {
4433	// Calculate next window if we have no more points.
4434	if len(itr.points) == 0 {
4435		var err error
4436		itr.points, err = itr.reduce()
4437		if len(itr.points) == 0 {
4438			return nil, err
4439		}
4440	}
4441
4442	// Pop next point off the stack.
4443	p := &itr.points[len(itr.points)-1]
4444	itr.points = itr.points[:len(itr.points)-1]
4445	return p, nil
4446}
4447
4448// reduce creates and manages aggregators for every point from the input.
4449// After aggregating a point, it always tries to emit a value using the emitter.
4450func (itr *integerStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) {
4451	// We have already read all of the input points.
4452	if itr.m == nil {
4453		return nil, nil
4454	}
4455
4456	for {
4457		// Read next point.
4458		curr, err := itr.input.Next()
4459		if err != nil {
4460			return nil, err
4461		} else if curr == nil {
4462			// Close all of the aggregators to flush any remaining points to emit.
4463			var points []UnsignedPoint
4464			for _, rp := range itr.m {
4465				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
4466					if err := aggregator.Close(); err != nil {
4467						return nil, err
4468					}
4469
4470					pts := rp.Emitter.Emit()
4471					if len(pts) == 0 {
4472						continue
4473					}
4474
4475					for i := range pts {
4476						pts[i].Name = rp.Name
4477						pts[i].Tags = rp.Tags
4478					}
4479					points = append(points, pts...)
4480				}
4481			}
4482
4483			// Eliminate the aggregators and emitters.
4484			itr.m = nil
4485			return points, nil
4486		} else if curr.Nil {
4487			continue
4488		}
4489		tags := curr.Tags.Subset(itr.dims)
4490
4491		id := curr.Name
4492		if len(tags.m) > 0 {
4493			id += "\x00" + tags.ID()
4494		}
4495
4496		// Retrieve the aggregator for this name/tag combination or create one.
4497		rp := itr.m[id]
4498		if rp == nil {
4499			aggregator, emitter := itr.create()
4500			rp = &integerReduceUnsignedPoint{
4501				Name:       curr.Name,
4502				Tags:       tags,
4503				Aggregator: aggregator,
4504				Emitter:    emitter,
4505			}
4506			itr.m[id] = rp
4507		}
4508		rp.Aggregator.AggregateInteger(curr)
4509
4510		// Attempt to emit points from the aggregator.
4511		points := rp.Emitter.Emit()
4512		if len(points) == 0 {
4513			continue
4514		}
4515
4516		for i := range points {
4517			points[i].Name = rp.Name
4518			points[i].Tags = rp.Tags
4519		}
4520		return points, nil
4521	}
4522}
4523
4524// integerReduceStringIterator executes a reducer for every interval and buffers the result.
4525type integerReduceStringIterator struct {
4526	input    *bufIntegerIterator
4527	create   func() (IntegerPointAggregator, StringPointEmitter)
4528	dims     []string
4529	opt      IteratorOptions
4530	points   []StringPoint
4531	keepTags bool
4532}
4533
4534func newIntegerReduceStringIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, StringPointEmitter)) *integerReduceStringIterator {
4535	return &integerReduceStringIterator{
4536		input:  newBufIntegerIterator(input),
4537		create: createFn,
4538		dims:   opt.GetDimensions(),
4539		opt:    opt,
4540	}
4541}
4542
4543// Stats returns stats from the input iterator.
4544func (itr *integerReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() }
4545
4546// Close closes the iterator and all child iterators.
4547func (itr *integerReduceStringIterator) Close() error { return itr.input.Close() }
4548
4549// Next returns the minimum value for the next available interval.
4550func (itr *integerReduceStringIterator) Next() (*StringPoint, error) {
4551	// Calculate next window if we have no more points.
4552	if len(itr.points) == 0 {
4553		var err error
4554		itr.points, err = itr.reduce()
4555		if len(itr.points) == 0 {
4556			return nil, err
4557		}
4558	}
4559
4560	// Pop next point off the stack.
4561	p := &itr.points[len(itr.points)-1]
4562	itr.points = itr.points[:len(itr.points)-1]
4563	return p, nil
4564}
4565
4566// integerReduceStringPoint stores the reduced data for a name/tag combination.
4567type integerReduceStringPoint struct {
4568	Name       string
4569	Tags       Tags
4570	Aggregator IntegerPointAggregator
4571	Emitter    StringPointEmitter
4572}
4573
4574// reduce executes fn once for every point in the next window.
4575// The previous value for the dimension is passed to fn.
4576func (itr *integerReduceStringIterator) reduce() ([]StringPoint, error) {
4577	// Calculate next window.
4578	var (
4579		startTime, endTime int64
4580		window             struct {
4581			name string
4582			tags string
4583		}
4584	)
4585	for {
4586		p, err := itr.input.Next()
4587		if err != nil || p == nil {
4588			return nil, err
4589		} else if p.Nil {
4590			continue
4591		}
4592
4593		// Unread the point so it can be processed.
4594		itr.input.unread(p)
4595		startTime, endTime = itr.opt.Window(p.Time)
4596		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
4597		break
4598	}
4599
4600	// Create points by tags.
4601	m := make(map[string]*integerReduceStringPoint)
4602	for {
4603		// Read next point.
4604		curr, err := itr.input.NextInWindow(startTime, endTime)
4605		if err != nil {
4606			return nil, err
4607		} else if curr == nil {
4608			break
4609		} else if curr.Nil {
4610			continue
4611		} else if curr.Name != window.name {
4612			itr.input.unread(curr)
4613			break
4614		}
4615
4616		// Ensure this point is within the same final window.
4617		if curr.Name != window.name {
4618			itr.input.unread(curr)
4619			break
4620		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
4621			itr.input.unread(curr)
4622			break
4623		}
4624
4625		// Retrieve the tags on this point for this level of the query.
4626		// This may be different than the bucket dimensions.
4627		tags := curr.Tags.Subset(itr.dims)
4628		id := tags.ID()
4629
4630		// Retrieve the aggregator for this name/tag combination or create one.
4631		rp := m[id]
4632		if rp == nil {
4633			aggregator, emitter := itr.create()
4634			rp = &integerReduceStringPoint{
4635				Name:       curr.Name,
4636				Tags:       tags,
4637				Aggregator: aggregator,
4638				Emitter:    emitter,
4639			}
4640			m[id] = rp
4641		}
4642		rp.Aggregator.AggregateInteger(curr)
4643	}
4644
4645	keys := make([]string, 0, len(m))
4646	for k := range m {
4647		keys = append(keys, k)
4648	}
4649
4650	// Reverse sort points by name & tag.
4651	// This ensures a consistent order of output.
4652	if len(keys) > 0 {
4653		var sorted sort.Interface = sort.StringSlice(keys)
4654		if itr.opt.Ascending {
4655			sorted = sort.Reverse(sorted)
4656		}
4657		sort.Sort(sorted)
4658	}
4659
4660	// Assume the points are already sorted until proven otherwise.
4661	sortedByTime := true
4662	// Emit the points for each name & tag combination.
4663	a := make([]StringPoint, 0, len(m))
4664	for _, k := range keys {
4665		rp := m[k]
4666		points := rp.Emitter.Emit()
4667		for i := len(points) - 1; i >= 0; i-- {
4668			points[i].Name = rp.Name
4669			if !itr.keepTags {
4670				points[i].Tags = rp.Tags
4671			}
4672			// Set the points time to the interval time if the reducer didn't provide one.
4673			if points[i].Time == ZeroTime {
4674				points[i].Time = startTime
4675			} else {
4676				sortedByTime = false
4677			}
4678			a = append(a, points[i])
4679		}
4680	}
4681	// Points may be out of order. Perform a stable sort by time if requested.
4682	if !sortedByTime && itr.opt.Ordered {
4683		var sorted sort.Interface = stringPointsByTime(a)
4684		if itr.opt.Ascending {
4685			sorted = sort.Reverse(sorted)
4686		}
4687		sort.Stable(sorted)
4688	}
4689	return a, nil
4690}
4691
4692// integerStreamStringIterator streams inputs into the iterator and emits points gradually.
4693type integerStreamStringIterator struct {
4694	input  *bufIntegerIterator
4695	create func() (IntegerPointAggregator, StringPointEmitter)
4696	dims   []string
4697	opt    IteratorOptions
4698	m      map[string]*integerReduceStringPoint
4699	points []StringPoint
4700}
4701
4702// newIntegerStreamStringIterator returns a new instance of integerStreamStringIterator.
4703func newIntegerStreamStringIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, StringPointEmitter), opt IteratorOptions) *integerStreamStringIterator {
4704	return &integerStreamStringIterator{
4705		input:  newBufIntegerIterator(input),
4706		create: createFn,
4707		dims:   opt.GetDimensions(),
4708		opt:    opt,
4709		m:      make(map[string]*integerReduceStringPoint),
4710	}
4711}
4712
4713// Stats returns stats from the input iterator.
4714func (itr *integerStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() }
4715
4716// Close closes the iterator and all child iterators.
4717func (itr *integerStreamStringIterator) Close() error { return itr.input.Close() }
4718
4719// Next returns the next value for the stream iterator.
4720func (itr *integerStreamStringIterator) Next() (*StringPoint, error) {
4721	// Calculate next window if we have no more points.
4722	if len(itr.points) == 0 {
4723		var err error
4724		itr.points, err = itr.reduce()
4725		if len(itr.points) == 0 {
4726			return nil, err
4727		}
4728	}
4729
4730	// Pop next point off the stack.
4731	p := &itr.points[len(itr.points)-1]
4732	itr.points = itr.points[:len(itr.points)-1]
4733	return p, nil
4734}
4735
4736// reduce creates and manages aggregators for every point from the input.
4737// After aggregating a point, it always tries to emit a value using the emitter.
4738func (itr *integerStreamStringIterator) reduce() ([]StringPoint, error) {
4739	// We have already read all of the input points.
4740	if itr.m == nil {
4741		return nil, nil
4742	}
4743
4744	for {
4745		// Read next point.
4746		curr, err := itr.input.Next()
4747		if err != nil {
4748			return nil, err
4749		} else if curr == nil {
4750			// Close all of the aggregators to flush any remaining points to emit.
4751			var points []StringPoint
4752			for _, rp := range itr.m {
4753				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
4754					if err := aggregator.Close(); err != nil {
4755						return nil, err
4756					}
4757
4758					pts := rp.Emitter.Emit()
4759					if len(pts) == 0 {
4760						continue
4761					}
4762
4763					for i := range pts {
4764						pts[i].Name = rp.Name
4765						pts[i].Tags = rp.Tags
4766					}
4767					points = append(points, pts...)
4768				}
4769			}
4770
4771			// Eliminate the aggregators and emitters.
4772			itr.m = nil
4773			return points, nil
4774		} else if curr.Nil {
4775			continue
4776		}
4777		tags := curr.Tags.Subset(itr.dims)
4778
4779		id := curr.Name
4780		if len(tags.m) > 0 {
4781			id += "\x00" + tags.ID()
4782		}
4783
4784		// Retrieve the aggregator for this name/tag combination or create one.
4785		rp := itr.m[id]
4786		if rp == nil {
4787			aggregator, emitter := itr.create()
4788			rp = &integerReduceStringPoint{
4789				Name:       curr.Name,
4790				Tags:       tags,
4791				Aggregator: aggregator,
4792				Emitter:    emitter,
4793			}
4794			itr.m[id] = rp
4795		}
4796		rp.Aggregator.AggregateInteger(curr)
4797
4798		// Attempt to emit points from the aggregator.
4799		points := rp.Emitter.Emit()
4800		if len(points) == 0 {
4801			continue
4802		}
4803
4804		for i := range points {
4805			points[i].Name = rp.Name
4806			points[i].Tags = rp.Tags
4807		}
4808		return points, nil
4809	}
4810}
4811
4812// integerReduceBooleanIterator executes a reducer for every interval and buffers the result.
4813type integerReduceBooleanIterator struct {
4814	input    *bufIntegerIterator
4815	create   func() (IntegerPointAggregator, BooleanPointEmitter)
4816	dims     []string
4817	opt      IteratorOptions
4818	points   []BooleanPoint
4819	keepTags bool
4820}
4821
4822func newIntegerReduceBooleanIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, BooleanPointEmitter)) *integerReduceBooleanIterator {
4823	return &integerReduceBooleanIterator{
4824		input:  newBufIntegerIterator(input),
4825		create: createFn,
4826		dims:   opt.GetDimensions(),
4827		opt:    opt,
4828	}
4829}
4830
4831// Stats returns stats from the input iterator.
4832func (itr *integerReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
4833
4834// Close closes the iterator and all child iterators.
4835func (itr *integerReduceBooleanIterator) Close() error { return itr.input.Close() }
4836
4837// Next returns the minimum value for the next available interval.
4838func (itr *integerReduceBooleanIterator) Next() (*BooleanPoint, error) {
4839	// Calculate next window if we have no more points.
4840	if len(itr.points) == 0 {
4841		var err error
4842		itr.points, err = itr.reduce()
4843		if len(itr.points) == 0 {
4844			return nil, err
4845		}
4846	}
4847
4848	// Pop next point off the stack.
4849	p := &itr.points[len(itr.points)-1]
4850	itr.points = itr.points[:len(itr.points)-1]
4851	return p, nil
4852}
4853
4854// integerReduceBooleanPoint stores the reduced data for a name/tag combination.
4855type integerReduceBooleanPoint struct {
4856	Name       string
4857	Tags       Tags
4858	Aggregator IntegerPointAggregator
4859	Emitter    BooleanPointEmitter
4860}
4861
4862// reduce executes fn once for every point in the next window.
4863// The previous value for the dimension is passed to fn.
4864func (itr *integerReduceBooleanIterator) reduce() ([]BooleanPoint, error) {
4865	// Calculate next window.
4866	var (
4867		startTime, endTime int64
4868		window             struct {
4869			name string
4870			tags string
4871		}
4872	)
4873	for {
4874		p, err := itr.input.Next()
4875		if err != nil || p == nil {
4876			return nil, err
4877		} else if p.Nil {
4878			continue
4879		}
4880
4881		// Unread the point so it can be processed.
4882		itr.input.unread(p)
4883		startTime, endTime = itr.opt.Window(p.Time)
4884		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
4885		break
4886	}
4887
4888	// Create points by tags.
4889	m := make(map[string]*integerReduceBooleanPoint)
4890	for {
4891		// Read next point.
4892		curr, err := itr.input.NextInWindow(startTime, endTime)
4893		if err != nil {
4894			return nil, err
4895		} else if curr == nil {
4896			break
4897		} else if curr.Nil {
4898			continue
4899		} else if curr.Name != window.name {
4900			itr.input.unread(curr)
4901			break
4902		}
4903
4904		// Ensure this point is within the same final window.
4905		if curr.Name != window.name {
4906			itr.input.unread(curr)
4907			break
4908		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
4909			itr.input.unread(curr)
4910			break
4911		}
4912
4913		// Retrieve the tags on this point for this level of the query.
4914		// This may be different than the bucket dimensions.
4915		tags := curr.Tags.Subset(itr.dims)
4916		id := tags.ID()
4917
4918		// Retrieve the aggregator for this name/tag combination or create one.
4919		rp := m[id]
4920		if rp == nil {
4921			aggregator, emitter := itr.create()
4922			rp = &integerReduceBooleanPoint{
4923				Name:       curr.Name,
4924				Tags:       tags,
4925				Aggregator: aggregator,
4926				Emitter:    emitter,
4927			}
4928			m[id] = rp
4929		}
4930		rp.Aggregator.AggregateInteger(curr)
4931	}
4932
4933	keys := make([]string, 0, len(m))
4934	for k := range m {
4935		keys = append(keys, k)
4936	}
4937
4938	// Reverse sort points by name & tag.
4939	// This ensures a consistent order of output.
4940	if len(keys) > 0 {
4941		var sorted sort.Interface = sort.StringSlice(keys)
4942		if itr.opt.Ascending {
4943			sorted = sort.Reverse(sorted)
4944		}
4945		sort.Sort(sorted)
4946	}
4947
4948	// Assume the points are already sorted until proven otherwise.
4949	sortedByTime := true
4950	// Emit the points for each name & tag combination.
4951	a := make([]BooleanPoint, 0, len(m))
4952	for _, k := range keys {
4953		rp := m[k]
4954		points := rp.Emitter.Emit()
4955		for i := len(points) - 1; i >= 0; i-- {
4956			points[i].Name = rp.Name
4957			if !itr.keepTags {
4958				points[i].Tags = rp.Tags
4959			}
4960			// Set the points time to the interval time if the reducer didn't provide one.
4961			if points[i].Time == ZeroTime {
4962				points[i].Time = startTime
4963			} else {
4964				sortedByTime = false
4965			}
4966			a = append(a, points[i])
4967		}
4968	}
4969	// Points may be out of order. Perform a stable sort by time if requested.
4970	if !sortedByTime && itr.opt.Ordered {
4971		var sorted sort.Interface = booleanPointsByTime(a)
4972		if itr.opt.Ascending {
4973			sorted = sort.Reverse(sorted)
4974		}
4975		sort.Stable(sorted)
4976	}
4977	return a, nil
4978}
4979
4980// integerStreamBooleanIterator streams inputs into the iterator and emits points gradually.
4981type integerStreamBooleanIterator struct {
4982	input  *bufIntegerIterator
4983	create func() (IntegerPointAggregator, BooleanPointEmitter)
4984	dims   []string
4985	opt    IteratorOptions
4986	m      map[string]*integerReduceBooleanPoint
4987	points []BooleanPoint
4988}
4989
4990// newIntegerStreamBooleanIterator returns a new instance of integerStreamBooleanIterator.
4991func newIntegerStreamBooleanIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, BooleanPointEmitter), opt IteratorOptions) *integerStreamBooleanIterator {
4992	return &integerStreamBooleanIterator{
4993		input:  newBufIntegerIterator(input),
4994		create: createFn,
4995		dims:   opt.GetDimensions(),
4996		opt:    opt,
4997		m:      make(map[string]*integerReduceBooleanPoint),
4998	}
4999}
5000
5001// Stats returns stats from the input iterator.
5002func (itr *integerStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
5003
5004// Close closes the iterator and all child iterators.
5005func (itr *integerStreamBooleanIterator) Close() error { return itr.input.Close() }
5006
5007// Next returns the next value for the stream iterator.
5008func (itr *integerStreamBooleanIterator) Next() (*BooleanPoint, error) {
5009	// Calculate next window if we have no more points.
5010	if len(itr.points) == 0 {
5011		var err error
5012		itr.points, err = itr.reduce()
5013		if len(itr.points) == 0 {
5014			return nil, err
5015		}
5016	}
5017
5018	// Pop next point off the stack.
5019	p := &itr.points[len(itr.points)-1]
5020	itr.points = itr.points[:len(itr.points)-1]
5021	return p, nil
5022}
5023
5024// reduce creates and manages aggregators for every point from the input.
5025// After aggregating a point, it always tries to emit a value using the emitter.
5026func (itr *integerStreamBooleanIterator) reduce() ([]BooleanPoint, error) {
5027	// We have already read all of the input points.
5028	if itr.m == nil {
5029		return nil, nil
5030	}
5031
5032	for {
5033		// Read next point.
5034		curr, err := itr.input.Next()
5035		if err != nil {
5036			return nil, err
5037		} else if curr == nil {
5038			// Close all of the aggregators to flush any remaining points to emit.
5039			var points []BooleanPoint
5040			for _, rp := range itr.m {
5041				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
5042					if err := aggregator.Close(); err != nil {
5043						return nil, err
5044					}
5045
5046					pts := rp.Emitter.Emit()
5047					if len(pts) == 0 {
5048						continue
5049					}
5050
5051					for i := range pts {
5052						pts[i].Name = rp.Name
5053						pts[i].Tags = rp.Tags
5054					}
5055					points = append(points, pts...)
5056				}
5057			}
5058
5059			// Eliminate the aggregators and emitters.
5060			itr.m = nil
5061			return points, nil
5062		} else if curr.Nil {
5063			continue
5064		}
5065		tags := curr.Tags.Subset(itr.dims)
5066
5067		id := curr.Name
5068		if len(tags.m) > 0 {
5069			id += "\x00" + tags.ID()
5070		}
5071
5072		// Retrieve the aggregator for this name/tag combination or create one.
5073		rp := itr.m[id]
5074		if rp == nil {
5075			aggregator, emitter := itr.create()
5076			rp = &integerReduceBooleanPoint{
5077				Name:       curr.Name,
5078				Tags:       tags,
5079				Aggregator: aggregator,
5080				Emitter:    emitter,
5081			}
5082			itr.m[id] = rp
5083		}
5084		rp.Aggregator.AggregateInteger(curr)
5085
5086		// Attempt to emit points from the aggregator.
5087		points := rp.Emitter.Emit()
5088		if len(points) == 0 {
5089			continue
5090		}
5091
5092		for i := range points {
5093			points[i].Name = rp.Name
5094			points[i].Tags = rp.Tags
5095		}
5096		return points, nil
5097	}
5098}
5099
5100// integerDedupeIterator only outputs unique points.
5101// This differs from the DistinctIterator in that it compares all aux fields too.
5102// This iterator is relatively inefficient and should only be used on small
5103// datasets such as meta query results.
5104type integerDedupeIterator struct {
5105	input IntegerIterator
5106	m     map[string]struct{} // lookup of points already sent
5107}
5108
5109type integerIteratorMapper struct {
5110	cur    Cursor
5111	row    Row
5112	driver IteratorMap   // which iterator to use for the primary value, can be nil
5113	fields []IteratorMap // which iterator to use for an aux field
5114	point  IntegerPoint
5115}
5116
5117func newIntegerIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *integerIteratorMapper {
5118	return &integerIteratorMapper{
5119		cur:    cur,
5120		driver: driver,
5121		fields: fields,
5122		point: IntegerPoint{
5123			Aux: make([]interface{}, len(fields)),
5124		},
5125	}
5126}
5127
5128func (itr *integerIteratorMapper) Next() (*IntegerPoint, error) {
5129	if !itr.cur.Scan(&itr.row) {
5130		if err := itr.cur.Err(); err != nil {
5131			return nil, err
5132		}
5133		return nil, nil
5134	}
5135
5136	itr.point.Time = itr.row.Time
5137	itr.point.Name = itr.row.Series.Name
5138	itr.point.Tags = itr.row.Series.Tags
5139
5140	if itr.driver != nil {
5141		if v := itr.driver.Value(&itr.row); v != nil {
5142			if v, ok := castToInteger(v); ok {
5143				itr.point.Value = v
5144				itr.point.Nil = false
5145			} else {
5146				itr.point.Value = 0
5147				itr.point.Nil = true
5148			}
5149		} else {
5150			itr.point.Value = 0
5151			itr.point.Nil = true
5152		}
5153	}
5154	for i, f := range itr.fields {
5155		itr.point.Aux[i] = f.Value(&itr.row)
5156	}
5157	return &itr.point, nil
5158}
5159
5160func (itr *integerIteratorMapper) Stats() IteratorStats {
5161	return itr.cur.Stats()
5162}
5163
5164func (itr *integerIteratorMapper) Close() error {
5165	return itr.cur.Close()
5166}
5167
5168type integerFilterIterator struct {
5169	input IntegerIterator
5170	cond  influxql.Expr
5171	opt   IteratorOptions
5172	m     map[string]interface{}
5173}
5174
5175func newIntegerFilterIterator(input IntegerIterator, cond influxql.Expr, opt IteratorOptions) IntegerIterator {
5176	// Strip out time conditions from the WHERE clause.
5177	// TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct.
5178	n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node {
5179		switch n := n.(type) {
5180		case *influxql.BinaryExpr:
5181			if n.LHS.String() == "time" {
5182				return &influxql.BooleanLiteral{Val: true}
5183			}
5184		}
5185		return n
5186	})
5187
5188	cond, _ = n.(influxql.Expr)
5189	if cond == nil {
5190		return input
5191	} else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val {
5192		return input
5193	}
5194
5195	return &integerFilterIterator{
5196		input: input,
5197		cond:  cond,
5198		opt:   opt,
5199		m:     make(map[string]interface{}),
5200	}
5201}
5202
5203func (itr *integerFilterIterator) Stats() IteratorStats { return itr.input.Stats() }
5204func (itr *integerFilterIterator) Close() error         { return itr.input.Close() }
5205
5206func (itr *integerFilterIterator) Next() (*IntegerPoint, error) {
5207	for {
5208		p, err := itr.input.Next()
5209		if err != nil || p == nil {
5210			return nil, err
5211		}
5212
5213		for i, ref := range itr.opt.Aux {
5214			itr.m[ref.Val] = p.Aux[i]
5215		}
5216		for k, v := range p.Tags.KeyValues() {
5217			itr.m[k] = v
5218		}
5219
5220		if !influxql.EvalBool(itr.cond, itr.m) {
5221			continue
5222		}
5223		return p, nil
5224	}
5225}
5226
5227type integerTagSubsetIterator struct {
5228	input      IntegerIterator
5229	point      IntegerPoint
5230	lastTags   Tags
5231	dimensions []string
5232}
5233
5234func newIntegerTagSubsetIterator(input IntegerIterator, opt IteratorOptions) *integerTagSubsetIterator {
5235	return &integerTagSubsetIterator{
5236		input:      input,
5237		dimensions: opt.GetDimensions(),
5238	}
5239}
5240
5241func (itr *integerTagSubsetIterator) Next() (*IntegerPoint, error) {
5242	p, err := itr.input.Next()
5243	if err != nil {
5244		return nil, err
5245	} else if p == nil {
5246		return nil, nil
5247	}
5248
5249	itr.point.Name = p.Name
5250	if !p.Tags.Equal(itr.lastTags) {
5251		itr.point.Tags = p.Tags.Subset(itr.dimensions)
5252		itr.lastTags = p.Tags
5253	}
5254	itr.point.Time = p.Time
5255	itr.point.Value = p.Value
5256	itr.point.Aux = p.Aux
5257	itr.point.Aggregated = p.Aggregated
5258	itr.point.Nil = p.Nil
5259	return &itr.point, nil
5260}
5261
5262func (itr *integerTagSubsetIterator) Stats() IteratorStats {
5263	return itr.input.Stats()
5264}
5265
5266func (itr *integerTagSubsetIterator) Close() error {
5267	return itr.input.Close()
5268}
5269
5270// newIntegerDedupeIterator returns a new instance of integerDedupeIterator.
5271func newIntegerDedupeIterator(input IntegerIterator) *integerDedupeIterator {
5272	return &integerDedupeIterator{
5273		input: input,
5274		m:     make(map[string]struct{}),
5275	}
5276}
5277
5278// Stats returns stats from the input iterator.
5279func (itr *integerDedupeIterator) Stats() IteratorStats { return itr.input.Stats() }
5280
5281// Close closes the iterator and all child iterators.
5282func (itr *integerDedupeIterator) Close() error { return itr.input.Close() }
5283
5284// Next returns the next unique point from the input iterator.
5285func (itr *integerDedupeIterator) Next() (*IntegerPoint, error) {
5286	for {
5287		// Read next point.
5288		p, err := itr.input.Next()
5289		if p == nil || err != nil {
5290			return nil, err
5291		}
5292
5293		// Serialize to bytes to store in lookup.
5294		buf, err := proto.Marshal(encodeIntegerPoint(p))
5295		if err != nil {
5296			return nil, err
5297		}
5298
5299		// If the point has already been output then move to the next point.
5300		if _, ok := itr.m[string(buf)]; ok {
5301			continue
5302		}
5303
5304		// Otherwise mark it as emitted and return point.
5305		itr.m[string(buf)] = struct{}{}
5306		return p, nil
5307	}
5308}
5309
5310// integerReaderIterator represents an iterator that streams from a reader.
5311type integerReaderIterator struct {
5312	r   io.Reader
5313	dec *IntegerPointDecoder
5314}
5315
5316// newIntegerReaderIterator returns a new instance of integerReaderIterator.
5317func newIntegerReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *integerReaderIterator {
5318	dec := NewIntegerPointDecoder(ctx, r)
5319	dec.stats = stats
5320
5321	return &integerReaderIterator{
5322		r:   r,
5323		dec: dec,
5324	}
5325}
5326
5327// Stats returns stats about points processed.
5328func (itr *integerReaderIterator) Stats() IteratorStats { return itr.dec.stats }
5329
5330// Close closes the underlying reader, if applicable.
5331func (itr *integerReaderIterator) Close() error {
5332	if r, ok := itr.r.(io.ReadCloser); ok {
5333		return r.Close()
5334	}
5335	return nil
5336}
5337
5338// Next returns the next point from the iterator.
5339func (itr *integerReaderIterator) Next() (*IntegerPoint, error) {
5340	// OPTIMIZE(benbjohnson): Reuse point on iterator.
5341
5342	// Unmarshal next point.
5343	p := &IntegerPoint{}
5344	if err := itr.dec.DecodeIntegerPoint(p); err == io.EOF {
5345		return nil, nil
5346	} else if err != nil {
5347		return nil, err
5348	}
5349	return p, nil
5350}
5351
5352// UnsignedIterator represents a stream of unsigned points.
5353type UnsignedIterator interface {
5354	Iterator
5355	Next() (*UnsignedPoint, error)
5356}
5357
5358// newUnsignedIterators converts a slice of Iterator to a slice of UnsignedIterator.
5359// Drop and closes any iterator in itrs that is not a UnsignedIterator and cannot
5360// be cast to a UnsignedIterator.
5361func newUnsignedIterators(itrs []Iterator) []UnsignedIterator {
5362	a := make([]UnsignedIterator, 0, len(itrs))
5363	for _, itr := range itrs {
5364		switch itr := itr.(type) {
5365		case UnsignedIterator:
5366			a = append(a, itr)
5367		default:
5368			itr.Close()
5369		}
5370	}
5371	return a
5372}
5373
5374// bufUnsignedIterator represents a buffered UnsignedIterator.
5375type bufUnsignedIterator struct {
5376	itr UnsignedIterator
5377	buf *UnsignedPoint
5378}
5379
5380// newBufUnsignedIterator returns a buffered UnsignedIterator.
5381func newBufUnsignedIterator(itr UnsignedIterator) *bufUnsignedIterator {
5382	return &bufUnsignedIterator{itr: itr}
5383}
5384
5385// Stats returns statistics from the input iterator.
5386func (itr *bufUnsignedIterator) Stats() IteratorStats { return itr.itr.Stats() }
5387
5388// Close closes the underlying iterator.
5389func (itr *bufUnsignedIterator) Close() error { return itr.itr.Close() }
5390
5391// peek returns the next point without removing it from the iterator.
5392func (itr *bufUnsignedIterator) peek() (*UnsignedPoint, error) {
5393	p, err := itr.Next()
5394	if err != nil {
5395		return nil, err
5396	}
5397	itr.unread(p)
5398	return p, nil
5399}
5400
5401// peekTime returns the time of the next point.
5402// Returns zero time if no more points available.
5403func (itr *bufUnsignedIterator) peekTime() (int64, error) {
5404	p, err := itr.peek()
5405	if p == nil || err != nil {
5406		return ZeroTime, err
5407	}
5408	return p.Time, nil
5409}
5410
5411// Next returns the current buffer, if exists, or calls the underlying iterator.
5412func (itr *bufUnsignedIterator) Next() (*UnsignedPoint, error) {
5413	buf := itr.buf
5414	if buf != nil {
5415		itr.buf = nil
5416		return buf, nil
5417	}
5418	return itr.itr.Next()
5419}
5420
5421// NextInWindow returns the next value if it is between [startTime, endTime).
5422// If the next value is outside the range then it is moved to the buffer.
5423func (itr *bufUnsignedIterator) NextInWindow(startTime, endTime int64) (*UnsignedPoint, error) {
5424	v, err := itr.Next()
5425	if v == nil || err != nil {
5426		return nil, err
5427	} else if t := v.Time; t >= endTime || t < startTime {
5428		itr.unread(v)
5429		return nil, nil
5430	}
5431	return v, nil
5432}
5433
5434// unread sets v to the buffer. It is read on the next call to Next().
5435func (itr *bufUnsignedIterator) unread(v *UnsignedPoint) { itr.buf = v }
5436
5437// unsignedMergeIterator represents an iterator that combines multiple unsigned iterators.
5438type unsignedMergeIterator struct {
5439	inputs []UnsignedIterator
5440	heap   *unsignedMergeHeap
5441	init   bool
5442
5443	closed bool
5444	mu     sync.RWMutex
5445
5446	// Current iterator and window.
5447	curr   *unsignedMergeHeapItem
5448	window struct {
5449		name      string
5450		tags      string
5451		startTime int64
5452		endTime   int64
5453	}
5454}
5455
5456// newUnsignedMergeIterator returns a new instance of unsignedMergeIterator.
5457func newUnsignedMergeIterator(inputs []UnsignedIterator, opt IteratorOptions) *unsignedMergeIterator {
5458	itr := &unsignedMergeIterator{
5459		inputs: inputs,
5460		heap: &unsignedMergeHeap{
5461			items: make([]*unsignedMergeHeapItem, 0, len(inputs)),
5462			opt:   opt,
5463		},
5464	}
5465
5466	// Initialize heap items.
5467	for _, input := range inputs {
5468		// Wrap in buffer, ignore any inputs without anymore points.
5469		bufInput := newBufUnsignedIterator(input)
5470
5471		// Append to the heap.
5472		itr.heap.items = append(itr.heap.items, &unsignedMergeHeapItem{itr: bufInput})
5473	}
5474
5475	return itr
5476}
5477
5478// Stats returns an aggregation of stats from the underlying iterators.
5479func (itr *unsignedMergeIterator) Stats() IteratorStats {
5480	var stats IteratorStats
5481	for _, input := range itr.inputs {
5482		stats.Add(input.Stats())
5483	}
5484	return stats
5485}
5486
5487// Close closes the underlying iterators.
5488func (itr *unsignedMergeIterator) Close() error {
5489	itr.mu.Lock()
5490	defer itr.mu.Unlock()
5491
5492	for _, input := range itr.inputs {
5493		input.Close()
5494	}
5495	itr.curr = nil
5496	itr.inputs = nil
5497	itr.heap.items = nil
5498	itr.closed = true
5499	return nil
5500}
5501
5502// Next returns the next point from the iterator.
5503func (itr *unsignedMergeIterator) Next() (*UnsignedPoint, error) {
5504	itr.mu.RLock()
5505	defer itr.mu.RUnlock()
5506	if itr.closed {
5507		return nil, nil
5508	}
5509
5510	// Initialize the heap. This needs to be done lazily on the first call to this iterator
5511	// so that iterator initialization done through the Select() call returns quickly.
5512	// Queries can only be interrupted after the Select() call completes so any operations
5513	// done during iterator creation cannot be interrupted, which is why we do it here
5514	// instead so an interrupt can happen while initializing the heap.
5515	if !itr.init {
5516		items := itr.heap.items
5517		itr.heap.items = make([]*unsignedMergeHeapItem, 0, len(items))
5518		for _, item := range items {
5519			if p, err := item.itr.peek(); err != nil {
5520				return nil, err
5521			} else if p == nil {
5522				continue
5523			}
5524			itr.heap.items = append(itr.heap.items, item)
5525		}
5526		heap.Init(itr.heap)
5527		itr.init = true
5528	}
5529
5530	for {
5531		// Retrieve the next iterator if we don't have one.
5532		if itr.curr == nil {
5533			if len(itr.heap.items) == 0 {
5534				return nil, nil
5535			}
5536			itr.curr = heap.Pop(itr.heap).(*unsignedMergeHeapItem)
5537
5538			// Read point and set current window.
5539			p, err := itr.curr.itr.Next()
5540			if err != nil {
5541				return nil, err
5542			}
5543			tags := p.Tags.Subset(itr.heap.opt.Dimensions)
5544			itr.window.name, itr.window.tags = p.Name, tags.ID()
5545			itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time)
5546			return p, nil
5547		}
5548
5549		// Read the next point from the current iterator.
5550		p, err := itr.curr.itr.Next()
5551		if err != nil {
5552			return nil, err
5553		}
5554
5555		// If there are no more points then remove iterator from heap and find next.
5556		if p == nil {
5557			itr.curr = nil
5558			continue
5559		}
5560
5561		// Check if the point is inside of our current window.
5562		inWindow := true
5563		if window := itr.window; window.name != p.Name {
5564			inWindow = false
5565		} else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() {
5566			inWindow = false
5567		} else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime {
5568			inWindow = false
5569		} else if !opt.Ascending && p.Time < window.startTime {
5570			inWindow = false
5571		}
5572
5573		// If it's outside our window then push iterator back on the heap and find new iterator.
5574		if !inWindow {
5575			itr.curr.itr.unread(p)
5576			heap.Push(itr.heap, itr.curr)
5577			itr.curr = nil
5578			continue
5579		}
5580
5581		return p, nil
5582	}
5583}
5584
5585// unsignedMergeHeap represents a heap of unsignedMergeHeapItems.
5586// Items are sorted by their next window and then by name/tags.
5587type unsignedMergeHeap struct {
5588	opt   IteratorOptions
5589	items []*unsignedMergeHeapItem
5590}
5591
5592func (h *unsignedMergeHeap) Len() int      { return len(h.items) }
5593func (h *unsignedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
5594func (h *unsignedMergeHeap) Less(i, j int) bool {
5595	x, err := h.items[i].itr.peek()
5596	if err != nil {
5597		return true
5598	}
5599	y, err := h.items[j].itr.peek()
5600	if err != nil {
5601		return false
5602	}
5603
5604	if h.opt.Ascending {
5605		if x.Name != y.Name {
5606			return x.Name < y.Name
5607		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
5608			return xTags.ID() < yTags.ID()
5609		}
5610	} else {
5611		if x.Name != y.Name {
5612			return x.Name > y.Name
5613		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
5614			return xTags.ID() > yTags.ID()
5615		}
5616	}
5617
5618	xt, _ := h.opt.Window(x.Time)
5619	yt, _ := h.opt.Window(y.Time)
5620
5621	if h.opt.Ascending {
5622		return xt < yt
5623	}
5624	return xt > yt
5625}
5626
5627func (h *unsignedMergeHeap) Push(x interface{}) {
5628	h.items = append(h.items, x.(*unsignedMergeHeapItem))
5629}
5630
5631func (h *unsignedMergeHeap) Pop() interface{} {
5632	old := h.items
5633	n := len(old)
5634	item := old[n-1]
5635	h.items = old[0 : n-1]
5636	return item
5637}
5638
5639type unsignedMergeHeapItem struct {
5640	itr *bufUnsignedIterator
5641}
5642
5643// unsignedSortedMergeIterator is an iterator that sorts and merges multiple iterators into one.
5644type unsignedSortedMergeIterator struct {
5645	inputs []UnsignedIterator
5646	heap   *unsignedSortedMergeHeap
5647	init   bool
5648}
5649
5650// newUnsignedSortedMergeIterator returns an instance of unsignedSortedMergeIterator.
5651func newUnsignedSortedMergeIterator(inputs []UnsignedIterator, opt IteratorOptions) Iterator {
5652	itr := &unsignedSortedMergeIterator{
5653		inputs: inputs,
5654		heap: &unsignedSortedMergeHeap{
5655			items: make([]*unsignedSortedMergeHeapItem, 0, len(inputs)),
5656			opt:   opt,
5657		},
5658	}
5659
5660	// Initialize heap items.
5661	for _, input := range inputs {
5662		// Append to the heap.
5663		itr.heap.items = append(itr.heap.items, &unsignedSortedMergeHeapItem{itr: input})
5664	}
5665
5666	return itr
5667}
5668
5669// Stats returns an aggregation of stats from the underlying iterators.
5670func (itr *unsignedSortedMergeIterator) Stats() IteratorStats {
5671	var stats IteratorStats
5672	for _, input := range itr.inputs {
5673		stats.Add(input.Stats())
5674	}
5675	return stats
5676}
5677
5678// Close closes the underlying iterators.
5679func (itr *unsignedSortedMergeIterator) Close() error {
5680	for _, input := range itr.inputs {
5681		input.Close()
5682	}
5683	return nil
5684}
5685
5686// Next returns the next points from the iterator.
5687func (itr *unsignedSortedMergeIterator) Next() (*UnsignedPoint, error) { return itr.pop() }
5688
5689// pop returns the next point from the heap.
5690// Reads the next point from item's cursor and puts it back on the heap.
5691func (itr *unsignedSortedMergeIterator) pop() (*UnsignedPoint, error) {
5692	// Initialize the heap. See the MergeIterator to see why this has to be done lazily.
5693	if !itr.init {
5694		items := itr.heap.items
5695		itr.heap.items = make([]*unsignedSortedMergeHeapItem, 0, len(items))
5696		for _, item := range items {
5697			var err error
5698			if item.point, err = item.itr.Next(); err != nil {
5699				return nil, err
5700			} else if item.point == nil {
5701				continue
5702			}
5703			itr.heap.items = append(itr.heap.items, item)
5704		}
5705		heap.Init(itr.heap)
5706		itr.init = true
5707	}
5708
5709	if len(itr.heap.items) == 0 {
5710		return nil, nil
5711	}
5712
5713	// Read the next item from the heap.
5714	item := heap.Pop(itr.heap).(*unsignedSortedMergeHeapItem)
5715	if item.err != nil {
5716		return nil, item.err
5717	} else if item.point == nil {
5718		return nil, nil
5719	}
5720
5721	// Copy the point for return.
5722	p := item.point.Clone()
5723
5724	// Read the next item from the cursor. Push back to heap if one exists.
5725	if item.point, item.err = item.itr.Next(); item.point != nil {
5726		heap.Push(itr.heap, item)
5727	}
5728
5729	return p, nil
5730}
5731
5732// unsignedSortedMergeHeap represents a heap of unsignedSortedMergeHeapItems.
5733// Items are sorted with the following priority:
5734//     - By their measurement name;
5735//     - By their tag keys/values;
5736//     - By time; or
5737//     - By their Aux field values.
5738//
5739type unsignedSortedMergeHeap struct {
5740	opt   IteratorOptions
5741	items []*unsignedSortedMergeHeapItem
5742}
5743
5744func (h *unsignedSortedMergeHeap) Len() int      { return len(h.items) }
5745func (h *unsignedSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
5746func (h *unsignedSortedMergeHeap) Less(i, j int) bool {
5747	x, y := h.items[i].point, h.items[j].point
5748
5749	if h.opt.Ascending {
5750		if x.Name != y.Name {
5751			return x.Name < y.Name
5752		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
5753			return xTags.ID() < yTags.ID()
5754		}
5755
5756		if x.Time != y.Time {
5757			return x.Time < y.Time
5758		}
5759
5760		if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
5761			for i := 0; i < len(x.Aux); i++ {
5762				v1, ok1 := x.Aux[i].(string)
5763				v2, ok2 := y.Aux[i].(string)
5764				if !ok1 || !ok2 {
5765					// Unsupported types used in Aux fields. Maybe they
5766					// need to be added here?
5767					return false
5768				} else if v1 == v2 {
5769					continue
5770				}
5771				return v1 < v2
5772			}
5773		}
5774		return false // Times and/or Aux fields are equal.
5775	}
5776
5777	if x.Name != y.Name {
5778		return x.Name > y.Name
5779	} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
5780		return xTags.ID() > yTags.ID()
5781	}
5782
5783	if x.Time != y.Time {
5784		return x.Time > y.Time
5785	}
5786
5787	if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
5788		for i := 0; i < len(x.Aux); i++ {
5789			v1, ok1 := x.Aux[i].(string)
5790			v2, ok2 := y.Aux[i].(string)
5791			if !ok1 || !ok2 {
5792				// Unsupported types used in Aux fields. Maybe they
5793				// need to be added here?
5794				return false
5795			} else if v1 == v2 {
5796				continue
5797			}
5798			return v1 > v2
5799		}
5800	}
5801	return false // Times and/or Aux fields are equal.
5802}
5803
5804func (h *unsignedSortedMergeHeap) Push(x interface{}) {
5805	h.items = append(h.items, x.(*unsignedSortedMergeHeapItem))
5806}
5807
5808func (h *unsignedSortedMergeHeap) Pop() interface{} {
5809	old := h.items
5810	n := len(old)
5811	item := old[n-1]
5812	h.items = old[0 : n-1]
5813	return item
5814}
5815
5816type unsignedSortedMergeHeapItem struct {
5817	point *UnsignedPoint
5818	err   error
5819	itr   UnsignedIterator
5820}
5821
5822// unsignedIteratorScanner scans the results of a UnsignedIterator into a map.
5823type unsignedIteratorScanner struct {
5824	input        *bufUnsignedIterator
5825	err          error
5826	keys         []influxql.VarRef
5827	defaultValue interface{}
5828}
5829
5830// newUnsignedIteratorScanner creates a new IteratorScanner.
5831func newUnsignedIteratorScanner(input UnsignedIterator, keys []influxql.VarRef, defaultValue interface{}) *unsignedIteratorScanner {
5832	return &unsignedIteratorScanner{
5833		input:        newBufUnsignedIterator(input),
5834		keys:         keys,
5835		defaultValue: defaultValue,
5836	}
5837}
5838
5839func (s *unsignedIteratorScanner) Peek() (int64, string, Tags) {
5840	if s.err != nil {
5841		return ZeroTime, "", Tags{}
5842	}
5843
5844	p, err := s.input.peek()
5845	if err != nil {
5846		s.err = err
5847		return ZeroTime, "", Tags{}
5848	} else if p == nil {
5849		return ZeroTime, "", Tags{}
5850	}
5851	return p.Time, p.Name, p.Tags
5852}
5853
5854func (s *unsignedIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) {
5855	if s.err != nil {
5856		return
5857	}
5858
5859	p, err := s.input.Next()
5860	if err != nil {
5861		s.err = err
5862		return
5863	} else if p == nil {
5864		s.useDefaults(m)
5865		return
5866	} else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) {
5867		s.useDefaults(m)
5868		s.input.unread(p)
5869		return
5870	}
5871
5872	if k := s.keys[0]; k.Val != "" {
5873		if p.Nil {
5874			if s.defaultValue != SkipDefault {
5875				m[k.Val] = castToType(s.defaultValue, k.Type)
5876			}
5877		} else {
5878			m[k.Val] = p.Value
5879		}
5880	}
5881	for i, v := range p.Aux {
5882		k := s.keys[i+1]
5883		switch v.(type) {
5884		case float64, int64, uint64, string, bool:
5885			m[k.Val] = v
5886		default:
5887			// Insert the fill value if one was specified.
5888			if s.defaultValue != SkipDefault {
5889				m[k.Val] = castToType(s.defaultValue, k.Type)
5890			}
5891		}
5892	}
5893}
5894
5895func (s *unsignedIteratorScanner) useDefaults(m map[string]interface{}) {
5896	if s.defaultValue == SkipDefault {
5897		return
5898	}
5899	for _, k := range s.keys {
5900		if k.Val == "" {
5901			continue
5902		}
5903		m[k.Val] = castToType(s.defaultValue, k.Type)
5904	}
5905}
5906
5907func (s *unsignedIteratorScanner) Stats() IteratorStats { return s.input.Stats() }
5908func (s *unsignedIteratorScanner) Err() error           { return s.err }
5909func (s *unsignedIteratorScanner) Close() error         { return s.input.Close() }
5910
5911// unsignedParallelIterator represents an iterator that pulls data in a separate goroutine.
5912type unsignedParallelIterator struct {
5913	input UnsignedIterator
5914	ch    chan unsignedPointError
5915
5916	once    sync.Once
5917	closing chan struct{}
5918	wg      sync.WaitGroup
5919}
5920
5921// newUnsignedParallelIterator returns a new instance of unsignedParallelIterator.
5922func newUnsignedParallelIterator(input UnsignedIterator) *unsignedParallelIterator {
5923	itr := &unsignedParallelIterator{
5924		input:   input,
5925		ch:      make(chan unsignedPointError, 256),
5926		closing: make(chan struct{}),
5927	}
5928	itr.wg.Add(1)
5929	go itr.monitor()
5930	return itr
5931}
5932
5933// Stats returns stats from the underlying iterator.
5934func (itr *unsignedParallelIterator) Stats() IteratorStats { return itr.input.Stats() }
5935
5936// Close closes the underlying iterators.
5937func (itr *unsignedParallelIterator) Close() error {
5938	itr.once.Do(func() { close(itr.closing) })
5939	itr.wg.Wait()
5940	return itr.input.Close()
5941}
5942
5943// Next returns the next point from the iterator.
5944func (itr *unsignedParallelIterator) Next() (*UnsignedPoint, error) {
5945	v, ok := <-itr.ch
5946	if !ok {
5947		return nil, io.EOF
5948	}
5949	return v.point, v.err
5950}
5951
5952// monitor runs in a separate goroutine and actively pulls the next point.
5953func (itr *unsignedParallelIterator) monitor() {
5954	defer close(itr.ch)
5955	defer itr.wg.Done()
5956
5957	for {
5958		// Read next point.
5959		p, err := itr.input.Next()
5960		if p != nil {
5961			p = p.Clone()
5962		}
5963
5964		select {
5965		case <-itr.closing:
5966			return
5967		case itr.ch <- unsignedPointError{point: p, err: err}:
5968		}
5969	}
5970}
5971
5972type unsignedPointError struct {
5973	point *UnsignedPoint
5974	err   error
5975}
5976
5977// unsignedLimitIterator represents an iterator that limits points per group.
5978type unsignedLimitIterator struct {
5979	input UnsignedIterator
5980	opt   IteratorOptions
5981	n     int
5982
5983	prev struct {
5984		name string
5985		tags Tags
5986	}
5987}
5988
5989// newUnsignedLimitIterator returns a new instance of unsignedLimitIterator.
5990func newUnsignedLimitIterator(input UnsignedIterator, opt IteratorOptions) *unsignedLimitIterator {
5991	return &unsignedLimitIterator{
5992		input: input,
5993		opt:   opt,
5994	}
5995}
5996
5997// Stats returns stats from the underlying iterator.
5998func (itr *unsignedLimitIterator) Stats() IteratorStats { return itr.input.Stats() }
5999
6000// Close closes the underlying iterators.
6001func (itr *unsignedLimitIterator) Close() error { return itr.input.Close() }
6002
6003// Next returns the next point from the iterator.
6004func (itr *unsignedLimitIterator) Next() (*UnsignedPoint, error) {
6005	for {
6006		p, err := itr.input.Next()
6007		if p == nil || err != nil {
6008			return nil, err
6009		}
6010
6011		// Reset window and counter if a new window is encountered.
6012		if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) {
6013			itr.prev.name = p.Name
6014			itr.prev.tags = p.Tags
6015			itr.n = 0
6016		}
6017
6018		// Increment counter.
6019		itr.n++
6020
6021		// Read next point if not beyond the offset.
6022		if itr.n <= itr.opt.Offset {
6023			continue
6024		}
6025
6026		// Read next point if we're beyond the limit.
6027		if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit {
6028			continue
6029		}
6030
6031		return p, nil
6032	}
6033}
6034
6035type unsignedFillIterator struct {
6036	input     *bufUnsignedIterator
6037	prev      UnsignedPoint
6038	startTime int64
6039	endTime   int64
6040	auxFields []interface{}
6041	init      bool
6042	opt       IteratorOptions
6043
6044	window struct {
6045		name   string
6046		tags   Tags
6047		time   int64
6048		offset int64
6049	}
6050}
6051
6052func newUnsignedFillIterator(input UnsignedIterator, expr influxql.Expr, opt IteratorOptions) *unsignedFillIterator {
6053	if opt.Fill == influxql.NullFill {
6054		if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" {
6055			opt.Fill = influxql.NumberFill
6056			opt.FillValue = uint64(0)
6057		}
6058	}
6059
6060	var startTime, endTime int64
6061	if opt.Ascending {
6062		startTime, _ = opt.Window(opt.StartTime)
6063		endTime, _ = opt.Window(opt.EndTime)
6064	} else {
6065		startTime, _ = opt.Window(opt.EndTime)
6066		endTime, _ = opt.Window(opt.StartTime)
6067	}
6068
6069	var auxFields []interface{}
6070	if len(opt.Aux) > 0 {
6071		auxFields = make([]interface{}, len(opt.Aux))
6072	}
6073
6074	return &unsignedFillIterator{
6075		input:     newBufUnsignedIterator(input),
6076		prev:      UnsignedPoint{Nil: true},
6077		startTime: startTime,
6078		endTime:   endTime,
6079		auxFields: auxFields,
6080		opt:       opt,
6081	}
6082}
6083
6084func (itr *unsignedFillIterator) Stats() IteratorStats { return itr.input.Stats() }
6085func (itr *unsignedFillIterator) Close() error         { return itr.input.Close() }
6086
6087func (itr *unsignedFillIterator) Next() (*UnsignedPoint, error) {
6088	if !itr.init {
6089		p, err := itr.input.peek()
6090		if p == nil || err != nil {
6091			return nil, err
6092		}
6093		itr.window.name, itr.window.tags = p.Name, p.Tags
6094		itr.window.time = itr.startTime
6095		if itr.startTime == influxql.MinTime {
6096			itr.window.time, _ = itr.opt.Window(p.Time)
6097		}
6098		if itr.opt.Location != nil {
6099			_, itr.window.offset = itr.opt.Zone(itr.window.time)
6100		}
6101		itr.init = true
6102	}
6103
6104	p, err := itr.input.Next()
6105	if err != nil {
6106		return nil, err
6107	}
6108
6109	// Check if the next point is outside of our window or is nil.
6110	if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() {
6111		// If we are inside of an interval, unread the point and continue below to
6112		// constructing a new point.
6113		if itr.opt.Ascending && itr.window.time <= itr.endTime {
6114			itr.input.unread(p)
6115			p = nil
6116			goto CONSTRUCT
6117		} else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime {
6118			itr.input.unread(p)
6119			p = nil
6120			goto CONSTRUCT
6121		}
6122
6123		// We are *not* in a current interval. If there is no next point,
6124		// we are at the end of all intervals.
6125		if p == nil {
6126			return nil, nil
6127		}
6128
6129		// Set the new interval.
6130		itr.window.name, itr.window.tags = p.Name, p.Tags
6131		itr.window.time = itr.startTime
6132		if itr.window.time == influxql.MinTime {
6133			itr.window.time, _ = itr.opt.Window(p.Time)
6134		}
6135		if itr.opt.Location != nil {
6136			_, itr.window.offset = itr.opt.Zone(itr.window.time)
6137		}
6138		itr.prev = UnsignedPoint{Nil: true}
6139	}
6140
6141	// Check if the point is our next expected point.
6142CONSTRUCT:
6143	if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) {
6144		if p != nil {
6145			itr.input.unread(p)
6146		}
6147
6148		p = &UnsignedPoint{
6149			Name: itr.window.name,
6150			Tags: itr.window.tags,
6151			Time: itr.window.time,
6152			Aux:  itr.auxFields,
6153		}
6154
6155		switch itr.opt.Fill {
6156		case influxql.LinearFill:
6157			if !itr.prev.Nil {
6158				next, err := itr.input.peek()
6159				if err != nil {
6160					return nil, err
6161				} else if next != nil && next.Name == itr.window.name && next.Tags.ID() == itr.window.tags.ID() {
6162					interval := int64(itr.opt.Interval.Duration)
6163					start := itr.window.time / interval
6164					p.Value = linearUnsigned(start, itr.prev.Time/interval, next.Time/interval, itr.prev.Value, next.Value)
6165				} else {
6166					p.Nil = true
6167				}
6168			} else {
6169				p.Nil = true
6170			}
6171
6172		case influxql.NullFill:
6173			p.Nil = true
6174		case influxql.NumberFill:
6175			p.Value, _ = castToUnsigned(itr.opt.FillValue)
6176		case influxql.PreviousFill:
6177			if !itr.prev.Nil {
6178				p.Value = itr.prev.Value
6179				p.Nil = itr.prev.Nil
6180			} else {
6181				p.Nil = true
6182			}
6183		}
6184	} else {
6185		itr.prev = *p
6186	}
6187
6188	// Advance the expected time. Do not advance to a new window here
6189	// as there may be lingering points with the same timestamp in the previous
6190	// window.
6191	if itr.opt.Ascending {
6192		itr.window.time += int64(itr.opt.Interval.Duration)
6193	} else {
6194		itr.window.time -= int64(itr.opt.Interval.Duration)
6195	}
6196
6197	// Check to see if we have passed over an offset change and adjust the time
6198	// to account for this new offset.
6199	if itr.opt.Location != nil {
6200		if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset {
6201			diff := itr.window.offset - offset
6202			if abs(diff) < int64(itr.opt.Interval.Duration) {
6203				itr.window.time += diff
6204			}
6205			itr.window.offset = offset
6206		}
6207	}
6208	return p, nil
6209}
6210
6211// unsignedIntervalIterator represents a unsigned implementation of IntervalIterator.
6212type unsignedIntervalIterator struct {
6213	input UnsignedIterator
6214	opt   IteratorOptions
6215}
6216
6217func newUnsignedIntervalIterator(input UnsignedIterator, opt IteratorOptions) *unsignedIntervalIterator {
6218	return &unsignedIntervalIterator{input: input, opt: opt}
6219}
6220
6221func (itr *unsignedIntervalIterator) Stats() IteratorStats { return itr.input.Stats() }
6222func (itr *unsignedIntervalIterator) Close() error         { return itr.input.Close() }
6223
6224func (itr *unsignedIntervalIterator) Next() (*UnsignedPoint, error) {
6225	p, err := itr.input.Next()
6226	if p == nil || err != nil {
6227		return nil, err
6228	}
6229	p.Time, _ = itr.opt.Window(p.Time)
6230	// If we see the minimum allowable time, set the time to zero so we don't
6231	// break the default returned time for aggregate queries without times.
6232	if p.Time == influxql.MinTime {
6233		p.Time = 0
6234	}
6235	return p, nil
6236}
6237
6238// unsignedInterruptIterator represents a unsigned implementation of InterruptIterator.
6239type unsignedInterruptIterator struct {
6240	input   UnsignedIterator
6241	closing <-chan struct{}
6242	count   int
6243}
6244
6245func newUnsignedInterruptIterator(input UnsignedIterator, closing <-chan struct{}) *unsignedInterruptIterator {
6246	return &unsignedInterruptIterator{input: input, closing: closing}
6247}
6248
6249func (itr *unsignedInterruptIterator) Stats() IteratorStats { return itr.input.Stats() }
6250func (itr *unsignedInterruptIterator) Close() error         { return itr.input.Close() }
6251
6252func (itr *unsignedInterruptIterator) Next() (*UnsignedPoint, error) {
6253	// Only check if the channel is closed every N points. This
6254	// intentionally checks on both 0 and N so that if the iterator
6255	// has been interrupted before the first point is emitted it will
6256	// not emit any points.
6257	if itr.count&0xFF == 0xFF {
6258		select {
6259		case <-itr.closing:
6260			return nil, itr.Close()
6261		default:
6262			// Reset iterator count to zero and fall through to emit the next point.
6263			itr.count = 0
6264		}
6265	}
6266
6267	// Increment the counter for every point read.
6268	itr.count++
6269	return itr.input.Next()
6270}
6271
6272// unsignedCloseInterruptIterator represents a unsigned implementation of CloseInterruptIterator.
6273type unsignedCloseInterruptIterator struct {
6274	input   UnsignedIterator
6275	closing <-chan struct{}
6276	done    chan struct{}
6277	once    sync.Once
6278}
6279
6280func newUnsignedCloseInterruptIterator(input UnsignedIterator, closing <-chan struct{}) *unsignedCloseInterruptIterator {
6281	itr := &unsignedCloseInterruptIterator{
6282		input:   input,
6283		closing: closing,
6284		done:    make(chan struct{}),
6285	}
6286	go itr.monitor()
6287	return itr
6288}
6289
6290func (itr *unsignedCloseInterruptIterator) monitor() {
6291	select {
6292	case <-itr.closing:
6293		itr.Close()
6294	case <-itr.done:
6295	}
6296}
6297
6298func (itr *unsignedCloseInterruptIterator) Stats() IteratorStats {
6299	return itr.input.Stats()
6300}
6301
6302func (itr *unsignedCloseInterruptIterator) Close() error {
6303	itr.once.Do(func() {
6304		close(itr.done)
6305		itr.input.Close()
6306	})
6307	return nil
6308}
6309
6310func (itr *unsignedCloseInterruptIterator) Next() (*UnsignedPoint, error) {
6311	p, err := itr.input.Next()
6312	if err != nil {
6313		// Check if the iterator was closed.
6314		select {
6315		case <-itr.done:
6316			return nil, nil
6317		default:
6318			return nil, err
6319		}
6320	}
6321	return p, nil
6322}
6323
6324// unsignedReduceFloatIterator executes a reducer for every interval and buffers the result.
6325type unsignedReduceFloatIterator struct {
6326	input    *bufUnsignedIterator
6327	create   func() (UnsignedPointAggregator, FloatPointEmitter)
6328	dims     []string
6329	opt      IteratorOptions
6330	points   []FloatPoint
6331	keepTags bool
6332}
6333
6334func newUnsignedReduceFloatIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, FloatPointEmitter)) *unsignedReduceFloatIterator {
6335	return &unsignedReduceFloatIterator{
6336		input:  newBufUnsignedIterator(input),
6337		create: createFn,
6338		dims:   opt.GetDimensions(),
6339		opt:    opt,
6340	}
6341}
6342
6343// Stats returns stats from the input iterator.
6344func (itr *unsignedReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
6345
6346// Close closes the iterator and all child iterators.
6347func (itr *unsignedReduceFloatIterator) Close() error { return itr.input.Close() }
6348
6349// Next returns the minimum value for the next available interval.
6350func (itr *unsignedReduceFloatIterator) Next() (*FloatPoint, error) {
6351	// Calculate next window if we have no more points.
6352	if len(itr.points) == 0 {
6353		var err error
6354		itr.points, err = itr.reduce()
6355		if len(itr.points) == 0 {
6356			return nil, err
6357		}
6358	}
6359
6360	// Pop next point off the stack.
6361	p := &itr.points[len(itr.points)-1]
6362	itr.points = itr.points[:len(itr.points)-1]
6363	return p, nil
6364}
6365
6366// unsignedReduceFloatPoint stores the reduced data for a name/tag combination.
6367type unsignedReduceFloatPoint struct {
6368	Name       string
6369	Tags       Tags
6370	Aggregator UnsignedPointAggregator
6371	Emitter    FloatPointEmitter
6372}
6373
6374// reduce executes fn once for every point in the next window.
6375// The previous value for the dimension is passed to fn.
6376func (itr *unsignedReduceFloatIterator) reduce() ([]FloatPoint, error) {
6377	// Calculate next window.
6378	var (
6379		startTime, endTime int64
6380		window             struct {
6381			name string
6382			tags string
6383		}
6384	)
6385	for {
6386		p, err := itr.input.Next()
6387		if err != nil || p == nil {
6388			return nil, err
6389		} else if p.Nil {
6390			continue
6391		}
6392
6393		// Unread the point so it can be processed.
6394		itr.input.unread(p)
6395		startTime, endTime = itr.opt.Window(p.Time)
6396		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
6397		break
6398	}
6399
6400	// Create points by tags.
6401	m := make(map[string]*unsignedReduceFloatPoint)
6402	for {
6403		// Read next point.
6404		curr, err := itr.input.NextInWindow(startTime, endTime)
6405		if err != nil {
6406			return nil, err
6407		} else if curr == nil {
6408			break
6409		} else if curr.Nil {
6410			continue
6411		} else if curr.Name != window.name {
6412			itr.input.unread(curr)
6413			break
6414		}
6415
6416		// Ensure this point is within the same final window.
6417		if curr.Name != window.name {
6418			itr.input.unread(curr)
6419			break
6420		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
6421			itr.input.unread(curr)
6422			break
6423		}
6424
6425		// Retrieve the tags on this point for this level of the query.
6426		// This may be different than the bucket dimensions.
6427		tags := curr.Tags.Subset(itr.dims)
6428		id := tags.ID()
6429
6430		// Retrieve the aggregator for this name/tag combination or create one.
6431		rp := m[id]
6432		if rp == nil {
6433			aggregator, emitter := itr.create()
6434			rp = &unsignedReduceFloatPoint{
6435				Name:       curr.Name,
6436				Tags:       tags,
6437				Aggregator: aggregator,
6438				Emitter:    emitter,
6439			}
6440			m[id] = rp
6441		}
6442		rp.Aggregator.AggregateUnsigned(curr)
6443	}
6444
6445	keys := make([]string, 0, len(m))
6446	for k := range m {
6447		keys = append(keys, k)
6448	}
6449
6450	// Reverse sort points by name & tag.
6451	// This ensures a consistent order of output.
6452	if len(keys) > 0 {
6453		var sorted sort.Interface = sort.StringSlice(keys)
6454		if itr.opt.Ascending {
6455			sorted = sort.Reverse(sorted)
6456		}
6457		sort.Sort(sorted)
6458	}
6459
6460	// Assume the points are already sorted until proven otherwise.
6461	sortedByTime := true
6462	// Emit the points for each name & tag combination.
6463	a := make([]FloatPoint, 0, len(m))
6464	for _, k := range keys {
6465		rp := m[k]
6466		points := rp.Emitter.Emit()
6467		for i := len(points) - 1; i >= 0; i-- {
6468			points[i].Name = rp.Name
6469			if !itr.keepTags {
6470				points[i].Tags = rp.Tags
6471			}
6472			// Set the points time to the interval time if the reducer didn't provide one.
6473			if points[i].Time == ZeroTime {
6474				points[i].Time = startTime
6475			} else {
6476				sortedByTime = false
6477			}
6478			a = append(a, points[i])
6479		}
6480	}
6481	// Points may be out of order. Perform a stable sort by time if requested.
6482	if !sortedByTime && itr.opt.Ordered {
6483		var sorted sort.Interface = floatPointsByTime(a)
6484		if itr.opt.Ascending {
6485			sorted = sort.Reverse(sorted)
6486		}
6487		sort.Stable(sorted)
6488	}
6489	return a, nil
6490}
6491
6492// unsignedStreamFloatIterator streams inputs into the iterator and emits points gradually.
6493type unsignedStreamFloatIterator struct {
6494	input  *bufUnsignedIterator
6495	create func() (UnsignedPointAggregator, FloatPointEmitter)
6496	dims   []string
6497	opt    IteratorOptions
6498	m      map[string]*unsignedReduceFloatPoint
6499	points []FloatPoint
6500}
6501
6502// newUnsignedStreamFloatIterator returns a new instance of unsignedStreamFloatIterator.
6503func newUnsignedStreamFloatIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, FloatPointEmitter), opt IteratorOptions) *unsignedStreamFloatIterator {
6504	return &unsignedStreamFloatIterator{
6505		input:  newBufUnsignedIterator(input),
6506		create: createFn,
6507		dims:   opt.GetDimensions(),
6508		opt:    opt,
6509		m:      make(map[string]*unsignedReduceFloatPoint),
6510	}
6511}
6512
6513// Stats returns stats from the input iterator.
6514func (itr *unsignedStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
6515
6516// Close closes the iterator and all child iterators.
6517func (itr *unsignedStreamFloatIterator) Close() error { return itr.input.Close() }
6518
6519// Next returns the next value for the stream iterator.
6520func (itr *unsignedStreamFloatIterator) Next() (*FloatPoint, error) {
6521	// Calculate next window if we have no more points.
6522	if len(itr.points) == 0 {
6523		var err error
6524		itr.points, err = itr.reduce()
6525		if len(itr.points) == 0 {
6526			return nil, err
6527		}
6528	}
6529
6530	// Pop next point off the stack.
6531	p := &itr.points[len(itr.points)-1]
6532	itr.points = itr.points[:len(itr.points)-1]
6533	return p, nil
6534}
6535
6536// reduce creates and manages aggregators for every point from the input.
6537// After aggregating a point, it always tries to emit a value using the emitter.
6538func (itr *unsignedStreamFloatIterator) reduce() ([]FloatPoint, error) {
6539	// We have already read all of the input points.
6540	if itr.m == nil {
6541		return nil, nil
6542	}
6543
6544	for {
6545		// Read next point.
6546		curr, err := itr.input.Next()
6547		if err != nil {
6548			return nil, err
6549		} else if curr == nil {
6550			// Close all of the aggregators to flush any remaining points to emit.
6551			var points []FloatPoint
6552			for _, rp := range itr.m {
6553				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
6554					if err := aggregator.Close(); err != nil {
6555						return nil, err
6556					}
6557
6558					pts := rp.Emitter.Emit()
6559					if len(pts) == 0 {
6560						continue
6561					}
6562
6563					for i := range pts {
6564						pts[i].Name = rp.Name
6565						pts[i].Tags = rp.Tags
6566					}
6567					points = append(points, pts...)
6568				}
6569			}
6570
6571			// Eliminate the aggregators and emitters.
6572			itr.m = nil
6573			return points, nil
6574		} else if curr.Nil {
6575			continue
6576		}
6577		tags := curr.Tags.Subset(itr.dims)
6578
6579		id := curr.Name
6580		if len(tags.m) > 0 {
6581			id += "\x00" + tags.ID()
6582		}
6583
6584		// Retrieve the aggregator for this name/tag combination or create one.
6585		rp := itr.m[id]
6586		if rp == nil {
6587			aggregator, emitter := itr.create()
6588			rp = &unsignedReduceFloatPoint{
6589				Name:       curr.Name,
6590				Tags:       tags,
6591				Aggregator: aggregator,
6592				Emitter:    emitter,
6593			}
6594			itr.m[id] = rp
6595		}
6596		rp.Aggregator.AggregateUnsigned(curr)
6597
6598		// Attempt to emit points from the aggregator.
6599		points := rp.Emitter.Emit()
6600		if len(points) == 0 {
6601			continue
6602		}
6603
6604		for i := range points {
6605			points[i].Name = rp.Name
6606			points[i].Tags = rp.Tags
6607		}
6608		return points, nil
6609	}
6610}
6611
6612// unsignedReduceIntegerIterator executes a reducer for every interval and buffers the result.
6613type unsignedReduceIntegerIterator struct {
6614	input    *bufUnsignedIterator
6615	create   func() (UnsignedPointAggregator, IntegerPointEmitter)
6616	dims     []string
6617	opt      IteratorOptions
6618	points   []IntegerPoint
6619	keepTags bool
6620}
6621
6622func newUnsignedReduceIntegerIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, IntegerPointEmitter)) *unsignedReduceIntegerIterator {
6623	return &unsignedReduceIntegerIterator{
6624		input:  newBufUnsignedIterator(input),
6625		create: createFn,
6626		dims:   opt.GetDimensions(),
6627		opt:    opt,
6628	}
6629}
6630
6631// Stats returns stats from the input iterator.
6632func (itr *unsignedReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
6633
6634// Close closes the iterator and all child iterators.
6635func (itr *unsignedReduceIntegerIterator) Close() error { return itr.input.Close() }
6636
6637// Next returns the minimum value for the next available interval.
6638func (itr *unsignedReduceIntegerIterator) Next() (*IntegerPoint, error) {
6639	// Calculate next window if we have no more points.
6640	if len(itr.points) == 0 {
6641		var err error
6642		itr.points, err = itr.reduce()
6643		if len(itr.points) == 0 {
6644			return nil, err
6645		}
6646	}
6647
6648	// Pop next point off the stack.
6649	p := &itr.points[len(itr.points)-1]
6650	itr.points = itr.points[:len(itr.points)-1]
6651	return p, nil
6652}
6653
6654// unsignedReduceIntegerPoint stores the reduced data for a name/tag combination.
6655type unsignedReduceIntegerPoint struct {
6656	Name       string
6657	Tags       Tags
6658	Aggregator UnsignedPointAggregator
6659	Emitter    IntegerPointEmitter
6660}
6661
6662// reduce executes fn once for every point in the next window.
6663// The previous value for the dimension is passed to fn.
6664func (itr *unsignedReduceIntegerIterator) reduce() ([]IntegerPoint, error) {
6665	// Calculate next window.
6666	var (
6667		startTime, endTime int64
6668		window             struct {
6669			name string
6670			tags string
6671		}
6672	)
6673	for {
6674		p, err := itr.input.Next()
6675		if err != nil || p == nil {
6676			return nil, err
6677		} else if p.Nil {
6678			continue
6679		}
6680
6681		// Unread the point so it can be processed.
6682		itr.input.unread(p)
6683		startTime, endTime = itr.opt.Window(p.Time)
6684		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
6685		break
6686	}
6687
6688	// Create points by tags.
6689	m := make(map[string]*unsignedReduceIntegerPoint)
6690	for {
6691		// Read next point.
6692		curr, err := itr.input.NextInWindow(startTime, endTime)
6693		if err != nil {
6694			return nil, err
6695		} else if curr == nil {
6696			break
6697		} else if curr.Nil {
6698			continue
6699		} else if curr.Name != window.name {
6700			itr.input.unread(curr)
6701			break
6702		}
6703
6704		// Ensure this point is within the same final window.
6705		if curr.Name != window.name {
6706			itr.input.unread(curr)
6707			break
6708		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
6709			itr.input.unread(curr)
6710			break
6711		}
6712
6713		// Retrieve the tags on this point for this level of the query.
6714		// This may be different than the bucket dimensions.
6715		tags := curr.Tags.Subset(itr.dims)
6716		id := tags.ID()
6717
6718		// Retrieve the aggregator for this name/tag combination or create one.
6719		rp := m[id]
6720		if rp == nil {
6721			aggregator, emitter := itr.create()
6722			rp = &unsignedReduceIntegerPoint{
6723				Name:       curr.Name,
6724				Tags:       tags,
6725				Aggregator: aggregator,
6726				Emitter:    emitter,
6727			}
6728			m[id] = rp
6729		}
6730		rp.Aggregator.AggregateUnsigned(curr)
6731	}
6732
6733	keys := make([]string, 0, len(m))
6734	for k := range m {
6735		keys = append(keys, k)
6736	}
6737
6738	// Reverse sort points by name & tag.
6739	// This ensures a consistent order of output.
6740	if len(keys) > 0 {
6741		var sorted sort.Interface = sort.StringSlice(keys)
6742		if itr.opt.Ascending {
6743			sorted = sort.Reverse(sorted)
6744		}
6745		sort.Sort(sorted)
6746	}
6747
6748	// Assume the points are already sorted until proven otherwise.
6749	sortedByTime := true
6750	// Emit the points for each name & tag combination.
6751	a := make([]IntegerPoint, 0, len(m))
6752	for _, k := range keys {
6753		rp := m[k]
6754		points := rp.Emitter.Emit()
6755		for i := len(points) - 1; i >= 0; i-- {
6756			points[i].Name = rp.Name
6757			if !itr.keepTags {
6758				points[i].Tags = rp.Tags
6759			}
6760			// Set the points time to the interval time if the reducer didn't provide one.
6761			if points[i].Time == ZeroTime {
6762				points[i].Time = startTime
6763			} else {
6764				sortedByTime = false
6765			}
6766			a = append(a, points[i])
6767		}
6768	}
6769	// Points may be out of order. Perform a stable sort by time if requested.
6770	if !sortedByTime && itr.opt.Ordered {
6771		var sorted sort.Interface = integerPointsByTime(a)
6772		if itr.opt.Ascending {
6773			sorted = sort.Reverse(sorted)
6774		}
6775		sort.Stable(sorted)
6776	}
6777	return a, nil
6778}
6779
6780// unsignedStreamIntegerIterator streams inputs into the iterator and emits points gradually.
6781type unsignedStreamIntegerIterator struct {
6782	input  *bufUnsignedIterator
6783	create func() (UnsignedPointAggregator, IntegerPointEmitter)
6784	dims   []string
6785	opt    IteratorOptions
6786	m      map[string]*unsignedReduceIntegerPoint
6787	points []IntegerPoint
6788}
6789
6790// newUnsignedStreamIntegerIterator returns a new instance of unsignedStreamIntegerIterator.
6791func newUnsignedStreamIntegerIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, IntegerPointEmitter), opt IteratorOptions) *unsignedStreamIntegerIterator {
6792	return &unsignedStreamIntegerIterator{
6793		input:  newBufUnsignedIterator(input),
6794		create: createFn,
6795		dims:   opt.GetDimensions(),
6796		opt:    opt,
6797		m:      make(map[string]*unsignedReduceIntegerPoint),
6798	}
6799}
6800
6801// Stats returns stats from the input iterator.
6802func (itr *unsignedStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
6803
6804// Close closes the iterator and all child iterators.
6805func (itr *unsignedStreamIntegerIterator) Close() error { return itr.input.Close() }
6806
6807// Next returns the next value for the stream iterator.
6808func (itr *unsignedStreamIntegerIterator) Next() (*IntegerPoint, error) {
6809	// Calculate next window if we have no more points.
6810	if len(itr.points) == 0 {
6811		var err error
6812		itr.points, err = itr.reduce()
6813		if len(itr.points) == 0 {
6814			return nil, err
6815		}
6816	}
6817
6818	// Pop next point off the stack.
6819	p := &itr.points[len(itr.points)-1]
6820	itr.points = itr.points[:len(itr.points)-1]
6821	return p, nil
6822}
6823
6824// reduce creates and manages aggregators for every point from the input.
6825// After aggregating a point, it always tries to emit a value using the emitter.
6826func (itr *unsignedStreamIntegerIterator) reduce() ([]IntegerPoint, error) {
6827	// We have already read all of the input points.
6828	if itr.m == nil {
6829		return nil, nil
6830	}
6831
6832	for {
6833		// Read next point.
6834		curr, err := itr.input.Next()
6835		if err != nil {
6836			return nil, err
6837		} else if curr == nil {
6838			// Close all of the aggregators to flush any remaining points to emit.
6839			var points []IntegerPoint
6840			for _, rp := range itr.m {
6841				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
6842					if err := aggregator.Close(); err != nil {
6843						return nil, err
6844					}
6845
6846					pts := rp.Emitter.Emit()
6847					if len(pts) == 0 {
6848						continue
6849					}
6850
6851					for i := range pts {
6852						pts[i].Name = rp.Name
6853						pts[i].Tags = rp.Tags
6854					}
6855					points = append(points, pts...)
6856				}
6857			}
6858
6859			// Eliminate the aggregators and emitters.
6860			itr.m = nil
6861			return points, nil
6862		} else if curr.Nil {
6863			continue
6864		}
6865		tags := curr.Tags.Subset(itr.dims)
6866
6867		id := curr.Name
6868		if len(tags.m) > 0 {
6869			id += "\x00" + tags.ID()
6870		}
6871
6872		// Retrieve the aggregator for this name/tag combination or create one.
6873		rp := itr.m[id]
6874		if rp == nil {
6875			aggregator, emitter := itr.create()
6876			rp = &unsignedReduceIntegerPoint{
6877				Name:       curr.Name,
6878				Tags:       tags,
6879				Aggregator: aggregator,
6880				Emitter:    emitter,
6881			}
6882			itr.m[id] = rp
6883		}
6884		rp.Aggregator.AggregateUnsigned(curr)
6885
6886		// Attempt to emit points from the aggregator.
6887		points := rp.Emitter.Emit()
6888		if len(points) == 0 {
6889			continue
6890		}
6891
6892		for i := range points {
6893			points[i].Name = rp.Name
6894			points[i].Tags = rp.Tags
6895		}
6896		return points, nil
6897	}
6898}
6899
6900// unsignedReduceUnsignedIterator executes a reducer for every interval and buffers the result.
6901type unsignedReduceUnsignedIterator struct {
6902	input    *bufUnsignedIterator
6903	create   func() (UnsignedPointAggregator, UnsignedPointEmitter)
6904	dims     []string
6905	opt      IteratorOptions
6906	points   []UnsignedPoint
6907	keepTags bool
6908}
6909
6910func newUnsignedReduceUnsignedIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, UnsignedPointEmitter)) *unsignedReduceUnsignedIterator {
6911	return &unsignedReduceUnsignedIterator{
6912		input:  newBufUnsignedIterator(input),
6913		create: createFn,
6914		dims:   opt.GetDimensions(),
6915		opt:    opt,
6916	}
6917}
6918
6919// Stats returns stats from the input iterator.
6920func (itr *unsignedReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
6921
6922// Close closes the iterator and all child iterators.
6923func (itr *unsignedReduceUnsignedIterator) Close() error { return itr.input.Close() }
6924
6925// Next returns the minimum value for the next available interval.
6926func (itr *unsignedReduceUnsignedIterator) Next() (*UnsignedPoint, error) {
6927	// Calculate next window if we have no more points.
6928	if len(itr.points) == 0 {
6929		var err error
6930		itr.points, err = itr.reduce()
6931		if len(itr.points) == 0 {
6932			return nil, err
6933		}
6934	}
6935
6936	// Pop next point off the stack.
6937	p := &itr.points[len(itr.points)-1]
6938	itr.points = itr.points[:len(itr.points)-1]
6939	return p, nil
6940}
6941
6942// unsignedReduceUnsignedPoint stores the reduced data for a name/tag combination.
6943type unsignedReduceUnsignedPoint struct {
6944	Name       string
6945	Tags       Tags
6946	Aggregator UnsignedPointAggregator
6947	Emitter    UnsignedPointEmitter
6948}
6949
6950// reduce executes fn once for every point in the next window.
6951// The previous value for the dimension is passed to fn.
6952func (itr *unsignedReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) {
6953	// Calculate next window.
6954	var (
6955		startTime, endTime int64
6956		window             struct {
6957			name string
6958			tags string
6959		}
6960	)
6961	for {
6962		p, err := itr.input.Next()
6963		if err != nil || p == nil {
6964			return nil, err
6965		} else if p.Nil {
6966			continue
6967		}
6968
6969		// Unread the point so it can be processed.
6970		itr.input.unread(p)
6971		startTime, endTime = itr.opt.Window(p.Time)
6972		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
6973		break
6974	}
6975
6976	// Create points by tags.
6977	m := make(map[string]*unsignedReduceUnsignedPoint)
6978	for {
6979		// Read next point.
6980		curr, err := itr.input.NextInWindow(startTime, endTime)
6981		if err != nil {
6982			return nil, err
6983		} else if curr == nil {
6984			break
6985		} else if curr.Nil {
6986			continue
6987		} else if curr.Name != window.name {
6988			itr.input.unread(curr)
6989			break
6990		}
6991
6992		// Ensure this point is within the same final window.
6993		if curr.Name != window.name {
6994			itr.input.unread(curr)
6995			break
6996		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
6997			itr.input.unread(curr)
6998			break
6999		}
7000
7001		// Retrieve the tags on this point for this level of the query.
7002		// This may be different than the bucket dimensions.
7003		tags := curr.Tags.Subset(itr.dims)
7004		id := tags.ID()
7005
7006		// Retrieve the aggregator for this name/tag combination or create one.
7007		rp := m[id]
7008		if rp == nil {
7009			aggregator, emitter := itr.create()
7010			rp = &unsignedReduceUnsignedPoint{
7011				Name:       curr.Name,
7012				Tags:       tags,
7013				Aggregator: aggregator,
7014				Emitter:    emitter,
7015			}
7016			m[id] = rp
7017		}
7018		rp.Aggregator.AggregateUnsigned(curr)
7019	}
7020
7021	keys := make([]string, 0, len(m))
7022	for k := range m {
7023		keys = append(keys, k)
7024	}
7025
7026	// Reverse sort points by name & tag.
7027	// This ensures a consistent order of output.
7028	if len(keys) > 0 {
7029		var sorted sort.Interface = sort.StringSlice(keys)
7030		if itr.opt.Ascending {
7031			sorted = sort.Reverse(sorted)
7032		}
7033		sort.Sort(sorted)
7034	}
7035
7036	// Assume the points are already sorted until proven otherwise.
7037	sortedByTime := true
7038	// Emit the points for each name & tag combination.
7039	a := make([]UnsignedPoint, 0, len(m))
7040	for _, k := range keys {
7041		rp := m[k]
7042		points := rp.Emitter.Emit()
7043		for i := len(points) - 1; i >= 0; i-- {
7044			points[i].Name = rp.Name
7045			if !itr.keepTags {
7046				points[i].Tags = rp.Tags
7047			}
7048			// Set the points time to the interval time if the reducer didn't provide one.
7049			if points[i].Time == ZeroTime {
7050				points[i].Time = startTime
7051			} else {
7052				sortedByTime = false
7053			}
7054			a = append(a, points[i])
7055		}
7056	}
7057	// Points may be out of order. Perform a stable sort by time if requested.
7058	if !sortedByTime && itr.opt.Ordered {
7059		var sorted sort.Interface = unsignedPointsByTime(a)
7060		if itr.opt.Ascending {
7061			sorted = sort.Reverse(sorted)
7062		}
7063		sort.Stable(sorted)
7064	}
7065	return a, nil
7066}
7067
7068// unsignedStreamUnsignedIterator streams inputs into the iterator and emits points gradually.
7069type unsignedStreamUnsignedIterator struct {
7070	input  *bufUnsignedIterator
7071	create func() (UnsignedPointAggregator, UnsignedPointEmitter)
7072	dims   []string
7073	opt    IteratorOptions
7074	m      map[string]*unsignedReduceUnsignedPoint
7075	points []UnsignedPoint
7076}
7077
7078// newUnsignedStreamUnsignedIterator returns a new instance of unsignedStreamUnsignedIterator.
7079func newUnsignedStreamUnsignedIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *unsignedStreamUnsignedIterator {
7080	return &unsignedStreamUnsignedIterator{
7081		input:  newBufUnsignedIterator(input),
7082		create: createFn,
7083		dims:   opt.GetDimensions(),
7084		opt:    opt,
7085		m:      make(map[string]*unsignedReduceUnsignedPoint),
7086	}
7087}
7088
7089// Stats returns stats from the input iterator.
7090func (itr *unsignedStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
7091
7092// Close closes the iterator and all child iterators.
7093func (itr *unsignedStreamUnsignedIterator) Close() error { return itr.input.Close() }
7094
7095// Next returns the next value for the stream iterator.
7096func (itr *unsignedStreamUnsignedIterator) Next() (*UnsignedPoint, error) {
7097	// Calculate next window if we have no more points.
7098	if len(itr.points) == 0 {
7099		var err error
7100		itr.points, err = itr.reduce()
7101		if len(itr.points) == 0 {
7102			return nil, err
7103		}
7104	}
7105
7106	// Pop next point off the stack.
7107	p := &itr.points[len(itr.points)-1]
7108	itr.points = itr.points[:len(itr.points)-1]
7109	return p, nil
7110}
7111
7112// reduce creates and manages aggregators for every point from the input.
7113// After aggregating a point, it always tries to emit a value using the emitter.
7114func (itr *unsignedStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) {
7115	// We have already read all of the input points.
7116	if itr.m == nil {
7117		return nil, nil
7118	}
7119
7120	for {
7121		// Read next point.
7122		curr, err := itr.input.Next()
7123		if err != nil {
7124			return nil, err
7125		} else if curr == nil {
7126			// Close all of the aggregators to flush any remaining points to emit.
7127			var points []UnsignedPoint
7128			for _, rp := range itr.m {
7129				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
7130					if err := aggregator.Close(); err != nil {
7131						return nil, err
7132					}
7133
7134					pts := rp.Emitter.Emit()
7135					if len(pts) == 0 {
7136						continue
7137					}
7138
7139					for i := range pts {
7140						pts[i].Name = rp.Name
7141						pts[i].Tags = rp.Tags
7142					}
7143					points = append(points, pts...)
7144				}
7145			}
7146
7147			// Eliminate the aggregators and emitters.
7148			itr.m = nil
7149			return points, nil
7150		} else if curr.Nil {
7151			continue
7152		}
7153		tags := curr.Tags.Subset(itr.dims)
7154
7155		id := curr.Name
7156		if len(tags.m) > 0 {
7157			id += "\x00" + tags.ID()
7158		}
7159
7160		// Retrieve the aggregator for this name/tag combination or create one.
7161		rp := itr.m[id]
7162		if rp == nil {
7163			aggregator, emitter := itr.create()
7164			rp = &unsignedReduceUnsignedPoint{
7165				Name:       curr.Name,
7166				Tags:       tags,
7167				Aggregator: aggregator,
7168				Emitter:    emitter,
7169			}
7170			itr.m[id] = rp
7171		}
7172		rp.Aggregator.AggregateUnsigned(curr)
7173
7174		// Attempt to emit points from the aggregator.
7175		points := rp.Emitter.Emit()
7176		if len(points) == 0 {
7177			continue
7178		}
7179
7180		for i := range points {
7181			points[i].Name = rp.Name
7182			points[i].Tags = rp.Tags
7183		}
7184		return points, nil
7185	}
7186}
7187
7188// unsignedReduceStringIterator executes a reducer for every interval and buffers the result.
7189type unsignedReduceStringIterator struct {
7190	input    *bufUnsignedIterator
7191	create   func() (UnsignedPointAggregator, StringPointEmitter)
7192	dims     []string
7193	opt      IteratorOptions
7194	points   []StringPoint
7195	keepTags bool
7196}
7197
7198func newUnsignedReduceStringIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, StringPointEmitter)) *unsignedReduceStringIterator {
7199	return &unsignedReduceStringIterator{
7200		input:  newBufUnsignedIterator(input),
7201		create: createFn,
7202		dims:   opt.GetDimensions(),
7203		opt:    opt,
7204	}
7205}
7206
7207// Stats returns stats from the input iterator.
7208func (itr *unsignedReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() }
7209
7210// Close closes the iterator and all child iterators.
7211func (itr *unsignedReduceStringIterator) Close() error { return itr.input.Close() }
7212
7213// Next returns the minimum value for the next available interval.
7214func (itr *unsignedReduceStringIterator) Next() (*StringPoint, error) {
7215	// Calculate next window if we have no more points.
7216	if len(itr.points) == 0 {
7217		var err error
7218		itr.points, err = itr.reduce()
7219		if len(itr.points) == 0 {
7220			return nil, err
7221		}
7222	}
7223
7224	// Pop next point off the stack.
7225	p := &itr.points[len(itr.points)-1]
7226	itr.points = itr.points[:len(itr.points)-1]
7227	return p, nil
7228}
7229
7230// unsignedReduceStringPoint stores the reduced data for a name/tag combination.
7231type unsignedReduceStringPoint struct {
7232	Name       string
7233	Tags       Tags
7234	Aggregator UnsignedPointAggregator
7235	Emitter    StringPointEmitter
7236}
7237
7238// reduce executes fn once for every point in the next window.
7239// The previous value for the dimension is passed to fn.
7240func (itr *unsignedReduceStringIterator) reduce() ([]StringPoint, error) {
7241	// Calculate next window.
7242	var (
7243		startTime, endTime int64
7244		window             struct {
7245			name string
7246			tags string
7247		}
7248	)
7249	for {
7250		p, err := itr.input.Next()
7251		if err != nil || p == nil {
7252			return nil, err
7253		} else if p.Nil {
7254			continue
7255		}
7256
7257		// Unread the point so it can be processed.
7258		itr.input.unread(p)
7259		startTime, endTime = itr.opt.Window(p.Time)
7260		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
7261		break
7262	}
7263
7264	// Create points by tags.
7265	m := make(map[string]*unsignedReduceStringPoint)
7266	for {
7267		// Read next point.
7268		curr, err := itr.input.NextInWindow(startTime, endTime)
7269		if err != nil {
7270			return nil, err
7271		} else if curr == nil {
7272			break
7273		} else if curr.Nil {
7274			continue
7275		} else if curr.Name != window.name {
7276			itr.input.unread(curr)
7277			break
7278		}
7279
7280		// Ensure this point is within the same final window.
7281		if curr.Name != window.name {
7282			itr.input.unread(curr)
7283			break
7284		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
7285			itr.input.unread(curr)
7286			break
7287		}
7288
7289		// Retrieve the tags on this point for this level of the query.
7290		// This may be different than the bucket dimensions.
7291		tags := curr.Tags.Subset(itr.dims)
7292		id := tags.ID()
7293
7294		// Retrieve the aggregator for this name/tag combination or create one.
7295		rp := m[id]
7296		if rp == nil {
7297			aggregator, emitter := itr.create()
7298			rp = &unsignedReduceStringPoint{
7299				Name:       curr.Name,
7300				Tags:       tags,
7301				Aggregator: aggregator,
7302				Emitter:    emitter,
7303			}
7304			m[id] = rp
7305		}
7306		rp.Aggregator.AggregateUnsigned(curr)
7307	}
7308
7309	keys := make([]string, 0, len(m))
7310	for k := range m {
7311		keys = append(keys, k)
7312	}
7313
7314	// Reverse sort points by name & tag.
7315	// This ensures a consistent order of output.
7316	if len(keys) > 0 {
7317		var sorted sort.Interface = sort.StringSlice(keys)
7318		if itr.opt.Ascending {
7319			sorted = sort.Reverse(sorted)
7320		}
7321		sort.Sort(sorted)
7322	}
7323
7324	// Assume the points are already sorted until proven otherwise.
7325	sortedByTime := true
7326	// Emit the points for each name & tag combination.
7327	a := make([]StringPoint, 0, len(m))
7328	for _, k := range keys {
7329		rp := m[k]
7330		points := rp.Emitter.Emit()
7331		for i := len(points) - 1; i >= 0; i-- {
7332			points[i].Name = rp.Name
7333			if !itr.keepTags {
7334				points[i].Tags = rp.Tags
7335			}
7336			// Set the points time to the interval time if the reducer didn't provide one.
7337			if points[i].Time == ZeroTime {
7338				points[i].Time = startTime
7339			} else {
7340				sortedByTime = false
7341			}
7342			a = append(a, points[i])
7343		}
7344	}
7345	// Points may be out of order. Perform a stable sort by time if requested.
7346	if !sortedByTime && itr.opt.Ordered {
7347		var sorted sort.Interface = stringPointsByTime(a)
7348		if itr.opt.Ascending {
7349			sorted = sort.Reverse(sorted)
7350		}
7351		sort.Stable(sorted)
7352	}
7353	return a, nil
7354}
7355
7356// unsignedStreamStringIterator streams inputs into the iterator and emits points gradually.
7357type unsignedStreamStringIterator struct {
7358	input  *bufUnsignedIterator
7359	create func() (UnsignedPointAggregator, StringPointEmitter)
7360	dims   []string
7361	opt    IteratorOptions
7362	m      map[string]*unsignedReduceStringPoint
7363	points []StringPoint
7364}
7365
7366// newUnsignedStreamStringIterator returns a new instance of unsignedStreamStringIterator.
7367func newUnsignedStreamStringIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, StringPointEmitter), opt IteratorOptions) *unsignedStreamStringIterator {
7368	return &unsignedStreamStringIterator{
7369		input:  newBufUnsignedIterator(input),
7370		create: createFn,
7371		dims:   opt.GetDimensions(),
7372		opt:    opt,
7373		m:      make(map[string]*unsignedReduceStringPoint),
7374	}
7375}
7376
7377// Stats returns stats from the input iterator.
7378func (itr *unsignedStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() }
7379
7380// Close closes the iterator and all child iterators.
7381func (itr *unsignedStreamStringIterator) Close() error { return itr.input.Close() }
7382
7383// Next returns the next value for the stream iterator.
7384func (itr *unsignedStreamStringIterator) Next() (*StringPoint, error) {
7385	// Calculate next window if we have no more points.
7386	if len(itr.points) == 0 {
7387		var err error
7388		itr.points, err = itr.reduce()
7389		if len(itr.points) == 0 {
7390			return nil, err
7391		}
7392	}
7393
7394	// Pop next point off the stack.
7395	p := &itr.points[len(itr.points)-1]
7396	itr.points = itr.points[:len(itr.points)-1]
7397	return p, nil
7398}
7399
7400// reduce creates and manages aggregators for every point from the input.
7401// After aggregating a point, it always tries to emit a value using the emitter.
7402func (itr *unsignedStreamStringIterator) reduce() ([]StringPoint, error) {
7403	// We have already read all of the input points.
7404	if itr.m == nil {
7405		return nil, nil
7406	}
7407
7408	for {
7409		// Read next point.
7410		curr, err := itr.input.Next()
7411		if err != nil {
7412			return nil, err
7413		} else if curr == nil {
7414			// Close all of the aggregators to flush any remaining points to emit.
7415			var points []StringPoint
7416			for _, rp := range itr.m {
7417				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
7418					if err := aggregator.Close(); err != nil {
7419						return nil, err
7420					}
7421
7422					pts := rp.Emitter.Emit()
7423					if len(pts) == 0 {
7424						continue
7425					}
7426
7427					for i := range pts {
7428						pts[i].Name = rp.Name
7429						pts[i].Tags = rp.Tags
7430					}
7431					points = append(points, pts...)
7432				}
7433			}
7434
7435			// Eliminate the aggregators and emitters.
7436			itr.m = nil
7437			return points, nil
7438		} else if curr.Nil {
7439			continue
7440		}
7441		tags := curr.Tags.Subset(itr.dims)
7442
7443		id := curr.Name
7444		if len(tags.m) > 0 {
7445			id += "\x00" + tags.ID()
7446		}
7447
7448		// Retrieve the aggregator for this name/tag combination or create one.
7449		rp := itr.m[id]
7450		if rp == nil {
7451			aggregator, emitter := itr.create()
7452			rp = &unsignedReduceStringPoint{
7453				Name:       curr.Name,
7454				Tags:       tags,
7455				Aggregator: aggregator,
7456				Emitter:    emitter,
7457			}
7458			itr.m[id] = rp
7459		}
7460		rp.Aggregator.AggregateUnsigned(curr)
7461
7462		// Attempt to emit points from the aggregator.
7463		points := rp.Emitter.Emit()
7464		if len(points) == 0 {
7465			continue
7466		}
7467
7468		for i := range points {
7469			points[i].Name = rp.Name
7470			points[i].Tags = rp.Tags
7471		}
7472		return points, nil
7473	}
7474}
7475
7476// unsignedReduceBooleanIterator executes a reducer for every interval and buffers the result.
7477type unsignedReduceBooleanIterator struct {
7478	input    *bufUnsignedIterator
7479	create   func() (UnsignedPointAggregator, BooleanPointEmitter)
7480	dims     []string
7481	opt      IteratorOptions
7482	points   []BooleanPoint
7483	keepTags bool
7484}
7485
7486func newUnsignedReduceBooleanIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, BooleanPointEmitter)) *unsignedReduceBooleanIterator {
7487	return &unsignedReduceBooleanIterator{
7488		input:  newBufUnsignedIterator(input),
7489		create: createFn,
7490		dims:   opt.GetDimensions(),
7491		opt:    opt,
7492	}
7493}
7494
7495// Stats returns stats from the input iterator.
7496func (itr *unsignedReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
7497
7498// Close closes the iterator and all child iterators.
7499func (itr *unsignedReduceBooleanIterator) Close() error { return itr.input.Close() }
7500
7501// Next returns the minimum value for the next available interval.
7502func (itr *unsignedReduceBooleanIterator) Next() (*BooleanPoint, error) {
7503	// Calculate next window if we have no more points.
7504	if len(itr.points) == 0 {
7505		var err error
7506		itr.points, err = itr.reduce()
7507		if len(itr.points) == 0 {
7508			return nil, err
7509		}
7510	}
7511
7512	// Pop next point off the stack.
7513	p := &itr.points[len(itr.points)-1]
7514	itr.points = itr.points[:len(itr.points)-1]
7515	return p, nil
7516}
7517
7518// unsignedReduceBooleanPoint stores the reduced data for a name/tag combination.
7519type unsignedReduceBooleanPoint struct {
7520	Name       string
7521	Tags       Tags
7522	Aggregator UnsignedPointAggregator
7523	Emitter    BooleanPointEmitter
7524}
7525
7526// reduce executes fn once for every point in the next window.
7527// The previous value for the dimension is passed to fn.
7528func (itr *unsignedReduceBooleanIterator) reduce() ([]BooleanPoint, error) {
7529	// Calculate next window.
7530	var (
7531		startTime, endTime int64
7532		window             struct {
7533			name string
7534			tags string
7535		}
7536	)
7537	for {
7538		p, err := itr.input.Next()
7539		if err != nil || p == nil {
7540			return nil, err
7541		} else if p.Nil {
7542			continue
7543		}
7544
7545		// Unread the point so it can be processed.
7546		itr.input.unread(p)
7547		startTime, endTime = itr.opt.Window(p.Time)
7548		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
7549		break
7550	}
7551
7552	// Create points by tags.
7553	m := make(map[string]*unsignedReduceBooleanPoint)
7554	for {
7555		// Read next point.
7556		curr, err := itr.input.NextInWindow(startTime, endTime)
7557		if err != nil {
7558			return nil, err
7559		} else if curr == nil {
7560			break
7561		} else if curr.Nil {
7562			continue
7563		} else if curr.Name != window.name {
7564			itr.input.unread(curr)
7565			break
7566		}
7567
7568		// Ensure this point is within the same final window.
7569		if curr.Name != window.name {
7570			itr.input.unread(curr)
7571			break
7572		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
7573			itr.input.unread(curr)
7574			break
7575		}
7576
7577		// Retrieve the tags on this point for this level of the query.
7578		// This may be different than the bucket dimensions.
7579		tags := curr.Tags.Subset(itr.dims)
7580		id := tags.ID()
7581
7582		// Retrieve the aggregator for this name/tag combination or create one.
7583		rp := m[id]
7584		if rp == nil {
7585			aggregator, emitter := itr.create()
7586			rp = &unsignedReduceBooleanPoint{
7587				Name:       curr.Name,
7588				Tags:       tags,
7589				Aggregator: aggregator,
7590				Emitter:    emitter,
7591			}
7592			m[id] = rp
7593		}
7594		rp.Aggregator.AggregateUnsigned(curr)
7595	}
7596
7597	keys := make([]string, 0, len(m))
7598	for k := range m {
7599		keys = append(keys, k)
7600	}
7601
7602	// Reverse sort points by name & tag.
7603	// This ensures a consistent order of output.
7604	if len(keys) > 0 {
7605		var sorted sort.Interface = sort.StringSlice(keys)
7606		if itr.opt.Ascending {
7607			sorted = sort.Reverse(sorted)
7608		}
7609		sort.Sort(sorted)
7610	}
7611
7612	// Assume the points are already sorted until proven otherwise.
7613	sortedByTime := true
7614	// Emit the points for each name & tag combination.
7615	a := make([]BooleanPoint, 0, len(m))
7616	for _, k := range keys {
7617		rp := m[k]
7618		points := rp.Emitter.Emit()
7619		for i := len(points) - 1; i >= 0; i-- {
7620			points[i].Name = rp.Name
7621			if !itr.keepTags {
7622				points[i].Tags = rp.Tags
7623			}
7624			// Set the points time to the interval time if the reducer didn't provide one.
7625			if points[i].Time == ZeroTime {
7626				points[i].Time = startTime
7627			} else {
7628				sortedByTime = false
7629			}
7630			a = append(a, points[i])
7631		}
7632	}
7633	// Points may be out of order. Perform a stable sort by time if requested.
7634	if !sortedByTime && itr.opt.Ordered {
7635		var sorted sort.Interface = booleanPointsByTime(a)
7636		if itr.opt.Ascending {
7637			sorted = sort.Reverse(sorted)
7638		}
7639		sort.Stable(sorted)
7640	}
7641	return a, nil
7642}
7643
7644// unsignedStreamBooleanIterator streams inputs into the iterator and emits points gradually.
7645type unsignedStreamBooleanIterator struct {
7646	input  *bufUnsignedIterator
7647	create func() (UnsignedPointAggregator, BooleanPointEmitter)
7648	dims   []string
7649	opt    IteratorOptions
7650	m      map[string]*unsignedReduceBooleanPoint
7651	points []BooleanPoint
7652}
7653
7654// newUnsignedStreamBooleanIterator returns a new instance of unsignedStreamBooleanIterator.
7655func newUnsignedStreamBooleanIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, BooleanPointEmitter), opt IteratorOptions) *unsignedStreamBooleanIterator {
7656	return &unsignedStreamBooleanIterator{
7657		input:  newBufUnsignedIterator(input),
7658		create: createFn,
7659		dims:   opt.GetDimensions(),
7660		opt:    opt,
7661		m:      make(map[string]*unsignedReduceBooleanPoint),
7662	}
7663}
7664
7665// Stats returns stats from the input iterator.
7666func (itr *unsignedStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
7667
7668// Close closes the iterator and all child iterators.
7669func (itr *unsignedStreamBooleanIterator) Close() error { return itr.input.Close() }
7670
7671// Next returns the next value for the stream iterator.
7672func (itr *unsignedStreamBooleanIterator) Next() (*BooleanPoint, error) {
7673	// Calculate next window if we have no more points.
7674	if len(itr.points) == 0 {
7675		var err error
7676		itr.points, err = itr.reduce()
7677		if len(itr.points) == 0 {
7678			return nil, err
7679		}
7680	}
7681
7682	// Pop next point off the stack.
7683	p := &itr.points[len(itr.points)-1]
7684	itr.points = itr.points[:len(itr.points)-1]
7685	return p, nil
7686}
7687
7688// reduce creates and manages aggregators for every point from the input.
7689// After aggregating a point, it always tries to emit a value using the emitter.
7690func (itr *unsignedStreamBooleanIterator) reduce() ([]BooleanPoint, error) {
7691	// We have already read all of the input points.
7692	if itr.m == nil {
7693		return nil, nil
7694	}
7695
7696	for {
7697		// Read next point.
7698		curr, err := itr.input.Next()
7699		if err != nil {
7700			return nil, err
7701		} else if curr == nil {
7702			// Close all of the aggregators to flush any remaining points to emit.
7703			var points []BooleanPoint
7704			for _, rp := range itr.m {
7705				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
7706					if err := aggregator.Close(); err != nil {
7707						return nil, err
7708					}
7709
7710					pts := rp.Emitter.Emit()
7711					if len(pts) == 0 {
7712						continue
7713					}
7714
7715					for i := range pts {
7716						pts[i].Name = rp.Name
7717						pts[i].Tags = rp.Tags
7718					}
7719					points = append(points, pts...)
7720				}
7721			}
7722
7723			// Eliminate the aggregators and emitters.
7724			itr.m = nil
7725			return points, nil
7726		} else if curr.Nil {
7727			continue
7728		}
7729		tags := curr.Tags.Subset(itr.dims)
7730
7731		id := curr.Name
7732		if len(tags.m) > 0 {
7733			id += "\x00" + tags.ID()
7734		}
7735
7736		// Retrieve the aggregator for this name/tag combination or create one.
7737		rp := itr.m[id]
7738		if rp == nil {
7739			aggregator, emitter := itr.create()
7740			rp = &unsignedReduceBooleanPoint{
7741				Name:       curr.Name,
7742				Tags:       tags,
7743				Aggregator: aggregator,
7744				Emitter:    emitter,
7745			}
7746			itr.m[id] = rp
7747		}
7748		rp.Aggregator.AggregateUnsigned(curr)
7749
7750		// Attempt to emit points from the aggregator.
7751		points := rp.Emitter.Emit()
7752		if len(points) == 0 {
7753			continue
7754		}
7755
7756		for i := range points {
7757			points[i].Name = rp.Name
7758			points[i].Tags = rp.Tags
7759		}
7760		return points, nil
7761	}
7762}
7763
7764// unsignedDedupeIterator only outputs unique points.
7765// This differs from the DistinctIterator in that it compares all aux fields too.
7766// This iterator is relatively inefficient and should only be used on small
7767// datasets such as meta query results.
7768type unsignedDedupeIterator struct {
7769	input UnsignedIterator
7770	m     map[string]struct{} // lookup of points already sent
7771}
7772
7773type unsignedIteratorMapper struct {
7774	cur    Cursor
7775	row    Row
7776	driver IteratorMap   // which iterator to use for the primary value, can be nil
7777	fields []IteratorMap // which iterator to use for an aux field
7778	point  UnsignedPoint
7779}
7780
7781func newUnsignedIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *unsignedIteratorMapper {
7782	return &unsignedIteratorMapper{
7783		cur:    cur,
7784		driver: driver,
7785		fields: fields,
7786		point: UnsignedPoint{
7787			Aux: make([]interface{}, len(fields)),
7788		},
7789	}
7790}
7791
7792func (itr *unsignedIteratorMapper) Next() (*UnsignedPoint, error) {
7793	if !itr.cur.Scan(&itr.row) {
7794		if err := itr.cur.Err(); err != nil {
7795			return nil, err
7796		}
7797		return nil, nil
7798	}
7799
7800	itr.point.Time = itr.row.Time
7801	itr.point.Name = itr.row.Series.Name
7802	itr.point.Tags = itr.row.Series.Tags
7803
7804	if itr.driver != nil {
7805		if v := itr.driver.Value(&itr.row); v != nil {
7806			if v, ok := castToUnsigned(v); ok {
7807				itr.point.Value = v
7808				itr.point.Nil = false
7809			} else {
7810				itr.point.Value = 0
7811				itr.point.Nil = true
7812			}
7813		} else {
7814			itr.point.Value = 0
7815			itr.point.Nil = true
7816		}
7817	}
7818	for i, f := range itr.fields {
7819		itr.point.Aux[i] = f.Value(&itr.row)
7820	}
7821	return &itr.point, nil
7822}
7823
7824func (itr *unsignedIteratorMapper) Stats() IteratorStats {
7825	return itr.cur.Stats()
7826}
7827
7828func (itr *unsignedIteratorMapper) Close() error {
7829	return itr.cur.Close()
7830}
7831
7832type unsignedFilterIterator struct {
7833	input UnsignedIterator
7834	cond  influxql.Expr
7835	opt   IteratorOptions
7836	m     map[string]interface{}
7837}
7838
7839func newUnsignedFilterIterator(input UnsignedIterator, cond influxql.Expr, opt IteratorOptions) UnsignedIterator {
7840	// Strip out time conditions from the WHERE clause.
7841	// TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct.
7842	n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node {
7843		switch n := n.(type) {
7844		case *influxql.BinaryExpr:
7845			if n.LHS.String() == "time" {
7846				return &influxql.BooleanLiteral{Val: true}
7847			}
7848		}
7849		return n
7850	})
7851
7852	cond, _ = n.(influxql.Expr)
7853	if cond == nil {
7854		return input
7855	} else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val {
7856		return input
7857	}
7858
7859	return &unsignedFilterIterator{
7860		input: input,
7861		cond:  cond,
7862		opt:   opt,
7863		m:     make(map[string]interface{}),
7864	}
7865}
7866
7867func (itr *unsignedFilterIterator) Stats() IteratorStats { return itr.input.Stats() }
7868func (itr *unsignedFilterIterator) Close() error         { return itr.input.Close() }
7869
7870func (itr *unsignedFilterIterator) Next() (*UnsignedPoint, error) {
7871	for {
7872		p, err := itr.input.Next()
7873		if err != nil || p == nil {
7874			return nil, err
7875		}
7876
7877		for i, ref := range itr.opt.Aux {
7878			itr.m[ref.Val] = p.Aux[i]
7879		}
7880		for k, v := range p.Tags.KeyValues() {
7881			itr.m[k] = v
7882		}
7883
7884		if !influxql.EvalBool(itr.cond, itr.m) {
7885			continue
7886		}
7887		return p, nil
7888	}
7889}
7890
7891type unsignedTagSubsetIterator struct {
7892	input      UnsignedIterator
7893	point      UnsignedPoint
7894	lastTags   Tags
7895	dimensions []string
7896}
7897
7898func newUnsignedTagSubsetIterator(input UnsignedIterator, opt IteratorOptions) *unsignedTagSubsetIterator {
7899	return &unsignedTagSubsetIterator{
7900		input:      input,
7901		dimensions: opt.GetDimensions(),
7902	}
7903}
7904
7905func (itr *unsignedTagSubsetIterator) Next() (*UnsignedPoint, error) {
7906	p, err := itr.input.Next()
7907	if err != nil {
7908		return nil, err
7909	} else if p == nil {
7910		return nil, nil
7911	}
7912
7913	itr.point.Name = p.Name
7914	if !p.Tags.Equal(itr.lastTags) {
7915		itr.point.Tags = p.Tags.Subset(itr.dimensions)
7916		itr.lastTags = p.Tags
7917	}
7918	itr.point.Time = p.Time
7919	itr.point.Value = p.Value
7920	itr.point.Aux = p.Aux
7921	itr.point.Aggregated = p.Aggregated
7922	itr.point.Nil = p.Nil
7923	return &itr.point, nil
7924}
7925
7926func (itr *unsignedTagSubsetIterator) Stats() IteratorStats {
7927	return itr.input.Stats()
7928}
7929
7930func (itr *unsignedTagSubsetIterator) Close() error {
7931	return itr.input.Close()
7932}
7933
7934// newUnsignedDedupeIterator returns a new instance of unsignedDedupeIterator.
7935func newUnsignedDedupeIterator(input UnsignedIterator) *unsignedDedupeIterator {
7936	return &unsignedDedupeIterator{
7937		input: input,
7938		m:     make(map[string]struct{}),
7939	}
7940}
7941
7942// Stats returns stats from the input iterator.
7943func (itr *unsignedDedupeIterator) Stats() IteratorStats { return itr.input.Stats() }
7944
7945// Close closes the iterator and all child iterators.
7946func (itr *unsignedDedupeIterator) Close() error { return itr.input.Close() }
7947
7948// Next returns the next unique point from the input iterator.
7949func (itr *unsignedDedupeIterator) Next() (*UnsignedPoint, error) {
7950	for {
7951		// Read next point.
7952		p, err := itr.input.Next()
7953		if p == nil || err != nil {
7954			return nil, err
7955		}
7956
7957		// Serialize to bytes to store in lookup.
7958		buf, err := proto.Marshal(encodeUnsignedPoint(p))
7959		if err != nil {
7960			return nil, err
7961		}
7962
7963		// If the point has already been output then move to the next point.
7964		if _, ok := itr.m[string(buf)]; ok {
7965			continue
7966		}
7967
7968		// Otherwise mark it as emitted and return point.
7969		itr.m[string(buf)] = struct{}{}
7970		return p, nil
7971	}
7972}
7973
7974// unsignedReaderIterator represents an iterator that streams from a reader.
7975type unsignedReaderIterator struct {
7976	r   io.Reader
7977	dec *UnsignedPointDecoder
7978}
7979
7980// newUnsignedReaderIterator returns a new instance of unsignedReaderIterator.
7981func newUnsignedReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *unsignedReaderIterator {
7982	dec := NewUnsignedPointDecoder(ctx, r)
7983	dec.stats = stats
7984
7985	return &unsignedReaderIterator{
7986		r:   r,
7987		dec: dec,
7988	}
7989}
7990
7991// Stats returns stats about points processed.
7992func (itr *unsignedReaderIterator) Stats() IteratorStats { return itr.dec.stats }
7993
7994// Close closes the underlying reader, if applicable.
7995func (itr *unsignedReaderIterator) Close() error {
7996	if r, ok := itr.r.(io.ReadCloser); ok {
7997		return r.Close()
7998	}
7999	return nil
8000}
8001
8002// Next returns the next point from the iterator.
8003func (itr *unsignedReaderIterator) Next() (*UnsignedPoint, error) {
8004	// OPTIMIZE(benbjohnson): Reuse point on iterator.
8005
8006	// Unmarshal next point.
8007	p := &UnsignedPoint{}
8008	if err := itr.dec.DecodeUnsignedPoint(p); err == io.EOF {
8009		return nil, nil
8010	} else if err != nil {
8011		return nil, err
8012	}
8013	return p, nil
8014}
8015
8016// StringIterator represents a stream of string points.
8017type StringIterator interface {
8018	Iterator
8019	Next() (*StringPoint, error)
8020}
8021
8022// newStringIterators converts a slice of Iterator to a slice of StringIterator.
8023// Drop and closes any iterator in itrs that is not a StringIterator and cannot
8024// be cast to a StringIterator.
8025func newStringIterators(itrs []Iterator) []StringIterator {
8026	a := make([]StringIterator, 0, len(itrs))
8027	for _, itr := range itrs {
8028		switch itr := itr.(type) {
8029		case StringIterator:
8030			a = append(a, itr)
8031		default:
8032			itr.Close()
8033		}
8034	}
8035	return a
8036}
8037
8038// bufStringIterator represents a buffered StringIterator.
8039type bufStringIterator struct {
8040	itr StringIterator
8041	buf *StringPoint
8042}
8043
8044// newBufStringIterator returns a buffered StringIterator.
8045func newBufStringIterator(itr StringIterator) *bufStringIterator {
8046	return &bufStringIterator{itr: itr}
8047}
8048
8049// Stats returns statistics from the input iterator.
8050func (itr *bufStringIterator) Stats() IteratorStats { return itr.itr.Stats() }
8051
8052// Close closes the underlying iterator.
8053func (itr *bufStringIterator) Close() error { return itr.itr.Close() }
8054
8055// peek returns the next point without removing it from the iterator.
8056func (itr *bufStringIterator) peek() (*StringPoint, error) {
8057	p, err := itr.Next()
8058	if err != nil {
8059		return nil, err
8060	}
8061	itr.unread(p)
8062	return p, nil
8063}
8064
8065// peekTime returns the time of the next point.
8066// Returns zero time if no more points available.
8067func (itr *bufStringIterator) peekTime() (int64, error) {
8068	p, err := itr.peek()
8069	if p == nil || err != nil {
8070		return ZeroTime, err
8071	}
8072	return p.Time, nil
8073}
8074
8075// Next returns the current buffer, if exists, or calls the underlying iterator.
8076func (itr *bufStringIterator) Next() (*StringPoint, error) {
8077	buf := itr.buf
8078	if buf != nil {
8079		itr.buf = nil
8080		return buf, nil
8081	}
8082	return itr.itr.Next()
8083}
8084
8085// NextInWindow returns the next value if it is between [startTime, endTime).
8086// If the next value is outside the range then it is moved to the buffer.
8087func (itr *bufStringIterator) NextInWindow(startTime, endTime int64) (*StringPoint, error) {
8088	v, err := itr.Next()
8089	if v == nil || err != nil {
8090		return nil, err
8091	} else if t := v.Time; t >= endTime || t < startTime {
8092		itr.unread(v)
8093		return nil, nil
8094	}
8095	return v, nil
8096}
8097
8098// unread sets v to the buffer. It is read on the next call to Next().
8099func (itr *bufStringIterator) unread(v *StringPoint) { itr.buf = v }
8100
8101// stringMergeIterator represents an iterator that combines multiple string iterators.
8102type stringMergeIterator struct {
8103	inputs []StringIterator
8104	heap   *stringMergeHeap
8105	init   bool
8106
8107	closed bool
8108	mu     sync.RWMutex
8109
8110	// Current iterator and window.
8111	curr   *stringMergeHeapItem
8112	window struct {
8113		name      string
8114		tags      string
8115		startTime int64
8116		endTime   int64
8117	}
8118}
8119
8120// newStringMergeIterator returns a new instance of stringMergeIterator.
8121func newStringMergeIterator(inputs []StringIterator, opt IteratorOptions) *stringMergeIterator {
8122	itr := &stringMergeIterator{
8123		inputs: inputs,
8124		heap: &stringMergeHeap{
8125			items: make([]*stringMergeHeapItem, 0, len(inputs)),
8126			opt:   opt,
8127		},
8128	}
8129
8130	// Initialize heap items.
8131	for _, input := range inputs {
8132		// Wrap in buffer, ignore any inputs without anymore points.
8133		bufInput := newBufStringIterator(input)
8134
8135		// Append to the heap.
8136		itr.heap.items = append(itr.heap.items, &stringMergeHeapItem{itr: bufInput})
8137	}
8138
8139	return itr
8140}
8141
8142// Stats returns an aggregation of stats from the underlying iterators.
8143func (itr *stringMergeIterator) Stats() IteratorStats {
8144	var stats IteratorStats
8145	for _, input := range itr.inputs {
8146		stats.Add(input.Stats())
8147	}
8148	return stats
8149}
8150
8151// Close closes the underlying iterators.
8152func (itr *stringMergeIterator) Close() error {
8153	itr.mu.Lock()
8154	defer itr.mu.Unlock()
8155
8156	for _, input := range itr.inputs {
8157		input.Close()
8158	}
8159	itr.curr = nil
8160	itr.inputs = nil
8161	itr.heap.items = nil
8162	itr.closed = true
8163	return nil
8164}
8165
8166// Next returns the next point from the iterator.
8167func (itr *stringMergeIterator) Next() (*StringPoint, error) {
8168	itr.mu.RLock()
8169	defer itr.mu.RUnlock()
8170	if itr.closed {
8171		return nil, nil
8172	}
8173
8174	// Initialize the heap. This needs to be done lazily on the first call to this iterator
8175	// so that iterator initialization done through the Select() call returns quickly.
8176	// Queries can only be interrupted after the Select() call completes so any operations
8177	// done during iterator creation cannot be interrupted, which is why we do it here
8178	// instead so an interrupt can happen while initializing the heap.
8179	if !itr.init {
8180		items := itr.heap.items
8181		itr.heap.items = make([]*stringMergeHeapItem, 0, len(items))
8182		for _, item := range items {
8183			if p, err := item.itr.peek(); err != nil {
8184				return nil, err
8185			} else if p == nil {
8186				continue
8187			}
8188			itr.heap.items = append(itr.heap.items, item)
8189		}
8190		heap.Init(itr.heap)
8191		itr.init = true
8192	}
8193
8194	for {
8195		// Retrieve the next iterator if we don't have one.
8196		if itr.curr == nil {
8197			if len(itr.heap.items) == 0 {
8198				return nil, nil
8199			}
8200			itr.curr = heap.Pop(itr.heap).(*stringMergeHeapItem)
8201
8202			// Read point and set current window.
8203			p, err := itr.curr.itr.Next()
8204			if err != nil {
8205				return nil, err
8206			}
8207			tags := p.Tags.Subset(itr.heap.opt.Dimensions)
8208			itr.window.name, itr.window.tags = p.Name, tags.ID()
8209			itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time)
8210			return p, nil
8211		}
8212
8213		// Read the next point from the current iterator.
8214		p, err := itr.curr.itr.Next()
8215		if err != nil {
8216			return nil, err
8217		}
8218
8219		// If there are no more points then remove iterator from heap and find next.
8220		if p == nil {
8221			itr.curr = nil
8222			continue
8223		}
8224
8225		// Check if the point is inside of our current window.
8226		inWindow := true
8227		if window := itr.window; window.name != p.Name {
8228			inWindow = false
8229		} else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() {
8230			inWindow = false
8231		} else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime {
8232			inWindow = false
8233		} else if !opt.Ascending && p.Time < window.startTime {
8234			inWindow = false
8235		}
8236
8237		// If it's outside our window then push iterator back on the heap and find new iterator.
8238		if !inWindow {
8239			itr.curr.itr.unread(p)
8240			heap.Push(itr.heap, itr.curr)
8241			itr.curr = nil
8242			continue
8243		}
8244
8245		return p, nil
8246	}
8247}
8248
8249// stringMergeHeap represents a heap of stringMergeHeapItems.
8250// Items are sorted by their next window and then by name/tags.
8251type stringMergeHeap struct {
8252	opt   IteratorOptions
8253	items []*stringMergeHeapItem
8254}
8255
8256func (h *stringMergeHeap) Len() int      { return len(h.items) }
8257func (h *stringMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
8258func (h *stringMergeHeap) Less(i, j int) bool {
8259	x, err := h.items[i].itr.peek()
8260	if err != nil {
8261		return true
8262	}
8263	y, err := h.items[j].itr.peek()
8264	if err != nil {
8265		return false
8266	}
8267
8268	if h.opt.Ascending {
8269		if x.Name != y.Name {
8270			return x.Name < y.Name
8271		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
8272			return xTags.ID() < yTags.ID()
8273		}
8274	} else {
8275		if x.Name != y.Name {
8276			return x.Name > y.Name
8277		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
8278			return xTags.ID() > yTags.ID()
8279		}
8280	}
8281
8282	xt, _ := h.opt.Window(x.Time)
8283	yt, _ := h.opt.Window(y.Time)
8284
8285	if h.opt.Ascending {
8286		return xt < yt
8287	}
8288	return xt > yt
8289}
8290
8291func (h *stringMergeHeap) Push(x interface{}) {
8292	h.items = append(h.items, x.(*stringMergeHeapItem))
8293}
8294
8295func (h *stringMergeHeap) Pop() interface{} {
8296	old := h.items
8297	n := len(old)
8298	item := old[n-1]
8299	h.items = old[0 : n-1]
8300	return item
8301}
8302
8303type stringMergeHeapItem struct {
8304	itr *bufStringIterator
8305}
8306
8307// stringSortedMergeIterator is an iterator that sorts and merges multiple iterators into one.
8308type stringSortedMergeIterator struct {
8309	inputs []StringIterator
8310	heap   *stringSortedMergeHeap
8311	init   bool
8312}
8313
8314// newStringSortedMergeIterator returns an instance of stringSortedMergeIterator.
8315func newStringSortedMergeIterator(inputs []StringIterator, opt IteratorOptions) Iterator {
8316	itr := &stringSortedMergeIterator{
8317		inputs: inputs,
8318		heap: &stringSortedMergeHeap{
8319			items: make([]*stringSortedMergeHeapItem, 0, len(inputs)),
8320			opt:   opt,
8321		},
8322	}
8323
8324	// Initialize heap items.
8325	for _, input := range inputs {
8326		// Append to the heap.
8327		itr.heap.items = append(itr.heap.items, &stringSortedMergeHeapItem{itr: input})
8328	}
8329
8330	return itr
8331}
8332
8333// Stats returns an aggregation of stats from the underlying iterators.
8334func (itr *stringSortedMergeIterator) Stats() IteratorStats {
8335	var stats IteratorStats
8336	for _, input := range itr.inputs {
8337		stats.Add(input.Stats())
8338	}
8339	return stats
8340}
8341
8342// Close closes the underlying iterators.
8343func (itr *stringSortedMergeIterator) Close() error {
8344	for _, input := range itr.inputs {
8345		input.Close()
8346	}
8347	return nil
8348}
8349
8350// Next returns the next points from the iterator.
8351func (itr *stringSortedMergeIterator) Next() (*StringPoint, error) { return itr.pop() }
8352
8353// pop returns the next point from the heap.
8354// Reads the next point from item's cursor and puts it back on the heap.
8355func (itr *stringSortedMergeIterator) pop() (*StringPoint, error) {
8356	// Initialize the heap. See the MergeIterator to see why this has to be done lazily.
8357	if !itr.init {
8358		items := itr.heap.items
8359		itr.heap.items = make([]*stringSortedMergeHeapItem, 0, len(items))
8360		for _, item := range items {
8361			var err error
8362			if item.point, err = item.itr.Next(); err != nil {
8363				return nil, err
8364			} else if item.point == nil {
8365				continue
8366			}
8367			itr.heap.items = append(itr.heap.items, item)
8368		}
8369		heap.Init(itr.heap)
8370		itr.init = true
8371	}
8372
8373	if len(itr.heap.items) == 0 {
8374		return nil, nil
8375	}
8376
8377	// Read the next item from the heap.
8378	item := heap.Pop(itr.heap).(*stringSortedMergeHeapItem)
8379	if item.err != nil {
8380		return nil, item.err
8381	} else if item.point == nil {
8382		return nil, nil
8383	}
8384
8385	// Copy the point for return.
8386	p := item.point.Clone()
8387
8388	// Read the next item from the cursor. Push back to heap if one exists.
8389	if item.point, item.err = item.itr.Next(); item.point != nil {
8390		heap.Push(itr.heap, item)
8391	}
8392
8393	return p, nil
8394}
8395
8396// stringSortedMergeHeap represents a heap of stringSortedMergeHeapItems.
8397// Items are sorted with the following priority:
8398//     - By their measurement name;
8399//     - By their tag keys/values;
8400//     - By time; or
8401//     - By their Aux field values.
8402//
8403type stringSortedMergeHeap struct {
8404	opt   IteratorOptions
8405	items []*stringSortedMergeHeapItem
8406}
8407
8408func (h *stringSortedMergeHeap) Len() int      { return len(h.items) }
8409func (h *stringSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
8410func (h *stringSortedMergeHeap) Less(i, j int) bool {
8411	x, y := h.items[i].point, h.items[j].point
8412
8413	if h.opt.Ascending {
8414		if x.Name != y.Name {
8415			return x.Name < y.Name
8416		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
8417			return xTags.ID() < yTags.ID()
8418		}
8419
8420		if x.Time != y.Time {
8421			return x.Time < y.Time
8422		}
8423
8424		if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
8425			for i := 0; i < len(x.Aux); i++ {
8426				v1, ok1 := x.Aux[i].(string)
8427				v2, ok2 := y.Aux[i].(string)
8428				if !ok1 || !ok2 {
8429					// Unsupported types used in Aux fields. Maybe they
8430					// need to be added here?
8431					return false
8432				} else if v1 == v2 {
8433					continue
8434				}
8435				return v1 < v2
8436			}
8437		}
8438		return false // Times and/or Aux fields are equal.
8439	}
8440
8441	if x.Name != y.Name {
8442		return x.Name > y.Name
8443	} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
8444		return xTags.ID() > yTags.ID()
8445	}
8446
8447	if x.Time != y.Time {
8448		return x.Time > y.Time
8449	}
8450
8451	if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
8452		for i := 0; i < len(x.Aux); i++ {
8453			v1, ok1 := x.Aux[i].(string)
8454			v2, ok2 := y.Aux[i].(string)
8455			if !ok1 || !ok2 {
8456				// Unsupported types used in Aux fields. Maybe they
8457				// need to be added here?
8458				return false
8459			} else if v1 == v2 {
8460				continue
8461			}
8462			return v1 > v2
8463		}
8464	}
8465	return false // Times and/or Aux fields are equal.
8466}
8467
8468func (h *stringSortedMergeHeap) Push(x interface{}) {
8469	h.items = append(h.items, x.(*stringSortedMergeHeapItem))
8470}
8471
8472func (h *stringSortedMergeHeap) Pop() interface{} {
8473	old := h.items
8474	n := len(old)
8475	item := old[n-1]
8476	h.items = old[0 : n-1]
8477	return item
8478}
8479
8480type stringSortedMergeHeapItem struct {
8481	point *StringPoint
8482	err   error
8483	itr   StringIterator
8484}
8485
8486// stringIteratorScanner scans the results of a StringIterator into a map.
8487type stringIteratorScanner struct {
8488	input        *bufStringIterator
8489	err          error
8490	keys         []influxql.VarRef
8491	defaultValue interface{}
8492}
8493
8494// newStringIteratorScanner creates a new IteratorScanner.
8495func newStringIteratorScanner(input StringIterator, keys []influxql.VarRef, defaultValue interface{}) *stringIteratorScanner {
8496	return &stringIteratorScanner{
8497		input:        newBufStringIterator(input),
8498		keys:         keys,
8499		defaultValue: defaultValue,
8500	}
8501}
8502
8503func (s *stringIteratorScanner) Peek() (int64, string, Tags) {
8504	if s.err != nil {
8505		return ZeroTime, "", Tags{}
8506	}
8507
8508	p, err := s.input.peek()
8509	if err != nil {
8510		s.err = err
8511		return ZeroTime, "", Tags{}
8512	} else if p == nil {
8513		return ZeroTime, "", Tags{}
8514	}
8515	return p.Time, p.Name, p.Tags
8516}
8517
8518func (s *stringIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) {
8519	if s.err != nil {
8520		return
8521	}
8522
8523	p, err := s.input.Next()
8524	if err != nil {
8525		s.err = err
8526		return
8527	} else if p == nil {
8528		s.useDefaults(m)
8529		return
8530	} else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) {
8531		s.useDefaults(m)
8532		s.input.unread(p)
8533		return
8534	}
8535
8536	if k := s.keys[0]; k.Val != "" {
8537		if p.Nil {
8538			if s.defaultValue != SkipDefault {
8539				m[k.Val] = castToType(s.defaultValue, k.Type)
8540			}
8541		} else {
8542			m[k.Val] = p.Value
8543		}
8544	}
8545	for i, v := range p.Aux {
8546		k := s.keys[i+1]
8547		switch v.(type) {
8548		case float64, int64, uint64, string, bool:
8549			m[k.Val] = v
8550		default:
8551			// Insert the fill value if one was specified.
8552			if s.defaultValue != SkipDefault {
8553				m[k.Val] = castToType(s.defaultValue, k.Type)
8554			}
8555		}
8556	}
8557}
8558
8559func (s *stringIteratorScanner) useDefaults(m map[string]interface{}) {
8560	if s.defaultValue == SkipDefault {
8561		return
8562	}
8563	for _, k := range s.keys {
8564		if k.Val == "" {
8565			continue
8566		}
8567		m[k.Val] = castToType(s.defaultValue, k.Type)
8568	}
8569}
8570
8571func (s *stringIteratorScanner) Stats() IteratorStats { return s.input.Stats() }
8572func (s *stringIteratorScanner) Err() error           { return s.err }
8573func (s *stringIteratorScanner) Close() error         { return s.input.Close() }
8574
8575// stringParallelIterator represents an iterator that pulls data in a separate goroutine.
8576type stringParallelIterator struct {
8577	input StringIterator
8578	ch    chan stringPointError
8579
8580	once    sync.Once
8581	closing chan struct{}
8582	wg      sync.WaitGroup
8583}
8584
8585// newStringParallelIterator returns a new instance of stringParallelIterator.
8586func newStringParallelIterator(input StringIterator) *stringParallelIterator {
8587	itr := &stringParallelIterator{
8588		input:   input,
8589		ch:      make(chan stringPointError, 256),
8590		closing: make(chan struct{}),
8591	}
8592	itr.wg.Add(1)
8593	go itr.monitor()
8594	return itr
8595}
8596
8597// Stats returns stats from the underlying iterator.
8598func (itr *stringParallelIterator) Stats() IteratorStats { return itr.input.Stats() }
8599
8600// Close closes the underlying iterators.
8601func (itr *stringParallelIterator) Close() error {
8602	itr.once.Do(func() { close(itr.closing) })
8603	itr.wg.Wait()
8604	return itr.input.Close()
8605}
8606
8607// Next returns the next point from the iterator.
8608func (itr *stringParallelIterator) Next() (*StringPoint, error) {
8609	v, ok := <-itr.ch
8610	if !ok {
8611		return nil, io.EOF
8612	}
8613	return v.point, v.err
8614}
8615
8616// monitor runs in a separate goroutine and actively pulls the next point.
8617func (itr *stringParallelIterator) monitor() {
8618	defer close(itr.ch)
8619	defer itr.wg.Done()
8620
8621	for {
8622		// Read next point.
8623		p, err := itr.input.Next()
8624		if p != nil {
8625			p = p.Clone()
8626		}
8627
8628		select {
8629		case <-itr.closing:
8630			return
8631		case itr.ch <- stringPointError{point: p, err: err}:
8632		}
8633	}
8634}
8635
8636type stringPointError struct {
8637	point *StringPoint
8638	err   error
8639}
8640
8641// stringLimitIterator represents an iterator that limits points per group.
8642type stringLimitIterator struct {
8643	input StringIterator
8644	opt   IteratorOptions
8645	n     int
8646
8647	prev struct {
8648		name string
8649		tags Tags
8650	}
8651}
8652
8653// newStringLimitIterator returns a new instance of stringLimitIterator.
8654func newStringLimitIterator(input StringIterator, opt IteratorOptions) *stringLimitIterator {
8655	return &stringLimitIterator{
8656		input: input,
8657		opt:   opt,
8658	}
8659}
8660
8661// Stats returns stats from the underlying iterator.
8662func (itr *stringLimitIterator) Stats() IteratorStats { return itr.input.Stats() }
8663
8664// Close closes the underlying iterators.
8665func (itr *stringLimitIterator) Close() error { return itr.input.Close() }
8666
8667// Next returns the next point from the iterator.
8668func (itr *stringLimitIterator) Next() (*StringPoint, error) {
8669	for {
8670		p, err := itr.input.Next()
8671		if p == nil || err != nil {
8672			return nil, err
8673		}
8674
8675		// Reset window and counter if a new window is encountered.
8676		if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) {
8677			itr.prev.name = p.Name
8678			itr.prev.tags = p.Tags
8679			itr.n = 0
8680		}
8681
8682		// Increment counter.
8683		itr.n++
8684
8685		// Read next point if not beyond the offset.
8686		if itr.n <= itr.opt.Offset {
8687			continue
8688		}
8689
8690		// Read next point if we're beyond the limit.
8691		if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit {
8692			continue
8693		}
8694
8695		return p, nil
8696	}
8697}
8698
8699type stringFillIterator struct {
8700	input     *bufStringIterator
8701	prev      StringPoint
8702	startTime int64
8703	endTime   int64
8704	auxFields []interface{}
8705	init      bool
8706	opt       IteratorOptions
8707
8708	window struct {
8709		name   string
8710		tags   Tags
8711		time   int64
8712		offset int64
8713	}
8714}
8715
8716func newStringFillIterator(input StringIterator, expr influxql.Expr, opt IteratorOptions) *stringFillIterator {
8717	if opt.Fill == influxql.NullFill {
8718		if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" {
8719			opt.Fill = influxql.NumberFill
8720			opt.FillValue = ""
8721		}
8722	}
8723
8724	var startTime, endTime int64
8725	if opt.Ascending {
8726		startTime, _ = opt.Window(opt.StartTime)
8727		endTime, _ = opt.Window(opt.EndTime)
8728	} else {
8729		startTime, _ = opt.Window(opt.EndTime)
8730		endTime, _ = opt.Window(opt.StartTime)
8731	}
8732
8733	var auxFields []interface{}
8734	if len(opt.Aux) > 0 {
8735		auxFields = make([]interface{}, len(opt.Aux))
8736	}
8737
8738	return &stringFillIterator{
8739		input:     newBufStringIterator(input),
8740		prev:      StringPoint{Nil: true},
8741		startTime: startTime,
8742		endTime:   endTime,
8743		auxFields: auxFields,
8744		opt:       opt,
8745	}
8746}
8747
8748func (itr *stringFillIterator) Stats() IteratorStats { return itr.input.Stats() }
8749func (itr *stringFillIterator) Close() error         { return itr.input.Close() }
8750
8751func (itr *stringFillIterator) Next() (*StringPoint, error) {
8752	if !itr.init {
8753		p, err := itr.input.peek()
8754		if p == nil || err != nil {
8755			return nil, err
8756		}
8757		itr.window.name, itr.window.tags = p.Name, p.Tags
8758		itr.window.time = itr.startTime
8759		if itr.startTime == influxql.MinTime {
8760			itr.window.time, _ = itr.opt.Window(p.Time)
8761		}
8762		if itr.opt.Location != nil {
8763			_, itr.window.offset = itr.opt.Zone(itr.window.time)
8764		}
8765		itr.init = true
8766	}
8767
8768	p, err := itr.input.Next()
8769	if err != nil {
8770		return nil, err
8771	}
8772
8773	// Check if the next point is outside of our window or is nil.
8774	if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() {
8775		// If we are inside of an interval, unread the point and continue below to
8776		// constructing a new point.
8777		if itr.opt.Ascending && itr.window.time <= itr.endTime {
8778			itr.input.unread(p)
8779			p = nil
8780			goto CONSTRUCT
8781		} else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime {
8782			itr.input.unread(p)
8783			p = nil
8784			goto CONSTRUCT
8785		}
8786
8787		// We are *not* in a current interval. If there is no next point,
8788		// we are at the end of all intervals.
8789		if p == nil {
8790			return nil, nil
8791		}
8792
8793		// Set the new interval.
8794		itr.window.name, itr.window.tags = p.Name, p.Tags
8795		itr.window.time = itr.startTime
8796		if itr.window.time == influxql.MinTime {
8797			itr.window.time, _ = itr.opt.Window(p.Time)
8798		}
8799		if itr.opt.Location != nil {
8800			_, itr.window.offset = itr.opt.Zone(itr.window.time)
8801		}
8802		itr.prev = StringPoint{Nil: true}
8803	}
8804
8805	// Check if the point is our next expected point.
8806CONSTRUCT:
8807	if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) {
8808		if p != nil {
8809			itr.input.unread(p)
8810		}
8811
8812		p = &StringPoint{
8813			Name: itr.window.name,
8814			Tags: itr.window.tags,
8815			Time: itr.window.time,
8816			Aux:  itr.auxFields,
8817		}
8818
8819		switch itr.opt.Fill {
8820		case influxql.LinearFill:
8821			fallthrough
8822		case influxql.NullFill:
8823			p.Nil = true
8824		case influxql.NumberFill:
8825			p.Value, _ = castToString(itr.opt.FillValue)
8826		case influxql.PreviousFill:
8827			if !itr.prev.Nil {
8828				p.Value = itr.prev.Value
8829				p.Nil = itr.prev.Nil
8830			} else {
8831				p.Nil = true
8832			}
8833		}
8834	} else {
8835		itr.prev = *p
8836	}
8837
8838	// Advance the expected time. Do not advance to a new window here
8839	// as there may be lingering points with the same timestamp in the previous
8840	// window.
8841	if itr.opt.Ascending {
8842		itr.window.time += int64(itr.opt.Interval.Duration)
8843	} else {
8844		itr.window.time -= int64(itr.opt.Interval.Duration)
8845	}
8846
8847	// Check to see if we have passed over an offset change and adjust the time
8848	// to account for this new offset.
8849	if itr.opt.Location != nil {
8850		if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset {
8851			diff := itr.window.offset - offset
8852			if abs(diff) < int64(itr.opt.Interval.Duration) {
8853				itr.window.time += diff
8854			}
8855			itr.window.offset = offset
8856		}
8857	}
8858	return p, nil
8859}
8860
8861// stringIntervalIterator represents a string implementation of IntervalIterator.
8862type stringIntervalIterator struct {
8863	input StringIterator
8864	opt   IteratorOptions
8865}
8866
8867func newStringIntervalIterator(input StringIterator, opt IteratorOptions) *stringIntervalIterator {
8868	return &stringIntervalIterator{input: input, opt: opt}
8869}
8870
8871func (itr *stringIntervalIterator) Stats() IteratorStats { return itr.input.Stats() }
8872func (itr *stringIntervalIterator) Close() error         { return itr.input.Close() }
8873
8874func (itr *stringIntervalIterator) Next() (*StringPoint, error) {
8875	p, err := itr.input.Next()
8876	if p == nil || err != nil {
8877		return nil, err
8878	}
8879	p.Time, _ = itr.opt.Window(p.Time)
8880	// If we see the minimum allowable time, set the time to zero so we don't
8881	// break the default returned time for aggregate queries without times.
8882	if p.Time == influxql.MinTime {
8883		p.Time = 0
8884	}
8885	return p, nil
8886}
8887
8888// stringInterruptIterator represents a string implementation of InterruptIterator.
8889type stringInterruptIterator struct {
8890	input   StringIterator
8891	closing <-chan struct{}
8892	count   int
8893}
8894
8895func newStringInterruptIterator(input StringIterator, closing <-chan struct{}) *stringInterruptIterator {
8896	return &stringInterruptIterator{input: input, closing: closing}
8897}
8898
8899func (itr *stringInterruptIterator) Stats() IteratorStats { return itr.input.Stats() }
8900func (itr *stringInterruptIterator) Close() error         { return itr.input.Close() }
8901
8902func (itr *stringInterruptIterator) Next() (*StringPoint, error) {
8903	// Only check if the channel is closed every N points. This
8904	// intentionally checks on both 0 and N so that if the iterator
8905	// has been interrupted before the first point is emitted it will
8906	// not emit any points.
8907	if itr.count&0xFF == 0xFF {
8908		select {
8909		case <-itr.closing:
8910			return nil, itr.Close()
8911		default:
8912			// Reset iterator count to zero and fall through to emit the next point.
8913			itr.count = 0
8914		}
8915	}
8916
8917	// Increment the counter for every point read.
8918	itr.count++
8919	return itr.input.Next()
8920}
8921
8922// stringCloseInterruptIterator represents a string implementation of CloseInterruptIterator.
8923type stringCloseInterruptIterator struct {
8924	input   StringIterator
8925	closing <-chan struct{}
8926	done    chan struct{}
8927	once    sync.Once
8928}
8929
8930func newStringCloseInterruptIterator(input StringIterator, closing <-chan struct{}) *stringCloseInterruptIterator {
8931	itr := &stringCloseInterruptIterator{
8932		input:   input,
8933		closing: closing,
8934		done:    make(chan struct{}),
8935	}
8936	go itr.monitor()
8937	return itr
8938}
8939
8940func (itr *stringCloseInterruptIterator) monitor() {
8941	select {
8942	case <-itr.closing:
8943		itr.Close()
8944	case <-itr.done:
8945	}
8946}
8947
8948func (itr *stringCloseInterruptIterator) Stats() IteratorStats {
8949	return itr.input.Stats()
8950}
8951
8952func (itr *stringCloseInterruptIterator) Close() error {
8953	itr.once.Do(func() {
8954		close(itr.done)
8955		itr.input.Close()
8956	})
8957	return nil
8958}
8959
8960func (itr *stringCloseInterruptIterator) Next() (*StringPoint, error) {
8961	p, err := itr.input.Next()
8962	if err != nil {
8963		// Check if the iterator was closed.
8964		select {
8965		case <-itr.done:
8966			return nil, nil
8967		default:
8968			return nil, err
8969		}
8970	}
8971	return p, nil
8972}
8973
8974// stringReduceFloatIterator executes a reducer for every interval and buffers the result.
8975type stringReduceFloatIterator struct {
8976	input    *bufStringIterator
8977	create   func() (StringPointAggregator, FloatPointEmitter)
8978	dims     []string
8979	opt      IteratorOptions
8980	points   []FloatPoint
8981	keepTags bool
8982}
8983
8984func newStringReduceFloatIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, FloatPointEmitter)) *stringReduceFloatIterator {
8985	return &stringReduceFloatIterator{
8986		input:  newBufStringIterator(input),
8987		create: createFn,
8988		dims:   opt.GetDimensions(),
8989		opt:    opt,
8990	}
8991}
8992
8993// Stats returns stats from the input iterator.
8994func (itr *stringReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
8995
8996// Close closes the iterator and all child iterators.
8997func (itr *stringReduceFloatIterator) Close() error { return itr.input.Close() }
8998
8999// Next returns the minimum value for the next available interval.
9000func (itr *stringReduceFloatIterator) Next() (*FloatPoint, error) {
9001	// Calculate next window if we have no more points.
9002	if len(itr.points) == 0 {
9003		var err error
9004		itr.points, err = itr.reduce()
9005		if len(itr.points) == 0 {
9006			return nil, err
9007		}
9008	}
9009
9010	// Pop next point off the stack.
9011	p := &itr.points[len(itr.points)-1]
9012	itr.points = itr.points[:len(itr.points)-1]
9013	return p, nil
9014}
9015
9016// stringReduceFloatPoint stores the reduced data for a name/tag combination.
9017type stringReduceFloatPoint struct {
9018	Name       string
9019	Tags       Tags
9020	Aggregator StringPointAggregator
9021	Emitter    FloatPointEmitter
9022}
9023
9024// reduce executes fn once for every point in the next window.
9025// The previous value for the dimension is passed to fn.
9026func (itr *stringReduceFloatIterator) reduce() ([]FloatPoint, error) {
9027	// Calculate next window.
9028	var (
9029		startTime, endTime int64
9030		window             struct {
9031			name string
9032			tags string
9033		}
9034	)
9035	for {
9036		p, err := itr.input.Next()
9037		if err != nil || p == nil {
9038			return nil, err
9039		} else if p.Nil {
9040			continue
9041		}
9042
9043		// Unread the point so it can be processed.
9044		itr.input.unread(p)
9045		startTime, endTime = itr.opt.Window(p.Time)
9046		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
9047		break
9048	}
9049
9050	// Create points by tags.
9051	m := make(map[string]*stringReduceFloatPoint)
9052	for {
9053		// Read next point.
9054		curr, err := itr.input.NextInWindow(startTime, endTime)
9055		if err != nil {
9056			return nil, err
9057		} else if curr == nil {
9058			break
9059		} else if curr.Nil {
9060			continue
9061		} else if curr.Name != window.name {
9062			itr.input.unread(curr)
9063			break
9064		}
9065
9066		// Ensure this point is within the same final window.
9067		if curr.Name != window.name {
9068			itr.input.unread(curr)
9069			break
9070		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
9071			itr.input.unread(curr)
9072			break
9073		}
9074
9075		// Retrieve the tags on this point for this level of the query.
9076		// This may be different than the bucket dimensions.
9077		tags := curr.Tags.Subset(itr.dims)
9078		id := tags.ID()
9079
9080		// Retrieve the aggregator for this name/tag combination or create one.
9081		rp := m[id]
9082		if rp == nil {
9083			aggregator, emitter := itr.create()
9084			rp = &stringReduceFloatPoint{
9085				Name:       curr.Name,
9086				Tags:       tags,
9087				Aggregator: aggregator,
9088				Emitter:    emitter,
9089			}
9090			m[id] = rp
9091		}
9092		rp.Aggregator.AggregateString(curr)
9093	}
9094
9095	keys := make([]string, 0, len(m))
9096	for k := range m {
9097		keys = append(keys, k)
9098	}
9099
9100	// Reverse sort points by name & tag.
9101	// This ensures a consistent order of output.
9102	if len(keys) > 0 {
9103		var sorted sort.Interface = sort.StringSlice(keys)
9104		if itr.opt.Ascending {
9105			sorted = sort.Reverse(sorted)
9106		}
9107		sort.Sort(sorted)
9108	}
9109
9110	// Assume the points are already sorted until proven otherwise.
9111	sortedByTime := true
9112	// Emit the points for each name & tag combination.
9113	a := make([]FloatPoint, 0, len(m))
9114	for _, k := range keys {
9115		rp := m[k]
9116		points := rp.Emitter.Emit()
9117		for i := len(points) - 1; i >= 0; i-- {
9118			points[i].Name = rp.Name
9119			if !itr.keepTags {
9120				points[i].Tags = rp.Tags
9121			}
9122			// Set the points time to the interval time if the reducer didn't provide one.
9123			if points[i].Time == ZeroTime {
9124				points[i].Time = startTime
9125			} else {
9126				sortedByTime = false
9127			}
9128			a = append(a, points[i])
9129		}
9130	}
9131	// Points may be out of order. Perform a stable sort by time if requested.
9132	if !sortedByTime && itr.opt.Ordered {
9133		var sorted sort.Interface = floatPointsByTime(a)
9134		if itr.opt.Ascending {
9135			sorted = sort.Reverse(sorted)
9136		}
9137		sort.Stable(sorted)
9138	}
9139	return a, nil
9140}
9141
9142// stringStreamFloatIterator streams inputs into the iterator and emits points gradually.
9143type stringStreamFloatIterator struct {
9144	input  *bufStringIterator
9145	create func() (StringPointAggregator, FloatPointEmitter)
9146	dims   []string
9147	opt    IteratorOptions
9148	m      map[string]*stringReduceFloatPoint
9149	points []FloatPoint
9150}
9151
9152// newStringStreamFloatIterator returns a new instance of stringStreamFloatIterator.
9153func newStringStreamFloatIterator(input StringIterator, createFn func() (StringPointAggregator, FloatPointEmitter), opt IteratorOptions) *stringStreamFloatIterator {
9154	return &stringStreamFloatIterator{
9155		input:  newBufStringIterator(input),
9156		create: createFn,
9157		dims:   opt.GetDimensions(),
9158		opt:    opt,
9159		m:      make(map[string]*stringReduceFloatPoint),
9160	}
9161}
9162
9163// Stats returns stats from the input iterator.
9164func (itr *stringStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
9165
9166// Close closes the iterator and all child iterators.
9167func (itr *stringStreamFloatIterator) Close() error { return itr.input.Close() }
9168
9169// Next returns the next value for the stream iterator.
9170func (itr *stringStreamFloatIterator) Next() (*FloatPoint, error) {
9171	// Calculate next window if we have no more points.
9172	if len(itr.points) == 0 {
9173		var err error
9174		itr.points, err = itr.reduce()
9175		if len(itr.points) == 0 {
9176			return nil, err
9177		}
9178	}
9179
9180	// Pop next point off the stack.
9181	p := &itr.points[len(itr.points)-1]
9182	itr.points = itr.points[:len(itr.points)-1]
9183	return p, nil
9184}
9185
9186// reduce creates and manages aggregators for every point from the input.
9187// After aggregating a point, it always tries to emit a value using the emitter.
9188func (itr *stringStreamFloatIterator) reduce() ([]FloatPoint, error) {
9189	// We have already read all of the input points.
9190	if itr.m == nil {
9191		return nil, nil
9192	}
9193
9194	for {
9195		// Read next point.
9196		curr, err := itr.input.Next()
9197		if err != nil {
9198			return nil, err
9199		} else if curr == nil {
9200			// Close all of the aggregators to flush any remaining points to emit.
9201			var points []FloatPoint
9202			for _, rp := range itr.m {
9203				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
9204					if err := aggregator.Close(); err != nil {
9205						return nil, err
9206					}
9207
9208					pts := rp.Emitter.Emit()
9209					if len(pts) == 0 {
9210						continue
9211					}
9212
9213					for i := range pts {
9214						pts[i].Name = rp.Name
9215						pts[i].Tags = rp.Tags
9216					}
9217					points = append(points, pts...)
9218				}
9219			}
9220
9221			// Eliminate the aggregators and emitters.
9222			itr.m = nil
9223			return points, nil
9224		} else if curr.Nil {
9225			continue
9226		}
9227		tags := curr.Tags.Subset(itr.dims)
9228
9229		id := curr.Name
9230		if len(tags.m) > 0 {
9231			id += "\x00" + tags.ID()
9232		}
9233
9234		// Retrieve the aggregator for this name/tag combination or create one.
9235		rp := itr.m[id]
9236		if rp == nil {
9237			aggregator, emitter := itr.create()
9238			rp = &stringReduceFloatPoint{
9239				Name:       curr.Name,
9240				Tags:       tags,
9241				Aggregator: aggregator,
9242				Emitter:    emitter,
9243			}
9244			itr.m[id] = rp
9245		}
9246		rp.Aggregator.AggregateString(curr)
9247
9248		// Attempt to emit points from the aggregator.
9249		points := rp.Emitter.Emit()
9250		if len(points) == 0 {
9251			continue
9252		}
9253
9254		for i := range points {
9255			points[i].Name = rp.Name
9256			points[i].Tags = rp.Tags
9257		}
9258		return points, nil
9259	}
9260}
9261
9262// stringReduceIntegerIterator executes a reducer for every interval and buffers the result.
9263type stringReduceIntegerIterator struct {
9264	input    *bufStringIterator
9265	create   func() (StringPointAggregator, IntegerPointEmitter)
9266	dims     []string
9267	opt      IteratorOptions
9268	points   []IntegerPoint
9269	keepTags bool
9270}
9271
9272func newStringReduceIntegerIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, IntegerPointEmitter)) *stringReduceIntegerIterator {
9273	return &stringReduceIntegerIterator{
9274		input:  newBufStringIterator(input),
9275		create: createFn,
9276		dims:   opt.GetDimensions(),
9277		opt:    opt,
9278	}
9279}
9280
9281// Stats returns stats from the input iterator.
9282func (itr *stringReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
9283
9284// Close closes the iterator and all child iterators.
9285func (itr *stringReduceIntegerIterator) Close() error { return itr.input.Close() }
9286
9287// Next returns the minimum value for the next available interval.
9288func (itr *stringReduceIntegerIterator) Next() (*IntegerPoint, error) {
9289	// Calculate next window if we have no more points.
9290	if len(itr.points) == 0 {
9291		var err error
9292		itr.points, err = itr.reduce()
9293		if len(itr.points) == 0 {
9294			return nil, err
9295		}
9296	}
9297
9298	// Pop next point off the stack.
9299	p := &itr.points[len(itr.points)-1]
9300	itr.points = itr.points[:len(itr.points)-1]
9301	return p, nil
9302}
9303
9304// stringReduceIntegerPoint stores the reduced data for a name/tag combination.
9305type stringReduceIntegerPoint struct {
9306	Name       string
9307	Tags       Tags
9308	Aggregator StringPointAggregator
9309	Emitter    IntegerPointEmitter
9310}
9311
9312// reduce executes fn once for every point in the next window.
9313// The previous value for the dimension is passed to fn.
9314func (itr *stringReduceIntegerIterator) reduce() ([]IntegerPoint, error) {
9315	// Calculate next window.
9316	var (
9317		startTime, endTime int64
9318		window             struct {
9319			name string
9320			tags string
9321		}
9322	)
9323	for {
9324		p, err := itr.input.Next()
9325		if err != nil || p == nil {
9326			return nil, err
9327		} else if p.Nil {
9328			continue
9329		}
9330
9331		// Unread the point so it can be processed.
9332		itr.input.unread(p)
9333		startTime, endTime = itr.opt.Window(p.Time)
9334		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
9335		break
9336	}
9337
9338	// Create points by tags.
9339	m := make(map[string]*stringReduceIntegerPoint)
9340	for {
9341		// Read next point.
9342		curr, err := itr.input.NextInWindow(startTime, endTime)
9343		if err != nil {
9344			return nil, err
9345		} else if curr == nil {
9346			break
9347		} else if curr.Nil {
9348			continue
9349		} else if curr.Name != window.name {
9350			itr.input.unread(curr)
9351			break
9352		}
9353
9354		// Ensure this point is within the same final window.
9355		if curr.Name != window.name {
9356			itr.input.unread(curr)
9357			break
9358		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
9359			itr.input.unread(curr)
9360			break
9361		}
9362
9363		// Retrieve the tags on this point for this level of the query.
9364		// This may be different than the bucket dimensions.
9365		tags := curr.Tags.Subset(itr.dims)
9366		id := tags.ID()
9367
9368		// Retrieve the aggregator for this name/tag combination or create one.
9369		rp := m[id]
9370		if rp == nil {
9371			aggregator, emitter := itr.create()
9372			rp = &stringReduceIntegerPoint{
9373				Name:       curr.Name,
9374				Tags:       tags,
9375				Aggregator: aggregator,
9376				Emitter:    emitter,
9377			}
9378			m[id] = rp
9379		}
9380		rp.Aggregator.AggregateString(curr)
9381	}
9382
9383	keys := make([]string, 0, len(m))
9384	for k := range m {
9385		keys = append(keys, k)
9386	}
9387
9388	// Reverse sort points by name & tag.
9389	// This ensures a consistent order of output.
9390	if len(keys) > 0 {
9391		var sorted sort.Interface = sort.StringSlice(keys)
9392		if itr.opt.Ascending {
9393			sorted = sort.Reverse(sorted)
9394		}
9395		sort.Sort(sorted)
9396	}
9397
9398	// Assume the points are already sorted until proven otherwise.
9399	sortedByTime := true
9400	// Emit the points for each name & tag combination.
9401	a := make([]IntegerPoint, 0, len(m))
9402	for _, k := range keys {
9403		rp := m[k]
9404		points := rp.Emitter.Emit()
9405		for i := len(points) - 1; i >= 0; i-- {
9406			points[i].Name = rp.Name
9407			if !itr.keepTags {
9408				points[i].Tags = rp.Tags
9409			}
9410			// Set the points time to the interval time if the reducer didn't provide one.
9411			if points[i].Time == ZeroTime {
9412				points[i].Time = startTime
9413			} else {
9414				sortedByTime = false
9415			}
9416			a = append(a, points[i])
9417		}
9418	}
9419	// Points may be out of order. Perform a stable sort by time if requested.
9420	if !sortedByTime && itr.opt.Ordered {
9421		var sorted sort.Interface = integerPointsByTime(a)
9422		if itr.opt.Ascending {
9423			sorted = sort.Reverse(sorted)
9424		}
9425		sort.Stable(sorted)
9426	}
9427	return a, nil
9428}
9429
9430// stringStreamIntegerIterator streams inputs into the iterator and emits points gradually.
9431type stringStreamIntegerIterator struct {
9432	input  *bufStringIterator
9433	create func() (StringPointAggregator, IntegerPointEmitter)
9434	dims   []string
9435	opt    IteratorOptions
9436	m      map[string]*stringReduceIntegerPoint
9437	points []IntegerPoint
9438}
9439
9440// newStringStreamIntegerIterator returns a new instance of stringStreamIntegerIterator.
9441func newStringStreamIntegerIterator(input StringIterator, createFn func() (StringPointAggregator, IntegerPointEmitter), opt IteratorOptions) *stringStreamIntegerIterator {
9442	return &stringStreamIntegerIterator{
9443		input:  newBufStringIterator(input),
9444		create: createFn,
9445		dims:   opt.GetDimensions(),
9446		opt:    opt,
9447		m:      make(map[string]*stringReduceIntegerPoint),
9448	}
9449}
9450
9451// Stats returns stats from the input iterator.
9452func (itr *stringStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
9453
9454// Close closes the iterator and all child iterators.
9455func (itr *stringStreamIntegerIterator) Close() error { return itr.input.Close() }
9456
9457// Next returns the next value for the stream iterator.
9458func (itr *stringStreamIntegerIterator) Next() (*IntegerPoint, error) {
9459	// Calculate next window if we have no more points.
9460	if len(itr.points) == 0 {
9461		var err error
9462		itr.points, err = itr.reduce()
9463		if len(itr.points) == 0 {
9464			return nil, err
9465		}
9466	}
9467
9468	// Pop next point off the stack.
9469	p := &itr.points[len(itr.points)-1]
9470	itr.points = itr.points[:len(itr.points)-1]
9471	return p, nil
9472}
9473
9474// reduce creates and manages aggregators for every point from the input.
9475// After aggregating a point, it always tries to emit a value using the emitter.
9476func (itr *stringStreamIntegerIterator) reduce() ([]IntegerPoint, error) {
9477	// We have already read all of the input points.
9478	if itr.m == nil {
9479		return nil, nil
9480	}
9481
9482	for {
9483		// Read next point.
9484		curr, err := itr.input.Next()
9485		if err != nil {
9486			return nil, err
9487		} else if curr == nil {
9488			// Close all of the aggregators to flush any remaining points to emit.
9489			var points []IntegerPoint
9490			for _, rp := range itr.m {
9491				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
9492					if err := aggregator.Close(); err != nil {
9493						return nil, err
9494					}
9495
9496					pts := rp.Emitter.Emit()
9497					if len(pts) == 0 {
9498						continue
9499					}
9500
9501					for i := range pts {
9502						pts[i].Name = rp.Name
9503						pts[i].Tags = rp.Tags
9504					}
9505					points = append(points, pts...)
9506				}
9507			}
9508
9509			// Eliminate the aggregators and emitters.
9510			itr.m = nil
9511			return points, nil
9512		} else if curr.Nil {
9513			continue
9514		}
9515		tags := curr.Tags.Subset(itr.dims)
9516
9517		id := curr.Name
9518		if len(tags.m) > 0 {
9519			id += "\x00" + tags.ID()
9520		}
9521
9522		// Retrieve the aggregator for this name/tag combination or create one.
9523		rp := itr.m[id]
9524		if rp == nil {
9525			aggregator, emitter := itr.create()
9526			rp = &stringReduceIntegerPoint{
9527				Name:       curr.Name,
9528				Tags:       tags,
9529				Aggregator: aggregator,
9530				Emitter:    emitter,
9531			}
9532			itr.m[id] = rp
9533		}
9534		rp.Aggregator.AggregateString(curr)
9535
9536		// Attempt to emit points from the aggregator.
9537		points := rp.Emitter.Emit()
9538		if len(points) == 0 {
9539			continue
9540		}
9541
9542		for i := range points {
9543			points[i].Name = rp.Name
9544			points[i].Tags = rp.Tags
9545		}
9546		return points, nil
9547	}
9548}
9549
9550// stringReduceUnsignedIterator executes a reducer for every interval and buffers the result.
9551type stringReduceUnsignedIterator struct {
9552	input    *bufStringIterator
9553	create   func() (StringPointAggregator, UnsignedPointEmitter)
9554	dims     []string
9555	opt      IteratorOptions
9556	points   []UnsignedPoint
9557	keepTags bool
9558}
9559
9560func newStringReduceUnsignedIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, UnsignedPointEmitter)) *stringReduceUnsignedIterator {
9561	return &stringReduceUnsignedIterator{
9562		input:  newBufStringIterator(input),
9563		create: createFn,
9564		dims:   opt.GetDimensions(),
9565		opt:    opt,
9566	}
9567}
9568
9569// Stats returns stats from the input iterator.
9570func (itr *stringReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
9571
9572// Close closes the iterator and all child iterators.
9573func (itr *stringReduceUnsignedIterator) Close() error { return itr.input.Close() }
9574
9575// Next returns the minimum value for the next available interval.
9576func (itr *stringReduceUnsignedIterator) Next() (*UnsignedPoint, error) {
9577	// Calculate next window if we have no more points.
9578	if len(itr.points) == 0 {
9579		var err error
9580		itr.points, err = itr.reduce()
9581		if len(itr.points) == 0 {
9582			return nil, err
9583		}
9584	}
9585
9586	// Pop next point off the stack.
9587	p := &itr.points[len(itr.points)-1]
9588	itr.points = itr.points[:len(itr.points)-1]
9589	return p, nil
9590}
9591
9592// stringReduceUnsignedPoint stores the reduced data for a name/tag combination.
9593type stringReduceUnsignedPoint struct {
9594	Name       string
9595	Tags       Tags
9596	Aggregator StringPointAggregator
9597	Emitter    UnsignedPointEmitter
9598}
9599
9600// reduce executes fn once for every point in the next window.
9601// The previous value for the dimension is passed to fn.
9602func (itr *stringReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) {
9603	// Calculate next window.
9604	var (
9605		startTime, endTime int64
9606		window             struct {
9607			name string
9608			tags string
9609		}
9610	)
9611	for {
9612		p, err := itr.input.Next()
9613		if err != nil || p == nil {
9614			return nil, err
9615		} else if p.Nil {
9616			continue
9617		}
9618
9619		// Unread the point so it can be processed.
9620		itr.input.unread(p)
9621		startTime, endTime = itr.opt.Window(p.Time)
9622		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
9623		break
9624	}
9625
9626	// Create points by tags.
9627	m := make(map[string]*stringReduceUnsignedPoint)
9628	for {
9629		// Read next point.
9630		curr, err := itr.input.NextInWindow(startTime, endTime)
9631		if err != nil {
9632			return nil, err
9633		} else if curr == nil {
9634			break
9635		} else if curr.Nil {
9636			continue
9637		} else if curr.Name != window.name {
9638			itr.input.unread(curr)
9639			break
9640		}
9641
9642		// Ensure this point is within the same final window.
9643		if curr.Name != window.name {
9644			itr.input.unread(curr)
9645			break
9646		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
9647			itr.input.unread(curr)
9648			break
9649		}
9650
9651		// Retrieve the tags on this point for this level of the query.
9652		// This may be different than the bucket dimensions.
9653		tags := curr.Tags.Subset(itr.dims)
9654		id := tags.ID()
9655
9656		// Retrieve the aggregator for this name/tag combination or create one.
9657		rp := m[id]
9658		if rp == nil {
9659			aggregator, emitter := itr.create()
9660			rp = &stringReduceUnsignedPoint{
9661				Name:       curr.Name,
9662				Tags:       tags,
9663				Aggregator: aggregator,
9664				Emitter:    emitter,
9665			}
9666			m[id] = rp
9667		}
9668		rp.Aggregator.AggregateString(curr)
9669	}
9670
9671	keys := make([]string, 0, len(m))
9672	for k := range m {
9673		keys = append(keys, k)
9674	}
9675
9676	// Reverse sort points by name & tag.
9677	// This ensures a consistent order of output.
9678	if len(keys) > 0 {
9679		var sorted sort.Interface = sort.StringSlice(keys)
9680		if itr.opt.Ascending {
9681			sorted = sort.Reverse(sorted)
9682		}
9683		sort.Sort(sorted)
9684	}
9685
9686	// Assume the points are already sorted until proven otherwise.
9687	sortedByTime := true
9688	// Emit the points for each name & tag combination.
9689	a := make([]UnsignedPoint, 0, len(m))
9690	for _, k := range keys {
9691		rp := m[k]
9692		points := rp.Emitter.Emit()
9693		for i := len(points) - 1; i >= 0; i-- {
9694			points[i].Name = rp.Name
9695			if !itr.keepTags {
9696				points[i].Tags = rp.Tags
9697			}
9698			// Set the points time to the interval time if the reducer didn't provide one.
9699			if points[i].Time == ZeroTime {
9700				points[i].Time = startTime
9701			} else {
9702				sortedByTime = false
9703			}
9704			a = append(a, points[i])
9705		}
9706	}
9707	// Points may be out of order. Perform a stable sort by time if requested.
9708	if !sortedByTime && itr.opt.Ordered {
9709		var sorted sort.Interface = unsignedPointsByTime(a)
9710		if itr.opt.Ascending {
9711			sorted = sort.Reverse(sorted)
9712		}
9713		sort.Stable(sorted)
9714	}
9715	return a, nil
9716}
9717
9718// stringStreamUnsignedIterator streams inputs into the iterator and emits points gradually.
9719type stringStreamUnsignedIterator struct {
9720	input  *bufStringIterator
9721	create func() (StringPointAggregator, UnsignedPointEmitter)
9722	dims   []string
9723	opt    IteratorOptions
9724	m      map[string]*stringReduceUnsignedPoint
9725	points []UnsignedPoint
9726}
9727
9728// newStringStreamUnsignedIterator returns a new instance of stringStreamUnsignedIterator.
9729func newStringStreamUnsignedIterator(input StringIterator, createFn func() (StringPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *stringStreamUnsignedIterator {
9730	return &stringStreamUnsignedIterator{
9731		input:  newBufStringIterator(input),
9732		create: createFn,
9733		dims:   opt.GetDimensions(),
9734		opt:    opt,
9735		m:      make(map[string]*stringReduceUnsignedPoint),
9736	}
9737}
9738
9739// Stats returns stats from the input iterator.
9740func (itr *stringStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
9741
9742// Close closes the iterator and all child iterators.
9743func (itr *stringStreamUnsignedIterator) Close() error { return itr.input.Close() }
9744
9745// Next returns the next value for the stream iterator.
9746func (itr *stringStreamUnsignedIterator) Next() (*UnsignedPoint, error) {
9747	// Calculate next window if we have no more points.
9748	if len(itr.points) == 0 {
9749		var err error
9750		itr.points, err = itr.reduce()
9751		if len(itr.points) == 0 {
9752			return nil, err
9753		}
9754	}
9755
9756	// Pop next point off the stack.
9757	p := &itr.points[len(itr.points)-1]
9758	itr.points = itr.points[:len(itr.points)-1]
9759	return p, nil
9760}
9761
9762// reduce creates and manages aggregators for every point from the input.
9763// After aggregating a point, it always tries to emit a value using the emitter.
9764func (itr *stringStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) {
9765	// We have already read all of the input points.
9766	if itr.m == nil {
9767		return nil, nil
9768	}
9769
9770	for {
9771		// Read next point.
9772		curr, err := itr.input.Next()
9773		if err != nil {
9774			return nil, err
9775		} else if curr == nil {
9776			// Close all of the aggregators to flush any remaining points to emit.
9777			var points []UnsignedPoint
9778			for _, rp := range itr.m {
9779				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
9780					if err := aggregator.Close(); err != nil {
9781						return nil, err
9782					}
9783
9784					pts := rp.Emitter.Emit()
9785					if len(pts) == 0 {
9786						continue
9787					}
9788
9789					for i := range pts {
9790						pts[i].Name = rp.Name
9791						pts[i].Tags = rp.Tags
9792					}
9793					points = append(points, pts...)
9794				}
9795			}
9796
9797			// Eliminate the aggregators and emitters.
9798			itr.m = nil
9799			return points, nil
9800		} else if curr.Nil {
9801			continue
9802		}
9803		tags := curr.Tags.Subset(itr.dims)
9804
9805		id := curr.Name
9806		if len(tags.m) > 0 {
9807			id += "\x00" + tags.ID()
9808		}
9809
9810		// Retrieve the aggregator for this name/tag combination or create one.
9811		rp := itr.m[id]
9812		if rp == nil {
9813			aggregator, emitter := itr.create()
9814			rp = &stringReduceUnsignedPoint{
9815				Name:       curr.Name,
9816				Tags:       tags,
9817				Aggregator: aggregator,
9818				Emitter:    emitter,
9819			}
9820			itr.m[id] = rp
9821		}
9822		rp.Aggregator.AggregateString(curr)
9823
9824		// Attempt to emit points from the aggregator.
9825		points := rp.Emitter.Emit()
9826		if len(points) == 0 {
9827			continue
9828		}
9829
9830		for i := range points {
9831			points[i].Name = rp.Name
9832			points[i].Tags = rp.Tags
9833		}
9834		return points, nil
9835	}
9836}
9837
9838// stringReduceStringIterator executes a reducer for every interval and buffers the result.
9839type stringReduceStringIterator struct {
9840	input    *bufStringIterator
9841	create   func() (StringPointAggregator, StringPointEmitter)
9842	dims     []string
9843	opt      IteratorOptions
9844	points   []StringPoint
9845	keepTags bool
9846}
9847
9848func newStringReduceStringIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, StringPointEmitter)) *stringReduceStringIterator {
9849	return &stringReduceStringIterator{
9850		input:  newBufStringIterator(input),
9851		create: createFn,
9852		dims:   opt.GetDimensions(),
9853		opt:    opt,
9854	}
9855}
9856
9857// Stats returns stats from the input iterator.
9858func (itr *stringReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() }
9859
9860// Close closes the iterator and all child iterators.
9861func (itr *stringReduceStringIterator) Close() error { return itr.input.Close() }
9862
9863// Next returns the minimum value for the next available interval.
9864func (itr *stringReduceStringIterator) Next() (*StringPoint, error) {
9865	// Calculate next window if we have no more points.
9866	if len(itr.points) == 0 {
9867		var err error
9868		itr.points, err = itr.reduce()
9869		if len(itr.points) == 0 {
9870			return nil, err
9871		}
9872	}
9873
9874	// Pop next point off the stack.
9875	p := &itr.points[len(itr.points)-1]
9876	itr.points = itr.points[:len(itr.points)-1]
9877	return p, nil
9878}
9879
9880// stringReduceStringPoint stores the reduced data for a name/tag combination.
9881type stringReduceStringPoint struct {
9882	Name       string
9883	Tags       Tags
9884	Aggregator StringPointAggregator
9885	Emitter    StringPointEmitter
9886}
9887
9888// reduce executes fn once for every point in the next window.
9889// The previous value for the dimension is passed to fn.
9890func (itr *stringReduceStringIterator) reduce() ([]StringPoint, error) {
9891	// Calculate next window.
9892	var (
9893		startTime, endTime int64
9894		window             struct {
9895			name string
9896			tags string
9897		}
9898	)
9899	for {
9900		p, err := itr.input.Next()
9901		if err != nil || p == nil {
9902			return nil, err
9903		} else if p.Nil {
9904			continue
9905		}
9906
9907		// Unread the point so it can be processed.
9908		itr.input.unread(p)
9909		startTime, endTime = itr.opt.Window(p.Time)
9910		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
9911		break
9912	}
9913
9914	// Create points by tags.
9915	m := make(map[string]*stringReduceStringPoint)
9916	for {
9917		// Read next point.
9918		curr, err := itr.input.NextInWindow(startTime, endTime)
9919		if err != nil {
9920			return nil, err
9921		} else if curr == nil {
9922			break
9923		} else if curr.Nil {
9924			continue
9925		} else if curr.Name != window.name {
9926			itr.input.unread(curr)
9927			break
9928		}
9929
9930		// Ensure this point is within the same final window.
9931		if curr.Name != window.name {
9932			itr.input.unread(curr)
9933			break
9934		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
9935			itr.input.unread(curr)
9936			break
9937		}
9938
9939		// Retrieve the tags on this point for this level of the query.
9940		// This may be different than the bucket dimensions.
9941		tags := curr.Tags.Subset(itr.dims)
9942		id := tags.ID()
9943
9944		// Retrieve the aggregator for this name/tag combination or create one.
9945		rp := m[id]
9946		if rp == nil {
9947			aggregator, emitter := itr.create()
9948			rp = &stringReduceStringPoint{
9949				Name:       curr.Name,
9950				Tags:       tags,
9951				Aggregator: aggregator,
9952				Emitter:    emitter,
9953			}
9954			m[id] = rp
9955		}
9956		rp.Aggregator.AggregateString(curr)
9957	}
9958
9959	keys := make([]string, 0, len(m))
9960	for k := range m {
9961		keys = append(keys, k)
9962	}
9963
9964	// Reverse sort points by name & tag.
9965	// This ensures a consistent order of output.
9966	if len(keys) > 0 {
9967		var sorted sort.Interface = sort.StringSlice(keys)
9968		if itr.opt.Ascending {
9969			sorted = sort.Reverse(sorted)
9970		}
9971		sort.Sort(sorted)
9972	}
9973
9974	// Assume the points are already sorted until proven otherwise.
9975	sortedByTime := true
9976	// Emit the points for each name & tag combination.
9977	a := make([]StringPoint, 0, len(m))
9978	for _, k := range keys {
9979		rp := m[k]
9980		points := rp.Emitter.Emit()
9981		for i := len(points) - 1; i >= 0; i-- {
9982			points[i].Name = rp.Name
9983			if !itr.keepTags {
9984				points[i].Tags = rp.Tags
9985			}
9986			// Set the points time to the interval time if the reducer didn't provide one.
9987			if points[i].Time == ZeroTime {
9988				points[i].Time = startTime
9989			} else {
9990				sortedByTime = false
9991			}
9992			a = append(a, points[i])
9993		}
9994	}
9995	// Points may be out of order. Perform a stable sort by time if requested.
9996	if !sortedByTime && itr.opt.Ordered {
9997		var sorted sort.Interface = stringPointsByTime(a)
9998		if itr.opt.Ascending {
9999			sorted = sort.Reverse(sorted)
10000		}
10001		sort.Stable(sorted)
10002	}
10003	return a, nil
10004}
10005
10006// stringStreamStringIterator streams inputs into the iterator and emits points gradually.
10007type stringStreamStringIterator struct {
10008	input  *bufStringIterator
10009	create func() (StringPointAggregator, StringPointEmitter)
10010	dims   []string
10011	opt    IteratorOptions
10012	m      map[string]*stringReduceStringPoint
10013	points []StringPoint
10014}
10015
10016// newStringStreamStringIterator returns a new instance of stringStreamStringIterator.
10017func newStringStreamStringIterator(input StringIterator, createFn func() (StringPointAggregator, StringPointEmitter), opt IteratorOptions) *stringStreamStringIterator {
10018	return &stringStreamStringIterator{
10019		input:  newBufStringIterator(input),
10020		create: createFn,
10021		dims:   opt.GetDimensions(),
10022		opt:    opt,
10023		m:      make(map[string]*stringReduceStringPoint),
10024	}
10025}
10026
10027// Stats returns stats from the input iterator.
10028func (itr *stringStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() }
10029
10030// Close closes the iterator and all child iterators.
10031func (itr *stringStreamStringIterator) Close() error { return itr.input.Close() }
10032
10033// Next returns the next value for the stream iterator.
10034func (itr *stringStreamStringIterator) Next() (*StringPoint, error) {
10035	// Calculate next window if we have no more points.
10036	if len(itr.points) == 0 {
10037		var err error
10038		itr.points, err = itr.reduce()
10039		if len(itr.points) == 0 {
10040			return nil, err
10041		}
10042	}
10043
10044	// Pop next point off the stack.
10045	p := &itr.points[len(itr.points)-1]
10046	itr.points = itr.points[:len(itr.points)-1]
10047	return p, nil
10048}
10049
10050// reduce creates and manages aggregators for every point from the input.
10051// After aggregating a point, it always tries to emit a value using the emitter.
10052func (itr *stringStreamStringIterator) reduce() ([]StringPoint, error) {
10053	// We have already read all of the input points.
10054	if itr.m == nil {
10055		return nil, nil
10056	}
10057
10058	for {
10059		// Read next point.
10060		curr, err := itr.input.Next()
10061		if err != nil {
10062			return nil, err
10063		} else if curr == nil {
10064			// Close all of the aggregators to flush any remaining points to emit.
10065			var points []StringPoint
10066			for _, rp := range itr.m {
10067				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
10068					if err := aggregator.Close(); err != nil {
10069						return nil, err
10070					}
10071
10072					pts := rp.Emitter.Emit()
10073					if len(pts) == 0 {
10074						continue
10075					}
10076
10077					for i := range pts {
10078						pts[i].Name = rp.Name
10079						pts[i].Tags = rp.Tags
10080					}
10081					points = append(points, pts...)
10082				}
10083			}
10084
10085			// Eliminate the aggregators and emitters.
10086			itr.m = nil
10087			return points, nil
10088		} else if curr.Nil {
10089			continue
10090		}
10091		tags := curr.Tags.Subset(itr.dims)
10092
10093		id := curr.Name
10094		if len(tags.m) > 0 {
10095			id += "\x00" + tags.ID()
10096		}
10097
10098		// Retrieve the aggregator for this name/tag combination or create one.
10099		rp := itr.m[id]
10100		if rp == nil {
10101			aggregator, emitter := itr.create()
10102			rp = &stringReduceStringPoint{
10103				Name:       curr.Name,
10104				Tags:       tags,
10105				Aggregator: aggregator,
10106				Emitter:    emitter,
10107			}
10108			itr.m[id] = rp
10109		}
10110		rp.Aggregator.AggregateString(curr)
10111
10112		// Attempt to emit points from the aggregator.
10113		points := rp.Emitter.Emit()
10114		if len(points) == 0 {
10115			continue
10116		}
10117
10118		for i := range points {
10119			points[i].Name = rp.Name
10120			points[i].Tags = rp.Tags
10121		}
10122		return points, nil
10123	}
10124}
10125
10126// stringReduceBooleanIterator executes a reducer for every interval and buffers the result.
10127type stringReduceBooleanIterator struct {
10128	input    *bufStringIterator
10129	create   func() (StringPointAggregator, BooleanPointEmitter)
10130	dims     []string
10131	opt      IteratorOptions
10132	points   []BooleanPoint
10133	keepTags bool
10134}
10135
10136func newStringReduceBooleanIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, BooleanPointEmitter)) *stringReduceBooleanIterator {
10137	return &stringReduceBooleanIterator{
10138		input:  newBufStringIterator(input),
10139		create: createFn,
10140		dims:   opt.GetDimensions(),
10141		opt:    opt,
10142	}
10143}
10144
10145// Stats returns stats from the input iterator.
10146func (itr *stringReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
10147
10148// Close closes the iterator and all child iterators.
10149func (itr *stringReduceBooleanIterator) Close() error { return itr.input.Close() }
10150
10151// Next returns the minimum value for the next available interval.
10152func (itr *stringReduceBooleanIterator) Next() (*BooleanPoint, error) {
10153	// Calculate next window if we have no more points.
10154	if len(itr.points) == 0 {
10155		var err error
10156		itr.points, err = itr.reduce()
10157		if len(itr.points) == 0 {
10158			return nil, err
10159		}
10160	}
10161
10162	// Pop next point off the stack.
10163	p := &itr.points[len(itr.points)-1]
10164	itr.points = itr.points[:len(itr.points)-1]
10165	return p, nil
10166}
10167
10168// stringReduceBooleanPoint stores the reduced data for a name/tag combination.
10169type stringReduceBooleanPoint struct {
10170	Name       string
10171	Tags       Tags
10172	Aggregator StringPointAggregator
10173	Emitter    BooleanPointEmitter
10174}
10175
10176// reduce executes fn once for every point in the next window.
10177// The previous value for the dimension is passed to fn.
10178func (itr *stringReduceBooleanIterator) reduce() ([]BooleanPoint, error) {
10179	// Calculate next window.
10180	var (
10181		startTime, endTime int64
10182		window             struct {
10183			name string
10184			tags string
10185		}
10186	)
10187	for {
10188		p, err := itr.input.Next()
10189		if err != nil || p == nil {
10190			return nil, err
10191		} else if p.Nil {
10192			continue
10193		}
10194
10195		// Unread the point so it can be processed.
10196		itr.input.unread(p)
10197		startTime, endTime = itr.opt.Window(p.Time)
10198		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
10199		break
10200	}
10201
10202	// Create points by tags.
10203	m := make(map[string]*stringReduceBooleanPoint)
10204	for {
10205		// Read next point.
10206		curr, err := itr.input.NextInWindow(startTime, endTime)
10207		if err != nil {
10208			return nil, err
10209		} else if curr == nil {
10210			break
10211		} else if curr.Nil {
10212			continue
10213		} else if curr.Name != window.name {
10214			itr.input.unread(curr)
10215			break
10216		}
10217
10218		// Ensure this point is within the same final window.
10219		if curr.Name != window.name {
10220			itr.input.unread(curr)
10221			break
10222		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
10223			itr.input.unread(curr)
10224			break
10225		}
10226
10227		// Retrieve the tags on this point for this level of the query.
10228		// This may be different than the bucket dimensions.
10229		tags := curr.Tags.Subset(itr.dims)
10230		id := tags.ID()
10231
10232		// Retrieve the aggregator for this name/tag combination or create one.
10233		rp := m[id]
10234		if rp == nil {
10235			aggregator, emitter := itr.create()
10236			rp = &stringReduceBooleanPoint{
10237				Name:       curr.Name,
10238				Tags:       tags,
10239				Aggregator: aggregator,
10240				Emitter:    emitter,
10241			}
10242			m[id] = rp
10243		}
10244		rp.Aggregator.AggregateString(curr)
10245	}
10246
10247	keys := make([]string, 0, len(m))
10248	for k := range m {
10249		keys = append(keys, k)
10250	}
10251
10252	// Reverse sort points by name & tag.
10253	// This ensures a consistent order of output.
10254	if len(keys) > 0 {
10255		var sorted sort.Interface = sort.StringSlice(keys)
10256		if itr.opt.Ascending {
10257			sorted = sort.Reverse(sorted)
10258		}
10259		sort.Sort(sorted)
10260	}
10261
10262	// Assume the points are already sorted until proven otherwise.
10263	sortedByTime := true
10264	// Emit the points for each name & tag combination.
10265	a := make([]BooleanPoint, 0, len(m))
10266	for _, k := range keys {
10267		rp := m[k]
10268		points := rp.Emitter.Emit()
10269		for i := len(points) - 1; i >= 0; i-- {
10270			points[i].Name = rp.Name
10271			if !itr.keepTags {
10272				points[i].Tags = rp.Tags
10273			}
10274			// Set the points time to the interval time if the reducer didn't provide one.
10275			if points[i].Time == ZeroTime {
10276				points[i].Time = startTime
10277			} else {
10278				sortedByTime = false
10279			}
10280			a = append(a, points[i])
10281		}
10282	}
10283	// Points may be out of order. Perform a stable sort by time if requested.
10284	if !sortedByTime && itr.opt.Ordered {
10285		var sorted sort.Interface = booleanPointsByTime(a)
10286		if itr.opt.Ascending {
10287			sorted = sort.Reverse(sorted)
10288		}
10289		sort.Stable(sorted)
10290	}
10291	return a, nil
10292}
10293
10294// stringStreamBooleanIterator streams inputs into the iterator and emits points gradually.
10295type stringStreamBooleanIterator struct {
10296	input  *bufStringIterator
10297	create func() (StringPointAggregator, BooleanPointEmitter)
10298	dims   []string
10299	opt    IteratorOptions
10300	m      map[string]*stringReduceBooleanPoint
10301	points []BooleanPoint
10302}
10303
10304// newStringStreamBooleanIterator returns a new instance of stringStreamBooleanIterator.
10305func newStringStreamBooleanIterator(input StringIterator, createFn func() (StringPointAggregator, BooleanPointEmitter), opt IteratorOptions) *stringStreamBooleanIterator {
10306	return &stringStreamBooleanIterator{
10307		input:  newBufStringIterator(input),
10308		create: createFn,
10309		dims:   opt.GetDimensions(),
10310		opt:    opt,
10311		m:      make(map[string]*stringReduceBooleanPoint),
10312	}
10313}
10314
10315// Stats returns stats from the input iterator.
10316func (itr *stringStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
10317
10318// Close closes the iterator and all child iterators.
10319func (itr *stringStreamBooleanIterator) Close() error { return itr.input.Close() }
10320
10321// Next returns the next value for the stream iterator.
10322func (itr *stringStreamBooleanIterator) Next() (*BooleanPoint, error) {
10323	// Calculate next window if we have no more points.
10324	if len(itr.points) == 0 {
10325		var err error
10326		itr.points, err = itr.reduce()
10327		if len(itr.points) == 0 {
10328			return nil, err
10329		}
10330	}
10331
10332	// Pop next point off the stack.
10333	p := &itr.points[len(itr.points)-1]
10334	itr.points = itr.points[:len(itr.points)-1]
10335	return p, nil
10336}
10337
10338// reduce creates and manages aggregators for every point from the input.
10339// After aggregating a point, it always tries to emit a value using the emitter.
10340func (itr *stringStreamBooleanIterator) reduce() ([]BooleanPoint, error) {
10341	// We have already read all of the input points.
10342	if itr.m == nil {
10343		return nil, nil
10344	}
10345
10346	for {
10347		// Read next point.
10348		curr, err := itr.input.Next()
10349		if err != nil {
10350			return nil, err
10351		} else if curr == nil {
10352			// Close all of the aggregators to flush any remaining points to emit.
10353			var points []BooleanPoint
10354			for _, rp := range itr.m {
10355				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
10356					if err := aggregator.Close(); err != nil {
10357						return nil, err
10358					}
10359
10360					pts := rp.Emitter.Emit()
10361					if len(pts) == 0 {
10362						continue
10363					}
10364
10365					for i := range pts {
10366						pts[i].Name = rp.Name
10367						pts[i].Tags = rp.Tags
10368					}
10369					points = append(points, pts...)
10370				}
10371			}
10372
10373			// Eliminate the aggregators and emitters.
10374			itr.m = nil
10375			return points, nil
10376		} else if curr.Nil {
10377			continue
10378		}
10379		tags := curr.Tags.Subset(itr.dims)
10380
10381		id := curr.Name
10382		if len(tags.m) > 0 {
10383			id += "\x00" + tags.ID()
10384		}
10385
10386		// Retrieve the aggregator for this name/tag combination or create one.
10387		rp := itr.m[id]
10388		if rp == nil {
10389			aggregator, emitter := itr.create()
10390			rp = &stringReduceBooleanPoint{
10391				Name:       curr.Name,
10392				Tags:       tags,
10393				Aggregator: aggregator,
10394				Emitter:    emitter,
10395			}
10396			itr.m[id] = rp
10397		}
10398		rp.Aggregator.AggregateString(curr)
10399
10400		// Attempt to emit points from the aggregator.
10401		points := rp.Emitter.Emit()
10402		if len(points) == 0 {
10403			continue
10404		}
10405
10406		for i := range points {
10407			points[i].Name = rp.Name
10408			points[i].Tags = rp.Tags
10409		}
10410		return points, nil
10411	}
10412}
10413
10414// stringDedupeIterator only outputs unique points.
10415// This differs from the DistinctIterator in that it compares all aux fields too.
10416// This iterator is relatively inefficient and should only be used on small
10417// datasets such as meta query results.
10418type stringDedupeIterator struct {
10419	input StringIterator
10420	m     map[string]struct{} // lookup of points already sent
10421}
10422
10423type stringIteratorMapper struct {
10424	cur    Cursor
10425	row    Row
10426	driver IteratorMap   // which iterator to use for the primary value, can be nil
10427	fields []IteratorMap // which iterator to use for an aux field
10428	point  StringPoint
10429}
10430
10431func newStringIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *stringIteratorMapper {
10432	return &stringIteratorMapper{
10433		cur:    cur,
10434		driver: driver,
10435		fields: fields,
10436		point: StringPoint{
10437			Aux: make([]interface{}, len(fields)),
10438		},
10439	}
10440}
10441
10442func (itr *stringIteratorMapper) Next() (*StringPoint, error) {
10443	if !itr.cur.Scan(&itr.row) {
10444		if err := itr.cur.Err(); err != nil {
10445			return nil, err
10446		}
10447		return nil, nil
10448	}
10449
10450	itr.point.Time = itr.row.Time
10451	itr.point.Name = itr.row.Series.Name
10452	itr.point.Tags = itr.row.Series.Tags
10453
10454	if itr.driver != nil {
10455		if v := itr.driver.Value(&itr.row); v != nil {
10456			if v, ok := castToString(v); ok {
10457				itr.point.Value = v
10458				itr.point.Nil = false
10459			} else {
10460				itr.point.Value = ""
10461				itr.point.Nil = true
10462			}
10463		} else {
10464			itr.point.Value = ""
10465			itr.point.Nil = true
10466		}
10467	}
10468	for i, f := range itr.fields {
10469		itr.point.Aux[i] = f.Value(&itr.row)
10470	}
10471	return &itr.point, nil
10472}
10473
10474func (itr *stringIteratorMapper) Stats() IteratorStats {
10475	return itr.cur.Stats()
10476}
10477
10478func (itr *stringIteratorMapper) Close() error {
10479	return itr.cur.Close()
10480}
10481
10482type stringFilterIterator struct {
10483	input StringIterator
10484	cond  influxql.Expr
10485	opt   IteratorOptions
10486	m     map[string]interface{}
10487}
10488
10489func newStringFilterIterator(input StringIterator, cond influxql.Expr, opt IteratorOptions) StringIterator {
10490	// Strip out time conditions from the WHERE clause.
10491	// TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct.
10492	n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node {
10493		switch n := n.(type) {
10494		case *influxql.BinaryExpr:
10495			if n.LHS.String() == "time" {
10496				return &influxql.BooleanLiteral{Val: true}
10497			}
10498		}
10499		return n
10500	})
10501
10502	cond, _ = n.(influxql.Expr)
10503	if cond == nil {
10504		return input
10505	} else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val {
10506		return input
10507	}
10508
10509	return &stringFilterIterator{
10510		input: input,
10511		cond:  cond,
10512		opt:   opt,
10513		m:     make(map[string]interface{}),
10514	}
10515}
10516
10517func (itr *stringFilterIterator) Stats() IteratorStats { return itr.input.Stats() }
10518func (itr *stringFilterIterator) Close() error         { return itr.input.Close() }
10519
10520func (itr *stringFilterIterator) Next() (*StringPoint, error) {
10521	for {
10522		p, err := itr.input.Next()
10523		if err != nil || p == nil {
10524			return nil, err
10525		}
10526
10527		for i, ref := range itr.opt.Aux {
10528			itr.m[ref.Val] = p.Aux[i]
10529		}
10530		for k, v := range p.Tags.KeyValues() {
10531			itr.m[k] = v
10532		}
10533
10534		if !influxql.EvalBool(itr.cond, itr.m) {
10535			continue
10536		}
10537		return p, nil
10538	}
10539}
10540
10541type stringTagSubsetIterator struct {
10542	input      StringIterator
10543	point      StringPoint
10544	lastTags   Tags
10545	dimensions []string
10546}
10547
10548func newStringTagSubsetIterator(input StringIterator, opt IteratorOptions) *stringTagSubsetIterator {
10549	return &stringTagSubsetIterator{
10550		input:      input,
10551		dimensions: opt.GetDimensions(),
10552	}
10553}
10554
10555func (itr *stringTagSubsetIterator) Next() (*StringPoint, error) {
10556	p, err := itr.input.Next()
10557	if err != nil {
10558		return nil, err
10559	} else if p == nil {
10560		return nil, nil
10561	}
10562
10563	itr.point.Name = p.Name
10564	if !p.Tags.Equal(itr.lastTags) {
10565		itr.point.Tags = p.Tags.Subset(itr.dimensions)
10566		itr.lastTags = p.Tags
10567	}
10568	itr.point.Time = p.Time
10569	itr.point.Value = p.Value
10570	itr.point.Aux = p.Aux
10571	itr.point.Aggregated = p.Aggregated
10572	itr.point.Nil = p.Nil
10573	return &itr.point, nil
10574}
10575
10576func (itr *stringTagSubsetIterator) Stats() IteratorStats {
10577	return itr.input.Stats()
10578}
10579
10580func (itr *stringTagSubsetIterator) Close() error {
10581	return itr.input.Close()
10582}
10583
10584// newStringDedupeIterator returns a new instance of stringDedupeIterator.
10585func newStringDedupeIterator(input StringIterator) *stringDedupeIterator {
10586	return &stringDedupeIterator{
10587		input: input,
10588		m:     make(map[string]struct{}),
10589	}
10590}
10591
10592// Stats returns stats from the input iterator.
10593func (itr *stringDedupeIterator) Stats() IteratorStats { return itr.input.Stats() }
10594
10595// Close closes the iterator and all child iterators.
10596func (itr *stringDedupeIterator) Close() error { return itr.input.Close() }
10597
10598// Next returns the next unique point from the input iterator.
10599func (itr *stringDedupeIterator) Next() (*StringPoint, error) {
10600	for {
10601		// Read next point.
10602		p, err := itr.input.Next()
10603		if p == nil || err != nil {
10604			return nil, err
10605		}
10606
10607		// Serialize to bytes to store in lookup.
10608		buf, err := proto.Marshal(encodeStringPoint(p))
10609		if err != nil {
10610			return nil, err
10611		}
10612
10613		// If the point has already been output then move to the next point.
10614		if _, ok := itr.m[string(buf)]; ok {
10615			continue
10616		}
10617
10618		// Otherwise mark it as emitted and return point.
10619		itr.m[string(buf)] = struct{}{}
10620		return p, nil
10621	}
10622}
10623
10624// stringReaderIterator represents an iterator that streams from a reader.
10625type stringReaderIterator struct {
10626	r   io.Reader
10627	dec *StringPointDecoder
10628}
10629
10630// newStringReaderIterator returns a new instance of stringReaderIterator.
10631func newStringReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *stringReaderIterator {
10632	dec := NewStringPointDecoder(ctx, r)
10633	dec.stats = stats
10634
10635	return &stringReaderIterator{
10636		r:   r,
10637		dec: dec,
10638	}
10639}
10640
10641// Stats returns stats about points processed.
10642func (itr *stringReaderIterator) Stats() IteratorStats { return itr.dec.stats }
10643
10644// Close closes the underlying reader, if applicable.
10645func (itr *stringReaderIterator) Close() error {
10646	if r, ok := itr.r.(io.ReadCloser); ok {
10647		return r.Close()
10648	}
10649	return nil
10650}
10651
10652// Next returns the next point from the iterator.
10653func (itr *stringReaderIterator) Next() (*StringPoint, error) {
10654	// OPTIMIZE(benbjohnson): Reuse point on iterator.
10655
10656	// Unmarshal next point.
10657	p := &StringPoint{}
10658	if err := itr.dec.DecodeStringPoint(p); err == io.EOF {
10659		return nil, nil
10660	} else if err != nil {
10661		return nil, err
10662	}
10663	return p, nil
10664}
10665
10666// BooleanIterator represents a stream of boolean points.
10667type BooleanIterator interface {
10668	Iterator
10669	Next() (*BooleanPoint, error)
10670}
10671
10672// newBooleanIterators converts a slice of Iterator to a slice of BooleanIterator.
10673// Drop and closes any iterator in itrs that is not a BooleanIterator and cannot
10674// be cast to a BooleanIterator.
10675func newBooleanIterators(itrs []Iterator) []BooleanIterator {
10676	a := make([]BooleanIterator, 0, len(itrs))
10677	for _, itr := range itrs {
10678		switch itr := itr.(type) {
10679		case BooleanIterator:
10680			a = append(a, itr)
10681		default:
10682			itr.Close()
10683		}
10684	}
10685	return a
10686}
10687
10688// bufBooleanIterator represents a buffered BooleanIterator.
10689type bufBooleanIterator struct {
10690	itr BooleanIterator
10691	buf *BooleanPoint
10692}
10693
10694// newBufBooleanIterator returns a buffered BooleanIterator.
10695func newBufBooleanIterator(itr BooleanIterator) *bufBooleanIterator {
10696	return &bufBooleanIterator{itr: itr}
10697}
10698
10699// Stats returns statistics from the input iterator.
10700func (itr *bufBooleanIterator) Stats() IteratorStats { return itr.itr.Stats() }
10701
10702// Close closes the underlying iterator.
10703func (itr *bufBooleanIterator) Close() error { return itr.itr.Close() }
10704
10705// peek returns the next point without removing it from the iterator.
10706func (itr *bufBooleanIterator) peek() (*BooleanPoint, error) {
10707	p, err := itr.Next()
10708	if err != nil {
10709		return nil, err
10710	}
10711	itr.unread(p)
10712	return p, nil
10713}
10714
10715// peekTime returns the time of the next point.
10716// Returns zero time if no more points available.
10717func (itr *bufBooleanIterator) peekTime() (int64, error) {
10718	p, err := itr.peek()
10719	if p == nil || err != nil {
10720		return ZeroTime, err
10721	}
10722	return p.Time, nil
10723}
10724
10725// Next returns the current buffer, if exists, or calls the underlying iterator.
10726func (itr *bufBooleanIterator) Next() (*BooleanPoint, error) {
10727	buf := itr.buf
10728	if buf != nil {
10729		itr.buf = nil
10730		return buf, nil
10731	}
10732	return itr.itr.Next()
10733}
10734
10735// NextInWindow returns the next value if it is between [startTime, endTime).
10736// If the next value is outside the range then it is moved to the buffer.
10737func (itr *bufBooleanIterator) NextInWindow(startTime, endTime int64) (*BooleanPoint, error) {
10738	v, err := itr.Next()
10739	if v == nil || err != nil {
10740		return nil, err
10741	} else if t := v.Time; t >= endTime || t < startTime {
10742		itr.unread(v)
10743		return nil, nil
10744	}
10745	return v, nil
10746}
10747
10748// unread sets v to the buffer. It is read on the next call to Next().
10749func (itr *bufBooleanIterator) unread(v *BooleanPoint) { itr.buf = v }
10750
10751// booleanMergeIterator represents an iterator that combines multiple boolean iterators.
10752type booleanMergeIterator struct {
10753	inputs []BooleanIterator
10754	heap   *booleanMergeHeap
10755	init   bool
10756
10757	closed bool
10758	mu     sync.RWMutex
10759
10760	// Current iterator and window.
10761	curr   *booleanMergeHeapItem
10762	window struct {
10763		name      string
10764		tags      string
10765		startTime int64
10766		endTime   int64
10767	}
10768}
10769
10770// newBooleanMergeIterator returns a new instance of booleanMergeIterator.
10771func newBooleanMergeIterator(inputs []BooleanIterator, opt IteratorOptions) *booleanMergeIterator {
10772	itr := &booleanMergeIterator{
10773		inputs: inputs,
10774		heap: &booleanMergeHeap{
10775			items: make([]*booleanMergeHeapItem, 0, len(inputs)),
10776			opt:   opt,
10777		},
10778	}
10779
10780	// Initialize heap items.
10781	for _, input := range inputs {
10782		// Wrap in buffer, ignore any inputs without anymore points.
10783		bufInput := newBufBooleanIterator(input)
10784
10785		// Append to the heap.
10786		itr.heap.items = append(itr.heap.items, &booleanMergeHeapItem{itr: bufInput})
10787	}
10788
10789	return itr
10790}
10791
10792// Stats returns an aggregation of stats from the underlying iterators.
10793func (itr *booleanMergeIterator) Stats() IteratorStats {
10794	var stats IteratorStats
10795	for _, input := range itr.inputs {
10796		stats.Add(input.Stats())
10797	}
10798	return stats
10799}
10800
10801// Close closes the underlying iterators.
10802func (itr *booleanMergeIterator) Close() error {
10803	itr.mu.Lock()
10804	defer itr.mu.Unlock()
10805
10806	for _, input := range itr.inputs {
10807		input.Close()
10808	}
10809	itr.curr = nil
10810	itr.inputs = nil
10811	itr.heap.items = nil
10812	itr.closed = true
10813	return nil
10814}
10815
10816// Next returns the next point from the iterator.
10817func (itr *booleanMergeIterator) Next() (*BooleanPoint, error) {
10818	itr.mu.RLock()
10819	defer itr.mu.RUnlock()
10820	if itr.closed {
10821		return nil, nil
10822	}
10823
10824	// Initialize the heap. This needs to be done lazily on the first call to this iterator
10825	// so that iterator initialization done through the Select() call returns quickly.
10826	// Queries can only be interrupted after the Select() call completes so any operations
10827	// done during iterator creation cannot be interrupted, which is why we do it here
10828	// instead so an interrupt can happen while initializing the heap.
10829	if !itr.init {
10830		items := itr.heap.items
10831		itr.heap.items = make([]*booleanMergeHeapItem, 0, len(items))
10832		for _, item := range items {
10833			if p, err := item.itr.peek(); err != nil {
10834				return nil, err
10835			} else if p == nil {
10836				continue
10837			}
10838			itr.heap.items = append(itr.heap.items, item)
10839		}
10840		heap.Init(itr.heap)
10841		itr.init = true
10842	}
10843
10844	for {
10845		// Retrieve the next iterator if we don't have one.
10846		if itr.curr == nil {
10847			if len(itr.heap.items) == 0 {
10848				return nil, nil
10849			}
10850			itr.curr = heap.Pop(itr.heap).(*booleanMergeHeapItem)
10851
10852			// Read point and set current window.
10853			p, err := itr.curr.itr.Next()
10854			if err != nil {
10855				return nil, err
10856			}
10857			tags := p.Tags.Subset(itr.heap.opt.Dimensions)
10858			itr.window.name, itr.window.tags = p.Name, tags.ID()
10859			itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time)
10860			return p, nil
10861		}
10862
10863		// Read the next point from the current iterator.
10864		p, err := itr.curr.itr.Next()
10865		if err != nil {
10866			return nil, err
10867		}
10868
10869		// If there are no more points then remove iterator from heap and find next.
10870		if p == nil {
10871			itr.curr = nil
10872			continue
10873		}
10874
10875		// Check if the point is inside of our current window.
10876		inWindow := true
10877		if window := itr.window; window.name != p.Name {
10878			inWindow = false
10879		} else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() {
10880			inWindow = false
10881		} else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime {
10882			inWindow = false
10883		} else if !opt.Ascending && p.Time < window.startTime {
10884			inWindow = false
10885		}
10886
10887		// If it's outside our window then push iterator back on the heap and find new iterator.
10888		if !inWindow {
10889			itr.curr.itr.unread(p)
10890			heap.Push(itr.heap, itr.curr)
10891			itr.curr = nil
10892			continue
10893		}
10894
10895		return p, nil
10896	}
10897}
10898
10899// booleanMergeHeap represents a heap of booleanMergeHeapItems.
10900// Items are sorted by their next window and then by name/tags.
10901type booleanMergeHeap struct {
10902	opt   IteratorOptions
10903	items []*booleanMergeHeapItem
10904}
10905
10906func (h *booleanMergeHeap) Len() int      { return len(h.items) }
10907func (h *booleanMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
10908func (h *booleanMergeHeap) Less(i, j int) bool {
10909	x, err := h.items[i].itr.peek()
10910	if err != nil {
10911		return true
10912	}
10913	y, err := h.items[j].itr.peek()
10914	if err != nil {
10915		return false
10916	}
10917
10918	if h.opt.Ascending {
10919		if x.Name != y.Name {
10920			return x.Name < y.Name
10921		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
10922			return xTags.ID() < yTags.ID()
10923		}
10924	} else {
10925		if x.Name != y.Name {
10926			return x.Name > y.Name
10927		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
10928			return xTags.ID() > yTags.ID()
10929		}
10930	}
10931
10932	xt, _ := h.opt.Window(x.Time)
10933	yt, _ := h.opt.Window(y.Time)
10934
10935	if h.opt.Ascending {
10936		return xt < yt
10937	}
10938	return xt > yt
10939}
10940
10941func (h *booleanMergeHeap) Push(x interface{}) {
10942	h.items = append(h.items, x.(*booleanMergeHeapItem))
10943}
10944
10945func (h *booleanMergeHeap) Pop() interface{} {
10946	old := h.items
10947	n := len(old)
10948	item := old[n-1]
10949	h.items = old[0 : n-1]
10950	return item
10951}
10952
10953type booleanMergeHeapItem struct {
10954	itr *bufBooleanIterator
10955}
10956
10957// booleanSortedMergeIterator is an iterator that sorts and merges multiple iterators into one.
10958type booleanSortedMergeIterator struct {
10959	inputs []BooleanIterator
10960	heap   *booleanSortedMergeHeap
10961	init   bool
10962}
10963
10964// newBooleanSortedMergeIterator returns an instance of booleanSortedMergeIterator.
10965func newBooleanSortedMergeIterator(inputs []BooleanIterator, opt IteratorOptions) Iterator {
10966	itr := &booleanSortedMergeIterator{
10967		inputs: inputs,
10968		heap: &booleanSortedMergeHeap{
10969			items: make([]*booleanSortedMergeHeapItem, 0, len(inputs)),
10970			opt:   opt,
10971		},
10972	}
10973
10974	// Initialize heap items.
10975	for _, input := range inputs {
10976		// Append to the heap.
10977		itr.heap.items = append(itr.heap.items, &booleanSortedMergeHeapItem{itr: input})
10978	}
10979
10980	return itr
10981}
10982
10983// Stats returns an aggregation of stats from the underlying iterators.
10984func (itr *booleanSortedMergeIterator) Stats() IteratorStats {
10985	var stats IteratorStats
10986	for _, input := range itr.inputs {
10987		stats.Add(input.Stats())
10988	}
10989	return stats
10990}
10991
10992// Close closes the underlying iterators.
10993func (itr *booleanSortedMergeIterator) Close() error {
10994	for _, input := range itr.inputs {
10995		input.Close()
10996	}
10997	return nil
10998}
10999
11000// Next returns the next points from the iterator.
11001func (itr *booleanSortedMergeIterator) Next() (*BooleanPoint, error) { return itr.pop() }
11002
11003// pop returns the next point from the heap.
11004// Reads the next point from item's cursor and puts it back on the heap.
11005func (itr *booleanSortedMergeIterator) pop() (*BooleanPoint, error) {
11006	// Initialize the heap. See the MergeIterator to see why this has to be done lazily.
11007	if !itr.init {
11008		items := itr.heap.items
11009		itr.heap.items = make([]*booleanSortedMergeHeapItem, 0, len(items))
11010		for _, item := range items {
11011			var err error
11012			if item.point, err = item.itr.Next(); err != nil {
11013				return nil, err
11014			} else if item.point == nil {
11015				continue
11016			}
11017			itr.heap.items = append(itr.heap.items, item)
11018		}
11019		heap.Init(itr.heap)
11020		itr.init = true
11021	}
11022
11023	if len(itr.heap.items) == 0 {
11024		return nil, nil
11025	}
11026
11027	// Read the next item from the heap.
11028	item := heap.Pop(itr.heap).(*booleanSortedMergeHeapItem)
11029	if item.err != nil {
11030		return nil, item.err
11031	} else if item.point == nil {
11032		return nil, nil
11033	}
11034
11035	// Copy the point for return.
11036	p := item.point.Clone()
11037
11038	// Read the next item from the cursor. Push back to heap if one exists.
11039	if item.point, item.err = item.itr.Next(); item.point != nil {
11040		heap.Push(itr.heap, item)
11041	}
11042
11043	return p, nil
11044}
11045
11046// booleanSortedMergeHeap represents a heap of booleanSortedMergeHeapItems.
11047// Items are sorted with the following priority:
11048//     - By their measurement name;
11049//     - By their tag keys/values;
11050//     - By time; or
11051//     - By their Aux field values.
11052//
11053type booleanSortedMergeHeap struct {
11054	opt   IteratorOptions
11055	items []*booleanSortedMergeHeapItem
11056}
11057
11058func (h *booleanSortedMergeHeap) Len() int      { return len(h.items) }
11059func (h *booleanSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
11060func (h *booleanSortedMergeHeap) Less(i, j int) bool {
11061	x, y := h.items[i].point, h.items[j].point
11062
11063	if h.opt.Ascending {
11064		if x.Name != y.Name {
11065			return x.Name < y.Name
11066		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
11067			return xTags.ID() < yTags.ID()
11068		}
11069
11070		if x.Time != y.Time {
11071			return x.Time < y.Time
11072		}
11073
11074		if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
11075			for i := 0; i < len(x.Aux); i++ {
11076				v1, ok1 := x.Aux[i].(string)
11077				v2, ok2 := y.Aux[i].(string)
11078				if !ok1 || !ok2 {
11079					// Unsupported types used in Aux fields. Maybe they
11080					// need to be added here?
11081					return false
11082				} else if v1 == v2 {
11083					continue
11084				}
11085				return v1 < v2
11086			}
11087		}
11088		return false // Times and/or Aux fields are equal.
11089	}
11090
11091	if x.Name != y.Name {
11092		return x.Name > y.Name
11093	} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
11094		return xTags.ID() > yTags.ID()
11095	}
11096
11097	if x.Time != y.Time {
11098		return x.Time > y.Time
11099	}
11100
11101	if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
11102		for i := 0; i < len(x.Aux); i++ {
11103			v1, ok1 := x.Aux[i].(string)
11104			v2, ok2 := y.Aux[i].(string)
11105			if !ok1 || !ok2 {
11106				// Unsupported types used in Aux fields. Maybe they
11107				// need to be added here?
11108				return false
11109			} else if v1 == v2 {
11110				continue
11111			}
11112			return v1 > v2
11113		}
11114	}
11115	return false // Times and/or Aux fields are equal.
11116}
11117
11118func (h *booleanSortedMergeHeap) Push(x interface{}) {
11119	h.items = append(h.items, x.(*booleanSortedMergeHeapItem))
11120}
11121
11122func (h *booleanSortedMergeHeap) Pop() interface{} {
11123	old := h.items
11124	n := len(old)
11125	item := old[n-1]
11126	h.items = old[0 : n-1]
11127	return item
11128}
11129
11130type booleanSortedMergeHeapItem struct {
11131	point *BooleanPoint
11132	err   error
11133	itr   BooleanIterator
11134}
11135
11136// booleanIteratorScanner scans the results of a BooleanIterator into a map.
11137type booleanIteratorScanner struct {
11138	input        *bufBooleanIterator
11139	err          error
11140	keys         []influxql.VarRef
11141	defaultValue interface{}
11142}
11143
11144// newBooleanIteratorScanner creates a new IteratorScanner.
11145func newBooleanIteratorScanner(input BooleanIterator, keys []influxql.VarRef, defaultValue interface{}) *booleanIteratorScanner {
11146	return &booleanIteratorScanner{
11147		input:        newBufBooleanIterator(input),
11148		keys:         keys,
11149		defaultValue: defaultValue,
11150	}
11151}
11152
11153func (s *booleanIteratorScanner) Peek() (int64, string, Tags) {
11154	if s.err != nil {
11155		return ZeroTime, "", Tags{}
11156	}
11157
11158	p, err := s.input.peek()
11159	if err != nil {
11160		s.err = err
11161		return ZeroTime, "", Tags{}
11162	} else if p == nil {
11163		return ZeroTime, "", Tags{}
11164	}
11165	return p.Time, p.Name, p.Tags
11166}
11167
11168func (s *booleanIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) {
11169	if s.err != nil {
11170		return
11171	}
11172
11173	p, err := s.input.Next()
11174	if err != nil {
11175		s.err = err
11176		return
11177	} else if p == nil {
11178		s.useDefaults(m)
11179		return
11180	} else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) {
11181		s.useDefaults(m)
11182		s.input.unread(p)
11183		return
11184	}
11185
11186	if k := s.keys[0]; k.Val != "" {
11187		if p.Nil {
11188			if s.defaultValue != SkipDefault {
11189				m[k.Val] = castToType(s.defaultValue, k.Type)
11190			}
11191		} else {
11192			m[k.Val] = p.Value
11193		}
11194	}
11195	for i, v := range p.Aux {
11196		k := s.keys[i+1]
11197		switch v.(type) {
11198		case float64, int64, uint64, string, bool:
11199			m[k.Val] = v
11200		default:
11201			// Insert the fill value if one was specified.
11202			if s.defaultValue != SkipDefault {
11203				m[k.Val] = castToType(s.defaultValue, k.Type)
11204			}
11205		}
11206	}
11207}
11208
11209func (s *booleanIteratorScanner) useDefaults(m map[string]interface{}) {
11210	if s.defaultValue == SkipDefault {
11211		return
11212	}
11213	for _, k := range s.keys {
11214		if k.Val == "" {
11215			continue
11216		}
11217		m[k.Val] = castToType(s.defaultValue, k.Type)
11218	}
11219}
11220
11221func (s *booleanIteratorScanner) Stats() IteratorStats { return s.input.Stats() }
11222func (s *booleanIteratorScanner) Err() error           { return s.err }
11223func (s *booleanIteratorScanner) Close() error         { return s.input.Close() }
11224
11225// booleanParallelIterator represents an iterator that pulls data in a separate goroutine.
11226type booleanParallelIterator struct {
11227	input BooleanIterator
11228	ch    chan booleanPointError
11229
11230	once    sync.Once
11231	closing chan struct{}
11232	wg      sync.WaitGroup
11233}
11234
11235// newBooleanParallelIterator returns a new instance of booleanParallelIterator.
11236func newBooleanParallelIterator(input BooleanIterator) *booleanParallelIterator {
11237	itr := &booleanParallelIterator{
11238		input:   input,
11239		ch:      make(chan booleanPointError, 256),
11240		closing: make(chan struct{}),
11241	}
11242	itr.wg.Add(1)
11243	go itr.monitor()
11244	return itr
11245}
11246
11247// Stats returns stats from the underlying iterator.
11248func (itr *booleanParallelIterator) Stats() IteratorStats { return itr.input.Stats() }
11249
11250// Close closes the underlying iterators.
11251func (itr *booleanParallelIterator) Close() error {
11252	itr.once.Do(func() { close(itr.closing) })
11253	itr.wg.Wait()
11254	return itr.input.Close()
11255}
11256
11257// Next returns the next point from the iterator.
11258func (itr *booleanParallelIterator) Next() (*BooleanPoint, error) {
11259	v, ok := <-itr.ch
11260	if !ok {
11261		return nil, io.EOF
11262	}
11263	return v.point, v.err
11264}
11265
11266// monitor runs in a separate goroutine and actively pulls the next point.
11267func (itr *booleanParallelIterator) monitor() {
11268	defer close(itr.ch)
11269	defer itr.wg.Done()
11270
11271	for {
11272		// Read next point.
11273		p, err := itr.input.Next()
11274		if p != nil {
11275			p = p.Clone()
11276		}
11277
11278		select {
11279		case <-itr.closing:
11280			return
11281		case itr.ch <- booleanPointError{point: p, err: err}:
11282		}
11283	}
11284}
11285
11286type booleanPointError struct {
11287	point *BooleanPoint
11288	err   error
11289}
11290
11291// booleanLimitIterator represents an iterator that limits points per group.
11292type booleanLimitIterator struct {
11293	input BooleanIterator
11294	opt   IteratorOptions
11295	n     int
11296
11297	prev struct {
11298		name string
11299		tags Tags
11300	}
11301}
11302
11303// newBooleanLimitIterator returns a new instance of booleanLimitIterator.
11304func newBooleanLimitIterator(input BooleanIterator, opt IteratorOptions) *booleanLimitIterator {
11305	return &booleanLimitIterator{
11306		input: input,
11307		opt:   opt,
11308	}
11309}
11310
11311// Stats returns stats from the underlying iterator.
11312func (itr *booleanLimitIterator) Stats() IteratorStats { return itr.input.Stats() }
11313
11314// Close closes the underlying iterators.
11315func (itr *booleanLimitIterator) Close() error { return itr.input.Close() }
11316
11317// Next returns the next point from the iterator.
11318func (itr *booleanLimitIterator) Next() (*BooleanPoint, error) {
11319	for {
11320		p, err := itr.input.Next()
11321		if p == nil || err != nil {
11322			return nil, err
11323		}
11324
11325		// Reset window and counter if a new window is encountered.
11326		if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) {
11327			itr.prev.name = p.Name
11328			itr.prev.tags = p.Tags
11329			itr.n = 0
11330		}
11331
11332		// Increment counter.
11333		itr.n++
11334
11335		// Read next point if not beyond the offset.
11336		if itr.n <= itr.opt.Offset {
11337			continue
11338		}
11339
11340		// Read next point if we're beyond the limit.
11341		if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit {
11342			continue
11343		}
11344
11345		return p, nil
11346	}
11347}
11348
11349type booleanFillIterator struct {
11350	input     *bufBooleanIterator
11351	prev      BooleanPoint
11352	startTime int64
11353	endTime   int64
11354	auxFields []interface{}
11355	init      bool
11356	opt       IteratorOptions
11357
11358	window struct {
11359		name   string
11360		tags   Tags
11361		time   int64
11362		offset int64
11363	}
11364}
11365
11366func newBooleanFillIterator(input BooleanIterator, expr influxql.Expr, opt IteratorOptions) *booleanFillIterator {
11367	if opt.Fill == influxql.NullFill {
11368		if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" {
11369			opt.Fill = influxql.NumberFill
11370			opt.FillValue = false
11371		}
11372	}
11373
11374	var startTime, endTime int64
11375	if opt.Ascending {
11376		startTime, _ = opt.Window(opt.StartTime)
11377		endTime, _ = opt.Window(opt.EndTime)
11378	} else {
11379		startTime, _ = opt.Window(opt.EndTime)
11380		endTime, _ = opt.Window(opt.StartTime)
11381	}
11382
11383	var auxFields []interface{}
11384	if len(opt.Aux) > 0 {
11385		auxFields = make([]interface{}, len(opt.Aux))
11386	}
11387
11388	return &booleanFillIterator{
11389		input:     newBufBooleanIterator(input),
11390		prev:      BooleanPoint{Nil: true},
11391		startTime: startTime,
11392		endTime:   endTime,
11393		auxFields: auxFields,
11394		opt:       opt,
11395	}
11396}
11397
11398func (itr *booleanFillIterator) Stats() IteratorStats { return itr.input.Stats() }
11399func (itr *booleanFillIterator) Close() error         { return itr.input.Close() }
11400
11401func (itr *booleanFillIterator) Next() (*BooleanPoint, error) {
11402	if !itr.init {
11403		p, err := itr.input.peek()
11404		if p == nil || err != nil {
11405			return nil, err
11406		}
11407		itr.window.name, itr.window.tags = p.Name, p.Tags
11408		itr.window.time = itr.startTime
11409		if itr.startTime == influxql.MinTime {
11410			itr.window.time, _ = itr.opt.Window(p.Time)
11411		}
11412		if itr.opt.Location != nil {
11413			_, itr.window.offset = itr.opt.Zone(itr.window.time)
11414		}
11415		itr.init = true
11416	}
11417
11418	p, err := itr.input.Next()
11419	if err != nil {
11420		return nil, err
11421	}
11422
11423	// Check if the next point is outside of our window or is nil.
11424	if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() {
11425		// If we are inside of an interval, unread the point and continue below to
11426		// constructing a new point.
11427		if itr.opt.Ascending && itr.window.time <= itr.endTime {
11428			itr.input.unread(p)
11429			p = nil
11430			goto CONSTRUCT
11431		} else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime {
11432			itr.input.unread(p)
11433			p = nil
11434			goto CONSTRUCT
11435		}
11436
11437		// We are *not* in a current interval. If there is no next point,
11438		// we are at the end of all intervals.
11439		if p == nil {
11440			return nil, nil
11441		}
11442
11443		// Set the new interval.
11444		itr.window.name, itr.window.tags = p.Name, p.Tags
11445		itr.window.time = itr.startTime
11446		if itr.window.time == influxql.MinTime {
11447			itr.window.time, _ = itr.opt.Window(p.Time)
11448		}
11449		if itr.opt.Location != nil {
11450			_, itr.window.offset = itr.opt.Zone(itr.window.time)
11451		}
11452		itr.prev = BooleanPoint{Nil: true}
11453	}
11454
11455	// Check if the point is our next expected point.
11456CONSTRUCT:
11457	if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) {
11458		if p != nil {
11459			itr.input.unread(p)
11460		}
11461
11462		p = &BooleanPoint{
11463			Name: itr.window.name,
11464			Tags: itr.window.tags,
11465			Time: itr.window.time,
11466			Aux:  itr.auxFields,
11467		}
11468
11469		switch itr.opt.Fill {
11470		case influxql.LinearFill:
11471			fallthrough
11472		case influxql.NullFill:
11473			p.Nil = true
11474		case influxql.NumberFill:
11475			p.Value, _ = castToBoolean(itr.opt.FillValue)
11476		case influxql.PreviousFill:
11477			if !itr.prev.Nil {
11478				p.Value = itr.prev.Value
11479				p.Nil = itr.prev.Nil
11480			} else {
11481				p.Nil = true
11482			}
11483		}
11484	} else {
11485		itr.prev = *p
11486	}
11487
11488	// Advance the expected time. Do not advance to a new window here
11489	// as there may be lingering points with the same timestamp in the previous
11490	// window.
11491	if itr.opt.Ascending {
11492		itr.window.time += int64(itr.opt.Interval.Duration)
11493	} else {
11494		itr.window.time -= int64(itr.opt.Interval.Duration)
11495	}
11496
11497	// Check to see if we have passed over an offset change and adjust the time
11498	// to account for this new offset.
11499	if itr.opt.Location != nil {
11500		if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset {
11501			diff := itr.window.offset - offset
11502			if abs(diff) < int64(itr.opt.Interval.Duration) {
11503				itr.window.time += diff
11504			}
11505			itr.window.offset = offset
11506		}
11507	}
11508	return p, nil
11509}
11510
11511// booleanIntervalIterator represents a boolean implementation of IntervalIterator.
11512type booleanIntervalIterator struct {
11513	input BooleanIterator
11514	opt   IteratorOptions
11515}
11516
11517func newBooleanIntervalIterator(input BooleanIterator, opt IteratorOptions) *booleanIntervalIterator {
11518	return &booleanIntervalIterator{input: input, opt: opt}
11519}
11520
11521func (itr *booleanIntervalIterator) Stats() IteratorStats { return itr.input.Stats() }
11522func (itr *booleanIntervalIterator) Close() error         { return itr.input.Close() }
11523
11524func (itr *booleanIntervalIterator) Next() (*BooleanPoint, error) {
11525	p, err := itr.input.Next()
11526	if p == nil || err != nil {
11527		return nil, err
11528	}
11529	p.Time, _ = itr.opt.Window(p.Time)
11530	// If we see the minimum allowable time, set the time to zero so we don't
11531	// break the default returned time for aggregate queries without times.
11532	if p.Time == influxql.MinTime {
11533		p.Time = 0
11534	}
11535	return p, nil
11536}
11537
11538// booleanInterruptIterator represents a boolean implementation of InterruptIterator.
11539type booleanInterruptIterator struct {
11540	input   BooleanIterator
11541	closing <-chan struct{}
11542	count   int
11543}
11544
11545func newBooleanInterruptIterator(input BooleanIterator, closing <-chan struct{}) *booleanInterruptIterator {
11546	return &booleanInterruptIterator{input: input, closing: closing}
11547}
11548
11549func (itr *booleanInterruptIterator) Stats() IteratorStats { return itr.input.Stats() }
11550func (itr *booleanInterruptIterator) Close() error         { return itr.input.Close() }
11551
11552func (itr *booleanInterruptIterator) Next() (*BooleanPoint, error) {
11553	// Only check if the channel is closed every N points. This
11554	// intentionally checks on both 0 and N so that if the iterator
11555	// has been interrupted before the first point is emitted it will
11556	// not emit any points.
11557	if itr.count&0xFF == 0xFF {
11558		select {
11559		case <-itr.closing:
11560			return nil, itr.Close()
11561		default:
11562			// Reset iterator count to zero and fall through to emit the next point.
11563			itr.count = 0
11564		}
11565	}
11566
11567	// Increment the counter for every point read.
11568	itr.count++
11569	return itr.input.Next()
11570}
11571
11572// booleanCloseInterruptIterator represents a boolean implementation of CloseInterruptIterator.
11573type booleanCloseInterruptIterator struct {
11574	input   BooleanIterator
11575	closing <-chan struct{}
11576	done    chan struct{}
11577	once    sync.Once
11578}
11579
11580func newBooleanCloseInterruptIterator(input BooleanIterator, closing <-chan struct{}) *booleanCloseInterruptIterator {
11581	itr := &booleanCloseInterruptIterator{
11582		input:   input,
11583		closing: closing,
11584		done:    make(chan struct{}),
11585	}
11586	go itr.monitor()
11587	return itr
11588}
11589
11590func (itr *booleanCloseInterruptIterator) monitor() {
11591	select {
11592	case <-itr.closing:
11593		itr.Close()
11594	case <-itr.done:
11595	}
11596}
11597
11598func (itr *booleanCloseInterruptIterator) Stats() IteratorStats {
11599	return itr.input.Stats()
11600}
11601
11602func (itr *booleanCloseInterruptIterator) Close() error {
11603	itr.once.Do(func() {
11604		close(itr.done)
11605		itr.input.Close()
11606	})
11607	return nil
11608}
11609
11610func (itr *booleanCloseInterruptIterator) Next() (*BooleanPoint, error) {
11611	p, err := itr.input.Next()
11612	if err != nil {
11613		// Check if the iterator was closed.
11614		select {
11615		case <-itr.done:
11616			return nil, nil
11617		default:
11618			return nil, err
11619		}
11620	}
11621	return p, nil
11622}
11623
11624// booleanReduceFloatIterator executes a reducer for every interval and buffers the result.
11625type booleanReduceFloatIterator struct {
11626	input    *bufBooleanIterator
11627	create   func() (BooleanPointAggregator, FloatPointEmitter)
11628	dims     []string
11629	opt      IteratorOptions
11630	points   []FloatPoint
11631	keepTags bool
11632}
11633
11634func newBooleanReduceFloatIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, FloatPointEmitter)) *booleanReduceFloatIterator {
11635	return &booleanReduceFloatIterator{
11636		input:  newBufBooleanIterator(input),
11637		create: createFn,
11638		dims:   opt.GetDimensions(),
11639		opt:    opt,
11640	}
11641}
11642
11643// Stats returns stats from the input iterator.
11644func (itr *booleanReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
11645
11646// Close closes the iterator and all child iterators.
11647func (itr *booleanReduceFloatIterator) Close() error { return itr.input.Close() }
11648
11649// Next returns the minimum value for the next available interval.
11650func (itr *booleanReduceFloatIterator) Next() (*FloatPoint, error) {
11651	// Calculate next window if we have no more points.
11652	if len(itr.points) == 0 {
11653		var err error
11654		itr.points, err = itr.reduce()
11655		if len(itr.points) == 0 {
11656			return nil, err
11657		}
11658	}
11659
11660	// Pop next point off the stack.
11661	p := &itr.points[len(itr.points)-1]
11662	itr.points = itr.points[:len(itr.points)-1]
11663	return p, nil
11664}
11665
11666// booleanReduceFloatPoint stores the reduced data for a name/tag combination.
11667type booleanReduceFloatPoint struct {
11668	Name       string
11669	Tags       Tags
11670	Aggregator BooleanPointAggregator
11671	Emitter    FloatPointEmitter
11672}
11673
11674// reduce executes fn once for every point in the next window.
11675// The previous value for the dimension is passed to fn.
11676func (itr *booleanReduceFloatIterator) reduce() ([]FloatPoint, error) {
11677	// Calculate next window.
11678	var (
11679		startTime, endTime int64
11680		window             struct {
11681			name string
11682			tags string
11683		}
11684	)
11685	for {
11686		p, err := itr.input.Next()
11687		if err != nil || p == nil {
11688			return nil, err
11689		} else if p.Nil {
11690			continue
11691		}
11692
11693		// Unread the point so it can be processed.
11694		itr.input.unread(p)
11695		startTime, endTime = itr.opt.Window(p.Time)
11696		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
11697		break
11698	}
11699
11700	// Create points by tags.
11701	m := make(map[string]*booleanReduceFloatPoint)
11702	for {
11703		// Read next point.
11704		curr, err := itr.input.NextInWindow(startTime, endTime)
11705		if err != nil {
11706			return nil, err
11707		} else if curr == nil {
11708			break
11709		} else if curr.Nil {
11710			continue
11711		} else if curr.Name != window.name {
11712			itr.input.unread(curr)
11713			break
11714		}
11715
11716		// Ensure this point is within the same final window.
11717		if curr.Name != window.name {
11718			itr.input.unread(curr)
11719			break
11720		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
11721			itr.input.unread(curr)
11722			break
11723		}
11724
11725		// Retrieve the tags on this point for this level of the query.
11726		// This may be different than the bucket dimensions.
11727		tags := curr.Tags.Subset(itr.dims)
11728		id := tags.ID()
11729
11730		// Retrieve the aggregator for this name/tag combination or create one.
11731		rp := m[id]
11732		if rp == nil {
11733			aggregator, emitter := itr.create()
11734			rp = &booleanReduceFloatPoint{
11735				Name:       curr.Name,
11736				Tags:       tags,
11737				Aggregator: aggregator,
11738				Emitter:    emitter,
11739			}
11740			m[id] = rp
11741		}
11742		rp.Aggregator.AggregateBoolean(curr)
11743	}
11744
11745	keys := make([]string, 0, len(m))
11746	for k := range m {
11747		keys = append(keys, k)
11748	}
11749
11750	// Reverse sort points by name & tag.
11751	// This ensures a consistent order of output.
11752	if len(keys) > 0 {
11753		var sorted sort.Interface = sort.StringSlice(keys)
11754		if itr.opt.Ascending {
11755			sorted = sort.Reverse(sorted)
11756		}
11757		sort.Sort(sorted)
11758	}
11759
11760	// Assume the points are already sorted until proven otherwise.
11761	sortedByTime := true
11762	// Emit the points for each name & tag combination.
11763	a := make([]FloatPoint, 0, len(m))
11764	for _, k := range keys {
11765		rp := m[k]
11766		points := rp.Emitter.Emit()
11767		for i := len(points) - 1; i >= 0; i-- {
11768			points[i].Name = rp.Name
11769			if !itr.keepTags {
11770				points[i].Tags = rp.Tags
11771			}
11772			// Set the points time to the interval time if the reducer didn't provide one.
11773			if points[i].Time == ZeroTime {
11774				points[i].Time = startTime
11775			} else {
11776				sortedByTime = false
11777			}
11778			a = append(a, points[i])
11779		}
11780	}
11781	// Points may be out of order. Perform a stable sort by time if requested.
11782	if !sortedByTime && itr.opt.Ordered {
11783		var sorted sort.Interface = floatPointsByTime(a)
11784		if itr.opt.Ascending {
11785			sorted = sort.Reverse(sorted)
11786		}
11787		sort.Stable(sorted)
11788	}
11789	return a, nil
11790}
11791
11792// booleanStreamFloatIterator streams inputs into the iterator and emits points gradually.
11793type booleanStreamFloatIterator struct {
11794	input  *bufBooleanIterator
11795	create func() (BooleanPointAggregator, FloatPointEmitter)
11796	dims   []string
11797	opt    IteratorOptions
11798	m      map[string]*booleanReduceFloatPoint
11799	points []FloatPoint
11800}
11801
11802// newBooleanStreamFloatIterator returns a new instance of booleanStreamFloatIterator.
11803func newBooleanStreamFloatIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, FloatPointEmitter), opt IteratorOptions) *booleanStreamFloatIterator {
11804	return &booleanStreamFloatIterator{
11805		input:  newBufBooleanIterator(input),
11806		create: createFn,
11807		dims:   opt.GetDimensions(),
11808		opt:    opt,
11809		m:      make(map[string]*booleanReduceFloatPoint),
11810	}
11811}
11812
11813// Stats returns stats from the input iterator.
11814func (itr *booleanStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
11815
11816// Close closes the iterator and all child iterators.
11817func (itr *booleanStreamFloatIterator) Close() error { return itr.input.Close() }
11818
11819// Next returns the next value for the stream iterator.
11820func (itr *booleanStreamFloatIterator) Next() (*FloatPoint, error) {
11821	// Calculate next window if we have no more points.
11822	if len(itr.points) == 0 {
11823		var err error
11824		itr.points, err = itr.reduce()
11825		if len(itr.points) == 0 {
11826			return nil, err
11827		}
11828	}
11829
11830	// Pop next point off the stack.
11831	p := &itr.points[len(itr.points)-1]
11832	itr.points = itr.points[:len(itr.points)-1]
11833	return p, nil
11834}
11835
11836// reduce creates and manages aggregators for every point from the input.
11837// After aggregating a point, it always tries to emit a value using the emitter.
11838func (itr *booleanStreamFloatIterator) reduce() ([]FloatPoint, error) {
11839	// We have already read all of the input points.
11840	if itr.m == nil {
11841		return nil, nil
11842	}
11843
11844	for {
11845		// Read next point.
11846		curr, err := itr.input.Next()
11847		if err != nil {
11848			return nil, err
11849		} else if curr == nil {
11850			// Close all of the aggregators to flush any remaining points to emit.
11851			var points []FloatPoint
11852			for _, rp := range itr.m {
11853				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
11854					if err := aggregator.Close(); err != nil {
11855						return nil, err
11856					}
11857
11858					pts := rp.Emitter.Emit()
11859					if len(pts) == 0 {
11860						continue
11861					}
11862
11863					for i := range pts {
11864						pts[i].Name = rp.Name
11865						pts[i].Tags = rp.Tags
11866					}
11867					points = append(points, pts...)
11868				}
11869			}
11870
11871			// Eliminate the aggregators and emitters.
11872			itr.m = nil
11873			return points, nil
11874		} else if curr.Nil {
11875			continue
11876		}
11877		tags := curr.Tags.Subset(itr.dims)
11878
11879		id := curr.Name
11880		if len(tags.m) > 0 {
11881			id += "\x00" + tags.ID()
11882		}
11883
11884		// Retrieve the aggregator for this name/tag combination or create one.
11885		rp := itr.m[id]
11886		if rp == nil {
11887			aggregator, emitter := itr.create()
11888			rp = &booleanReduceFloatPoint{
11889				Name:       curr.Name,
11890				Tags:       tags,
11891				Aggregator: aggregator,
11892				Emitter:    emitter,
11893			}
11894			itr.m[id] = rp
11895		}
11896		rp.Aggregator.AggregateBoolean(curr)
11897
11898		// Attempt to emit points from the aggregator.
11899		points := rp.Emitter.Emit()
11900		if len(points) == 0 {
11901			continue
11902		}
11903
11904		for i := range points {
11905			points[i].Name = rp.Name
11906			points[i].Tags = rp.Tags
11907		}
11908		return points, nil
11909	}
11910}
11911
11912// booleanReduceIntegerIterator executes a reducer for every interval and buffers the result.
11913type booleanReduceIntegerIterator struct {
11914	input    *bufBooleanIterator
11915	create   func() (BooleanPointAggregator, IntegerPointEmitter)
11916	dims     []string
11917	opt      IteratorOptions
11918	points   []IntegerPoint
11919	keepTags bool
11920}
11921
11922func newBooleanReduceIntegerIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, IntegerPointEmitter)) *booleanReduceIntegerIterator {
11923	return &booleanReduceIntegerIterator{
11924		input:  newBufBooleanIterator(input),
11925		create: createFn,
11926		dims:   opt.GetDimensions(),
11927		opt:    opt,
11928	}
11929}
11930
11931// Stats returns stats from the input iterator.
11932func (itr *booleanReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
11933
11934// Close closes the iterator and all child iterators.
11935func (itr *booleanReduceIntegerIterator) Close() error { return itr.input.Close() }
11936
11937// Next returns the minimum value for the next available interval.
11938func (itr *booleanReduceIntegerIterator) Next() (*IntegerPoint, error) {
11939	// Calculate next window if we have no more points.
11940	if len(itr.points) == 0 {
11941		var err error
11942		itr.points, err = itr.reduce()
11943		if len(itr.points) == 0 {
11944			return nil, err
11945		}
11946	}
11947
11948	// Pop next point off the stack.
11949	p := &itr.points[len(itr.points)-1]
11950	itr.points = itr.points[:len(itr.points)-1]
11951	return p, nil
11952}
11953
11954// booleanReduceIntegerPoint stores the reduced data for a name/tag combination.
11955type booleanReduceIntegerPoint struct {
11956	Name       string
11957	Tags       Tags
11958	Aggregator BooleanPointAggregator
11959	Emitter    IntegerPointEmitter
11960}
11961
11962// reduce executes fn once for every point in the next window.
11963// The previous value for the dimension is passed to fn.
11964func (itr *booleanReduceIntegerIterator) reduce() ([]IntegerPoint, error) {
11965	// Calculate next window.
11966	var (
11967		startTime, endTime int64
11968		window             struct {
11969			name string
11970			tags string
11971		}
11972	)
11973	for {
11974		p, err := itr.input.Next()
11975		if err != nil || p == nil {
11976			return nil, err
11977		} else if p.Nil {
11978			continue
11979		}
11980
11981		// Unread the point so it can be processed.
11982		itr.input.unread(p)
11983		startTime, endTime = itr.opt.Window(p.Time)
11984		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
11985		break
11986	}
11987
11988	// Create points by tags.
11989	m := make(map[string]*booleanReduceIntegerPoint)
11990	for {
11991		// Read next point.
11992		curr, err := itr.input.NextInWindow(startTime, endTime)
11993		if err != nil {
11994			return nil, err
11995		} else if curr == nil {
11996			break
11997		} else if curr.Nil {
11998			continue
11999		} else if curr.Name != window.name {
12000			itr.input.unread(curr)
12001			break
12002		}
12003
12004		// Ensure this point is within the same final window.
12005		if curr.Name != window.name {
12006			itr.input.unread(curr)
12007			break
12008		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
12009			itr.input.unread(curr)
12010			break
12011		}
12012
12013		// Retrieve the tags on this point for this level of the query.
12014		// This may be different than the bucket dimensions.
12015		tags := curr.Tags.Subset(itr.dims)
12016		id := tags.ID()
12017
12018		// Retrieve the aggregator for this name/tag combination or create one.
12019		rp := m[id]
12020		if rp == nil {
12021			aggregator, emitter := itr.create()
12022			rp = &booleanReduceIntegerPoint{
12023				Name:       curr.Name,
12024				Tags:       tags,
12025				Aggregator: aggregator,
12026				Emitter:    emitter,
12027			}
12028			m[id] = rp
12029		}
12030		rp.Aggregator.AggregateBoolean(curr)
12031	}
12032
12033	keys := make([]string, 0, len(m))
12034	for k := range m {
12035		keys = append(keys, k)
12036	}
12037
12038	// Reverse sort points by name & tag.
12039	// This ensures a consistent order of output.
12040	if len(keys) > 0 {
12041		var sorted sort.Interface = sort.StringSlice(keys)
12042		if itr.opt.Ascending {
12043			sorted = sort.Reverse(sorted)
12044		}
12045		sort.Sort(sorted)
12046	}
12047
12048	// Assume the points are already sorted until proven otherwise.
12049	sortedByTime := true
12050	// Emit the points for each name & tag combination.
12051	a := make([]IntegerPoint, 0, len(m))
12052	for _, k := range keys {
12053		rp := m[k]
12054		points := rp.Emitter.Emit()
12055		for i := len(points) - 1; i >= 0; i-- {
12056			points[i].Name = rp.Name
12057			if !itr.keepTags {
12058				points[i].Tags = rp.Tags
12059			}
12060			// Set the points time to the interval time if the reducer didn't provide one.
12061			if points[i].Time == ZeroTime {
12062				points[i].Time = startTime
12063			} else {
12064				sortedByTime = false
12065			}
12066			a = append(a, points[i])
12067		}
12068	}
12069	// Points may be out of order. Perform a stable sort by time if requested.
12070	if !sortedByTime && itr.opt.Ordered {
12071		var sorted sort.Interface = integerPointsByTime(a)
12072		if itr.opt.Ascending {
12073			sorted = sort.Reverse(sorted)
12074		}
12075		sort.Stable(sorted)
12076	}
12077	return a, nil
12078}
12079
12080// booleanStreamIntegerIterator streams inputs into the iterator and emits points gradually.
12081type booleanStreamIntegerIterator struct {
12082	input  *bufBooleanIterator
12083	create func() (BooleanPointAggregator, IntegerPointEmitter)
12084	dims   []string
12085	opt    IteratorOptions
12086	m      map[string]*booleanReduceIntegerPoint
12087	points []IntegerPoint
12088}
12089
12090// newBooleanStreamIntegerIterator returns a new instance of booleanStreamIntegerIterator.
12091func newBooleanStreamIntegerIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, IntegerPointEmitter), opt IteratorOptions) *booleanStreamIntegerIterator {
12092	return &booleanStreamIntegerIterator{
12093		input:  newBufBooleanIterator(input),
12094		create: createFn,
12095		dims:   opt.GetDimensions(),
12096		opt:    opt,
12097		m:      make(map[string]*booleanReduceIntegerPoint),
12098	}
12099}
12100
12101// Stats returns stats from the input iterator.
12102func (itr *booleanStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
12103
12104// Close closes the iterator and all child iterators.
12105func (itr *booleanStreamIntegerIterator) Close() error { return itr.input.Close() }
12106
12107// Next returns the next value for the stream iterator.
12108func (itr *booleanStreamIntegerIterator) Next() (*IntegerPoint, error) {
12109	// Calculate next window if we have no more points.
12110	if len(itr.points) == 0 {
12111		var err error
12112		itr.points, err = itr.reduce()
12113		if len(itr.points) == 0 {
12114			return nil, err
12115		}
12116	}
12117
12118	// Pop next point off the stack.
12119	p := &itr.points[len(itr.points)-1]
12120	itr.points = itr.points[:len(itr.points)-1]
12121	return p, nil
12122}
12123
12124// reduce creates and manages aggregators for every point from the input.
12125// After aggregating a point, it always tries to emit a value using the emitter.
12126func (itr *booleanStreamIntegerIterator) reduce() ([]IntegerPoint, error) {
12127	// We have already read all of the input points.
12128	if itr.m == nil {
12129		return nil, nil
12130	}
12131
12132	for {
12133		// Read next point.
12134		curr, err := itr.input.Next()
12135		if err != nil {
12136			return nil, err
12137		} else if curr == nil {
12138			// Close all of the aggregators to flush any remaining points to emit.
12139			var points []IntegerPoint
12140			for _, rp := range itr.m {
12141				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
12142					if err := aggregator.Close(); err != nil {
12143						return nil, err
12144					}
12145
12146					pts := rp.Emitter.Emit()
12147					if len(pts) == 0 {
12148						continue
12149					}
12150
12151					for i := range pts {
12152						pts[i].Name = rp.Name
12153						pts[i].Tags = rp.Tags
12154					}
12155					points = append(points, pts...)
12156				}
12157			}
12158
12159			// Eliminate the aggregators and emitters.
12160			itr.m = nil
12161			return points, nil
12162		} else if curr.Nil {
12163			continue
12164		}
12165		tags := curr.Tags.Subset(itr.dims)
12166
12167		id := curr.Name
12168		if len(tags.m) > 0 {
12169			id += "\x00" + tags.ID()
12170		}
12171
12172		// Retrieve the aggregator for this name/tag combination or create one.
12173		rp := itr.m[id]
12174		if rp == nil {
12175			aggregator, emitter := itr.create()
12176			rp = &booleanReduceIntegerPoint{
12177				Name:       curr.Name,
12178				Tags:       tags,
12179				Aggregator: aggregator,
12180				Emitter:    emitter,
12181			}
12182			itr.m[id] = rp
12183		}
12184		rp.Aggregator.AggregateBoolean(curr)
12185
12186		// Attempt to emit points from the aggregator.
12187		points := rp.Emitter.Emit()
12188		if len(points) == 0 {
12189			continue
12190		}
12191
12192		for i := range points {
12193			points[i].Name = rp.Name
12194			points[i].Tags = rp.Tags
12195		}
12196		return points, nil
12197	}
12198}
12199
12200// booleanReduceUnsignedIterator executes a reducer for every interval and buffers the result.
12201type booleanReduceUnsignedIterator struct {
12202	input    *bufBooleanIterator
12203	create   func() (BooleanPointAggregator, UnsignedPointEmitter)
12204	dims     []string
12205	opt      IteratorOptions
12206	points   []UnsignedPoint
12207	keepTags bool
12208}
12209
12210func newBooleanReduceUnsignedIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, UnsignedPointEmitter)) *booleanReduceUnsignedIterator {
12211	return &booleanReduceUnsignedIterator{
12212		input:  newBufBooleanIterator(input),
12213		create: createFn,
12214		dims:   opt.GetDimensions(),
12215		opt:    opt,
12216	}
12217}
12218
12219// Stats returns stats from the input iterator.
12220func (itr *booleanReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
12221
12222// Close closes the iterator and all child iterators.
12223func (itr *booleanReduceUnsignedIterator) Close() error { return itr.input.Close() }
12224
12225// Next returns the minimum value for the next available interval.
12226func (itr *booleanReduceUnsignedIterator) Next() (*UnsignedPoint, error) {
12227	// Calculate next window if we have no more points.
12228	if len(itr.points) == 0 {
12229		var err error
12230		itr.points, err = itr.reduce()
12231		if len(itr.points) == 0 {
12232			return nil, err
12233		}
12234	}
12235
12236	// Pop next point off the stack.
12237	p := &itr.points[len(itr.points)-1]
12238	itr.points = itr.points[:len(itr.points)-1]
12239	return p, nil
12240}
12241
12242// booleanReduceUnsignedPoint stores the reduced data for a name/tag combination.
12243type booleanReduceUnsignedPoint struct {
12244	Name       string
12245	Tags       Tags
12246	Aggregator BooleanPointAggregator
12247	Emitter    UnsignedPointEmitter
12248}
12249
12250// reduce executes fn once for every point in the next window.
12251// The previous value for the dimension is passed to fn.
12252func (itr *booleanReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) {
12253	// Calculate next window.
12254	var (
12255		startTime, endTime int64
12256		window             struct {
12257			name string
12258			tags string
12259		}
12260	)
12261	for {
12262		p, err := itr.input.Next()
12263		if err != nil || p == nil {
12264			return nil, err
12265		} else if p.Nil {
12266			continue
12267		}
12268
12269		// Unread the point so it can be processed.
12270		itr.input.unread(p)
12271		startTime, endTime = itr.opt.Window(p.Time)
12272		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
12273		break
12274	}
12275
12276	// Create points by tags.
12277	m := make(map[string]*booleanReduceUnsignedPoint)
12278	for {
12279		// Read next point.
12280		curr, err := itr.input.NextInWindow(startTime, endTime)
12281		if err != nil {
12282			return nil, err
12283		} else if curr == nil {
12284			break
12285		} else if curr.Nil {
12286			continue
12287		} else if curr.Name != window.name {
12288			itr.input.unread(curr)
12289			break
12290		}
12291
12292		// Ensure this point is within the same final window.
12293		if curr.Name != window.name {
12294			itr.input.unread(curr)
12295			break
12296		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
12297			itr.input.unread(curr)
12298			break
12299		}
12300
12301		// Retrieve the tags on this point for this level of the query.
12302		// This may be different than the bucket dimensions.
12303		tags := curr.Tags.Subset(itr.dims)
12304		id := tags.ID()
12305
12306		// Retrieve the aggregator for this name/tag combination or create one.
12307		rp := m[id]
12308		if rp == nil {
12309			aggregator, emitter := itr.create()
12310			rp = &booleanReduceUnsignedPoint{
12311				Name:       curr.Name,
12312				Tags:       tags,
12313				Aggregator: aggregator,
12314				Emitter:    emitter,
12315			}
12316			m[id] = rp
12317		}
12318		rp.Aggregator.AggregateBoolean(curr)
12319	}
12320
12321	keys := make([]string, 0, len(m))
12322	for k := range m {
12323		keys = append(keys, k)
12324	}
12325
12326	// Reverse sort points by name & tag.
12327	// This ensures a consistent order of output.
12328	if len(keys) > 0 {
12329		var sorted sort.Interface = sort.StringSlice(keys)
12330		if itr.opt.Ascending {
12331			sorted = sort.Reverse(sorted)
12332		}
12333		sort.Sort(sorted)
12334	}
12335
12336	// Assume the points are already sorted until proven otherwise.
12337	sortedByTime := true
12338	// Emit the points for each name & tag combination.
12339	a := make([]UnsignedPoint, 0, len(m))
12340	for _, k := range keys {
12341		rp := m[k]
12342		points := rp.Emitter.Emit()
12343		for i := len(points) - 1; i >= 0; i-- {
12344			points[i].Name = rp.Name
12345			if !itr.keepTags {
12346				points[i].Tags = rp.Tags
12347			}
12348			// Set the points time to the interval time if the reducer didn't provide one.
12349			if points[i].Time == ZeroTime {
12350				points[i].Time = startTime
12351			} else {
12352				sortedByTime = false
12353			}
12354			a = append(a, points[i])
12355		}
12356	}
12357	// Points may be out of order. Perform a stable sort by time if requested.
12358	if !sortedByTime && itr.opt.Ordered {
12359		var sorted sort.Interface = unsignedPointsByTime(a)
12360		if itr.opt.Ascending {
12361			sorted = sort.Reverse(sorted)
12362		}
12363		sort.Stable(sorted)
12364	}
12365	return a, nil
12366}
12367
12368// booleanStreamUnsignedIterator streams inputs into the iterator and emits points gradually.
12369type booleanStreamUnsignedIterator struct {
12370	input  *bufBooleanIterator
12371	create func() (BooleanPointAggregator, UnsignedPointEmitter)
12372	dims   []string
12373	opt    IteratorOptions
12374	m      map[string]*booleanReduceUnsignedPoint
12375	points []UnsignedPoint
12376}
12377
12378// newBooleanStreamUnsignedIterator returns a new instance of booleanStreamUnsignedIterator.
12379func newBooleanStreamUnsignedIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *booleanStreamUnsignedIterator {
12380	return &booleanStreamUnsignedIterator{
12381		input:  newBufBooleanIterator(input),
12382		create: createFn,
12383		dims:   opt.GetDimensions(),
12384		opt:    opt,
12385		m:      make(map[string]*booleanReduceUnsignedPoint),
12386	}
12387}
12388
12389// Stats returns stats from the input iterator.
12390func (itr *booleanStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
12391
12392// Close closes the iterator and all child iterators.
12393func (itr *booleanStreamUnsignedIterator) Close() error { return itr.input.Close() }
12394
12395// Next returns the next value for the stream iterator.
12396func (itr *booleanStreamUnsignedIterator) Next() (*UnsignedPoint, error) {
12397	// Calculate next window if we have no more points.
12398	if len(itr.points) == 0 {
12399		var err error
12400		itr.points, err = itr.reduce()
12401		if len(itr.points) == 0 {
12402			return nil, err
12403		}
12404	}
12405
12406	// Pop next point off the stack.
12407	p := &itr.points[len(itr.points)-1]
12408	itr.points = itr.points[:len(itr.points)-1]
12409	return p, nil
12410}
12411
12412// reduce creates and manages aggregators for every point from the input.
12413// After aggregating a point, it always tries to emit a value using the emitter.
12414func (itr *booleanStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) {
12415	// We have already read all of the input points.
12416	if itr.m == nil {
12417		return nil, nil
12418	}
12419
12420	for {
12421		// Read next point.
12422		curr, err := itr.input.Next()
12423		if err != nil {
12424			return nil, err
12425		} else if curr == nil {
12426			// Close all of the aggregators to flush any remaining points to emit.
12427			var points []UnsignedPoint
12428			for _, rp := range itr.m {
12429				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
12430					if err := aggregator.Close(); err != nil {
12431						return nil, err
12432					}
12433
12434					pts := rp.Emitter.Emit()
12435					if len(pts) == 0 {
12436						continue
12437					}
12438
12439					for i := range pts {
12440						pts[i].Name = rp.Name
12441						pts[i].Tags = rp.Tags
12442					}
12443					points = append(points, pts...)
12444				}
12445			}
12446
12447			// Eliminate the aggregators and emitters.
12448			itr.m = nil
12449			return points, nil
12450		} else if curr.Nil {
12451			continue
12452		}
12453		tags := curr.Tags.Subset(itr.dims)
12454
12455		id := curr.Name
12456		if len(tags.m) > 0 {
12457			id += "\x00" + tags.ID()
12458		}
12459
12460		// Retrieve the aggregator for this name/tag combination or create one.
12461		rp := itr.m[id]
12462		if rp == nil {
12463			aggregator, emitter := itr.create()
12464			rp = &booleanReduceUnsignedPoint{
12465				Name:       curr.Name,
12466				Tags:       tags,
12467				Aggregator: aggregator,
12468				Emitter:    emitter,
12469			}
12470			itr.m[id] = rp
12471		}
12472		rp.Aggregator.AggregateBoolean(curr)
12473
12474		// Attempt to emit points from the aggregator.
12475		points := rp.Emitter.Emit()
12476		if len(points) == 0 {
12477			continue
12478		}
12479
12480		for i := range points {
12481			points[i].Name = rp.Name
12482			points[i].Tags = rp.Tags
12483		}
12484		return points, nil
12485	}
12486}
12487
12488// booleanReduceStringIterator executes a reducer for every interval and buffers the result.
12489type booleanReduceStringIterator struct {
12490	input    *bufBooleanIterator
12491	create   func() (BooleanPointAggregator, StringPointEmitter)
12492	dims     []string
12493	opt      IteratorOptions
12494	points   []StringPoint
12495	keepTags bool
12496}
12497
12498func newBooleanReduceStringIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, StringPointEmitter)) *booleanReduceStringIterator {
12499	return &booleanReduceStringIterator{
12500		input:  newBufBooleanIterator(input),
12501		create: createFn,
12502		dims:   opt.GetDimensions(),
12503		opt:    opt,
12504	}
12505}
12506
12507// Stats returns stats from the input iterator.
12508func (itr *booleanReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() }
12509
12510// Close closes the iterator and all child iterators.
12511func (itr *booleanReduceStringIterator) Close() error { return itr.input.Close() }
12512
12513// Next returns the minimum value for the next available interval.
12514func (itr *booleanReduceStringIterator) Next() (*StringPoint, error) {
12515	// Calculate next window if we have no more points.
12516	if len(itr.points) == 0 {
12517		var err error
12518		itr.points, err = itr.reduce()
12519		if len(itr.points) == 0 {
12520			return nil, err
12521		}
12522	}
12523
12524	// Pop next point off the stack.
12525	p := &itr.points[len(itr.points)-1]
12526	itr.points = itr.points[:len(itr.points)-1]
12527	return p, nil
12528}
12529
12530// booleanReduceStringPoint stores the reduced data for a name/tag combination.
12531type booleanReduceStringPoint struct {
12532	Name       string
12533	Tags       Tags
12534	Aggregator BooleanPointAggregator
12535	Emitter    StringPointEmitter
12536}
12537
12538// reduce executes fn once for every point in the next window.
12539// The previous value for the dimension is passed to fn.
12540func (itr *booleanReduceStringIterator) reduce() ([]StringPoint, error) {
12541	// Calculate next window.
12542	var (
12543		startTime, endTime int64
12544		window             struct {
12545			name string
12546			tags string
12547		}
12548	)
12549	for {
12550		p, err := itr.input.Next()
12551		if err != nil || p == nil {
12552			return nil, err
12553		} else if p.Nil {
12554			continue
12555		}
12556
12557		// Unread the point so it can be processed.
12558		itr.input.unread(p)
12559		startTime, endTime = itr.opt.Window(p.Time)
12560		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
12561		break
12562	}
12563
12564	// Create points by tags.
12565	m := make(map[string]*booleanReduceStringPoint)
12566	for {
12567		// Read next point.
12568		curr, err := itr.input.NextInWindow(startTime, endTime)
12569		if err != nil {
12570			return nil, err
12571		} else if curr == nil {
12572			break
12573		} else if curr.Nil {
12574			continue
12575		} else if curr.Name != window.name {
12576			itr.input.unread(curr)
12577			break
12578		}
12579
12580		// Ensure this point is within the same final window.
12581		if curr.Name != window.name {
12582			itr.input.unread(curr)
12583			break
12584		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
12585			itr.input.unread(curr)
12586			break
12587		}
12588
12589		// Retrieve the tags on this point for this level of the query.
12590		// This may be different than the bucket dimensions.
12591		tags := curr.Tags.Subset(itr.dims)
12592		id := tags.ID()
12593
12594		// Retrieve the aggregator for this name/tag combination or create one.
12595		rp := m[id]
12596		if rp == nil {
12597			aggregator, emitter := itr.create()
12598			rp = &booleanReduceStringPoint{
12599				Name:       curr.Name,
12600				Tags:       tags,
12601				Aggregator: aggregator,
12602				Emitter:    emitter,
12603			}
12604			m[id] = rp
12605		}
12606		rp.Aggregator.AggregateBoolean(curr)
12607	}
12608
12609	keys := make([]string, 0, len(m))
12610	for k := range m {
12611		keys = append(keys, k)
12612	}
12613
12614	// Reverse sort points by name & tag.
12615	// This ensures a consistent order of output.
12616	if len(keys) > 0 {
12617		var sorted sort.Interface = sort.StringSlice(keys)
12618		if itr.opt.Ascending {
12619			sorted = sort.Reverse(sorted)
12620		}
12621		sort.Sort(sorted)
12622	}
12623
12624	// Assume the points are already sorted until proven otherwise.
12625	sortedByTime := true
12626	// Emit the points for each name & tag combination.
12627	a := make([]StringPoint, 0, len(m))
12628	for _, k := range keys {
12629		rp := m[k]
12630		points := rp.Emitter.Emit()
12631		for i := len(points) - 1; i >= 0; i-- {
12632			points[i].Name = rp.Name
12633			if !itr.keepTags {
12634				points[i].Tags = rp.Tags
12635			}
12636			// Set the points time to the interval time if the reducer didn't provide one.
12637			if points[i].Time == ZeroTime {
12638				points[i].Time = startTime
12639			} else {
12640				sortedByTime = false
12641			}
12642			a = append(a, points[i])
12643		}
12644	}
12645	// Points may be out of order. Perform a stable sort by time if requested.
12646	if !sortedByTime && itr.opt.Ordered {
12647		var sorted sort.Interface = stringPointsByTime(a)
12648		if itr.opt.Ascending {
12649			sorted = sort.Reverse(sorted)
12650		}
12651		sort.Stable(sorted)
12652	}
12653	return a, nil
12654}
12655
12656// booleanStreamStringIterator streams inputs into the iterator and emits points gradually.
12657type booleanStreamStringIterator struct {
12658	input  *bufBooleanIterator
12659	create func() (BooleanPointAggregator, StringPointEmitter)
12660	dims   []string
12661	opt    IteratorOptions
12662	m      map[string]*booleanReduceStringPoint
12663	points []StringPoint
12664}
12665
12666// newBooleanStreamStringIterator returns a new instance of booleanStreamStringIterator.
12667func newBooleanStreamStringIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, StringPointEmitter), opt IteratorOptions) *booleanStreamStringIterator {
12668	return &booleanStreamStringIterator{
12669		input:  newBufBooleanIterator(input),
12670		create: createFn,
12671		dims:   opt.GetDimensions(),
12672		opt:    opt,
12673		m:      make(map[string]*booleanReduceStringPoint),
12674	}
12675}
12676
12677// Stats returns stats from the input iterator.
12678func (itr *booleanStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() }
12679
12680// Close closes the iterator and all child iterators.
12681func (itr *booleanStreamStringIterator) Close() error { return itr.input.Close() }
12682
12683// Next returns the next value for the stream iterator.
12684func (itr *booleanStreamStringIterator) Next() (*StringPoint, error) {
12685	// Calculate next window if we have no more points.
12686	if len(itr.points) == 0 {
12687		var err error
12688		itr.points, err = itr.reduce()
12689		if len(itr.points) == 0 {
12690			return nil, err
12691		}
12692	}
12693
12694	// Pop next point off the stack.
12695	p := &itr.points[len(itr.points)-1]
12696	itr.points = itr.points[:len(itr.points)-1]
12697	return p, nil
12698}
12699
12700// reduce creates and manages aggregators for every point from the input.
12701// After aggregating a point, it always tries to emit a value using the emitter.
12702func (itr *booleanStreamStringIterator) reduce() ([]StringPoint, error) {
12703	// We have already read all of the input points.
12704	if itr.m == nil {
12705		return nil, nil
12706	}
12707
12708	for {
12709		// Read next point.
12710		curr, err := itr.input.Next()
12711		if err != nil {
12712			return nil, err
12713		} else if curr == nil {
12714			// Close all of the aggregators to flush any remaining points to emit.
12715			var points []StringPoint
12716			for _, rp := range itr.m {
12717				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
12718					if err := aggregator.Close(); err != nil {
12719						return nil, err
12720					}
12721
12722					pts := rp.Emitter.Emit()
12723					if len(pts) == 0 {
12724						continue
12725					}
12726
12727					for i := range pts {
12728						pts[i].Name = rp.Name
12729						pts[i].Tags = rp.Tags
12730					}
12731					points = append(points, pts...)
12732				}
12733			}
12734
12735			// Eliminate the aggregators and emitters.
12736			itr.m = nil
12737			return points, nil
12738		} else if curr.Nil {
12739			continue
12740		}
12741		tags := curr.Tags.Subset(itr.dims)
12742
12743		id := curr.Name
12744		if len(tags.m) > 0 {
12745			id += "\x00" + tags.ID()
12746		}
12747
12748		// Retrieve the aggregator for this name/tag combination or create one.
12749		rp := itr.m[id]
12750		if rp == nil {
12751			aggregator, emitter := itr.create()
12752			rp = &booleanReduceStringPoint{
12753				Name:       curr.Name,
12754				Tags:       tags,
12755				Aggregator: aggregator,
12756				Emitter:    emitter,
12757			}
12758			itr.m[id] = rp
12759		}
12760		rp.Aggregator.AggregateBoolean(curr)
12761
12762		// Attempt to emit points from the aggregator.
12763		points := rp.Emitter.Emit()
12764		if len(points) == 0 {
12765			continue
12766		}
12767
12768		for i := range points {
12769			points[i].Name = rp.Name
12770			points[i].Tags = rp.Tags
12771		}
12772		return points, nil
12773	}
12774}
12775
12776// booleanReduceBooleanIterator executes a reducer for every interval and buffers the result.
12777type booleanReduceBooleanIterator struct {
12778	input    *bufBooleanIterator
12779	create   func() (BooleanPointAggregator, BooleanPointEmitter)
12780	dims     []string
12781	opt      IteratorOptions
12782	points   []BooleanPoint
12783	keepTags bool
12784}
12785
12786func newBooleanReduceBooleanIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, BooleanPointEmitter)) *booleanReduceBooleanIterator {
12787	return &booleanReduceBooleanIterator{
12788		input:  newBufBooleanIterator(input),
12789		create: createFn,
12790		dims:   opt.GetDimensions(),
12791		opt:    opt,
12792	}
12793}
12794
12795// Stats returns stats from the input iterator.
12796func (itr *booleanReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
12797
12798// Close closes the iterator and all child iterators.
12799func (itr *booleanReduceBooleanIterator) Close() error { return itr.input.Close() }
12800
12801// Next returns the minimum value for the next available interval.
12802func (itr *booleanReduceBooleanIterator) Next() (*BooleanPoint, error) {
12803	// Calculate next window if we have no more points.
12804	if len(itr.points) == 0 {
12805		var err error
12806		itr.points, err = itr.reduce()
12807		if len(itr.points) == 0 {
12808			return nil, err
12809		}
12810	}
12811
12812	// Pop next point off the stack.
12813	p := &itr.points[len(itr.points)-1]
12814	itr.points = itr.points[:len(itr.points)-1]
12815	return p, nil
12816}
12817
12818// booleanReduceBooleanPoint stores the reduced data for a name/tag combination.
12819type booleanReduceBooleanPoint struct {
12820	Name       string
12821	Tags       Tags
12822	Aggregator BooleanPointAggregator
12823	Emitter    BooleanPointEmitter
12824}
12825
12826// reduce executes fn once for every point in the next window.
12827// The previous value for the dimension is passed to fn.
12828func (itr *booleanReduceBooleanIterator) reduce() ([]BooleanPoint, error) {
12829	// Calculate next window.
12830	var (
12831		startTime, endTime int64
12832		window             struct {
12833			name string
12834			tags string
12835		}
12836	)
12837	for {
12838		p, err := itr.input.Next()
12839		if err != nil || p == nil {
12840			return nil, err
12841		} else if p.Nil {
12842			continue
12843		}
12844
12845		// Unread the point so it can be processed.
12846		itr.input.unread(p)
12847		startTime, endTime = itr.opt.Window(p.Time)
12848		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
12849		break
12850	}
12851
12852	// Create points by tags.
12853	m := make(map[string]*booleanReduceBooleanPoint)
12854	for {
12855		// Read next point.
12856		curr, err := itr.input.NextInWindow(startTime, endTime)
12857		if err != nil {
12858			return nil, err
12859		} else if curr == nil {
12860			break
12861		} else if curr.Nil {
12862			continue
12863		} else if curr.Name != window.name {
12864			itr.input.unread(curr)
12865			break
12866		}
12867
12868		// Ensure this point is within the same final window.
12869		if curr.Name != window.name {
12870			itr.input.unread(curr)
12871			break
12872		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
12873			itr.input.unread(curr)
12874			break
12875		}
12876
12877		// Retrieve the tags on this point for this level of the query.
12878		// This may be different than the bucket dimensions.
12879		tags := curr.Tags.Subset(itr.dims)
12880		id := tags.ID()
12881
12882		// Retrieve the aggregator for this name/tag combination or create one.
12883		rp := m[id]
12884		if rp == nil {
12885			aggregator, emitter := itr.create()
12886			rp = &booleanReduceBooleanPoint{
12887				Name:       curr.Name,
12888				Tags:       tags,
12889				Aggregator: aggregator,
12890				Emitter:    emitter,
12891			}
12892			m[id] = rp
12893		}
12894		rp.Aggregator.AggregateBoolean(curr)
12895	}
12896
12897	keys := make([]string, 0, len(m))
12898	for k := range m {
12899		keys = append(keys, k)
12900	}
12901
12902	// Reverse sort points by name & tag.
12903	// This ensures a consistent order of output.
12904	if len(keys) > 0 {
12905		var sorted sort.Interface = sort.StringSlice(keys)
12906		if itr.opt.Ascending {
12907			sorted = sort.Reverse(sorted)
12908		}
12909		sort.Sort(sorted)
12910	}
12911
12912	// Assume the points are already sorted until proven otherwise.
12913	sortedByTime := true
12914	// Emit the points for each name & tag combination.
12915	a := make([]BooleanPoint, 0, len(m))
12916	for _, k := range keys {
12917		rp := m[k]
12918		points := rp.Emitter.Emit()
12919		for i := len(points) - 1; i >= 0; i-- {
12920			points[i].Name = rp.Name
12921			if !itr.keepTags {
12922				points[i].Tags = rp.Tags
12923			}
12924			// Set the points time to the interval time if the reducer didn't provide one.
12925			if points[i].Time == ZeroTime {
12926				points[i].Time = startTime
12927			} else {
12928				sortedByTime = false
12929			}
12930			a = append(a, points[i])
12931		}
12932	}
12933	// Points may be out of order. Perform a stable sort by time if requested.
12934	if !sortedByTime && itr.opt.Ordered {
12935		var sorted sort.Interface = booleanPointsByTime(a)
12936		if itr.opt.Ascending {
12937			sorted = sort.Reverse(sorted)
12938		}
12939		sort.Stable(sorted)
12940	}
12941	return a, nil
12942}
12943
12944// booleanStreamBooleanIterator streams inputs into the iterator and emits points gradually.
12945type booleanStreamBooleanIterator struct {
12946	input  *bufBooleanIterator
12947	create func() (BooleanPointAggregator, BooleanPointEmitter)
12948	dims   []string
12949	opt    IteratorOptions
12950	m      map[string]*booleanReduceBooleanPoint
12951	points []BooleanPoint
12952}
12953
12954// newBooleanStreamBooleanIterator returns a new instance of booleanStreamBooleanIterator.
12955func newBooleanStreamBooleanIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, BooleanPointEmitter), opt IteratorOptions) *booleanStreamBooleanIterator {
12956	return &booleanStreamBooleanIterator{
12957		input:  newBufBooleanIterator(input),
12958		create: createFn,
12959		dims:   opt.GetDimensions(),
12960		opt:    opt,
12961		m:      make(map[string]*booleanReduceBooleanPoint),
12962	}
12963}
12964
12965// Stats returns stats from the input iterator.
12966func (itr *booleanStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
12967
12968// Close closes the iterator and all child iterators.
12969func (itr *booleanStreamBooleanIterator) Close() error { return itr.input.Close() }
12970
12971// Next returns the next value for the stream iterator.
12972func (itr *booleanStreamBooleanIterator) Next() (*BooleanPoint, error) {
12973	// Calculate next window if we have no more points.
12974	if len(itr.points) == 0 {
12975		var err error
12976		itr.points, err = itr.reduce()
12977		if len(itr.points) == 0 {
12978			return nil, err
12979		}
12980	}
12981
12982	// Pop next point off the stack.
12983	p := &itr.points[len(itr.points)-1]
12984	itr.points = itr.points[:len(itr.points)-1]
12985	return p, nil
12986}
12987
12988// reduce creates and manages aggregators for every point from the input.
12989// After aggregating a point, it always tries to emit a value using the emitter.
12990func (itr *booleanStreamBooleanIterator) reduce() ([]BooleanPoint, error) {
12991	// We have already read all of the input points.
12992	if itr.m == nil {
12993		return nil, nil
12994	}
12995
12996	for {
12997		// Read next point.
12998		curr, err := itr.input.Next()
12999		if err != nil {
13000			return nil, err
13001		} else if curr == nil {
13002			// Close all of the aggregators to flush any remaining points to emit.
13003			var points []BooleanPoint
13004			for _, rp := range itr.m {
13005				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
13006					if err := aggregator.Close(); err != nil {
13007						return nil, err
13008					}
13009
13010					pts := rp.Emitter.Emit()
13011					if len(pts) == 0 {
13012						continue
13013					}
13014
13015					for i := range pts {
13016						pts[i].Name = rp.Name
13017						pts[i].Tags = rp.Tags
13018					}
13019					points = append(points, pts...)
13020				}
13021			}
13022
13023			// Eliminate the aggregators and emitters.
13024			itr.m = nil
13025			return points, nil
13026		} else if curr.Nil {
13027			continue
13028		}
13029		tags := curr.Tags.Subset(itr.dims)
13030
13031		id := curr.Name
13032		if len(tags.m) > 0 {
13033			id += "\x00" + tags.ID()
13034		}
13035
13036		// Retrieve the aggregator for this name/tag combination or create one.
13037		rp := itr.m[id]
13038		if rp == nil {
13039			aggregator, emitter := itr.create()
13040			rp = &booleanReduceBooleanPoint{
13041				Name:       curr.Name,
13042				Tags:       tags,
13043				Aggregator: aggregator,
13044				Emitter:    emitter,
13045			}
13046			itr.m[id] = rp
13047		}
13048		rp.Aggregator.AggregateBoolean(curr)
13049
13050		// Attempt to emit points from the aggregator.
13051		points := rp.Emitter.Emit()
13052		if len(points) == 0 {
13053			continue
13054		}
13055
13056		for i := range points {
13057			points[i].Name = rp.Name
13058			points[i].Tags = rp.Tags
13059		}
13060		return points, nil
13061	}
13062}
13063
13064// booleanDedupeIterator only outputs unique points.
13065// This differs from the DistinctIterator in that it compares all aux fields too.
13066// This iterator is relatively inefficient and should only be used on small
13067// datasets such as meta query results.
13068type booleanDedupeIterator struct {
13069	input BooleanIterator
13070	m     map[string]struct{} // lookup of points already sent
13071}
13072
13073type booleanIteratorMapper struct {
13074	cur    Cursor
13075	row    Row
13076	driver IteratorMap   // which iterator to use for the primary value, can be nil
13077	fields []IteratorMap // which iterator to use for an aux field
13078	point  BooleanPoint
13079}
13080
13081func newBooleanIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *booleanIteratorMapper {
13082	return &booleanIteratorMapper{
13083		cur:    cur,
13084		driver: driver,
13085		fields: fields,
13086		point: BooleanPoint{
13087			Aux: make([]interface{}, len(fields)),
13088		},
13089	}
13090}
13091
13092func (itr *booleanIteratorMapper) Next() (*BooleanPoint, error) {
13093	if !itr.cur.Scan(&itr.row) {
13094		if err := itr.cur.Err(); err != nil {
13095			return nil, err
13096		}
13097		return nil, nil
13098	}
13099
13100	itr.point.Time = itr.row.Time
13101	itr.point.Name = itr.row.Series.Name
13102	itr.point.Tags = itr.row.Series.Tags
13103
13104	if itr.driver != nil {
13105		if v := itr.driver.Value(&itr.row); v != nil {
13106			if v, ok := castToBoolean(v); ok {
13107				itr.point.Value = v
13108				itr.point.Nil = false
13109			} else {
13110				itr.point.Value = false
13111				itr.point.Nil = true
13112			}
13113		} else {
13114			itr.point.Value = false
13115			itr.point.Nil = true
13116		}
13117	}
13118	for i, f := range itr.fields {
13119		itr.point.Aux[i] = f.Value(&itr.row)
13120	}
13121	return &itr.point, nil
13122}
13123
13124func (itr *booleanIteratorMapper) Stats() IteratorStats {
13125	return itr.cur.Stats()
13126}
13127
13128func (itr *booleanIteratorMapper) Close() error {
13129	return itr.cur.Close()
13130}
13131
13132type booleanFilterIterator struct {
13133	input BooleanIterator
13134	cond  influxql.Expr
13135	opt   IteratorOptions
13136	m     map[string]interface{}
13137}
13138
13139func newBooleanFilterIterator(input BooleanIterator, cond influxql.Expr, opt IteratorOptions) BooleanIterator {
13140	// Strip out time conditions from the WHERE clause.
13141	// TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct.
13142	n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node {
13143		switch n := n.(type) {
13144		case *influxql.BinaryExpr:
13145			if n.LHS.String() == "time" {
13146				return &influxql.BooleanLiteral{Val: true}
13147			}
13148		}
13149		return n
13150	})
13151
13152	cond, _ = n.(influxql.Expr)
13153	if cond == nil {
13154		return input
13155	} else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val {
13156		return input
13157	}
13158
13159	return &booleanFilterIterator{
13160		input: input,
13161		cond:  cond,
13162		opt:   opt,
13163		m:     make(map[string]interface{}),
13164	}
13165}
13166
13167func (itr *booleanFilterIterator) Stats() IteratorStats { return itr.input.Stats() }
13168func (itr *booleanFilterIterator) Close() error         { return itr.input.Close() }
13169
13170func (itr *booleanFilterIterator) Next() (*BooleanPoint, error) {
13171	for {
13172		p, err := itr.input.Next()
13173		if err != nil || p == nil {
13174			return nil, err
13175		}
13176
13177		for i, ref := range itr.opt.Aux {
13178			itr.m[ref.Val] = p.Aux[i]
13179		}
13180		for k, v := range p.Tags.KeyValues() {
13181			itr.m[k] = v
13182		}
13183
13184		if !influxql.EvalBool(itr.cond, itr.m) {
13185			continue
13186		}
13187		return p, nil
13188	}
13189}
13190
13191type booleanTagSubsetIterator struct {
13192	input      BooleanIterator
13193	point      BooleanPoint
13194	lastTags   Tags
13195	dimensions []string
13196}
13197
13198func newBooleanTagSubsetIterator(input BooleanIterator, opt IteratorOptions) *booleanTagSubsetIterator {
13199	return &booleanTagSubsetIterator{
13200		input:      input,
13201		dimensions: opt.GetDimensions(),
13202	}
13203}
13204
13205func (itr *booleanTagSubsetIterator) Next() (*BooleanPoint, error) {
13206	p, err := itr.input.Next()
13207	if err != nil {
13208		return nil, err
13209	} else if p == nil {
13210		return nil, nil
13211	}
13212
13213	itr.point.Name = p.Name
13214	if !p.Tags.Equal(itr.lastTags) {
13215		itr.point.Tags = p.Tags.Subset(itr.dimensions)
13216		itr.lastTags = p.Tags
13217	}
13218	itr.point.Time = p.Time
13219	itr.point.Value = p.Value
13220	itr.point.Aux = p.Aux
13221	itr.point.Aggregated = p.Aggregated
13222	itr.point.Nil = p.Nil
13223	return &itr.point, nil
13224}
13225
13226func (itr *booleanTagSubsetIterator) Stats() IteratorStats {
13227	return itr.input.Stats()
13228}
13229
13230func (itr *booleanTagSubsetIterator) Close() error {
13231	return itr.input.Close()
13232}
13233
13234// newBooleanDedupeIterator returns a new instance of booleanDedupeIterator.
13235func newBooleanDedupeIterator(input BooleanIterator) *booleanDedupeIterator {
13236	return &booleanDedupeIterator{
13237		input: input,
13238		m:     make(map[string]struct{}),
13239	}
13240}
13241
13242// Stats returns stats from the input iterator.
13243func (itr *booleanDedupeIterator) Stats() IteratorStats { return itr.input.Stats() }
13244
13245// Close closes the iterator and all child iterators.
13246func (itr *booleanDedupeIterator) Close() error { return itr.input.Close() }
13247
13248// Next returns the next unique point from the input iterator.
13249func (itr *booleanDedupeIterator) Next() (*BooleanPoint, error) {
13250	for {
13251		// Read next point.
13252		p, err := itr.input.Next()
13253		if p == nil || err != nil {
13254			return nil, err
13255		}
13256
13257		// Serialize to bytes to store in lookup.
13258		buf, err := proto.Marshal(encodeBooleanPoint(p))
13259		if err != nil {
13260			return nil, err
13261		}
13262
13263		// If the point has already been output then move to the next point.
13264		if _, ok := itr.m[string(buf)]; ok {
13265			continue
13266		}
13267
13268		// Otherwise mark it as emitted and return point.
13269		itr.m[string(buf)] = struct{}{}
13270		return p, nil
13271	}
13272}
13273
13274// booleanReaderIterator represents an iterator that streams from a reader.
13275type booleanReaderIterator struct {
13276	r   io.Reader
13277	dec *BooleanPointDecoder
13278}
13279
13280// newBooleanReaderIterator returns a new instance of booleanReaderIterator.
13281func newBooleanReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *booleanReaderIterator {
13282	dec := NewBooleanPointDecoder(ctx, r)
13283	dec.stats = stats
13284
13285	return &booleanReaderIterator{
13286		r:   r,
13287		dec: dec,
13288	}
13289}
13290
13291// Stats returns stats about points processed.
13292func (itr *booleanReaderIterator) Stats() IteratorStats { return itr.dec.stats }
13293
13294// Close closes the underlying reader, if applicable.
13295func (itr *booleanReaderIterator) Close() error {
13296	if r, ok := itr.r.(io.ReadCloser); ok {
13297		return r.Close()
13298	}
13299	return nil
13300}
13301
13302// Next returns the next point from the iterator.
13303func (itr *booleanReaderIterator) Next() (*BooleanPoint, error) {
13304	// OPTIMIZE(benbjohnson): Reuse point on iterator.
13305
13306	// Unmarshal next point.
13307	p := &BooleanPoint{}
13308	if err := itr.dec.DecodeBooleanPoint(p); err == io.EOF {
13309		return nil, nil
13310	} else if err != nil {
13311		return nil, err
13312	}
13313	return p, nil
13314}
13315
13316// encodeFloatIterator encodes all points from itr to the underlying writer.
13317func (enc *IteratorEncoder) encodeFloatIterator(itr FloatIterator) error {
13318	ticker := time.NewTicker(enc.StatsInterval)
13319	defer ticker.Stop()
13320
13321	// Emit initial stats.
13322	if err := enc.encodeStats(itr.Stats()); err != nil {
13323		return err
13324	}
13325
13326	// Continually stream points from the iterator into the encoder.
13327	penc := NewFloatPointEncoder(enc.w)
13328	for {
13329		// Emit stats periodically.
13330		select {
13331		case <-ticker.C:
13332			if err := enc.encodeStats(itr.Stats()); err != nil {
13333				return err
13334			}
13335		default:
13336		}
13337
13338		// Retrieve the next point from the iterator.
13339		p, err := itr.Next()
13340		if err != nil {
13341			return err
13342		} else if p == nil {
13343			break
13344		}
13345
13346		// Write the point to the point encoder.
13347		if err := penc.EncodeFloatPoint(p); err != nil {
13348			return err
13349		}
13350	}
13351
13352	// Emit final stats.
13353	if err := enc.encodeStats(itr.Stats()); err != nil {
13354		return err
13355	}
13356	return nil
13357}
13358
13359// encodeIntegerIterator encodes all points from itr to the underlying writer.
13360func (enc *IteratorEncoder) encodeIntegerIterator(itr IntegerIterator) error {
13361	ticker := time.NewTicker(enc.StatsInterval)
13362	defer ticker.Stop()
13363
13364	// Emit initial stats.
13365	if err := enc.encodeStats(itr.Stats()); err != nil {
13366		return err
13367	}
13368
13369	// Continually stream points from the iterator into the encoder.
13370	penc := NewIntegerPointEncoder(enc.w)
13371	for {
13372		// Emit stats periodically.
13373		select {
13374		case <-ticker.C:
13375			if err := enc.encodeStats(itr.Stats()); err != nil {
13376				return err
13377			}
13378		default:
13379		}
13380
13381		// Retrieve the next point from the iterator.
13382		p, err := itr.Next()
13383		if err != nil {
13384			return err
13385		} else if p == nil {
13386			break
13387		}
13388
13389		// Write the point to the point encoder.
13390		if err := penc.EncodeIntegerPoint(p); err != nil {
13391			return err
13392		}
13393	}
13394
13395	// Emit final stats.
13396	if err := enc.encodeStats(itr.Stats()); err != nil {
13397		return err
13398	}
13399	return nil
13400}
13401
13402// encodeUnsignedIterator encodes all points from itr to the underlying writer.
13403func (enc *IteratorEncoder) encodeUnsignedIterator(itr UnsignedIterator) error {
13404	ticker := time.NewTicker(enc.StatsInterval)
13405	defer ticker.Stop()
13406
13407	// Emit initial stats.
13408	if err := enc.encodeStats(itr.Stats()); err != nil {
13409		return err
13410	}
13411
13412	// Continually stream points from the iterator into the encoder.
13413	penc := NewUnsignedPointEncoder(enc.w)
13414	for {
13415		// Emit stats periodically.
13416		select {
13417		case <-ticker.C:
13418			if err := enc.encodeStats(itr.Stats()); err != nil {
13419				return err
13420			}
13421		default:
13422		}
13423
13424		// Retrieve the next point from the iterator.
13425		p, err := itr.Next()
13426		if err != nil {
13427			return err
13428		} else if p == nil {
13429			break
13430		}
13431
13432		// Write the point to the point encoder.
13433		if err := penc.EncodeUnsignedPoint(p); err != nil {
13434			return err
13435		}
13436	}
13437
13438	// Emit final stats.
13439	if err := enc.encodeStats(itr.Stats()); err != nil {
13440		return err
13441	}
13442	return nil
13443}
13444
13445// encodeStringIterator encodes all points from itr to the underlying writer.
13446func (enc *IteratorEncoder) encodeStringIterator(itr StringIterator) error {
13447	ticker := time.NewTicker(enc.StatsInterval)
13448	defer ticker.Stop()
13449
13450	// Emit initial stats.
13451	if err := enc.encodeStats(itr.Stats()); err != nil {
13452		return err
13453	}
13454
13455	// Continually stream points from the iterator into the encoder.
13456	penc := NewStringPointEncoder(enc.w)
13457	for {
13458		// Emit stats periodically.
13459		select {
13460		case <-ticker.C:
13461			if err := enc.encodeStats(itr.Stats()); err != nil {
13462				return err
13463			}
13464		default:
13465		}
13466
13467		// Retrieve the next point from the iterator.
13468		p, err := itr.Next()
13469		if err != nil {
13470			return err
13471		} else if p == nil {
13472			break
13473		}
13474
13475		// Write the point to the point encoder.
13476		if err := penc.EncodeStringPoint(p); err != nil {
13477			return err
13478		}
13479	}
13480
13481	// Emit final stats.
13482	if err := enc.encodeStats(itr.Stats()); err != nil {
13483		return err
13484	}
13485	return nil
13486}
13487
13488// encodeBooleanIterator encodes all points from itr to the underlying writer.
13489func (enc *IteratorEncoder) encodeBooleanIterator(itr BooleanIterator) error {
13490	ticker := time.NewTicker(enc.StatsInterval)
13491	defer ticker.Stop()
13492
13493	// Emit initial stats.
13494	if err := enc.encodeStats(itr.Stats()); err != nil {
13495		return err
13496	}
13497
13498	// Continually stream points from the iterator into the encoder.
13499	penc := NewBooleanPointEncoder(enc.w)
13500	for {
13501		// Emit stats periodically.
13502		select {
13503		case <-ticker.C:
13504			if err := enc.encodeStats(itr.Stats()); err != nil {
13505				return err
13506			}
13507		default:
13508		}
13509
13510		// Retrieve the next point from the iterator.
13511		p, err := itr.Next()
13512		if err != nil {
13513			return err
13514		} else if p == nil {
13515			break
13516		}
13517
13518		// Write the point to the point encoder.
13519		if err := penc.EncodeBooleanPoint(p); err != nil {
13520			return err
13521		}
13522	}
13523
13524	// Emit final stats.
13525	if err := enc.encodeStats(itr.Stats()); err != nil {
13526		return err
13527	}
13528	return nil
13529}
13530