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

     1  // Generated by tmpl
     2  // https://github.com/benbjohnson/tmpl
     3  //
     4  // DO NOT EDIT!
     5  // Source: iterator.gen.go.tmpl
     6  
     7  //lint:file-ignore U1000 this is generated code
     8  package query
     9  
    10  import (
    11  	"container/heap"
    12  	"context"
    13  	"io"
    14  	"sort"
    15  	"sync"
    16  	"time"
    17  
    18  	"github.com/influxdata/influxql"
    19  	"google.golang.org/protobuf/proto"
    20  )
    21  
    22  // DefaultStatsInterval is the default value for IteratorEncoder.StatsInterval.
    23  const DefaultStatsInterval = time.Second
    24  
    25  // FloatIterator represents a stream of float points.
    26  type FloatIterator interface {
    27  	Iterator
    28  	Next() (*FloatPoint, error)
    29  }
    30  
    31  // newFloatIterators converts a slice of Iterator to a slice of FloatIterator.
    32  // Drop and closes any iterator in itrs that is not a FloatIterator and cannot
    33  // be cast to a FloatIterator.
    34  func newFloatIterators(itrs []Iterator) []FloatIterator {
    35  	a := make([]FloatIterator, 0, len(itrs))
    36  	for _, itr := range itrs {
    37  		switch itr := itr.(type) {
    38  		case FloatIterator:
    39  			a = append(a, itr)
    40  		default:
    41  			itr.Close()
    42  		}
    43  	}
    44  	return a
    45  }
    46  
    47  // bufFloatIterator represents a buffered FloatIterator.
    48  type bufFloatIterator struct {
    49  	itr FloatIterator
    50  	buf *FloatPoint
    51  }
    52  
    53  // newBufFloatIterator returns a buffered FloatIterator.
    54  func newBufFloatIterator(itr FloatIterator) *bufFloatIterator {
    55  	return &bufFloatIterator{itr: itr}
    56  }
    57  
    58  // Stats returns statistics from the input iterator.
    59  func (itr *bufFloatIterator) Stats() IteratorStats { return itr.itr.Stats() }
    60  
    61  // Close closes the underlying iterator.
    62  func (itr *bufFloatIterator) Close() error { return itr.itr.Close() }
    63  
    64  // peek returns the next point without removing it from the iterator.
    65  func (itr *bufFloatIterator) peek() (*FloatPoint, error) {
    66  	p, err := itr.Next()
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	itr.unread(p)
    71  	return p, nil
    72  }
    73  
    74  // peekTime returns the time of the next point.
    75  // Returns zero time if no more points available.
    76  func (itr *bufFloatIterator) peekTime() (int64, error) {
    77  	p, err := itr.peek()
    78  	if p == nil || err != nil {
    79  		return ZeroTime, err
    80  	}
    81  	return p.Time, nil
    82  }
    83  
    84  // Next returns the current buffer, if exists, or calls the underlying iterator.
    85  func (itr *bufFloatIterator) Next() (*FloatPoint, error) {
    86  	buf := itr.buf
    87  	if buf != nil {
    88  		itr.buf = nil
    89  		return buf, nil
    90  	}
    91  	return itr.itr.Next()
    92  }
    93  
    94  // NextInWindow returns the next value if it is between [startTime, endTime).
    95  // If the next value is outside the range then it is moved to the buffer.
    96  func (itr *bufFloatIterator) NextInWindow(startTime, endTime int64) (*FloatPoint, error) {
    97  	v, err := itr.Next()
    98  	if v == nil || err != nil {
    99  		return nil, err
   100  	} else if t := v.Time; t >= endTime || t < startTime {
   101  		itr.unread(v)
   102  		return nil, nil
   103  	}
   104  	return v, nil
   105  }
   106  
   107  // unread sets v to the buffer. It is read on the next call to Next().
   108  func (itr *bufFloatIterator) unread(v *FloatPoint) { itr.buf = v }
   109  
   110  // floatMergeIterator represents an iterator that combines multiple float iterators.
   111  type floatMergeIterator struct {
   112  	inputs []FloatIterator
   113  	heap   *floatMergeHeap
   114  	init   bool
   115  
   116  	closed bool
   117  	mu     sync.RWMutex
   118  
   119  	// Current iterator and window.
   120  	curr   *floatMergeHeapItem
   121  	window struct {
   122  		name      string
   123  		tags      string
   124  		startTime int64
   125  		endTime   int64
   126  	}
   127  }
   128  
   129  // newFloatMergeIterator returns a new instance of floatMergeIterator.
   130  func newFloatMergeIterator(inputs []FloatIterator, opt IteratorOptions) *floatMergeIterator {
   131  	itr := &floatMergeIterator{
   132  		inputs: inputs,
   133  		heap: &floatMergeHeap{
   134  			items: make([]*floatMergeHeapItem, 0, len(inputs)),
   135  			opt:   opt,
   136  		},
   137  	}
   138  
   139  	// Initialize heap items.
   140  	for _, input := range inputs {
   141  		// Wrap in buffer, ignore any inputs without anymore points.
   142  		bufInput := newBufFloatIterator(input)
   143  
   144  		// Append to the heap.
   145  		itr.heap.items = append(itr.heap.items, &floatMergeHeapItem{itr: bufInput})
   146  	}
   147  
   148  	return itr
   149  }
   150  
   151  // Stats returns an aggregation of stats from the underlying iterators.
   152  func (itr *floatMergeIterator) Stats() IteratorStats {
   153  	var stats IteratorStats
   154  	for _, input := range itr.inputs {
   155  		stats.Add(input.Stats())
   156  	}
   157  	return stats
   158  }
   159  
   160  // Close closes the underlying iterators.
   161  func (itr *floatMergeIterator) Close() error {
   162  	itr.mu.Lock()
   163  	defer itr.mu.Unlock()
   164  
   165  	for _, input := range itr.inputs {
   166  		input.Close()
   167  	}
   168  	itr.curr = nil
   169  	itr.inputs = nil
   170  	itr.heap.items = nil
   171  	itr.closed = true
   172  	return nil
   173  }
   174  
   175  // Next returns the next point from the iterator.
   176  func (itr *floatMergeIterator) Next() (*FloatPoint, error) {
   177  	itr.mu.RLock()
   178  	defer itr.mu.RUnlock()
   179  	if itr.closed {
   180  		return nil, nil
   181  	}
   182  
   183  	// Initialize the heap. This needs to be done lazily on the first call to this iterator
   184  	// so that iterator initialization done through the Select() call returns quickly.
   185  	// Queries can only be interrupted after the Select() call completes so any operations
   186  	// done during iterator creation cannot be interrupted, which is why we do it here
   187  	// instead so an interrupt can happen while initializing the heap.
   188  	if !itr.init {
   189  		items := itr.heap.items
   190  		itr.heap.items = make([]*floatMergeHeapItem, 0, len(items))
   191  		for _, item := range items {
   192  			if p, err := item.itr.peek(); err != nil {
   193  				return nil, err
   194  			} else if p == nil {
   195  				continue
   196  			}
   197  			itr.heap.items = append(itr.heap.items, item)
   198  		}
   199  		heap.Init(itr.heap)
   200  		itr.init = true
   201  	}
   202  
   203  	for {
   204  		// Retrieve the next iterator if we don't have one.
   205  		if itr.curr == nil {
   206  			if len(itr.heap.items) == 0 {
   207  				return nil, nil
   208  			}
   209  			itr.curr = heap.Pop(itr.heap).(*floatMergeHeapItem)
   210  
   211  			// Read point and set current window.
   212  			p, err := itr.curr.itr.Next()
   213  			if err != nil {
   214  				return nil, err
   215  			}
   216  			tags := p.Tags.Subset(itr.heap.opt.Dimensions)
   217  			itr.window.name, itr.window.tags = p.Name, tags.ID()
   218  			itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time)
   219  			return p, nil
   220  		}
   221  
   222  		// Read the next point from the current iterator.
   223  		p, err := itr.curr.itr.Next()
   224  		if err != nil {
   225  			return nil, err
   226  		}
   227  
   228  		// If there are no more points then remove iterator from heap and find next.
   229  		if p == nil {
   230  			itr.curr = nil
   231  			continue
   232  		}
   233  
   234  		// Check if the point is inside of our current window.
   235  		inWindow := true
   236  		if window := itr.window; window.name != p.Name {
   237  			inWindow = false
   238  		} else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() {
   239  			inWindow = false
   240  		} else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime {
   241  			inWindow = false
   242  		} else if !opt.Ascending && p.Time < window.startTime {
   243  			inWindow = false
   244  		}
   245  
   246  		// If it's outside our window then push iterator back on the heap and find new iterator.
   247  		if !inWindow {
   248  			itr.curr.itr.unread(p)
   249  			heap.Push(itr.heap, itr.curr)
   250  			itr.curr = nil
   251  			continue
   252  		}
   253  
   254  		return p, nil
   255  	}
   256  }
   257  
   258  // floatMergeHeap represents a heap of floatMergeHeapItems.
   259  // Items are sorted by their next window and then by name/tags.
   260  type floatMergeHeap struct {
   261  	opt   IteratorOptions
   262  	items []*floatMergeHeapItem
   263  }
   264  
   265  func (h *floatMergeHeap) Len() int      { return len(h.items) }
   266  func (h *floatMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
   267  func (h *floatMergeHeap) Less(i, j int) bool {
   268  	x, err := h.items[i].itr.peek()
   269  	if err != nil {
   270  		return true
   271  	}
   272  	y, err := h.items[j].itr.peek()
   273  	if err != nil {
   274  		return false
   275  	}
   276  
   277  	if h.opt.Ascending {
   278  		if x.Name != y.Name {
   279  			return x.Name < y.Name
   280  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
   281  			return xTags.ID() < yTags.ID()
   282  		}
   283  	} else {
   284  		if x.Name != y.Name {
   285  			return x.Name > y.Name
   286  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
   287  			return xTags.ID() > yTags.ID()
   288  		}
   289  	}
   290  
   291  	xt, _ := h.opt.Window(x.Time)
   292  	yt, _ := h.opt.Window(y.Time)
   293  
   294  	if h.opt.Ascending {
   295  		return xt < yt
   296  	}
   297  	return xt > yt
   298  }
   299  
   300  func (h *floatMergeHeap) Push(x interface{}) {
   301  	h.items = append(h.items, x.(*floatMergeHeapItem))
   302  }
   303  
   304  func (h *floatMergeHeap) Pop() interface{} {
   305  	old := h.items
   306  	n := len(old)
   307  	item := old[n-1]
   308  	h.items = old[0 : n-1]
   309  	return item
   310  }
   311  
   312  type floatMergeHeapItem struct {
   313  	itr *bufFloatIterator
   314  }
   315  
   316  // floatSortedMergeIterator is an iterator that sorts and merges multiple iterators into one.
   317  type floatSortedMergeIterator struct {
   318  	inputs []FloatIterator
   319  	heap   *floatSortedMergeHeap
   320  	init   bool
   321  }
   322  
   323  // newFloatSortedMergeIterator returns an instance of floatSortedMergeIterator.
   324  func newFloatSortedMergeIterator(inputs []FloatIterator, opt IteratorOptions) Iterator {
   325  	itr := &floatSortedMergeIterator{
   326  		inputs: inputs,
   327  		heap: &floatSortedMergeHeap{
   328  			items: make([]*floatSortedMergeHeapItem, 0, len(inputs)),
   329  			opt:   opt,
   330  		},
   331  	}
   332  
   333  	// Initialize heap items.
   334  	for _, input := range inputs {
   335  		// Append to the heap.
   336  		itr.heap.items = append(itr.heap.items, &floatSortedMergeHeapItem{itr: input})
   337  	}
   338  
   339  	return itr
   340  }
   341  
   342  // Stats returns an aggregation of stats from the underlying iterators.
   343  func (itr *floatSortedMergeIterator) Stats() IteratorStats {
   344  	var stats IteratorStats
   345  	for _, input := range itr.inputs {
   346  		stats.Add(input.Stats())
   347  	}
   348  	return stats
   349  }
   350  
   351  // Close closes the underlying iterators.
   352  func (itr *floatSortedMergeIterator) Close() error {
   353  	for _, input := range itr.inputs {
   354  		input.Close()
   355  	}
   356  	return nil
   357  }
   358  
   359  // Next returns the next points from the iterator.
   360  func (itr *floatSortedMergeIterator) Next() (*FloatPoint, error) { return itr.pop() }
   361  
   362  // pop returns the next point from the heap.
   363  // Reads the next point from item's cursor and puts it back on the heap.
   364  func (itr *floatSortedMergeIterator) pop() (*FloatPoint, error) {
   365  	// Initialize the heap. See the MergeIterator to see why this has to be done lazily.
   366  	if !itr.init {
   367  		items := itr.heap.items
   368  		itr.heap.items = make([]*floatSortedMergeHeapItem, 0, len(items))
   369  		for _, item := range items {
   370  			var err error
   371  			if item.point, err = item.itr.Next(); err != nil {
   372  				return nil, err
   373  			} else if item.point == nil {
   374  				continue
   375  			}
   376  			itr.heap.items = append(itr.heap.items, item)
   377  		}
   378  		heap.Init(itr.heap)
   379  		itr.init = true
   380  	}
   381  
   382  	if len(itr.heap.items) == 0 {
   383  		return nil, nil
   384  	}
   385  
   386  	// Read the next item from the heap.
   387  	item := heap.Pop(itr.heap).(*floatSortedMergeHeapItem)
   388  	if item.err != nil {
   389  		return nil, item.err
   390  	} else if item.point == nil {
   391  		return nil, nil
   392  	}
   393  
   394  	// Copy the point for return.
   395  	p := item.point.Clone()
   396  
   397  	// Read the next item from the cursor. Push back to heap if one exists.
   398  	if item.point, item.err = item.itr.Next(); item.point != nil {
   399  		heap.Push(itr.heap, item)
   400  	}
   401  
   402  	return p, nil
   403  }
   404  
   405  // floatSortedMergeHeap represents a heap of floatSortedMergeHeapItems.
   406  // Items are sorted with the following priority:
   407  //   - By their measurement name;
   408  //   - By their tag keys/values;
   409  //   - By time; or
   410  //   - By their Aux field values.
   411  type floatSortedMergeHeap struct {
   412  	opt   IteratorOptions
   413  	items []*floatSortedMergeHeapItem
   414  }
   415  
   416  func (h *floatSortedMergeHeap) Len() int      { return len(h.items) }
   417  func (h *floatSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
   418  func (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  
   476  func (h *floatSortedMergeHeap) Push(x interface{}) {
   477  	h.items = append(h.items, x.(*floatSortedMergeHeapItem))
   478  }
   479  
   480  func (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  
   488  type floatSortedMergeHeapItem struct {
   489  	point *FloatPoint
   490  	err   error
   491  	itr   FloatIterator
   492  }
   493  
   494  // floatIteratorScanner scans the results of a FloatIterator into a map.
   495  type floatIteratorScanner struct {
   496  	input        *bufFloatIterator
   497  	err          error
   498  	keys         []influxql.VarRef
   499  	defaultValue interface{}
   500  }
   501  
   502  // newFloatIteratorScanner creates a new IteratorScanner.
   503  func 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  
   511  func (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  
   526  func (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  
   567  func (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  
   579  func (s *floatIteratorScanner) Stats() IteratorStats { return s.input.Stats() }
   580  func (s *floatIteratorScanner) Err() error           { return s.err }
   581  func (s *floatIteratorScanner) Close() error         { return s.input.Close() }
   582  
   583  // floatParallelIterator represents an iterator that pulls data in a separate goroutine.
   584  type 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.
   594  func 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.
   606  func (itr *floatParallelIterator) Stats() IteratorStats { return itr.input.Stats() }
   607  
   608  // Close closes the underlying iterators.
   609  func (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.
   616  func (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.
   625  func (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  
   644  type floatPointError struct {
   645  	point *FloatPoint
   646  	err   error
   647  }
   648  
   649  // floatLimitIterator represents an iterator that limits points per group.
   650  type 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.
   662  func 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.
   670  func (itr *floatLimitIterator) Stats() IteratorStats { return itr.input.Stats() }
   671  
   672  // Close closes the underlying iterators.
   673  func (itr *floatLimitIterator) Close() error { return itr.input.Close() }
   674  
   675  // Next returns the next point from the iterator.
   676  func (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  
   707  type 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  
   724  func 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  
   756  func (itr *floatFillIterator) Stats() IteratorStats { return itr.input.Stats() }
   757  func (itr *floatFillIterator) Close() error         { return itr.input.Close() }
   758  
   759  func (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.
   814  CONSTRUCT:
   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.
   884  type floatIntervalIterator struct {
   885  	input FloatIterator
   886  	opt   IteratorOptions
   887  }
   888  
   889  func newFloatIntervalIterator(input FloatIterator, opt IteratorOptions) *floatIntervalIterator {
   890  	return &floatIntervalIterator{input: input, opt: opt}
   891  }
   892  
   893  func (itr *floatIntervalIterator) Stats() IteratorStats { return itr.input.Stats() }
   894  func (itr *floatIntervalIterator) Close() error         { return itr.input.Close() }
   895  
   896  func (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.
   911  type floatInterruptIterator struct {
   912  	input   FloatIterator
   913  	closing <-chan struct{}
   914  	count   int
   915  }
   916  
   917  func newFloatInterruptIterator(input FloatIterator, closing <-chan struct{}) *floatInterruptIterator {
   918  	return &floatInterruptIterator{input: input, closing: closing}
   919  }
   920  
   921  func (itr *floatInterruptIterator) Stats() IteratorStats { return itr.input.Stats() }
   922  func (itr *floatInterruptIterator) Close() error         { return itr.input.Close() }
   923  
   924  func (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.
   945  type floatCloseInterruptIterator struct {
   946  	input   FloatIterator
   947  	closing <-chan struct{}
   948  	done    chan struct{}
   949  	once    sync.Once
   950  }
   951  
   952  func 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  
   962  func (itr *floatCloseInterruptIterator) monitor() {
   963  	select {
   964  	case <-itr.closing:
   965  		itr.Close()
   966  	case <-itr.done:
   967  	}
   968  }
   969  
   970  func (itr *floatCloseInterruptIterator) Stats() IteratorStats {
   971  	return itr.input.Stats()
   972  }
   973  
   974  func (itr *floatCloseInterruptIterator) Close() error {
   975  	itr.once.Do(func() {
   976  		close(itr.done)
   977  		itr.input.Close()
   978  	})
   979  	return nil
   980  }
   981  
   982  func (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.
   997  type floatReduceFloatIterator struct {
   998  	input    *bufFloatIterator
   999  	create   func() (FloatPointAggregator, FloatPointEmitter)
  1000  	dims     []string
  1001  	opt      IteratorOptions
  1002  	points   []FloatPoint
  1003  	keepTags bool
  1004  }
  1005  
  1006  func 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.
  1016  func (itr *floatReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
  1017  
  1018  // Close closes the iterator and all child iterators.
  1019  func (itr *floatReduceFloatIterator) Close() error { return itr.input.Close() }
  1020  
  1021  // Next returns the minimum value for the next available interval.
  1022  func (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.
  1039  type 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.
  1048  func (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.
  1165  type 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.
  1175  func 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.
  1186  func (itr *floatStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
  1187  
  1188  // Close closes the iterator and all child iterators.
  1189  func (itr *floatStreamFloatIterator) Close() error { return itr.input.Close() }
  1190  
  1191  // Next returns the next value for the stream iterator.
  1192  func (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.
  1210  func (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.
  1285  type floatReduceIntegerIterator struct {
  1286  	input    *bufFloatIterator
  1287  	create   func() (FloatPointAggregator, IntegerPointEmitter)
  1288  	dims     []string
  1289  	opt      IteratorOptions
  1290  	points   []IntegerPoint
  1291  	keepTags bool
  1292  }
  1293  
  1294  func 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.
  1304  func (itr *floatReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
  1305  
  1306  // Close closes the iterator and all child iterators.
  1307  func (itr *floatReduceIntegerIterator) Close() error { return itr.input.Close() }
  1308  
  1309  // Next returns the minimum value for the next available interval.
  1310  func (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.
  1327  type 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.
  1336  func (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.
  1453  type 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.
  1463  func 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.
  1474  func (itr *floatStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
  1475  
  1476  // Close closes the iterator and all child iterators.
  1477  func (itr *floatStreamIntegerIterator) Close() error { return itr.input.Close() }
  1478  
  1479  // Next returns the next value for the stream iterator.
  1480  func (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.
  1498  func (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.
  1573  type floatReduceUnsignedIterator struct {
  1574  	input    *bufFloatIterator
  1575  	create   func() (FloatPointAggregator, UnsignedPointEmitter)
  1576  	dims     []string
  1577  	opt      IteratorOptions
  1578  	points   []UnsignedPoint
  1579  	keepTags bool
  1580  }
  1581  
  1582  func 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.
  1592  func (itr *floatReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
  1593  
  1594  // Close closes the iterator and all child iterators.
  1595  func (itr *floatReduceUnsignedIterator) Close() error { return itr.input.Close() }
  1596  
  1597  // Next returns the minimum value for the next available interval.
  1598  func (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.
  1615  type 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.
  1624  func (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.
  1741  type 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.
  1751  func 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.
  1762  func (itr *floatStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
  1763  
  1764  // Close closes the iterator and all child iterators.
  1765  func (itr *floatStreamUnsignedIterator) Close() error { return itr.input.Close() }
  1766  
  1767  // Next returns the next value for the stream iterator.
  1768  func (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.
  1786  func (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.
  1861  type floatReduceStringIterator struct {
  1862  	input    *bufFloatIterator
  1863  	create   func() (FloatPointAggregator, StringPointEmitter)
  1864  	dims     []string
  1865  	opt      IteratorOptions
  1866  	points   []StringPoint
  1867  	keepTags bool
  1868  }
  1869  
  1870  func 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.
  1880  func (itr *floatReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() }
  1881  
  1882  // Close closes the iterator and all child iterators.
  1883  func (itr *floatReduceStringIterator) Close() error { return itr.input.Close() }
  1884  
  1885  // Next returns the minimum value for the next available interval.
  1886  func (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.
  1903  type 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.
  1912  func (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.
  2029  type 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.
  2039  func 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.
  2050  func (itr *floatStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() }
  2051  
  2052  // Close closes the iterator and all child iterators.
  2053  func (itr *floatStreamStringIterator) Close() error { return itr.input.Close() }
  2054  
  2055  // Next returns the next value for the stream iterator.
  2056  func (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.
  2074  func (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.
  2149  type floatReduceBooleanIterator struct {
  2150  	input    *bufFloatIterator
  2151  	create   func() (FloatPointAggregator, BooleanPointEmitter)
  2152  	dims     []string
  2153  	opt      IteratorOptions
  2154  	points   []BooleanPoint
  2155  	keepTags bool
  2156  }
  2157  
  2158  func 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.
  2168  func (itr *floatReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
  2169  
  2170  // Close closes the iterator and all child iterators.
  2171  func (itr *floatReduceBooleanIterator) Close() error { return itr.input.Close() }
  2172  
  2173  // Next returns the minimum value for the next available interval.
  2174  func (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.
  2191  type 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.
  2200  func (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.
  2317  type 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.
  2327  func 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.
  2338  func (itr *floatStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
  2339  
  2340  // Close closes the iterator and all child iterators.
  2341  func (itr *floatStreamBooleanIterator) Close() error { return itr.input.Close() }
  2342  
  2343  // Next returns the next value for the stream iterator.
  2344  func (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.
  2362  func (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.
  2440  type floatDedupeIterator struct {
  2441  	input FloatIterator
  2442  	m     map[string]struct{} // lookup of points already sent
  2443  }
  2444  
  2445  type 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  
  2453  func 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  
  2464  func (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  
  2496  func (itr *floatIteratorMapper) Stats() IteratorStats {
  2497  	return itr.cur.Stats()
  2498  }
  2499  
  2500  func (itr *floatIteratorMapper) Close() error {
  2501  	return itr.cur.Close()
  2502  }
  2503  
  2504  type floatFilterIterator struct {
  2505  	input FloatIterator
  2506  	cond  influxql.Expr
  2507  	opt   IteratorOptions
  2508  	m     map[string]interface{}
  2509  }
  2510  
  2511  func 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  
  2539  func (itr *floatFilterIterator) Stats() IteratorStats { return itr.input.Stats() }
  2540  func (itr *floatFilterIterator) Close() error         { return itr.input.Close() }
  2541  
  2542  func (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  
  2563  type floatTagSubsetIterator struct {
  2564  	input      FloatIterator
  2565  	point      FloatPoint
  2566  	lastTags   Tags
  2567  	dimensions []string
  2568  }
  2569  
  2570  func newFloatTagSubsetIterator(input FloatIterator, opt IteratorOptions) *floatTagSubsetIterator {
  2571  	return &floatTagSubsetIterator{
  2572  		input:      input,
  2573  		dimensions: opt.GetDimensions(),
  2574  	}
  2575  }
  2576  
  2577  func (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  
  2598  func (itr *floatTagSubsetIterator) Stats() IteratorStats {
  2599  	return itr.input.Stats()
  2600  }
  2601  
  2602  func (itr *floatTagSubsetIterator) Close() error {
  2603  	return itr.input.Close()
  2604  }
  2605  
  2606  // newFloatDedupeIterator returns a new instance of floatDedupeIterator.
  2607  func 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.
  2615  func (itr *floatDedupeIterator) Stats() IteratorStats { return itr.input.Stats() }
  2616  
  2617  // Close closes the iterator and all child iterators.
  2618  func (itr *floatDedupeIterator) Close() error { return itr.input.Close() }
  2619  
  2620  // Next returns the next unique point from the input iterator.
  2621  func (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.
  2647  type floatReaderIterator struct {
  2648  	r   io.Reader
  2649  	dec *FloatPointDecoder
  2650  }
  2651  
  2652  // newFloatReaderIterator returns a new instance of floatReaderIterator.
  2653  func 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.
  2664  func (itr *floatReaderIterator) Stats() IteratorStats { return itr.dec.stats }
  2665  
  2666  // Close closes the underlying reader, if applicable.
  2667  func (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.
  2675  func (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.
  2689  type 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.
  2697  func 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.
  2711  type bufIntegerIterator struct {
  2712  	itr IntegerIterator
  2713  	buf *IntegerPoint
  2714  }
  2715  
  2716  // newBufIntegerIterator returns a buffered IntegerIterator.
  2717  func newBufIntegerIterator(itr IntegerIterator) *bufIntegerIterator {
  2718  	return &bufIntegerIterator{itr: itr}
  2719  }
  2720  
  2721  // Stats returns statistics from the input iterator.
  2722  func (itr *bufIntegerIterator) Stats() IteratorStats { return itr.itr.Stats() }
  2723  
  2724  // Close closes the underlying iterator.
  2725  func (itr *bufIntegerIterator) Close() error { return itr.itr.Close() }
  2726  
  2727  // peek returns the next point without removing it from the iterator.
  2728  func (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.
  2739  func (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.
  2748  func (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.
  2759  func (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().
  2771  func (itr *bufIntegerIterator) unread(v *IntegerPoint) { itr.buf = v }
  2772  
  2773  // integerMergeIterator represents an iterator that combines multiple integer iterators.
  2774  type 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.
  2793  func 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.
  2815  func (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.
  2824  func (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.
  2839  func (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.
  2923  type integerMergeHeap struct {
  2924  	opt   IteratorOptions
  2925  	items []*integerMergeHeapItem
  2926  }
  2927  
  2928  func (h *integerMergeHeap) Len() int      { return len(h.items) }
  2929  func (h *integerMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
  2930  func (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  
  2963  func (h *integerMergeHeap) Push(x interface{}) {
  2964  	h.items = append(h.items, x.(*integerMergeHeapItem))
  2965  }
  2966  
  2967  func (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  
  2975  type integerMergeHeapItem struct {
  2976  	itr *bufIntegerIterator
  2977  }
  2978  
  2979  // integerSortedMergeIterator is an iterator that sorts and merges multiple iterators into one.
  2980  type integerSortedMergeIterator struct {
  2981  	inputs []IntegerIterator
  2982  	heap   *integerSortedMergeHeap
  2983  	init   bool
  2984  }
  2985  
  2986  // newIntegerSortedMergeIterator returns an instance of integerSortedMergeIterator.
  2987  func 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.
  3006  func (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.
  3015  func (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.
  3023  func (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.
  3027  func (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  type integerSortedMergeHeap struct {
  3075  	opt   IteratorOptions
  3076  	items []*integerSortedMergeHeapItem
  3077  }
  3078  
  3079  func (h *integerSortedMergeHeap) Len() int      { return len(h.items) }
  3080  func (h *integerSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
  3081  func (h *integerSortedMergeHeap) Less(i, j int) bool {
  3082  	x, y := h.items[i].point, h.items[j].point
  3083  
  3084  	if h.opt.Ascending {
  3085  		if x.Name != y.Name {
  3086  			return x.Name < y.Name
  3087  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
  3088  			return xTags.ID() < yTags.ID()
  3089  		}
  3090  
  3091  		if x.Time != y.Time {
  3092  			return x.Time < y.Time
  3093  		}
  3094  
  3095  		if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
  3096  			for i := 0; i < len(x.Aux); i++ {
  3097  				v1, ok1 := x.Aux[i].(string)
  3098  				v2, ok2 := y.Aux[i].(string)
  3099  				if !ok1 || !ok2 {
  3100  					// Unsupported types used in Aux fields. Maybe they
  3101  					// need to be added here?
  3102  					return false
  3103  				} else if v1 == v2 {
  3104  					continue
  3105  				}
  3106  				return v1 < v2
  3107  			}
  3108  		}
  3109  		return false // Times and/or Aux fields are equal.
  3110  	}
  3111  
  3112  	if x.Name != y.Name {
  3113  		return x.Name > y.Name
  3114  	} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
  3115  		return xTags.ID() > yTags.ID()
  3116  	}
  3117  
  3118  	if x.Time != y.Time {
  3119  		return x.Time > y.Time
  3120  	}
  3121  
  3122  	if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
  3123  		for i := 0; i < len(x.Aux); i++ {
  3124  			v1, ok1 := x.Aux[i].(string)
  3125  			v2, ok2 := y.Aux[i].(string)
  3126  			if !ok1 || !ok2 {
  3127  				// Unsupported types used in Aux fields. Maybe they
  3128  				// need to be added here?
  3129  				return false
  3130  			} else if v1 == v2 {
  3131  				continue
  3132  			}
  3133  			return v1 > v2
  3134  		}
  3135  	}
  3136  	return false // Times and/or Aux fields are equal.
  3137  }
  3138  
  3139  func (h *integerSortedMergeHeap) Push(x interface{}) {
  3140  	h.items = append(h.items, x.(*integerSortedMergeHeapItem))
  3141  }
  3142  
  3143  func (h *integerSortedMergeHeap) Pop() interface{} {
  3144  	old := h.items
  3145  	n := len(old)
  3146  	item := old[n-1]
  3147  	h.items = old[0 : n-1]
  3148  	return item
  3149  }
  3150  
  3151  type integerSortedMergeHeapItem struct {
  3152  	point *IntegerPoint
  3153  	err   error
  3154  	itr   IntegerIterator
  3155  }
  3156  
  3157  // integerIteratorScanner scans the results of a IntegerIterator into a map.
  3158  type integerIteratorScanner struct {
  3159  	input        *bufIntegerIterator
  3160  	err          error
  3161  	keys         []influxql.VarRef
  3162  	defaultValue interface{}
  3163  }
  3164  
  3165  // newIntegerIteratorScanner creates a new IteratorScanner.
  3166  func newIntegerIteratorScanner(input IntegerIterator, keys []influxql.VarRef, defaultValue interface{}) *integerIteratorScanner {
  3167  	return &integerIteratorScanner{
  3168  		input:        newBufIntegerIterator(input),
  3169  		keys:         keys,
  3170  		defaultValue: defaultValue,
  3171  	}
  3172  }
  3173  
  3174  func (s *integerIteratorScanner) Peek() (int64, string, Tags) {
  3175  	if s.err != nil {
  3176  		return ZeroTime, "", Tags{}
  3177  	}
  3178  
  3179  	p, err := s.input.peek()
  3180  	if err != nil {
  3181  		s.err = err
  3182  		return ZeroTime, "", Tags{}
  3183  	} else if p == nil {
  3184  		return ZeroTime, "", Tags{}
  3185  	}
  3186  	return p.Time, p.Name, p.Tags
  3187  }
  3188  
  3189  func (s *integerIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) {
  3190  	if s.err != nil {
  3191  		return
  3192  	}
  3193  
  3194  	p, err := s.input.Next()
  3195  	if err != nil {
  3196  		s.err = err
  3197  		return
  3198  	} else if p == nil {
  3199  		s.useDefaults(m)
  3200  		return
  3201  	} else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) {
  3202  		s.useDefaults(m)
  3203  		s.input.unread(p)
  3204  		return
  3205  	}
  3206  
  3207  	if k := s.keys[0]; k.Val != "" {
  3208  		if p.Nil {
  3209  			if s.defaultValue != SkipDefault {
  3210  				m[k.Val] = castToType(s.defaultValue, k.Type)
  3211  			}
  3212  		} else {
  3213  			m[k.Val] = p.Value
  3214  		}
  3215  	}
  3216  	for i, v := range p.Aux {
  3217  		k := s.keys[i+1]
  3218  		switch v.(type) {
  3219  		case float64, int64, uint64, string, bool:
  3220  			m[k.Val] = v
  3221  		default:
  3222  			// Insert the fill value if one was specified.
  3223  			if s.defaultValue != SkipDefault {
  3224  				m[k.Val] = castToType(s.defaultValue, k.Type)
  3225  			}
  3226  		}
  3227  	}
  3228  }
  3229  
  3230  func (s *integerIteratorScanner) useDefaults(m map[string]interface{}) {
  3231  	if s.defaultValue == SkipDefault {
  3232  		return
  3233  	}
  3234  	for _, k := range s.keys {
  3235  		if k.Val == "" {
  3236  			continue
  3237  		}
  3238  		m[k.Val] = castToType(s.defaultValue, k.Type)
  3239  	}
  3240  }
  3241  
  3242  func (s *integerIteratorScanner) Stats() IteratorStats { return s.input.Stats() }
  3243  func (s *integerIteratorScanner) Err() error           { return s.err }
  3244  func (s *integerIteratorScanner) Close() error         { return s.input.Close() }
  3245  
  3246  // integerParallelIterator represents an iterator that pulls data in a separate goroutine.
  3247  type integerParallelIterator struct {
  3248  	input IntegerIterator
  3249  	ch    chan integerPointError
  3250  
  3251  	once    sync.Once
  3252  	closing chan struct{}
  3253  	wg      sync.WaitGroup
  3254  }
  3255  
  3256  // newIntegerParallelIterator returns a new instance of integerParallelIterator.
  3257  func newIntegerParallelIterator(input IntegerIterator) *integerParallelIterator {
  3258  	itr := &integerParallelIterator{
  3259  		input:   input,
  3260  		ch:      make(chan integerPointError, 256),
  3261  		closing: make(chan struct{}),
  3262  	}
  3263  	itr.wg.Add(1)
  3264  	go itr.monitor()
  3265  	return itr
  3266  }
  3267  
  3268  // Stats returns stats from the underlying iterator.
  3269  func (itr *integerParallelIterator) Stats() IteratorStats { return itr.input.Stats() }
  3270  
  3271  // Close closes the underlying iterators.
  3272  func (itr *integerParallelIterator) Close() error {
  3273  	itr.once.Do(func() { close(itr.closing) })
  3274  	itr.wg.Wait()
  3275  	return itr.input.Close()
  3276  }
  3277  
  3278  // Next returns the next point from the iterator.
  3279  func (itr *integerParallelIterator) Next() (*IntegerPoint, error) {
  3280  	v, ok := <-itr.ch
  3281  	if !ok {
  3282  		return nil, io.EOF
  3283  	}
  3284  	return v.point, v.err
  3285  }
  3286  
  3287  // monitor runs in a separate goroutine and actively pulls the next point.
  3288  func (itr *integerParallelIterator) monitor() {
  3289  	defer close(itr.ch)
  3290  	defer itr.wg.Done()
  3291  
  3292  	for {
  3293  		// Read next point.
  3294  		p, err := itr.input.Next()
  3295  		if p != nil {
  3296  			p = p.Clone()
  3297  		}
  3298  
  3299  		select {
  3300  		case <-itr.closing:
  3301  			return
  3302  		case itr.ch <- integerPointError{point: p, err: err}:
  3303  		}
  3304  	}
  3305  }
  3306  
  3307  type integerPointError struct {
  3308  	point *IntegerPoint
  3309  	err   error
  3310  }
  3311  
  3312  // integerLimitIterator represents an iterator that limits points per group.
  3313  type integerLimitIterator struct {
  3314  	input IntegerIterator
  3315  	opt   IteratorOptions
  3316  	n     int
  3317  
  3318  	prev struct {
  3319  		name string
  3320  		tags Tags
  3321  	}
  3322  }
  3323  
  3324  // newIntegerLimitIterator returns a new instance of integerLimitIterator.
  3325  func newIntegerLimitIterator(input IntegerIterator, opt IteratorOptions) *integerLimitIterator {
  3326  	return &integerLimitIterator{
  3327  		input: input,
  3328  		opt:   opt,
  3329  	}
  3330  }
  3331  
  3332  // Stats returns stats from the underlying iterator.
  3333  func (itr *integerLimitIterator) Stats() IteratorStats { return itr.input.Stats() }
  3334  
  3335  // Close closes the underlying iterators.
  3336  func (itr *integerLimitIterator) Close() error { return itr.input.Close() }
  3337  
  3338  // Next returns the next point from the iterator.
  3339  func (itr *integerLimitIterator) Next() (*IntegerPoint, error) {
  3340  	for {
  3341  		p, err := itr.input.Next()
  3342  		if p == nil || err != nil {
  3343  			return nil, err
  3344  		}
  3345  
  3346  		// Reset window and counter if a new window is encountered.
  3347  		if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) {
  3348  			itr.prev.name = p.Name
  3349  			itr.prev.tags = p.Tags
  3350  			itr.n = 0
  3351  		}
  3352  
  3353  		// Increment counter.
  3354  		itr.n++
  3355  
  3356  		// Read next point if not beyond the offset.
  3357  		if itr.n <= itr.opt.Offset {
  3358  			continue
  3359  		}
  3360  
  3361  		// Read next point if we're beyond the limit.
  3362  		if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit {
  3363  			continue
  3364  		}
  3365  
  3366  		return p, nil
  3367  	}
  3368  }
  3369  
  3370  type integerFillIterator struct {
  3371  	input     *bufIntegerIterator
  3372  	prev      IntegerPoint
  3373  	startTime int64
  3374  	endTime   int64
  3375  	auxFields []interface{}
  3376  	init      bool
  3377  	opt       IteratorOptions
  3378  
  3379  	window struct {
  3380  		name   string
  3381  		tags   Tags
  3382  		time   int64
  3383  		offset int64
  3384  	}
  3385  }
  3386  
  3387  func newIntegerFillIterator(input IntegerIterator, expr influxql.Expr, opt IteratorOptions) *integerFillIterator {
  3388  	if opt.Fill == influxql.NullFill {
  3389  		if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" {
  3390  			opt.Fill = influxql.NumberFill
  3391  			opt.FillValue = int64(0)
  3392  		}
  3393  	}
  3394  
  3395  	var startTime, endTime int64
  3396  	if opt.Ascending {
  3397  		startTime, _ = opt.Window(opt.StartTime)
  3398  		endTime, _ = opt.Window(opt.EndTime)
  3399  	} else {
  3400  		startTime, _ = opt.Window(opt.EndTime)
  3401  		endTime, _ = opt.Window(opt.StartTime)
  3402  	}
  3403  
  3404  	var auxFields []interface{}
  3405  	if len(opt.Aux) > 0 {
  3406  		auxFields = make([]interface{}, len(opt.Aux))
  3407  	}
  3408  
  3409  	return &integerFillIterator{
  3410  		input:     newBufIntegerIterator(input),
  3411  		prev:      IntegerPoint{Nil: true},
  3412  		startTime: startTime,
  3413  		endTime:   endTime,
  3414  		auxFields: auxFields,
  3415  		opt:       opt,
  3416  	}
  3417  }
  3418  
  3419  func (itr *integerFillIterator) Stats() IteratorStats { return itr.input.Stats() }
  3420  func (itr *integerFillIterator) Close() error         { return itr.input.Close() }
  3421  
  3422  func (itr *integerFillIterator) Next() (*IntegerPoint, error) {
  3423  	if !itr.init {
  3424  		p, err := itr.input.peek()
  3425  		if p == nil || err != nil {
  3426  			return nil, err
  3427  		}
  3428  		itr.window.name, itr.window.tags = p.Name, p.Tags
  3429  		itr.window.time = itr.startTime
  3430  		if itr.startTime == influxql.MinTime {
  3431  			itr.window.time, _ = itr.opt.Window(p.Time)
  3432  		}
  3433  		if itr.opt.Location != nil {
  3434  			_, itr.window.offset = itr.opt.Zone(itr.window.time)
  3435  		}
  3436  		itr.init = true
  3437  	}
  3438  
  3439  	p, err := itr.input.Next()
  3440  	if err != nil {
  3441  		return nil, err
  3442  	}
  3443  
  3444  	// Check if the next point is outside of our window or is nil.
  3445  	if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() {
  3446  		// If we are inside of an interval, unread the point and continue below to
  3447  		// constructing a new point.
  3448  		if itr.opt.Ascending && itr.window.time <= itr.endTime {
  3449  			itr.input.unread(p)
  3450  			p = nil
  3451  			goto CONSTRUCT
  3452  		} else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime {
  3453  			itr.input.unread(p)
  3454  			p = nil
  3455  			goto CONSTRUCT
  3456  		}
  3457  
  3458  		// We are *not* in a current interval. If there is no next point,
  3459  		// we are at the end of all intervals.
  3460  		if p == nil {
  3461  			return nil, nil
  3462  		}
  3463  
  3464  		// Set the new interval.
  3465  		itr.window.name, itr.window.tags = p.Name, p.Tags
  3466  		itr.window.time = itr.startTime
  3467  		if itr.window.time == influxql.MinTime {
  3468  			itr.window.time, _ = itr.opt.Window(p.Time)
  3469  		}
  3470  		if itr.opt.Location != nil {
  3471  			_, itr.window.offset = itr.opt.Zone(itr.window.time)
  3472  		}
  3473  		itr.prev = IntegerPoint{Nil: true}
  3474  	}
  3475  
  3476  	// Check if the point is our next expected point.
  3477  CONSTRUCT:
  3478  	if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) {
  3479  		if p != nil {
  3480  			itr.input.unread(p)
  3481  		}
  3482  
  3483  		p = &IntegerPoint{
  3484  			Name: itr.window.name,
  3485  			Tags: itr.window.tags,
  3486  			Time: itr.window.time,
  3487  			Aux:  itr.auxFields,
  3488  		}
  3489  
  3490  		switch itr.opt.Fill {
  3491  		case influxql.LinearFill:
  3492  			if !itr.prev.Nil {
  3493  				next, err := itr.input.peek()
  3494  				if err != nil {
  3495  					return nil, err
  3496  				} else if next != nil && next.Name == itr.window.name && next.Tags.ID() == itr.window.tags.ID() {
  3497  					interval := int64(itr.opt.Interval.Duration)
  3498  					start := itr.window.time / interval
  3499  					p.Value = linearInteger(start, itr.prev.Time/interval, next.Time/interval, itr.prev.Value, next.Value)
  3500  				} else {
  3501  					p.Nil = true
  3502  				}
  3503  			} else {
  3504  				p.Nil = true
  3505  			}
  3506  
  3507  		case influxql.NullFill:
  3508  			p.Nil = true
  3509  		case influxql.NumberFill:
  3510  			p.Value, _ = castToInteger(itr.opt.FillValue)
  3511  		case influxql.PreviousFill:
  3512  			if !itr.prev.Nil {
  3513  				p.Value = itr.prev.Value
  3514  				p.Nil = itr.prev.Nil
  3515  			} else {
  3516  				p.Nil = true
  3517  			}
  3518  		}
  3519  	} else {
  3520  		itr.prev = *p
  3521  	}
  3522  
  3523  	// Advance the expected time. Do not advance to a new window here
  3524  	// as there may be lingering points with the same timestamp in the previous
  3525  	// window.
  3526  	if itr.opt.Ascending {
  3527  		itr.window.time += int64(itr.opt.Interval.Duration)
  3528  	} else {
  3529  		itr.window.time -= int64(itr.opt.Interval.Duration)
  3530  	}
  3531  
  3532  	// Check to see if we have passed over an offset change and adjust the time
  3533  	// to account for this new offset.
  3534  	if itr.opt.Location != nil {
  3535  		if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset {
  3536  			diff := itr.window.offset - offset
  3537  			if abs(diff) < int64(itr.opt.Interval.Duration) {
  3538  				itr.window.time += diff
  3539  			}
  3540  			itr.window.offset = offset
  3541  		}
  3542  	}
  3543  	return p, nil
  3544  }
  3545  
  3546  // integerIntervalIterator represents a integer implementation of IntervalIterator.
  3547  type integerIntervalIterator struct {
  3548  	input IntegerIterator
  3549  	opt   IteratorOptions
  3550  }
  3551  
  3552  func newIntegerIntervalIterator(input IntegerIterator, opt IteratorOptions) *integerIntervalIterator {
  3553  	return &integerIntervalIterator{input: input, opt: opt}
  3554  }
  3555  
  3556  func (itr *integerIntervalIterator) Stats() IteratorStats { return itr.input.Stats() }
  3557  func (itr *integerIntervalIterator) Close() error         { return itr.input.Close() }
  3558  
  3559  func (itr *integerIntervalIterator) Next() (*IntegerPoint, error) {
  3560  	p, err := itr.input.Next()
  3561  	if p == nil || err != nil {
  3562  		return nil, err
  3563  	}
  3564  	p.Time, _ = itr.opt.Window(p.Time)
  3565  	// If we see the minimum allowable time, set the time to zero so we don't
  3566  	// break the default returned time for aggregate queries without times.
  3567  	if p.Time == influxql.MinTime {
  3568  		p.Time = 0
  3569  	}
  3570  	return p, nil
  3571  }
  3572  
  3573  // integerInterruptIterator represents a integer implementation of InterruptIterator.
  3574  type integerInterruptIterator struct {
  3575  	input   IntegerIterator
  3576  	closing <-chan struct{}
  3577  	count   int
  3578  }
  3579  
  3580  func newIntegerInterruptIterator(input IntegerIterator, closing <-chan struct{}) *integerInterruptIterator {
  3581  	return &integerInterruptIterator{input: input, closing: closing}
  3582  }
  3583  
  3584  func (itr *integerInterruptIterator) Stats() IteratorStats { return itr.input.Stats() }
  3585  func (itr *integerInterruptIterator) Close() error         { return itr.input.Close() }
  3586  
  3587  func (itr *integerInterruptIterator) Next() (*IntegerPoint, error) {
  3588  	// Only check if the channel is closed every N points. This
  3589  	// intentionally checks on both 0 and N so that if the iterator
  3590  	// has been interrupted before the first point is emitted it will
  3591  	// not emit any points.
  3592  	if itr.count&0xFF == 0xFF {
  3593  		select {
  3594  		case <-itr.closing:
  3595  			return nil, itr.Close()
  3596  		default:
  3597  			// Reset iterator count to zero and fall through to emit the next point.
  3598  			itr.count = 0
  3599  		}
  3600  	}
  3601  
  3602  	// Increment the counter for every point read.
  3603  	itr.count++
  3604  	return itr.input.Next()
  3605  }
  3606  
  3607  // integerCloseInterruptIterator represents a integer implementation of CloseInterruptIterator.
  3608  type integerCloseInterruptIterator struct {
  3609  	input   IntegerIterator
  3610  	closing <-chan struct{}
  3611  	done    chan struct{}
  3612  	once    sync.Once
  3613  }
  3614  
  3615  func newIntegerCloseInterruptIterator(input IntegerIterator, closing <-chan struct{}) *integerCloseInterruptIterator {
  3616  	itr := &integerCloseInterruptIterator{
  3617  		input:   input,
  3618  		closing: closing,
  3619  		done:    make(chan struct{}),
  3620  	}
  3621  	go itr.monitor()
  3622  	return itr
  3623  }
  3624  
  3625  func (itr *integerCloseInterruptIterator) monitor() {
  3626  	select {
  3627  	case <-itr.closing:
  3628  		itr.Close()
  3629  	case <-itr.done:
  3630  	}
  3631  }
  3632  
  3633  func (itr *integerCloseInterruptIterator) Stats() IteratorStats {
  3634  	return itr.input.Stats()
  3635  }
  3636  
  3637  func (itr *integerCloseInterruptIterator) Close() error {
  3638  	itr.once.Do(func() {
  3639  		close(itr.done)
  3640  		itr.input.Close()
  3641  	})
  3642  	return nil
  3643  }
  3644  
  3645  func (itr *integerCloseInterruptIterator) Next() (*IntegerPoint, error) {
  3646  	p, err := itr.input.Next()
  3647  	if err != nil {
  3648  		// Check if the iterator was closed.
  3649  		select {
  3650  		case <-itr.done:
  3651  			return nil, nil
  3652  		default:
  3653  			return nil, err
  3654  		}
  3655  	}
  3656  	return p, nil
  3657  }
  3658  
  3659  // integerReduceFloatIterator executes a reducer for every interval and buffers the result.
  3660  type integerReduceFloatIterator struct {
  3661  	input    *bufIntegerIterator
  3662  	create   func() (IntegerPointAggregator, FloatPointEmitter)
  3663  	dims     []string
  3664  	opt      IteratorOptions
  3665  	points   []FloatPoint
  3666  	keepTags bool
  3667  }
  3668  
  3669  func newIntegerReduceFloatIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, FloatPointEmitter)) *integerReduceFloatIterator {
  3670  	return &integerReduceFloatIterator{
  3671  		input:  newBufIntegerIterator(input),
  3672  		create: createFn,
  3673  		dims:   opt.GetDimensions(),
  3674  		opt:    opt,
  3675  	}
  3676  }
  3677  
  3678  // Stats returns stats from the input iterator.
  3679  func (itr *integerReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
  3680  
  3681  // Close closes the iterator and all child iterators.
  3682  func (itr *integerReduceFloatIterator) Close() error { return itr.input.Close() }
  3683  
  3684  // Next returns the minimum value for the next available interval.
  3685  func (itr *integerReduceFloatIterator) Next() (*FloatPoint, error) {
  3686  	// Calculate next window if we have no more points.
  3687  	if len(itr.points) == 0 {
  3688  		var err error
  3689  		itr.points, err = itr.reduce()
  3690  		if len(itr.points) == 0 {
  3691  			return nil, err
  3692  		}
  3693  	}
  3694  
  3695  	// Pop next point off the stack.
  3696  	p := &itr.points[len(itr.points)-1]
  3697  	itr.points = itr.points[:len(itr.points)-1]
  3698  	return p, nil
  3699  }
  3700  
  3701  // integerReduceFloatPoint stores the reduced data for a name/tag combination.
  3702  type integerReduceFloatPoint struct {
  3703  	Name       string
  3704  	Tags       Tags
  3705  	Aggregator IntegerPointAggregator
  3706  	Emitter    FloatPointEmitter
  3707  }
  3708  
  3709  // reduce executes fn once for every point in the next window.
  3710  // The previous value for the dimension is passed to fn.
  3711  func (itr *integerReduceFloatIterator) reduce() ([]FloatPoint, error) {
  3712  	// Calculate next window.
  3713  	var (
  3714  		startTime, endTime int64
  3715  		window             struct {
  3716  			name string
  3717  			tags string
  3718  		}
  3719  	)
  3720  	for {
  3721  		p, err := itr.input.Next()
  3722  		if err != nil || p == nil {
  3723  			return nil, err
  3724  		} else if p.Nil {
  3725  			continue
  3726  		}
  3727  
  3728  		// Unread the point so it can be processed.
  3729  		itr.input.unread(p)
  3730  		startTime, endTime = itr.opt.Window(p.Time)
  3731  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  3732  		break
  3733  	}
  3734  
  3735  	// Create points by tags.
  3736  	m := make(map[string]*integerReduceFloatPoint)
  3737  	for {
  3738  		// Read next point.
  3739  		curr, err := itr.input.NextInWindow(startTime, endTime)
  3740  		if err != nil {
  3741  			return nil, err
  3742  		} else if curr == nil {
  3743  			break
  3744  		} else if curr.Nil {
  3745  			continue
  3746  		} else if curr.Name != window.name {
  3747  			itr.input.unread(curr)
  3748  			break
  3749  		}
  3750  
  3751  		// Ensure this point is within the same final window.
  3752  		if curr.Name != window.name {
  3753  			itr.input.unread(curr)
  3754  			break
  3755  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  3756  			itr.input.unread(curr)
  3757  			break
  3758  		}
  3759  
  3760  		// Retrieve the tags on this point for this level of the query.
  3761  		// This may be different than the bucket dimensions.
  3762  		tags := curr.Tags.Subset(itr.dims)
  3763  		id := tags.ID()
  3764  
  3765  		// Retrieve the aggregator for this name/tag combination or create one.
  3766  		rp := m[id]
  3767  		if rp == nil {
  3768  			aggregator, emitter := itr.create()
  3769  			rp = &integerReduceFloatPoint{
  3770  				Name:       curr.Name,
  3771  				Tags:       tags,
  3772  				Aggregator: aggregator,
  3773  				Emitter:    emitter,
  3774  			}
  3775  			m[id] = rp
  3776  		}
  3777  		rp.Aggregator.AggregateInteger(curr)
  3778  	}
  3779  
  3780  	keys := make([]string, 0, len(m))
  3781  	for k := range m {
  3782  		keys = append(keys, k)
  3783  	}
  3784  
  3785  	// Reverse sort points by name & tag.
  3786  	// This ensures a consistent order of output.
  3787  	if len(keys) > 0 {
  3788  		var sorted sort.Interface = sort.StringSlice(keys)
  3789  		if itr.opt.Ascending {
  3790  			sorted = sort.Reverse(sorted)
  3791  		}
  3792  		sort.Sort(sorted)
  3793  	}
  3794  
  3795  	// Assume the points are already sorted until proven otherwise.
  3796  	sortedByTime := true
  3797  	// Emit the points for each name & tag combination.
  3798  	a := make([]FloatPoint, 0, len(m))
  3799  	for _, k := range keys {
  3800  		rp := m[k]
  3801  		points := rp.Emitter.Emit()
  3802  		for i := len(points) - 1; i >= 0; i-- {
  3803  			points[i].Name = rp.Name
  3804  			if !itr.keepTags {
  3805  				points[i].Tags = rp.Tags
  3806  			}
  3807  			// Set the points time to the interval time if the reducer didn't provide one.
  3808  			if points[i].Time == ZeroTime {
  3809  				points[i].Time = startTime
  3810  			} else {
  3811  				sortedByTime = false
  3812  			}
  3813  			a = append(a, points[i])
  3814  		}
  3815  	}
  3816  	// Points may be out of order. Perform a stable sort by time if requested.
  3817  	if !sortedByTime && itr.opt.Ordered {
  3818  		var sorted sort.Interface = floatPointsByTime(a)
  3819  		if itr.opt.Ascending {
  3820  			sorted = sort.Reverse(sorted)
  3821  		}
  3822  		sort.Stable(sorted)
  3823  	}
  3824  	return a, nil
  3825  }
  3826  
  3827  // integerStreamFloatIterator streams inputs into the iterator and emits points gradually.
  3828  type integerStreamFloatIterator struct {
  3829  	input  *bufIntegerIterator
  3830  	create func() (IntegerPointAggregator, FloatPointEmitter)
  3831  	dims   []string
  3832  	opt    IteratorOptions
  3833  	m      map[string]*integerReduceFloatPoint
  3834  	points []FloatPoint
  3835  }
  3836  
  3837  // newIntegerStreamFloatIterator returns a new instance of integerStreamFloatIterator.
  3838  func newIntegerStreamFloatIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, FloatPointEmitter), opt IteratorOptions) *integerStreamFloatIterator {
  3839  	return &integerStreamFloatIterator{
  3840  		input:  newBufIntegerIterator(input),
  3841  		create: createFn,
  3842  		dims:   opt.GetDimensions(),
  3843  		opt:    opt,
  3844  		m:      make(map[string]*integerReduceFloatPoint),
  3845  	}
  3846  }
  3847  
  3848  // Stats returns stats from the input iterator.
  3849  func (itr *integerStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
  3850  
  3851  // Close closes the iterator and all child iterators.
  3852  func (itr *integerStreamFloatIterator) Close() error { return itr.input.Close() }
  3853  
  3854  // Next returns the next value for the stream iterator.
  3855  func (itr *integerStreamFloatIterator) Next() (*FloatPoint, error) {
  3856  	// Calculate next window if we have no more points.
  3857  	if len(itr.points) == 0 {
  3858  		var err error
  3859  		itr.points, err = itr.reduce()
  3860  		if len(itr.points) == 0 {
  3861  			return nil, err
  3862  		}
  3863  	}
  3864  
  3865  	// Pop next point off the stack.
  3866  	p := &itr.points[len(itr.points)-1]
  3867  	itr.points = itr.points[:len(itr.points)-1]
  3868  	return p, nil
  3869  }
  3870  
  3871  // reduce creates and manages aggregators for every point from the input.
  3872  // After aggregating a point, it always tries to emit a value using the emitter.
  3873  func (itr *integerStreamFloatIterator) reduce() ([]FloatPoint, error) {
  3874  	// We have already read all of the input points.
  3875  	if itr.m == nil {
  3876  		return nil, nil
  3877  	}
  3878  
  3879  	for {
  3880  		// Read next point.
  3881  		curr, err := itr.input.Next()
  3882  		if err != nil {
  3883  			return nil, err
  3884  		} else if curr == nil {
  3885  			// Close all of the aggregators to flush any remaining points to emit.
  3886  			var points []FloatPoint
  3887  			for _, rp := range itr.m {
  3888  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  3889  					if err := aggregator.Close(); err != nil {
  3890  						return nil, err
  3891  					}
  3892  
  3893  					pts := rp.Emitter.Emit()
  3894  					if len(pts) == 0 {
  3895  						continue
  3896  					}
  3897  
  3898  					for i := range pts {
  3899  						pts[i].Name = rp.Name
  3900  						pts[i].Tags = rp.Tags
  3901  					}
  3902  					points = append(points, pts...)
  3903  				}
  3904  			}
  3905  
  3906  			// Eliminate the aggregators and emitters.
  3907  			itr.m = nil
  3908  			return points, nil
  3909  		} else if curr.Nil {
  3910  			continue
  3911  		}
  3912  		tags := curr.Tags.Subset(itr.dims)
  3913  
  3914  		id := curr.Name
  3915  		if len(tags.m) > 0 {
  3916  			id += "\x00" + tags.ID()
  3917  		}
  3918  
  3919  		// Retrieve the aggregator for this name/tag combination or create one.
  3920  		rp := itr.m[id]
  3921  		if rp == nil {
  3922  			aggregator, emitter := itr.create()
  3923  			rp = &integerReduceFloatPoint{
  3924  				Name:       curr.Name,
  3925  				Tags:       tags,
  3926  				Aggregator: aggregator,
  3927  				Emitter:    emitter,
  3928  			}
  3929  			itr.m[id] = rp
  3930  		}
  3931  		rp.Aggregator.AggregateInteger(curr)
  3932  
  3933  		// Attempt to emit points from the aggregator.
  3934  		points := rp.Emitter.Emit()
  3935  		if len(points) == 0 {
  3936  			continue
  3937  		}
  3938  
  3939  		for i := range points {
  3940  			points[i].Name = rp.Name
  3941  			points[i].Tags = rp.Tags
  3942  		}
  3943  		return points, nil
  3944  	}
  3945  }
  3946  
  3947  // integerReduceIntegerIterator executes a reducer for every interval and buffers the result.
  3948  type integerReduceIntegerIterator struct {
  3949  	input    *bufIntegerIterator
  3950  	create   func() (IntegerPointAggregator, IntegerPointEmitter)
  3951  	dims     []string
  3952  	opt      IteratorOptions
  3953  	points   []IntegerPoint
  3954  	keepTags bool
  3955  }
  3956  
  3957  func newIntegerReduceIntegerIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, IntegerPointEmitter)) *integerReduceIntegerIterator {
  3958  	return &integerReduceIntegerIterator{
  3959  		input:  newBufIntegerIterator(input),
  3960  		create: createFn,
  3961  		dims:   opt.GetDimensions(),
  3962  		opt:    opt,
  3963  	}
  3964  }
  3965  
  3966  // Stats returns stats from the input iterator.
  3967  func (itr *integerReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
  3968  
  3969  // Close closes the iterator and all child iterators.
  3970  func (itr *integerReduceIntegerIterator) Close() error { return itr.input.Close() }
  3971  
  3972  // Next returns the minimum value for the next available interval.
  3973  func (itr *integerReduceIntegerIterator) Next() (*IntegerPoint, error) {
  3974  	// Calculate next window if we have no more points.
  3975  	if len(itr.points) == 0 {
  3976  		var err error
  3977  		itr.points, err = itr.reduce()
  3978  		if len(itr.points) == 0 {
  3979  			return nil, err
  3980  		}
  3981  	}
  3982  
  3983  	// Pop next point off the stack.
  3984  	p := &itr.points[len(itr.points)-1]
  3985  	itr.points = itr.points[:len(itr.points)-1]
  3986  	return p, nil
  3987  }
  3988  
  3989  // integerReduceIntegerPoint stores the reduced data for a name/tag combination.
  3990  type integerReduceIntegerPoint struct {
  3991  	Name       string
  3992  	Tags       Tags
  3993  	Aggregator IntegerPointAggregator
  3994  	Emitter    IntegerPointEmitter
  3995  }
  3996  
  3997  // reduce executes fn once for every point in the next window.
  3998  // The previous value for the dimension is passed to fn.
  3999  func (itr *integerReduceIntegerIterator) reduce() ([]IntegerPoint, error) {
  4000  	// Calculate next window.
  4001  	var (
  4002  		startTime, endTime int64
  4003  		window             struct {
  4004  			name string
  4005  			tags string
  4006  		}
  4007  	)
  4008  	for {
  4009  		p, err := itr.input.Next()
  4010  		if err != nil || p == nil {
  4011  			return nil, err
  4012  		} else if p.Nil {
  4013  			continue
  4014  		}
  4015  
  4016  		// Unread the point so it can be processed.
  4017  		itr.input.unread(p)
  4018  		startTime, endTime = itr.opt.Window(p.Time)
  4019  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  4020  		break
  4021  	}
  4022  
  4023  	// Create points by tags.
  4024  	m := make(map[string]*integerReduceIntegerPoint)
  4025  	for {
  4026  		// Read next point.
  4027  		curr, err := itr.input.NextInWindow(startTime, endTime)
  4028  		if err != nil {
  4029  			return nil, err
  4030  		} else if curr == nil {
  4031  			break
  4032  		} else if curr.Nil {
  4033  			continue
  4034  		} else if curr.Name != window.name {
  4035  			itr.input.unread(curr)
  4036  			break
  4037  		}
  4038  
  4039  		// Ensure this point is within the same final window.
  4040  		if curr.Name != window.name {
  4041  			itr.input.unread(curr)
  4042  			break
  4043  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  4044  			itr.input.unread(curr)
  4045  			break
  4046  		}
  4047  
  4048  		// Retrieve the tags on this point for this level of the query.
  4049  		// This may be different than the bucket dimensions.
  4050  		tags := curr.Tags.Subset(itr.dims)
  4051  		id := tags.ID()
  4052  
  4053  		// Retrieve the aggregator for this name/tag combination or create one.
  4054  		rp := m[id]
  4055  		if rp == nil {
  4056  			aggregator, emitter := itr.create()
  4057  			rp = &integerReduceIntegerPoint{
  4058  				Name:       curr.Name,
  4059  				Tags:       tags,
  4060  				Aggregator: aggregator,
  4061  				Emitter:    emitter,
  4062  			}
  4063  			m[id] = rp
  4064  		}
  4065  		rp.Aggregator.AggregateInteger(curr)
  4066  	}
  4067  
  4068  	keys := make([]string, 0, len(m))
  4069  	for k := range m {
  4070  		keys = append(keys, k)
  4071  	}
  4072  
  4073  	// Reverse sort points by name & tag.
  4074  	// This ensures a consistent order of output.
  4075  	if len(keys) > 0 {
  4076  		var sorted sort.Interface = sort.StringSlice(keys)
  4077  		if itr.opt.Ascending {
  4078  			sorted = sort.Reverse(sorted)
  4079  		}
  4080  		sort.Sort(sorted)
  4081  	}
  4082  
  4083  	// Assume the points are already sorted until proven otherwise.
  4084  	sortedByTime := true
  4085  	// Emit the points for each name & tag combination.
  4086  	a := make([]IntegerPoint, 0, len(m))
  4087  	for _, k := range keys {
  4088  		rp := m[k]
  4089  		points := rp.Emitter.Emit()
  4090  		for i := len(points) - 1; i >= 0; i-- {
  4091  			points[i].Name = rp.Name
  4092  			if !itr.keepTags {
  4093  				points[i].Tags = rp.Tags
  4094  			}
  4095  			// Set the points time to the interval time if the reducer didn't provide one.
  4096  			if points[i].Time == ZeroTime {
  4097  				points[i].Time = startTime
  4098  			} else {
  4099  				sortedByTime = false
  4100  			}
  4101  			a = append(a, points[i])
  4102  		}
  4103  	}
  4104  	// Points may be out of order. Perform a stable sort by time if requested.
  4105  	if !sortedByTime && itr.opt.Ordered {
  4106  		var sorted sort.Interface = integerPointsByTime(a)
  4107  		if itr.opt.Ascending {
  4108  			sorted = sort.Reverse(sorted)
  4109  		}
  4110  		sort.Stable(sorted)
  4111  	}
  4112  	return a, nil
  4113  }
  4114  
  4115  // integerStreamIntegerIterator streams inputs into the iterator and emits points gradually.
  4116  type integerStreamIntegerIterator struct {
  4117  	input  *bufIntegerIterator
  4118  	create func() (IntegerPointAggregator, IntegerPointEmitter)
  4119  	dims   []string
  4120  	opt    IteratorOptions
  4121  	m      map[string]*integerReduceIntegerPoint
  4122  	points []IntegerPoint
  4123  }
  4124  
  4125  // newIntegerStreamIntegerIterator returns a new instance of integerStreamIntegerIterator.
  4126  func newIntegerStreamIntegerIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, IntegerPointEmitter), opt IteratorOptions) *integerStreamIntegerIterator {
  4127  	return &integerStreamIntegerIterator{
  4128  		input:  newBufIntegerIterator(input),
  4129  		create: createFn,
  4130  		dims:   opt.GetDimensions(),
  4131  		opt:    opt,
  4132  		m:      make(map[string]*integerReduceIntegerPoint),
  4133  	}
  4134  }
  4135  
  4136  // Stats returns stats from the input iterator.
  4137  func (itr *integerStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
  4138  
  4139  // Close closes the iterator and all child iterators.
  4140  func (itr *integerStreamIntegerIterator) Close() error { return itr.input.Close() }
  4141  
  4142  // Next returns the next value for the stream iterator.
  4143  func (itr *integerStreamIntegerIterator) Next() (*IntegerPoint, error) {
  4144  	// Calculate next window if we have no more points.
  4145  	if len(itr.points) == 0 {
  4146  		var err error
  4147  		itr.points, err = itr.reduce()
  4148  		if len(itr.points) == 0 {
  4149  			return nil, err
  4150  		}
  4151  	}
  4152  
  4153  	// Pop next point off the stack.
  4154  	p := &itr.points[len(itr.points)-1]
  4155  	itr.points = itr.points[:len(itr.points)-1]
  4156  	return p, nil
  4157  }
  4158  
  4159  // reduce creates and manages aggregators for every point from the input.
  4160  // After aggregating a point, it always tries to emit a value using the emitter.
  4161  func (itr *integerStreamIntegerIterator) reduce() ([]IntegerPoint, error) {
  4162  	// We have already read all of the input points.
  4163  	if itr.m == nil {
  4164  		return nil, nil
  4165  	}
  4166  
  4167  	for {
  4168  		// Read next point.
  4169  		curr, err := itr.input.Next()
  4170  		if err != nil {
  4171  			return nil, err
  4172  		} else if curr == nil {
  4173  			// Close all of the aggregators to flush any remaining points to emit.
  4174  			var points []IntegerPoint
  4175  			for _, rp := range itr.m {
  4176  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  4177  					if err := aggregator.Close(); err != nil {
  4178  						return nil, err
  4179  					}
  4180  
  4181  					pts := rp.Emitter.Emit()
  4182  					if len(pts) == 0 {
  4183  						continue
  4184  					}
  4185  
  4186  					for i := range pts {
  4187  						pts[i].Name = rp.Name
  4188  						pts[i].Tags = rp.Tags
  4189  					}
  4190  					points = append(points, pts...)
  4191  				}
  4192  			}
  4193  
  4194  			// Eliminate the aggregators and emitters.
  4195  			itr.m = nil
  4196  			return points, nil
  4197  		} else if curr.Nil {
  4198  			continue
  4199  		}
  4200  		tags := curr.Tags.Subset(itr.dims)
  4201  
  4202  		id := curr.Name
  4203  		if len(tags.m) > 0 {
  4204  			id += "\x00" + tags.ID()
  4205  		}
  4206  
  4207  		// Retrieve the aggregator for this name/tag combination or create one.
  4208  		rp := itr.m[id]
  4209  		if rp == nil {
  4210  			aggregator, emitter := itr.create()
  4211  			rp = &integerReduceIntegerPoint{
  4212  				Name:       curr.Name,
  4213  				Tags:       tags,
  4214  				Aggregator: aggregator,
  4215  				Emitter:    emitter,
  4216  			}
  4217  			itr.m[id] = rp
  4218  		}
  4219  		rp.Aggregator.AggregateInteger(curr)
  4220  
  4221  		// Attempt to emit points from the aggregator.
  4222  		points := rp.Emitter.Emit()
  4223  		if len(points) == 0 {
  4224  			continue
  4225  		}
  4226  
  4227  		for i := range points {
  4228  			points[i].Name = rp.Name
  4229  			points[i].Tags = rp.Tags
  4230  		}
  4231  		return points, nil
  4232  	}
  4233  }
  4234  
  4235  // integerReduceUnsignedIterator executes a reducer for every interval and buffers the result.
  4236  type integerReduceUnsignedIterator struct {
  4237  	input    *bufIntegerIterator
  4238  	create   func() (IntegerPointAggregator, UnsignedPointEmitter)
  4239  	dims     []string
  4240  	opt      IteratorOptions
  4241  	points   []UnsignedPoint
  4242  	keepTags bool
  4243  }
  4244  
  4245  func newIntegerReduceUnsignedIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, UnsignedPointEmitter)) *integerReduceUnsignedIterator {
  4246  	return &integerReduceUnsignedIterator{
  4247  		input:  newBufIntegerIterator(input),
  4248  		create: createFn,
  4249  		dims:   opt.GetDimensions(),
  4250  		opt:    opt,
  4251  	}
  4252  }
  4253  
  4254  // Stats returns stats from the input iterator.
  4255  func (itr *integerReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
  4256  
  4257  // Close closes the iterator and all child iterators.
  4258  func (itr *integerReduceUnsignedIterator) Close() error { return itr.input.Close() }
  4259  
  4260  // Next returns the minimum value for the next available interval.
  4261  func (itr *integerReduceUnsignedIterator) Next() (*UnsignedPoint, error) {
  4262  	// Calculate next window if we have no more points.
  4263  	if len(itr.points) == 0 {
  4264  		var err error
  4265  		itr.points, err = itr.reduce()
  4266  		if len(itr.points) == 0 {
  4267  			return nil, err
  4268  		}
  4269  	}
  4270  
  4271  	// Pop next point off the stack.
  4272  	p := &itr.points[len(itr.points)-1]
  4273  	itr.points = itr.points[:len(itr.points)-1]
  4274  	return p, nil
  4275  }
  4276  
  4277  // integerReduceUnsignedPoint stores the reduced data for a name/tag combination.
  4278  type integerReduceUnsignedPoint struct {
  4279  	Name       string
  4280  	Tags       Tags
  4281  	Aggregator IntegerPointAggregator
  4282  	Emitter    UnsignedPointEmitter
  4283  }
  4284  
  4285  // reduce executes fn once for every point in the next window.
  4286  // The previous value for the dimension is passed to fn.
  4287  func (itr *integerReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) {
  4288  	// Calculate next window.
  4289  	var (
  4290  		startTime, endTime int64
  4291  		window             struct {
  4292  			name string
  4293  			tags string
  4294  		}
  4295  	)
  4296  	for {
  4297  		p, err := itr.input.Next()
  4298  		if err != nil || p == nil {
  4299  			return nil, err
  4300  		} else if p.Nil {
  4301  			continue
  4302  		}
  4303  
  4304  		// Unread the point so it can be processed.
  4305  		itr.input.unread(p)
  4306  		startTime, endTime = itr.opt.Window(p.Time)
  4307  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  4308  		break
  4309  	}
  4310  
  4311  	// Create points by tags.
  4312  	m := make(map[string]*integerReduceUnsignedPoint)
  4313  	for {
  4314  		// Read next point.
  4315  		curr, err := itr.input.NextInWindow(startTime, endTime)
  4316  		if err != nil {
  4317  			return nil, err
  4318  		} else if curr == nil {
  4319  			break
  4320  		} else if curr.Nil {
  4321  			continue
  4322  		} else if curr.Name != window.name {
  4323  			itr.input.unread(curr)
  4324  			break
  4325  		}
  4326  
  4327  		// Ensure this point is within the same final window.
  4328  		if curr.Name != window.name {
  4329  			itr.input.unread(curr)
  4330  			break
  4331  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  4332  			itr.input.unread(curr)
  4333  			break
  4334  		}
  4335  
  4336  		// Retrieve the tags on this point for this level of the query.
  4337  		// This may be different than the bucket dimensions.
  4338  		tags := curr.Tags.Subset(itr.dims)
  4339  		id := tags.ID()
  4340  
  4341  		// Retrieve the aggregator for this name/tag combination or create one.
  4342  		rp := m[id]
  4343  		if rp == nil {
  4344  			aggregator, emitter := itr.create()
  4345  			rp = &integerReduceUnsignedPoint{
  4346  				Name:       curr.Name,
  4347  				Tags:       tags,
  4348  				Aggregator: aggregator,
  4349  				Emitter:    emitter,
  4350  			}
  4351  			m[id] = rp
  4352  		}
  4353  		rp.Aggregator.AggregateInteger(curr)
  4354  	}
  4355  
  4356  	keys := make([]string, 0, len(m))
  4357  	for k := range m {
  4358  		keys = append(keys, k)
  4359  	}
  4360  
  4361  	// Reverse sort points by name & tag.
  4362  	// This ensures a consistent order of output.
  4363  	if len(keys) > 0 {
  4364  		var sorted sort.Interface = sort.StringSlice(keys)
  4365  		if itr.opt.Ascending {
  4366  			sorted = sort.Reverse(sorted)
  4367  		}
  4368  		sort.Sort(sorted)
  4369  	}
  4370  
  4371  	// Assume the points are already sorted until proven otherwise.
  4372  	sortedByTime := true
  4373  	// Emit the points for each name & tag combination.
  4374  	a := make([]UnsignedPoint, 0, len(m))
  4375  	for _, k := range keys {
  4376  		rp := m[k]
  4377  		points := rp.Emitter.Emit()
  4378  		for i := len(points) - 1; i >= 0; i-- {
  4379  			points[i].Name = rp.Name
  4380  			if !itr.keepTags {
  4381  				points[i].Tags = rp.Tags
  4382  			}
  4383  			// Set the points time to the interval time if the reducer didn't provide one.
  4384  			if points[i].Time == ZeroTime {
  4385  				points[i].Time = startTime
  4386  			} else {
  4387  				sortedByTime = false
  4388  			}
  4389  			a = append(a, points[i])
  4390  		}
  4391  	}
  4392  	// Points may be out of order. Perform a stable sort by time if requested.
  4393  	if !sortedByTime && itr.opt.Ordered {
  4394  		var sorted sort.Interface = unsignedPointsByTime(a)
  4395  		if itr.opt.Ascending {
  4396  			sorted = sort.Reverse(sorted)
  4397  		}
  4398  		sort.Stable(sorted)
  4399  	}
  4400  	return a, nil
  4401  }
  4402  
  4403  // integerStreamUnsignedIterator streams inputs into the iterator and emits points gradually.
  4404  type integerStreamUnsignedIterator struct {
  4405  	input  *bufIntegerIterator
  4406  	create func() (IntegerPointAggregator, UnsignedPointEmitter)
  4407  	dims   []string
  4408  	opt    IteratorOptions
  4409  	m      map[string]*integerReduceUnsignedPoint
  4410  	points []UnsignedPoint
  4411  }
  4412  
  4413  // newIntegerStreamUnsignedIterator returns a new instance of integerStreamUnsignedIterator.
  4414  func newIntegerStreamUnsignedIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *integerStreamUnsignedIterator {
  4415  	return &integerStreamUnsignedIterator{
  4416  		input:  newBufIntegerIterator(input),
  4417  		create: createFn,
  4418  		dims:   opt.GetDimensions(),
  4419  		opt:    opt,
  4420  		m:      make(map[string]*integerReduceUnsignedPoint),
  4421  	}
  4422  }
  4423  
  4424  // Stats returns stats from the input iterator.
  4425  func (itr *integerStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
  4426  
  4427  // Close closes the iterator and all child iterators.
  4428  func (itr *integerStreamUnsignedIterator) Close() error { return itr.input.Close() }
  4429  
  4430  // Next returns the next value for the stream iterator.
  4431  func (itr *integerStreamUnsignedIterator) Next() (*UnsignedPoint, error) {
  4432  	// Calculate next window if we have no more points.
  4433  	if len(itr.points) == 0 {
  4434  		var err error
  4435  		itr.points, err = itr.reduce()
  4436  		if len(itr.points) == 0 {
  4437  			return nil, err
  4438  		}
  4439  	}
  4440  
  4441  	// Pop next point off the stack.
  4442  	p := &itr.points[len(itr.points)-1]
  4443  	itr.points = itr.points[:len(itr.points)-1]
  4444  	return p, nil
  4445  }
  4446  
  4447  // reduce creates and manages aggregators for every point from the input.
  4448  // After aggregating a point, it always tries to emit a value using the emitter.
  4449  func (itr *integerStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) {
  4450  	// We have already read all of the input points.
  4451  	if itr.m == nil {
  4452  		return nil, nil
  4453  	}
  4454  
  4455  	for {
  4456  		// Read next point.
  4457  		curr, err := itr.input.Next()
  4458  		if err != nil {
  4459  			return nil, err
  4460  		} else if curr == nil {
  4461  			// Close all of the aggregators to flush any remaining points to emit.
  4462  			var points []UnsignedPoint
  4463  			for _, rp := range itr.m {
  4464  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  4465  					if err := aggregator.Close(); err != nil {
  4466  						return nil, err
  4467  					}
  4468  
  4469  					pts := rp.Emitter.Emit()
  4470  					if len(pts) == 0 {
  4471  						continue
  4472  					}
  4473  
  4474  					for i := range pts {
  4475  						pts[i].Name = rp.Name
  4476  						pts[i].Tags = rp.Tags
  4477  					}
  4478  					points = append(points, pts...)
  4479  				}
  4480  			}
  4481  
  4482  			// Eliminate the aggregators and emitters.
  4483  			itr.m = nil
  4484  			return points, nil
  4485  		} else if curr.Nil {
  4486  			continue
  4487  		}
  4488  		tags := curr.Tags.Subset(itr.dims)
  4489  
  4490  		id := curr.Name
  4491  		if len(tags.m) > 0 {
  4492  			id += "\x00" + tags.ID()
  4493  		}
  4494  
  4495  		// Retrieve the aggregator for this name/tag combination or create one.
  4496  		rp := itr.m[id]
  4497  		if rp == nil {
  4498  			aggregator, emitter := itr.create()
  4499  			rp = &integerReduceUnsignedPoint{
  4500  				Name:       curr.Name,
  4501  				Tags:       tags,
  4502  				Aggregator: aggregator,
  4503  				Emitter:    emitter,
  4504  			}
  4505  			itr.m[id] = rp
  4506  		}
  4507  		rp.Aggregator.AggregateInteger(curr)
  4508  
  4509  		// Attempt to emit points from the aggregator.
  4510  		points := rp.Emitter.Emit()
  4511  		if len(points) == 0 {
  4512  			continue
  4513  		}
  4514  
  4515  		for i := range points {
  4516  			points[i].Name = rp.Name
  4517  			points[i].Tags = rp.Tags
  4518  		}
  4519  		return points, nil
  4520  	}
  4521  }
  4522  
  4523  // integerReduceStringIterator executes a reducer for every interval and buffers the result.
  4524  type integerReduceStringIterator struct {
  4525  	input    *bufIntegerIterator
  4526  	create   func() (IntegerPointAggregator, StringPointEmitter)
  4527  	dims     []string
  4528  	opt      IteratorOptions
  4529  	points   []StringPoint
  4530  	keepTags bool
  4531  }
  4532  
  4533  func newIntegerReduceStringIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, StringPointEmitter)) *integerReduceStringIterator {
  4534  	return &integerReduceStringIterator{
  4535  		input:  newBufIntegerIterator(input),
  4536  		create: createFn,
  4537  		dims:   opt.GetDimensions(),
  4538  		opt:    opt,
  4539  	}
  4540  }
  4541  
  4542  // Stats returns stats from the input iterator.
  4543  func (itr *integerReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() }
  4544  
  4545  // Close closes the iterator and all child iterators.
  4546  func (itr *integerReduceStringIterator) Close() error { return itr.input.Close() }
  4547  
  4548  // Next returns the minimum value for the next available interval.
  4549  func (itr *integerReduceStringIterator) Next() (*StringPoint, error) {
  4550  	// Calculate next window if we have no more points.
  4551  	if len(itr.points) == 0 {
  4552  		var err error
  4553  		itr.points, err = itr.reduce()
  4554  		if len(itr.points) == 0 {
  4555  			return nil, err
  4556  		}
  4557  	}
  4558  
  4559  	// Pop next point off the stack.
  4560  	p := &itr.points[len(itr.points)-1]
  4561  	itr.points = itr.points[:len(itr.points)-1]
  4562  	return p, nil
  4563  }
  4564  
  4565  // integerReduceStringPoint stores the reduced data for a name/tag combination.
  4566  type integerReduceStringPoint struct {
  4567  	Name       string
  4568  	Tags       Tags
  4569  	Aggregator IntegerPointAggregator
  4570  	Emitter    StringPointEmitter
  4571  }
  4572  
  4573  // reduce executes fn once for every point in the next window.
  4574  // The previous value for the dimension is passed to fn.
  4575  func (itr *integerReduceStringIterator) reduce() ([]StringPoint, error) {
  4576  	// Calculate next window.
  4577  	var (
  4578  		startTime, endTime int64
  4579  		window             struct {
  4580  			name string
  4581  			tags string
  4582  		}
  4583  	)
  4584  	for {
  4585  		p, err := itr.input.Next()
  4586  		if err != nil || p == nil {
  4587  			return nil, err
  4588  		} else if p.Nil {
  4589  			continue
  4590  		}
  4591  
  4592  		// Unread the point so it can be processed.
  4593  		itr.input.unread(p)
  4594  		startTime, endTime = itr.opt.Window(p.Time)
  4595  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  4596  		break
  4597  	}
  4598  
  4599  	// Create points by tags.
  4600  	m := make(map[string]*integerReduceStringPoint)
  4601  	for {
  4602  		// Read next point.
  4603  		curr, err := itr.input.NextInWindow(startTime, endTime)
  4604  		if err != nil {
  4605  			return nil, err
  4606  		} else if curr == nil {
  4607  			break
  4608  		} else if curr.Nil {
  4609  			continue
  4610  		} else if curr.Name != window.name {
  4611  			itr.input.unread(curr)
  4612  			break
  4613  		}
  4614  
  4615  		// Ensure this point is within the same final window.
  4616  		if curr.Name != window.name {
  4617  			itr.input.unread(curr)
  4618  			break
  4619  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  4620  			itr.input.unread(curr)
  4621  			break
  4622  		}
  4623  
  4624  		// Retrieve the tags on this point for this level of the query.
  4625  		// This may be different than the bucket dimensions.
  4626  		tags := curr.Tags.Subset(itr.dims)
  4627  		id := tags.ID()
  4628  
  4629  		// Retrieve the aggregator for this name/tag combination or create one.
  4630  		rp := m[id]
  4631  		if rp == nil {
  4632  			aggregator, emitter := itr.create()
  4633  			rp = &integerReduceStringPoint{
  4634  				Name:       curr.Name,
  4635  				Tags:       tags,
  4636  				Aggregator: aggregator,
  4637  				Emitter:    emitter,
  4638  			}
  4639  			m[id] = rp
  4640  		}
  4641  		rp.Aggregator.AggregateInteger(curr)
  4642  	}
  4643  
  4644  	keys := make([]string, 0, len(m))
  4645  	for k := range m {
  4646  		keys = append(keys, k)
  4647  	}
  4648  
  4649  	// Reverse sort points by name & tag.
  4650  	// This ensures a consistent order of output.
  4651  	if len(keys) > 0 {
  4652  		var sorted sort.Interface = sort.StringSlice(keys)
  4653  		if itr.opt.Ascending {
  4654  			sorted = sort.Reverse(sorted)
  4655  		}
  4656  		sort.Sort(sorted)
  4657  	}
  4658  
  4659  	// Assume the points are already sorted until proven otherwise.
  4660  	sortedByTime := true
  4661  	// Emit the points for each name & tag combination.
  4662  	a := make([]StringPoint, 0, len(m))
  4663  	for _, k := range keys {
  4664  		rp := m[k]
  4665  		points := rp.Emitter.Emit()
  4666  		for i := len(points) - 1; i >= 0; i-- {
  4667  			points[i].Name = rp.Name
  4668  			if !itr.keepTags {
  4669  				points[i].Tags = rp.Tags
  4670  			}
  4671  			// Set the points time to the interval time if the reducer didn't provide one.
  4672  			if points[i].Time == ZeroTime {
  4673  				points[i].Time = startTime
  4674  			} else {
  4675  				sortedByTime = false
  4676  			}
  4677  			a = append(a, points[i])
  4678  		}
  4679  	}
  4680  	// Points may be out of order. Perform a stable sort by time if requested.
  4681  	if !sortedByTime && itr.opt.Ordered {
  4682  		var sorted sort.Interface = stringPointsByTime(a)
  4683  		if itr.opt.Ascending {
  4684  			sorted = sort.Reverse(sorted)
  4685  		}
  4686  		sort.Stable(sorted)
  4687  	}
  4688  	return a, nil
  4689  }
  4690  
  4691  // integerStreamStringIterator streams inputs into the iterator and emits points gradually.
  4692  type integerStreamStringIterator struct {
  4693  	input  *bufIntegerIterator
  4694  	create func() (IntegerPointAggregator, StringPointEmitter)
  4695  	dims   []string
  4696  	opt    IteratorOptions
  4697  	m      map[string]*integerReduceStringPoint
  4698  	points []StringPoint
  4699  }
  4700  
  4701  // newIntegerStreamStringIterator returns a new instance of integerStreamStringIterator.
  4702  func newIntegerStreamStringIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, StringPointEmitter), opt IteratorOptions) *integerStreamStringIterator {
  4703  	return &integerStreamStringIterator{
  4704  		input:  newBufIntegerIterator(input),
  4705  		create: createFn,
  4706  		dims:   opt.GetDimensions(),
  4707  		opt:    opt,
  4708  		m:      make(map[string]*integerReduceStringPoint),
  4709  	}
  4710  }
  4711  
  4712  // Stats returns stats from the input iterator.
  4713  func (itr *integerStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() }
  4714  
  4715  // Close closes the iterator and all child iterators.
  4716  func (itr *integerStreamStringIterator) Close() error { return itr.input.Close() }
  4717  
  4718  // Next returns the next value for the stream iterator.
  4719  func (itr *integerStreamStringIterator) Next() (*StringPoint, error) {
  4720  	// Calculate next window if we have no more points.
  4721  	if len(itr.points) == 0 {
  4722  		var err error
  4723  		itr.points, err = itr.reduce()
  4724  		if len(itr.points) == 0 {
  4725  			return nil, err
  4726  		}
  4727  	}
  4728  
  4729  	// Pop next point off the stack.
  4730  	p := &itr.points[len(itr.points)-1]
  4731  	itr.points = itr.points[:len(itr.points)-1]
  4732  	return p, nil
  4733  }
  4734  
  4735  // reduce creates and manages aggregators for every point from the input.
  4736  // After aggregating a point, it always tries to emit a value using the emitter.
  4737  func (itr *integerStreamStringIterator) reduce() ([]StringPoint, error) {
  4738  	// We have already read all of the input points.
  4739  	if itr.m == nil {
  4740  		return nil, nil
  4741  	}
  4742  
  4743  	for {
  4744  		// Read next point.
  4745  		curr, err := itr.input.Next()
  4746  		if err != nil {
  4747  			return nil, err
  4748  		} else if curr == nil {
  4749  			// Close all of the aggregators to flush any remaining points to emit.
  4750  			var points []StringPoint
  4751  			for _, rp := range itr.m {
  4752  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  4753  					if err := aggregator.Close(); err != nil {
  4754  						return nil, err
  4755  					}
  4756  
  4757  					pts := rp.Emitter.Emit()
  4758  					if len(pts) == 0 {
  4759  						continue
  4760  					}
  4761  
  4762  					for i := range pts {
  4763  						pts[i].Name = rp.Name
  4764  						pts[i].Tags = rp.Tags
  4765  					}
  4766  					points = append(points, pts...)
  4767  				}
  4768  			}
  4769  
  4770  			// Eliminate the aggregators and emitters.
  4771  			itr.m = nil
  4772  			return points, nil
  4773  		} else if curr.Nil {
  4774  			continue
  4775  		}
  4776  		tags := curr.Tags.Subset(itr.dims)
  4777  
  4778  		id := curr.Name
  4779  		if len(tags.m) > 0 {
  4780  			id += "\x00" + tags.ID()
  4781  		}
  4782  
  4783  		// Retrieve the aggregator for this name/tag combination or create one.
  4784  		rp := itr.m[id]
  4785  		if rp == nil {
  4786  			aggregator, emitter := itr.create()
  4787  			rp = &integerReduceStringPoint{
  4788  				Name:       curr.Name,
  4789  				Tags:       tags,
  4790  				Aggregator: aggregator,
  4791  				Emitter:    emitter,
  4792  			}
  4793  			itr.m[id] = rp
  4794  		}
  4795  		rp.Aggregator.AggregateInteger(curr)
  4796  
  4797  		// Attempt to emit points from the aggregator.
  4798  		points := rp.Emitter.Emit()
  4799  		if len(points) == 0 {
  4800  			continue
  4801  		}
  4802  
  4803  		for i := range points {
  4804  			points[i].Name = rp.Name
  4805  			points[i].Tags = rp.Tags
  4806  		}
  4807  		return points, nil
  4808  	}
  4809  }
  4810  
  4811  // integerReduceBooleanIterator executes a reducer for every interval and buffers the result.
  4812  type integerReduceBooleanIterator struct {
  4813  	input    *bufIntegerIterator
  4814  	create   func() (IntegerPointAggregator, BooleanPointEmitter)
  4815  	dims     []string
  4816  	opt      IteratorOptions
  4817  	points   []BooleanPoint
  4818  	keepTags bool
  4819  }
  4820  
  4821  func newIntegerReduceBooleanIterator(input IntegerIterator, opt IteratorOptions, createFn func() (IntegerPointAggregator, BooleanPointEmitter)) *integerReduceBooleanIterator {
  4822  	return &integerReduceBooleanIterator{
  4823  		input:  newBufIntegerIterator(input),
  4824  		create: createFn,
  4825  		dims:   opt.GetDimensions(),
  4826  		opt:    opt,
  4827  	}
  4828  }
  4829  
  4830  // Stats returns stats from the input iterator.
  4831  func (itr *integerReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
  4832  
  4833  // Close closes the iterator and all child iterators.
  4834  func (itr *integerReduceBooleanIterator) Close() error { return itr.input.Close() }
  4835  
  4836  // Next returns the minimum value for the next available interval.
  4837  func (itr *integerReduceBooleanIterator) Next() (*BooleanPoint, error) {
  4838  	// Calculate next window if we have no more points.
  4839  	if len(itr.points) == 0 {
  4840  		var err error
  4841  		itr.points, err = itr.reduce()
  4842  		if len(itr.points) == 0 {
  4843  			return nil, err
  4844  		}
  4845  	}
  4846  
  4847  	// Pop next point off the stack.
  4848  	p := &itr.points[len(itr.points)-1]
  4849  	itr.points = itr.points[:len(itr.points)-1]
  4850  	return p, nil
  4851  }
  4852  
  4853  // integerReduceBooleanPoint stores the reduced data for a name/tag combination.
  4854  type integerReduceBooleanPoint struct {
  4855  	Name       string
  4856  	Tags       Tags
  4857  	Aggregator IntegerPointAggregator
  4858  	Emitter    BooleanPointEmitter
  4859  }
  4860  
  4861  // reduce executes fn once for every point in the next window.
  4862  // The previous value for the dimension is passed to fn.
  4863  func (itr *integerReduceBooleanIterator) reduce() ([]BooleanPoint, error) {
  4864  	// Calculate next window.
  4865  	var (
  4866  		startTime, endTime int64
  4867  		window             struct {
  4868  			name string
  4869  			tags string
  4870  		}
  4871  	)
  4872  	for {
  4873  		p, err := itr.input.Next()
  4874  		if err != nil || p == nil {
  4875  			return nil, err
  4876  		} else if p.Nil {
  4877  			continue
  4878  		}
  4879  
  4880  		// Unread the point so it can be processed.
  4881  		itr.input.unread(p)
  4882  		startTime, endTime = itr.opt.Window(p.Time)
  4883  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  4884  		break
  4885  	}
  4886  
  4887  	// Create points by tags.
  4888  	m := make(map[string]*integerReduceBooleanPoint)
  4889  	for {
  4890  		// Read next point.
  4891  		curr, err := itr.input.NextInWindow(startTime, endTime)
  4892  		if err != nil {
  4893  			return nil, err
  4894  		} else if curr == nil {
  4895  			break
  4896  		} else if curr.Nil {
  4897  			continue
  4898  		} else if curr.Name != window.name {
  4899  			itr.input.unread(curr)
  4900  			break
  4901  		}
  4902  
  4903  		// Ensure this point is within the same final window.
  4904  		if curr.Name != window.name {
  4905  			itr.input.unread(curr)
  4906  			break
  4907  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  4908  			itr.input.unread(curr)
  4909  			break
  4910  		}
  4911  
  4912  		// Retrieve the tags on this point for this level of the query.
  4913  		// This may be different than the bucket dimensions.
  4914  		tags := curr.Tags.Subset(itr.dims)
  4915  		id := tags.ID()
  4916  
  4917  		// Retrieve the aggregator for this name/tag combination or create one.
  4918  		rp := m[id]
  4919  		if rp == nil {
  4920  			aggregator, emitter := itr.create()
  4921  			rp = &integerReduceBooleanPoint{
  4922  				Name:       curr.Name,
  4923  				Tags:       tags,
  4924  				Aggregator: aggregator,
  4925  				Emitter:    emitter,
  4926  			}
  4927  			m[id] = rp
  4928  		}
  4929  		rp.Aggregator.AggregateInteger(curr)
  4930  	}
  4931  
  4932  	keys := make([]string, 0, len(m))
  4933  	for k := range m {
  4934  		keys = append(keys, k)
  4935  	}
  4936  
  4937  	// Reverse sort points by name & tag.
  4938  	// This ensures a consistent order of output.
  4939  	if len(keys) > 0 {
  4940  		var sorted sort.Interface = sort.StringSlice(keys)
  4941  		if itr.opt.Ascending {
  4942  			sorted = sort.Reverse(sorted)
  4943  		}
  4944  		sort.Sort(sorted)
  4945  	}
  4946  
  4947  	// Assume the points are already sorted until proven otherwise.
  4948  	sortedByTime := true
  4949  	// Emit the points for each name & tag combination.
  4950  	a := make([]BooleanPoint, 0, len(m))
  4951  	for _, k := range keys {
  4952  		rp := m[k]
  4953  		points := rp.Emitter.Emit()
  4954  		for i := len(points) - 1; i >= 0; i-- {
  4955  			points[i].Name = rp.Name
  4956  			if !itr.keepTags {
  4957  				points[i].Tags = rp.Tags
  4958  			}
  4959  			// Set the points time to the interval time if the reducer didn't provide one.
  4960  			if points[i].Time == ZeroTime {
  4961  				points[i].Time = startTime
  4962  			} else {
  4963  				sortedByTime = false
  4964  			}
  4965  			a = append(a, points[i])
  4966  		}
  4967  	}
  4968  	// Points may be out of order. Perform a stable sort by time if requested.
  4969  	if !sortedByTime && itr.opt.Ordered {
  4970  		var sorted sort.Interface = booleanPointsByTime(a)
  4971  		if itr.opt.Ascending {
  4972  			sorted = sort.Reverse(sorted)
  4973  		}
  4974  		sort.Stable(sorted)
  4975  	}
  4976  	return a, nil
  4977  }
  4978  
  4979  // integerStreamBooleanIterator streams inputs into the iterator and emits points gradually.
  4980  type integerStreamBooleanIterator struct {
  4981  	input  *bufIntegerIterator
  4982  	create func() (IntegerPointAggregator, BooleanPointEmitter)
  4983  	dims   []string
  4984  	opt    IteratorOptions
  4985  	m      map[string]*integerReduceBooleanPoint
  4986  	points []BooleanPoint
  4987  }
  4988  
  4989  // newIntegerStreamBooleanIterator returns a new instance of integerStreamBooleanIterator.
  4990  func newIntegerStreamBooleanIterator(input IntegerIterator, createFn func() (IntegerPointAggregator, BooleanPointEmitter), opt IteratorOptions) *integerStreamBooleanIterator {
  4991  	return &integerStreamBooleanIterator{
  4992  		input:  newBufIntegerIterator(input),
  4993  		create: createFn,
  4994  		dims:   opt.GetDimensions(),
  4995  		opt:    opt,
  4996  		m:      make(map[string]*integerReduceBooleanPoint),
  4997  	}
  4998  }
  4999  
  5000  // Stats returns stats from the input iterator.
  5001  func (itr *integerStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
  5002  
  5003  // Close closes the iterator and all child iterators.
  5004  func (itr *integerStreamBooleanIterator) Close() error { return itr.input.Close() }
  5005  
  5006  // Next returns the next value for the stream iterator.
  5007  func (itr *integerStreamBooleanIterator) Next() (*BooleanPoint, error) {
  5008  	// Calculate next window if we have no more points.
  5009  	if len(itr.points) == 0 {
  5010  		var err error
  5011  		itr.points, err = itr.reduce()
  5012  		if len(itr.points) == 0 {
  5013  			return nil, err
  5014  		}
  5015  	}
  5016  
  5017  	// Pop next point off the stack.
  5018  	p := &itr.points[len(itr.points)-1]
  5019  	itr.points = itr.points[:len(itr.points)-1]
  5020  	return p, nil
  5021  }
  5022  
  5023  // reduce creates and manages aggregators for every point from the input.
  5024  // After aggregating a point, it always tries to emit a value using the emitter.
  5025  func (itr *integerStreamBooleanIterator) reduce() ([]BooleanPoint, error) {
  5026  	// We have already read all of the input points.
  5027  	if itr.m == nil {
  5028  		return nil, nil
  5029  	}
  5030  
  5031  	for {
  5032  		// Read next point.
  5033  		curr, err := itr.input.Next()
  5034  		if err != nil {
  5035  			return nil, err
  5036  		} else if curr == nil {
  5037  			// Close all of the aggregators to flush any remaining points to emit.
  5038  			var points []BooleanPoint
  5039  			for _, rp := range itr.m {
  5040  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  5041  					if err := aggregator.Close(); err != nil {
  5042  						return nil, err
  5043  					}
  5044  
  5045  					pts := rp.Emitter.Emit()
  5046  					if len(pts) == 0 {
  5047  						continue
  5048  					}
  5049  
  5050  					for i := range pts {
  5051  						pts[i].Name = rp.Name
  5052  						pts[i].Tags = rp.Tags
  5053  					}
  5054  					points = append(points, pts...)
  5055  				}
  5056  			}
  5057  
  5058  			// Eliminate the aggregators and emitters.
  5059  			itr.m = nil
  5060  			return points, nil
  5061  		} else if curr.Nil {
  5062  			continue
  5063  		}
  5064  		tags := curr.Tags.Subset(itr.dims)
  5065  
  5066  		id := curr.Name
  5067  		if len(tags.m) > 0 {
  5068  			id += "\x00" + tags.ID()
  5069  		}
  5070  
  5071  		// Retrieve the aggregator for this name/tag combination or create one.
  5072  		rp := itr.m[id]
  5073  		if rp == nil {
  5074  			aggregator, emitter := itr.create()
  5075  			rp = &integerReduceBooleanPoint{
  5076  				Name:       curr.Name,
  5077  				Tags:       tags,
  5078  				Aggregator: aggregator,
  5079  				Emitter:    emitter,
  5080  			}
  5081  			itr.m[id] = rp
  5082  		}
  5083  		rp.Aggregator.AggregateInteger(curr)
  5084  
  5085  		// Attempt to emit points from the aggregator.
  5086  		points := rp.Emitter.Emit()
  5087  		if len(points) == 0 {
  5088  			continue
  5089  		}
  5090  
  5091  		for i := range points {
  5092  			points[i].Name = rp.Name
  5093  			points[i].Tags = rp.Tags
  5094  		}
  5095  		return points, nil
  5096  	}
  5097  }
  5098  
  5099  // integerDedupeIterator only outputs unique points.
  5100  // This differs from the DistinctIterator in that it compares all aux fields too.
  5101  // This iterator is relatively inefficient and should only be used on small
  5102  // datasets such as meta query results.
  5103  type integerDedupeIterator struct {
  5104  	input IntegerIterator
  5105  	m     map[string]struct{} // lookup of points already sent
  5106  }
  5107  
  5108  type integerIteratorMapper struct {
  5109  	cur    Cursor
  5110  	row    Row
  5111  	driver IteratorMap   // which iterator to use for the primary value, can be nil
  5112  	fields []IteratorMap // which iterator to use for an aux field
  5113  	point  IntegerPoint
  5114  }
  5115  
  5116  func newIntegerIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *integerIteratorMapper {
  5117  	return &integerIteratorMapper{
  5118  		cur:    cur,
  5119  		driver: driver,
  5120  		fields: fields,
  5121  		point: IntegerPoint{
  5122  			Aux: make([]interface{}, len(fields)),
  5123  		},
  5124  	}
  5125  }
  5126  
  5127  func (itr *integerIteratorMapper) Next() (*IntegerPoint, error) {
  5128  	if !itr.cur.Scan(&itr.row) {
  5129  		if err := itr.cur.Err(); err != nil {
  5130  			return nil, err
  5131  		}
  5132  		return nil, nil
  5133  	}
  5134  
  5135  	itr.point.Time = itr.row.Time
  5136  	itr.point.Name = itr.row.Series.Name
  5137  	itr.point.Tags = itr.row.Series.Tags
  5138  
  5139  	if itr.driver != nil {
  5140  		if v := itr.driver.Value(&itr.row); v != nil {
  5141  			if v, ok := castToInteger(v); ok {
  5142  				itr.point.Value = v
  5143  				itr.point.Nil = false
  5144  			} else {
  5145  				itr.point.Value = 0
  5146  				itr.point.Nil = true
  5147  			}
  5148  		} else {
  5149  			itr.point.Value = 0
  5150  			itr.point.Nil = true
  5151  		}
  5152  	}
  5153  	for i, f := range itr.fields {
  5154  		itr.point.Aux[i] = f.Value(&itr.row)
  5155  	}
  5156  	return &itr.point, nil
  5157  }
  5158  
  5159  func (itr *integerIteratorMapper) Stats() IteratorStats {
  5160  	return itr.cur.Stats()
  5161  }
  5162  
  5163  func (itr *integerIteratorMapper) Close() error {
  5164  	return itr.cur.Close()
  5165  }
  5166  
  5167  type integerFilterIterator struct {
  5168  	input IntegerIterator
  5169  	cond  influxql.Expr
  5170  	opt   IteratorOptions
  5171  	m     map[string]interface{}
  5172  }
  5173  
  5174  func newIntegerFilterIterator(input IntegerIterator, cond influxql.Expr, opt IteratorOptions) IntegerIterator {
  5175  	// Strip out time conditions from the WHERE clause.
  5176  	// TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct.
  5177  	n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node {
  5178  		switch n := n.(type) {
  5179  		case *influxql.BinaryExpr:
  5180  			if n.LHS.String() == "time" {
  5181  				return &influxql.BooleanLiteral{Val: true}
  5182  			}
  5183  		}
  5184  		return n
  5185  	})
  5186  
  5187  	cond, _ = n.(influxql.Expr)
  5188  	if cond == nil {
  5189  		return input
  5190  	} else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val {
  5191  		return input
  5192  	}
  5193  
  5194  	return &integerFilterIterator{
  5195  		input: input,
  5196  		cond:  cond,
  5197  		opt:   opt,
  5198  		m:     make(map[string]interface{}),
  5199  	}
  5200  }
  5201  
  5202  func (itr *integerFilterIterator) Stats() IteratorStats { return itr.input.Stats() }
  5203  func (itr *integerFilterIterator) Close() error         { return itr.input.Close() }
  5204  
  5205  func (itr *integerFilterIterator) Next() (*IntegerPoint, error) {
  5206  	for {
  5207  		p, err := itr.input.Next()
  5208  		if err != nil || p == nil {
  5209  			return nil, err
  5210  		}
  5211  
  5212  		for i, ref := range itr.opt.Aux {
  5213  			itr.m[ref.Val] = p.Aux[i]
  5214  		}
  5215  		for k, v := range p.Tags.KeyValues() {
  5216  			itr.m[k] = v
  5217  		}
  5218  
  5219  		if !influxql.EvalBool(itr.cond, itr.m) {
  5220  			continue
  5221  		}
  5222  		return p, nil
  5223  	}
  5224  }
  5225  
  5226  type integerTagSubsetIterator struct {
  5227  	input      IntegerIterator
  5228  	point      IntegerPoint
  5229  	lastTags   Tags
  5230  	dimensions []string
  5231  }
  5232  
  5233  func newIntegerTagSubsetIterator(input IntegerIterator, opt IteratorOptions) *integerTagSubsetIterator {
  5234  	return &integerTagSubsetIterator{
  5235  		input:      input,
  5236  		dimensions: opt.GetDimensions(),
  5237  	}
  5238  }
  5239  
  5240  func (itr *integerTagSubsetIterator) Next() (*IntegerPoint, error) {
  5241  	p, err := itr.input.Next()
  5242  	if err != nil {
  5243  		return nil, err
  5244  	} else if p == nil {
  5245  		return nil, nil
  5246  	}
  5247  
  5248  	itr.point.Name = p.Name
  5249  	if !p.Tags.Equal(itr.lastTags) {
  5250  		itr.point.Tags = p.Tags.Subset(itr.dimensions)
  5251  		itr.lastTags = p.Tags
  5252  	}
  5253  	itr.point.Time = p.Time
  5254  	itr.point.Value = p.Value
  5255  	itr.point.Aux = p.Aux
  5256  	itr.point.Aggregated = p.Aggregated
  5257  	itr.point.Nil = p.Nil
  5258  	return &itr.point, nil
  5259  }
  5260  
  5261  func (itr *integerTagSubsetIterator) Stats() IteratorStats {
  5262  	return itr.input.Stats()
  5263  }
  5264  
  5265  func (itr *integerTagSubsetIterator) Close() error {
  5266  	return itr.input.Close()
  5267  }
  5268  
  5269  // newIntegerDedupeIterator returns a new instance of integerDedupeIterator.
  5270  func newIntegerDedupeIterator(input IntegerIterator) *integerDedupeIterator {
  5271  	return &integerDedupeIterator{
  5272  		input: input,
  5273  		m:     make(map[string]struct{}),
  5274  	}
  5275  }
  5276  
  5277  // Stats returns stats from the input iterator.
  5278  func (itr *integerDedupeIterator) Stats() IteratorStats { return itr.input.Stats() }
  5279  
  5280  // Close closes the iterator and all child iterators.
  5281  func (itr *integerDedupeIterator) Close() error { return itr.input.Close() }
  5282  
  5283  // Next returns the next unique point from the input iterator.
  5284  func (itr *integerDedupeIterator) Next() (*IntegerPoint, error) {
  5285  	for {
  5286  		// Read next point.
  5287  		p, err := itr.input.Next()
  5288  		if p == nil || err != nil {
  5289  			return nil, err
  5290  		}
  5291  
  5292  		// Serialize to bytes to store in lookup.
  5293  		buf, err := proto.Marshal(encodeIntegerPoint(p))
  5294  		if err != nil {
  5295  			return nil, err
  5296  		}
  5297  
  5298  		// If the point has already been output then move to the next point.
  5299  		if _, ok := itr.m[string(buf)]; ok {
  5300  			continue
  5301  		}
  5302  
  5303  		// Otherwise mark it as emitted and return point.
  5304  		itr.m[string(buf)] = struct{}{}
  5305  		return p, nil
  5306  	}
  5307  }
  5308  
  5309  // integerReaderIterator represents an iterator that streams from a reader.
  5310  type integerReaderIterator struct {
  5311  	r   io.Reader
  5312  	dec *IntegerPointDecoder
  5313  }
  5314  
  5315  // newIntegerReaderIterator returns a new instance of integerReaderIterator.
  5316  func newIntegerReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *integerReaderIterator {
  5317  	dec := NewIntegerPointDecoder(ctx, r)
  5318  	dec.stats = stats
  5319  
  5320  	return &integerReaderIterator{
  5321  		r:   r,
  5322  		dec: dec,
  5323  	}
  5324  }
  5325  
  5326  // Stats returns stats about points processed.
  5327  func (itr *integerReaderIterator) Stats() IteratorStats { return itr.dec.stats }
  5328  
  5329  // Close closes the underlying reader, if applicable.
  5330  func (itr *integerReaderIterator) Close() error {
  5331  	if r, ok := itr.r.(io.ReadCloser); ok {
  5332  		return r.Close()
  5333  	}
  5334  	return nil
  5335  }
  5336  
  5337  // Next returns the next point from the iterator.
  5338  func (itr *integerReaderIterator) Next() (*IntegerPoint, error) {
  5339  	// OPTIMIZE(benbjohnson): Reuse point on iterator.
  5340  
  5341  	// Unmarshal next point.
  5342  	p := &IntegerPoint{}
  5343  	if err := itr.dec.DecodeIntegerPoint(p); err == io.EOF {
  5344  		return nil, nil
  5345  	} else if err != nil {
  5346  		return nil, err
  5347  	}
  5348  	return p, nil
  5349  }
  5350  
  5351  // UnsignedIterator represents a stream of unsigned points.
  5352  type UnsignedIterator interface {
  5353  	Iterator
  5354  	Next() (*UnsignedPoint, error)
  5355  }
  5356  
  5357  // newUnsignedIterators converts a slice of Iterator to a slice of UnsignedIterator.
  5358  // Drop and closes any iterator in itrs that is not a UnsignedIterator and cannot
  5359  // be cast to a UnsignedIterator.
  5360  func newUnsignedIterators(itrs []Iterator) []UnsignedIterator {
  5361  	a := make([]UnsignedIterator, 0, len(itrs))
  5362  	for _, itr := range itrs {
  5363  		switch itr := itr.(type) {
  5364  		case UnsignedIterator:
  5365  			a = append(a, itr)
  5366  		default:
  5367  			itr.Close()
  5368  		}
  5369  	}
  5370  	return a
  5371  }
  5372  
  5373  // bufUnsignedIterator represents a buffered UnsignedIterator.
  5374  type bufUnsignedIterator struct {
  5375  	itr UnsignedIterator
  5376  	buf *UnsignedPoint
  5377  }
  5378  
  5379  // newBufUnsignedIterator returns a buffered UnsignedIterator.
  5380  func newBufUnsignedIterator(itr UnsignedIterator) *bufUnsignedIterator {
  5381  	return &bufUnsignedIterator{itr: itr}
  5382  }
  5383  
  5384  // Stats returns statistics from the input iterator.
  5385  func (itr *bufUnsignedIterator) Stats() IteratorStats { return itr.itr.Stats() }
  5386  
  5387  // Close closes the underlying iterator.
  5388  func (itr *bufUnsignedIterator) Close() error { return itr.itr.Close() }
  5389  
  5390  // peek returns the next point without removing it from the iterator.
  5391  func (itr *bufUnsignedIterator) peek() (*UnsignedPoint, error) {
  5392  	p, err := itr.Next()
  5393  	if err != nil {
  5394  		return nil, err
  5395  	}
  5396  	itr.unread(p)
  5397  	return p, nil
  5398  }
  5399  
  5400  // peekTime returns the time of the next point.
  5401  // Returns zero time if no more points available.
  5402  func (itr *bufUnsignedIterator) peekTime() (int64, error) {
  5403  	p, err := itr.peek()
  5404  	if p == nil || err != nil {
  5405  		return ZeroTime, err
  5406  	}
  5407  	return p.Time, nil
  5408  }
  5409  
  5410  // Next returns the current buffer, if exists, or calls the underlying iterator.
  5411  func (itr *bufUnsignedIterator) Next() (*UnsignedPoint, error) {
  5412  	buf := itr.buf
  5413  	if buf != nil {
  5414  		itr.buf = nil
  5415  		return buf, nil
  5416  	}
  5417  	return itr.itr.Next()
  5418  }
  5419  
  5420  // NextInWindow returns the next value if it is between [startTime, endTime).
  5421  // If the next value is outside the range then it is moved to the buffer.
  5422  func (itr *bufUnsignedIterator) NextInWindow(startTime, endTime int64) (*UnsignedPoint, error) {
  5423  	v, err := itr.Next()
  5424  	if v == nil || err != nil {
  5425  		return nil, err
  5426  	} else if t := v.Time; t >= endTime || t < startTime {
  5427  		itr.unread(v)
  5428  		return nil, nil
  5429  	}
  5430  	return v, nil
  5431  }
  5432  
  5433  // unread sets v to the buffer. It is read on the next call to Next().
  5434  func (itr *bufUnsignedIterator) unread(v *UnsignedPoint) { itr.buf = v }
  5435  
  5436  // unsignedMergeIterator represents an iterator that combines multiple unsigned iterators.
  5437  type unsignedMergeIterator struct {
  5438  	inputs []UnsignedIterator
  5439  	heap   *unsignedMergeHeap
  5440  	init   bool
  5441  
  5442  	closed bool
  5443  	mu     sync.RWMutex
  5444  
  5445  	// Current iterator and window.
  5446  	curr   *unsignedMergeHeapItem
  5447  	window struct {
  5448  		name      string
  5449  		tags      string
  5450  		startTime int64
  5451  		endTime   int64
  5452  	}
  5453  }
  5454  
  5455  // newUnsignedMergeIterator returns a new instance of unsignedMergeIterator.
  5456  func newUnsignedMergeIterator(inputs []UnsignedIterator, opt IteratorOptions) *unsignedMergeIterator {
  5457  	itr := &unsignedMergeIterator{
  5458  		inputs: inputs,
  5459  		heap: &unsignedMergeHeap{
  5460  			items: make([]*unsignedMergeHeapItem, 0, len(inputs)),
  5461  			opt:   opt,
  5462  		},
  5463  	}
  5464  
  5465  	// Initialize heap items.
  5466  	for _, input := range inputs {
  5467  		// Wrap in buffer, ignore any inputs without anymore points.
  5468  		bufInput := newBufUnsignedIterator(input)
  5469  
  5470  		// Append to the heap.
  5471  		itr.heap.items = append(itr.heap.items, &unsignedMergeHeapItem{itr: bufInput})
  5472  	}
  5473  
  5474  	return itr
  5475  }
  5476  
  5477  // Stats returns an aggregation of stats from the underlying iterators.
  5478  func (itr *unsignedMergeIterator) Stats() IteratorStats {
  5479  	var stats IteratorStats
  5480  	for _, input := range itr.inputs {
  5481  		stats.Add(input.Stats())
  5482  	}
  5483  	return stats
  5484  }
  5485  
  5486  // Close closes the underlying iterators.
  5487  func (itr *unsignedMergeIterator) Close() error {
  5488  	itr.mu.Lock()
  5489  	defer itr.mu.Unlock()
  5490  
  5491  	for _, input := range itr.inputs {
  5492  		input.Close()
  5493  	}
  5494  	itr.curr = nil
  5495  	itr.inputs = nil
  5496  	itr.heap.items = nil
  5497  	itr.closed = true
  5498  	return nil
  5499  }
  5500  
  5501  // Next returns the next point from the iterator.
  5502  func (itr *unsignedMergeIterator) Next() (*UnsignedPoint, error) {
  5503  	itr.mu.RLock()
  5504  	defer itr.mu.RUnlock()
  5505  	if itr.closed {
  5506  		return nil, nil
  5507  	}
  5508  
  5509  	// Initialize the heap. This needs to be done lazily on the first call to this iterator
  5510  	// so that iterator initialization done through the Select() call returns quickly.
  5511  	// Queries can only be interrupted after the Select() call completes so any operations
  5512  	// done during iterator creation cannot be interrupted, which is why we do it here
  5513  	// instead so an interrupt can happen while initializing the heap.
  5514  	if !itr.init {
  5515  		items := itr.heap.items
  5516  		itr.heap.items = make([]*unsignedMergeHeapItem, 0, len(items))
  5517  		for _, item := range items {
  5518  			if p, err := item.itr.peek(); err != nil {
  5519  				return nil, err
  5520  			} else if p == nil {
  5521  				continue
  5522  			}
  5523  			itr.heap.items = append(itr.heap.items, item)
  5524  		}
  5525  		heap.Init(itr.heap)
  5526  		itr.init = true
  5527  	}
  5528  
  5529  	for {
  5530  		// Retrieve the next iterator if we don't have one.
  5531  		if itr.curr == nil {
  5532  			if len(itr.heap.items) == 0 {
  5533  				return nil, nil
  5534  			}
  5535  			itr.curr = heap.Pop(itr.heap).(*unsignedMergeHeapItem)
  5536  
  5537  			// Read point and set current window.
  5538  			p, err := itr.curr.itr.Next()
  5539  			if err != nil {
  5540  				return nil, err
  5541  			}
  5542  			tags := p.Tags.Subset(itr.heap.opt.Dimensions)
  5543  			itr.window.name, itr.window.tags = p.Name, tags.ID()
  5544  			itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time)
  5545  			return p, nil
  5546  		}
  5547  
  5548  		// Read the next point from the current iterator.
  5549  		p, err := itr.curr.itr.Next()
  5550  		if err != nil {
  5551  			return nil, err
  5552  		}
  5553  
  5554  		// If there are no more points then remove iterator from heap and find next.
  5555  		if p == nil {
  5556  			itr.curr = nil
  5557  			continue
  5558  		}
  5559  
  5560  		// Check if the point is inside of our current window.
  5561  		inWindow := true
  5562  		if window := itr.window; window.name != p.Name {
  5563  			inWindow = false
  5564  		} else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() {
  5565  			inWindow = false
  5566  		} else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime {
  5567  			inWindow = false
  5568  		} else if !opt.Ascending && p.Time < window.startTime {
  5569  			inWindow = false
  5570  		}
  5571  
  5572  		// If it's outside our window then push iterator back on the heap and find new iterator.
  5573  		if !inWindow {
  5574  			itr.curr.itr.unread(p)
  5575  			heap.Push(itr.heap, itr.curr)
  5576  			itr.curr = nil
  5577  			continue
  5578  		}
  5579  
  5580  		return p, nil
  5581  	}
  5582  }
  5583  
  5584  // unsignedMergeHeap represents a heap of unsignedMergeHeapItems.
  5585  // Items are sorted by their next window and then by name/tags.
  5586  type unsignedMergeHeap struct {
  5587  	opt   IteratorOptions
  5588  	items []*unsignedMergeHeapItem
  5589  }
  5590  
  5591  func (h *unsignedMergeHeap) Len() int      { return len(h.items) }
  5592  func (h *unsignedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
  5593  func (h *unsignedMergeHeap) Less(i, j int) bool {
  5594  	x, err := h.items[i].itr.peek()
  5595  	if err != nil {
  5596  		return true
  5597  	}
  5598  	y, err := h.items[j].itr.peek()
  5599  	if err != nil {
  5600  		return false
  5601  	}
  5602  
  5603  	if h.opt.Ascending {
  5604  		if x.Name != y.Name {
  5605  			return x.Name < y.Name
  5606  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
  5607  			return xTags.ID() < yTags.ID()
  5608  		}
  5609  	} else {
  5610  		if x.Name != y.Name {
  5611  			return x.Name > y.Name
  5612  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
  5613  			return xTags.ID() > yTags.ID()
  5614  		}
  5615  	}
  5616  
  5617  	xt, _ := h.opt.Window(x.Time)
  5618  	yt, _ := h.opt.Window(y.Time)
  5619  
  5620  	if h.opt.Ascending {
  5621  		return xt < yt
  5622  	}
  5623  	return xt > yt
  5624  }
  5625  
  5626  func (h *unsignedMergeHeap) Push(x interface{}) {
  5627  	h.items = append(h.items, x.(*unsignedMergeHeapItem))
  5628  }
  5629  
  5630  func (h *unsignedMergeHeap) Pop() interface{} {
  5631  	old := h.items
  5632  	n := len(old)
  5633  	item := old[n-1]
  5634  	h.items = old[0 : n-1]
  5635  	return item
  5636  }
  5637  
  5638  type unsignedMergeHeapItem struct {
  5639  	itr *bufUnsignedIterator
  5640  }
  5641  
  5642  // unsignedSortedMergeIterator is an iterator that sorts and merges multiple iterators into one.
  5643  type unsignedSortedMergeIterator struct {
  5644  	inputs []UnsignedIterator
  5645  	heap   *unsignedSortedMergeHeap
  5646  	init   bool
  5647  }
  5648  
  5649  // newUnsignedSortedMergeIterator returns an instance of unsignedSortedMergeIterator.
  5650  func newUnsignedSortedMergeIterator(inputs []UnsignedIterator, opt IteratorOptions) Iterator {
  5651  	itr := &unsignedSortedMergeIterator{
  5652  		inputs: inputs,
  5653  		heap: &unsignedSortedMergeHeap{
  5654  			items: make([]*unsignedSortedMergeHeapItem, 0, len(inputs)),
  5655  			opt:   opt,
  5656  		},
  5657  	}
  5658  
  5659  	// Initialize heap items.
  5660  	for _, input := range inputs {
  5661  		// Append to the heap.
  5662  		itr.heap.items = append(itr.heap.items, &unsignedSortedMergeHeapItem{itr: input})
  5663  	}
  5664  
  5665  	return itr
  5666  }
  5667  
  5668  // Stats returns an aggregation of stats from the underlying iterators.
  5669  func (itr *unsignedSortedMergeIterator) Stats() IteratorStats {
  5670  	var stats IteratorStats
  5671  	for _, input := range itr.inputs {
  5672  		stats.Add(input.Stats())
  5673  	}
  5674  	return stats
  5675  }
  5676  
  5677  // Close closes the underlying iterators.
  5678  func (itr *unsignedSortedMergeIterator) Close() error {
  5679  	for _, input := range itr.inputs {
  5680  		input.Close()
  5681  	}
  5682  	return nil
  5683  }
  5684  
  5685  // Next returns the next points from the iterator.
  5686  func (itr *unsignedSortedMergeIterator) Next() (*UnsignedPoint, error) { return itr.pop() }
  5687  
  5688  // pop returns the next point from the heap.
  5689  // Reads the next point from item's cursor and puts it back on the heap.
  5690  func (itr *unsignedSortedMergeIterator) pop() (*UnsignedPoint, error) {
  5691  	// Initialize the heap. See the MergeIterator to see why this has to be done lazily.
  5692  	if !itr.init {
  5693  		items := itr.heap.items
  5694  		itr.heap.items = make([]*unsignedSortedMergeHeapItem, 0, len(items))
  5695  		for _, item := range items {
  5696  			var err error
  5697  			if item.point, err = item.itr.Next(); err != nil {
  5698  				return nil, err
  5699  			} else if item.point == nil {
  5700  				continue
  5701  			}
  5702  			itr.heap.items = append(itr.heap.items, item)
  5703  		}
  5704  		heap.Init(itr.heap)
  5705  		itr.init = true
  5706  	}
  5707  
  5708  	if len(itr.heap.items) == 0 {
  5709  		return nil, nil
  5710  	}
  5711  
  5712  	// Read the next item from the heap.
  5713  	item := heap.Pop(itr.heap).(*unsignedSortedMergeHeapItem)
  5714  	if item.err != nil {
  5715  		return nil, item.err
  5716  	} else if item.point == nil {
  5717  		return nil, nil
  5718  	}
  5719  
  5720  	// Copy the point for return.
  5721  	p := item.point.Clone()
  5722  
  5723  	// Read the next item from the cursor. Push back to heap if one exists.
  5724  	if item.point, item.err = item.itr.Next(); item.point != nil {
  5725  		heap.Push(itr.heap, item)
  5726  	}
  5727  
  5728  	return p, nil
  5729  }
  5730  
  5731  // unsignedSortedMergeHeap represents a heap of unsignedSortedMergeHeapItems.
  5732  // Items are sorted with the following priority:
  5733  //   - By their measurement name;
  5734  //   - By their tag keys/values;
  5735  //   - By time; or
  5736  //   - By their Aux field values.
  5737  type unsignedSortedMergeHeap struct {
  5738  	opt   IteratorOptions
  5739  	items []*unsignedSortedMergeHeapItem
  5740  }
  5741  
  5742  func (h *unsignedSortedMergeHeap) Len() int      { return len(h.items) }
  5743  func (h *unsignedSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
  5744  func (h *unsignedSortedMergeHeap) Less(i, j int) bool {
  5745  	x, y := h.items[i].point, h.items[j].point
  5746  
  5747  	if h.opt.Ascending {
  5748  		if x.Name != y.Name {
  5749  			return x.Name < y.Name
  5750  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
  5751  			return xTags.ID() < yTags.ID()
  5752  		}
  5753  
  5754  		if x.Time != y.Time {
  5755  			return x.Time < y.Time
  5756  		}
  5757  
  5758  		if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
  5759  			for i := 0; i < len(x.Aux); i++ {
  5760  				v1, ok1 := x.Aux[i].(string)
  5761  				v2, ok2 := y.Aux[i].(string)
  5762  				if !ok1 || !ok2 {
  5763  					// Unsupported types used in Aux fields. Maybe they
  5764  					// need to be added here?
  5765  					return false
  5766  				} else if v1 == v2 {
  5767  					continue
  5768  				}
  5769  				return v1 < v2
  5770  			}
  5771  		}
  5772  		return false // Times and/or Aux fields are equal.
  5773  	}
  5774  
  5775  	if x.Name != y.Name {
  5776  		return x.Name > y.Name
  5777  	} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
  5778  		return xTags.ID() > yTags.ID()
  5779  	}
  5780  
  5781  	if x.Time != y.Time {
  5782  		return x.Time > y.Time
  5783  	}
  5784  
  5785  	if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
  5786  		for i := 0; i < len(x.Aux); i++ {
  5787  			v1, ok1 := x.Aux[i].(string)
  5788  			v2, ok2 := y.Aux[i].(string)
  5789  			if !ok1 || !ok2 {
  5790  				// Unsupported types used in Aux fields. Maybe they
  5791  				// need to be added here?
  5792  				return false
  5793  			} else if v1 == v2 {
  5794  				continue
  5795  			}
  5796  			return v1 > v2
  5797  		}
  5798  	}
  5799  	return false // Times and/or Aux fields are equal.
  5800  }
  5801  
  5802  func (h *unsignedSortedMergeHeap) Push(x interface{}) {
  5803  	h.items = append(h.items, x.(*unsignedSortedMergeHeapItem))
  5804  }
  5805  
  5806  func (h *unsignedSortedMergeHeap) Pop() interface{} {
  5807  	old := h.items
  5808  	n := len(old)
  5809  	item := old[n-1]
  5810  	h.items = old[0 : n-1]
  5811  	return item
  5812  }
  5813  
  5814  type unsignedSortedMergeHeapItem struct {
  5815  	point *UnsignedPoint
  5816  	err   error
  5817  	itr   UnsignedIterator
  5818  }
  5819  
  5820  // unsignedIteratorScanner scans the results of a UnsignedIterator into a map.
  5821  type unsignedIteratorScanner struct {
  5822  	input        *bufUnsignedIterator
  5823  	err          error
  5824  	keys         []influxql.VarRef
  5825  	defaultValue interface{}
  5826  }
  5827  
  5828  // newUnsignedIteratorScanner creates a new IteratorScanner.
  5829  func newUnsignedIteratorScanner(input UnsignedIterator, keys []influxql.VarRef, defaultValue interface{}) *unsignedIteratorScanner {
  5830  	return &unsignedIteratorScanner{
  5831  		input:        newBufUnsignedIterator(input),
  5832  		keys:         keys,
  5833  		defaultValue: defaultValue,
  5834  	}
  5835  }
  5836  
  5837  func (s *unsignedIteratorScanner) Peek() (int64, string, Tags) {
  5838  	if s.err != nil {
  5839  		return ZeroTime, "", Tags{}
  5840  	}
  5841  
  5842  	p, err := s.input.peek()
  5843  	if err != nil {
  5844  		s.err = err
  5845  		return ZeroTime, "", Tags{}
  5846  	} else if p == nil {
  5847  		return ZeroTime, "", Tags{}
  5848  	}
  5849  	return p.Time, p.Name, p.Tags
  5850  }
  5851  
  5852  func (s *unsignedIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) {
  5853  	if s.err != nil {
  5854  		return
  5855  	}
  5856  
  5857  	p, err := s.input.Next()
  5858  	if err != nil {
  5859  		s.err = err
  5860  		return
  5861  	} else if p == nil {
  5862  		s.useDefaults(m)
  5863  		return
  5864  	} else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) {
  5865  		s.useDefaults(m)
  5866  		s.input.unread(p)
  5867  		return
  5868  	}
  5869  
  5870  	if k := s.keys[0]; k.Val != "" {
  5871  		if p.Nil {
  5872  			if s.defaultValue != SkipDefault {
  5873  				m[k.Val] = castToType(s.defaultValue, k.Type)
  5874  			}
  5875  		} else {
  5876  			m[k.Val] = p.Value
  5877  		}
  5878  	}
  5879  	for i, v := range p.Aux {
  5880  		k := s.keys[i+1]
  5881  		switch v.(type) {
  5882  		case float64, int64, uint64, string, bool:
  5883  			m[k.Val] = v
  5884  		default:
  5885  			// Insert the fill value if one was specified.
  5886  			if s.defaultValue != SkipDefault {
  5887  				m[k.Val] = castToType(s.defaultValue, k.Type)
  5888  			}
  5889  		}
  5890  	}
  5891  }
  5892  
  5893  func (s *unsignedIteratorScanner) useDefaults(m map[string]interface{}) {
  5894  	if s.defaultValue == SkipDefault {
  5895  		return
  5896  	}
  5897  	for _, k := range s.keys {
  5898  		if k.Val == "" {
  5899  			continue
  5900  		}
  5901  		m[k.Val] = castToType(s.defaultValue, k.Type)
  5902  	}
  5903  }
  5904  
  5905  func (s *unsignedIteratorScanner) Stats() IteratorStats { return s.input.Stats() }
  5906  func (s *unsignedIteratorScanner) Err() error           { return s.err }
  5907  func (s *unsignedIteratorScanner) Close() error         { return s.input.Close() }
  5908  
  5909  // unsignedParallelIterator represents an iterator that pulls data in a separate goroutine.
  5910  type unsignedParallelIterator struct {
  5911  	input UnsignedIterator
  5912  	ch    chan unsignedPointError
  5913  
  5914  	once    sync.Once
  5915  	closing chan struct{}
  5916  	wg      sync.WaitGroup
  5917  }
  5918  
  5919  // newUnsignedParallelIterator returns a new instance of unsignedParallelIterator.
  5920  func newUnsignedParallelIterator(input UnsignedIterator) *unsignedParallelIterator {
  5921  	itr := &unsignedParallelIterator{
  5922  		input:   input,
  5923  		ch:      make(chan unsignedPointError, 256),
  5924  		closing: make(chan struct{}),
  5925  	}
  5926  	itr.wg.Add(1)
  5927  	go itr.monitor()
  5928  	return itr
  5929  }
  5930  
  5931  // Stats returns stats from the underlying iterator.
  5932  func (itr *unsignedParallelIterator) Stats() IteratorStats { return itr.input.Stats() }
  5933  
  5934  // Close closes the underlying iterators.
  5935  func (itr *unsignedParallelIterator) Close() error {
  5936  	itr.once.Do(func() { close(itr.closing) })
  5937  	itr.wg.Wait()
  5938  	return itr.input.Close()
  5939  }
  5940  
  5941  // Next returns the next point from the iterator.
  5942  func (itr *unsignedParallelIterator) Next() (*UnsignedPoint, error) {
  5943  	v, ok := <-itr.ch
  5944  	if !ok {
  5945  		return nil, io.EOF
  5946  	}
  5947  	return v.point, v.err
  5948  }
  5949  
  5950  // monitor runs in a separate goroutine and actively pulls the next point.
  5951  func (itr *unsignedParallelIterator) monitor() {
  5952  	defer close(itr.ch)
  5953  	defer itr.wg.Done()
  5954  
  5955  	for {
  5956  		// Read next point.
  5957  		p, err := itr.input.Next()
  5958  		if p != nil {
  5959  			p = p.Clone()
  5960  		}
  5961  
  5962  		select {
  5963  		case <-itr.closing:
  5964  			return
  5965  		case itr.ch <- unsignedPointError{point: p, err: err}:
  5966  		}
  5967  	}
  5968  }
  5969  
  5970  type unsignedPointError struct {
  5971  	point *UnsignedPoint
  5972  	err   error
  5973  }
  5974  
  5975  // unsignedLimitIterator represents an iterator that limits points per group.
  5976  type unsignedLimitIterator struct {
  5977  	input UnsignedIterator
  5978  	opt   IteratorOptions
  5979  	n     int
  5980  
  5981  	prev struct {
  5982  		name string
  5983  		tags Tags
  5984  	}
  5985  }
  5986  
  5987  // newUnsignedLimitIterator returns a new instance of unsignedLimitIterator.
  5988  func newUnsignedLimitIterator(input UnsignedIterator, opt IteratorOptions) *unsignedLimitIterator {
  5989  	return &unsignedLimitIterator{
  5990  		input: input,
  5991  		opt:   opt,
  5992  	}
  5993  }
  5994  
  5995  // Stats returns stats from the underlying iterator.
  5996  func (itr *unsignedLimitIterator) Stats() IteratorStats { return itr.input.Stats() }
  5997  
  5998  // Close closes the underlying iterators.
  5999  func (itr *unsignedLimitIterator) Close() error { return itr.input.Close() }
  6000  
  6001  // Next returns the next point from the iterator.
  6002  func (itr *unsignedLimitIterator) Next() (*UnsignedPoint, error) {
  6003  	for {
  6004  		p, err := itr.input.Next()
  6005  		if p == nil || err != nil {
  6006  			return nil, err
  6007  		}
  6008  
  6009  		// Reset window and counter if a new window is encountered.
  6010  		if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) {
  6011  			itr.prev.name = p.Name
  6012  			itr.prev.tags = p.Tags
  6013  			itr.n = 0
  6014  		}
  6015  
  6016  		// Increment counter.
  6017  		itr.n++
  6018  
  6019  		// Read next point if not beyond the offset.
  6020  		if itr.n <= itr.opt.Offset {
  6021  			continue
  6022  		}
  6023  
  6024  		// Read next point if we're beyond the limit.
  6025  		if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit {
  6026  			continue
  6027  		}
  6028  
  6029  		return p, nil
  6030  	}
  6031  }
  6032  
  6033  type unsignedFillIterator struct {
  6034  	input     *bufUnsignedIterator
  6035  	prev      UnsignedPoint
  6036  	startTime int64
  6037  	endTime   int64
  6038  	auxFields []interface{}
  6039  	init      bool
  6040  	opt       IteratorOptions
  6041  
  6042  	window struct {
  6043  		name   string
  6044  		tags   Tags
  6045  		time   int64
  6046  		offset int64
  6047  	}
  6048  }
  6049  
  6050  func newUnsignedFillIterator(input UnsignedIterator, expr influxql.Expr, opt IteratorOptions) *unsignedFillIterator {
  6051  	if opt.Fill == influxql.NullFill {
  6052  		if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" {
  6053  			opt.Fill = influxql.NumberFill
  6054  			opt.FillValue = uint64(0)
  6055  		}
  6056  	}
  6057  
  6058  	var startTime, endTime int64
  6059  	if opt.Ascending {
  6060  		startTime, _ = opt.Window(opt.StartTime)
  6061  		endTime, _ = opt.Window(opt.EndTime)
  6062  	} else {
  6063  		startTime, _ = opt.Window(opt.EndTime)
  6064  		endTime, _ = opt.Window(opt.StartTime)
  6065  	}
  6066  
  6067  	var auxFields []interface{}
  6068  	if len(opt.Aux) > 0 {
  6069  		auxFields = make([]interface{}, len(opt.Aux))
  6070  	}
  6071  
  6072  	return &unsignedFillIterator{
  6073  		input:     newBufUnsignedIterator(input),
  6074  		prev:      UnsignedPoint{Nil: true},
  6075  		startTime: startTime,
  6076  		endTime:   endTime,
  6077  		auxFields: auxFields,
  6078  		opt:       opt,
  6079  	}
  6080  }
  6081  
  6082  func (itr *unsignedFillIterator) Stats() IteratorStats { return itr.input.Stats() }
  6083  func (itr *unsignedFillIterator) Close() error         { return itr.input.Close() }
  6084  
  6085  func (itr *unsignedFillIterator) Next() (*UnsignedPoint, error) {
  6086  	if !itr.init {
  6087  		p, err := itr.input.peek()
  6088  		if p == nil || err != nil {
  6089  			return nil, err
  6090  		}
  6091  		itr.window.name, itr.window.tags = p.Name, p.Tags
  6092  		itr.window.time = itr.startTime
  6093  		if itr.startTime == influxql.MinTime {
  6094  			itr.window.time, _ = itr.opt.Window(p.Time)
  6095  		}
  6096  		if itr.opt.Location != nil {
  6097  			_, itr.window.offset = itr.opt.Zone(itr.window.time)
  6098  		}
  6099  		itr.init = true
  6100  	}
  6101  
  6102  	p, err := itr.input.Next()
  6103  	if err != nil {
  6104  		return nil, err
  6105  	}
  6106  
  6107  	// Check if the next point is outside of our window or is nil.
  6108  	if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() {
  6109  		// If we are inside of an interval, unread the point and continue below to
  6110  		// constructing a new point.
  6111  		if itr.opt.Ascending && itr.window.time <= itr.endTime {
  6112  			itr.input.unread(p)
  6113  			p = nil
  6114  			goto CONSTRUCT
  6115  		} else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime {
  6116  			itr.input.unread(p)
  6117  			p = nil
  6118  			goto CONSTRUCT
  6119  		}
  6120  
  6121  		// We are *not* in a current interval. If there is no next point,
  6122  		// we are at the end of all intervals.
  6123  		if p == nil {
  6124  			return nil, nil
  6125  		}
  6126  
  6127  		// Set the new interval.
  6128  		itr.window.name, itr.window.tags = p.Name, p.Tags
  6129  		itr.window.time = itr.startTime
  6130  		if itr.window.time == influxql.MinTime {
  6131  			itr.window.time, _ = itr.opt.Window(p.Time)
  6132  		}
  6133  		if itr.opt.Location != nil {
  6134  			_, itr.window.offset = itr.opt.Zone(itr.window.time)
  6135  		}
  6136  		itr.prev = UnsignedPoint{Nil: true}
  6137  	}
  6138  
  6139  	// Check if the point is our next expected point.
  6140  CONSTRUCT:
  6141  	if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) {
  6142  		if p != nil {
  6143  			itr.input.unread(p)
  6144  		}
  6145  
  6146  		p = &UnsignedPoint{
  6147  			Name: itr.window.name,
  6148  			Tags: itr.window.tags,
  6149  			Time: itr.window.time,
  6150  			Aux:  itr.auxFields,
  6151  		}
  6152  
  6153  		switch itr.opt.Fill {
  6154  		case influxql.LinearFill:
  6155  			if !itr.prev.Nil {
  6156  				next, err := itr.input.peek()
  6157  				if err != nil {
  6158  					return nil, err
  6159  				} else if next != nil && next.Name == itr.window.name && next.Tags.ID() == itr.window.tags.ID() {
  6160  					interval := int64(itr.opt.Interval.Duration)
  6161  					start := itr.window.time / interval
  6162  					p.Value = linearUnsigned(start, itr.prev.Time/interval, next.Time/interval, itr.prev.Value, next.Value)
  6163  				} else {
  6164  					p.Nil = true
  6165  				}
  6166  			} else {
  6167  				p.Nil = true
  6168  			}
  6169  
  6170  		case influxql.NullFill:
  6171  			p.Nil = true
  6172  		case influxql.NumberFill:
  6173  			p.Value, _ = castToUnsigned(itr.opt.FillValue)
  6174  		case influxql.PreviousFill:
  6175  			if !itr.prev.Nil {
  6176  				p.Value = itr.prev.Value
  6177  				p.Nil = itr.prev.Nil
  6178  			} else {
  6179  				p.Nil = true
  6180  			}
  6181  		}
  6182  	} else {
  6183  		itr.prev = *p
  6184  	}
  6185  
  6186  	// Advance the expected time. Do not advance to a new window here
  6187  	// as there may be lingering points with the same timestamp in the previous
  6188  	// window.
  6189  	if itr.opt.Ascending {
  6190  		itr.window.time += int64(itr.opt.Interval.Duration)
  6191  	} else {
  6192  		itr.window.time -= int64(itr.opt.Interval.Duration)
  6193  	}
  6194  
  6195  	// Check to see if we have passed over an offset change and adjust the time
  6196  	// to account for this new offset.
  6197  	if itr.opt.Location != nil {
  6198  		if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset {
  6199  			diff := itr.window.offset - offset
  6200  			if abs(diff) < int64(itr.opt.Interval.Duration) {
  6201  				itr.window.time += diff
  6202  			}
  6203  			itr.window.offset = offset
  6204  		}
  6205  	}
  6206  	return p, nil
  6207  }
  6208  
  6209  // unsignedIntervalIterator represents a unsigned implementation of IntervalIterator.
  6210  type unsignedIntervalIterator struct {
  6211  	input UnsignedIterator
  6212  	opt   IteratorOptions
  6213  }
  6214  
  6215  func newUnsignedIntervalIterator(input UnsignedIterator, opt IteratorOptions) *unsignedIntervalIterator {
  6216  	return &unsignedIntervalIterator{input: input, opt: opt}
  6217  }
  6218  
  6219  func (itr *unsignedIntervalIterator) Stats() IteratorStats { return itr.input.Stats() }
  6220  func (itr *unsignedIntervalIterator) Close() error         { return itr.input.Close() }
  6221  
  6222  func (itr *unsignedIntervalIterator) Next() (*UnsignedPoint, error) {
  6223  	p, err := itr.input.Next()
  6224  	if p == nil || err != nil {
  6225  		return nil, err
  6226  	}
  6227  	p.Time, _ = itr.opt.Window(p.Time)
  6228  	// If we see the minimum allowable time, set the time to zero so we don't
  6229  	// break the default returned time for aggregate queries without times.
  6230  	if p.Time == influxql.MinTime {
  6231  		p.Time = 0
  6232  	}
  6233  	return p, nil
  6234  }
  6235  
  6236  // unsignedInterruptIterator represents a unsigned implementation of InterruptIterator.
  6237  type unsignedInterruptIterator struct {
  6238  	input   UnsignedIterator
  6239  	closing <-chan struct{}
  6240  	count   int
  6241  }
  6242  
  6243  func newUnsignedInterruptIterator(input UnsignedIterator, closing <-chan struct{}) *unsignedInterruptIterator {
  6244  	return &unsignedInterruptIterator{input: input, closing: closing}
  6245  }
  6246  
  6247  func (itr *unsignedInterruptIterator) Stats() IteratorStats { return itr.input.Stats() }
  6248  func (itr *unsignedInterruptIterator) Close() error         { return itr.input.Close() }
  6249  
  6250  func (itr *unsignedInterruptIterator) Next() (*UnsignedPoint, error) {
  6251  	// Only check if the channel is closed every N points. This
  6252  	// intentionally checks on both 0 and N so that if the iterator
  6253  	// has been interrupted before the first point is emitted it will
  6254  	// not emit any points.
  6255  	if itr.count&0xFF == 0xFF {
  6256  		select {
  6257  		case <-itr.closing:
  6258  			return nil, itr.Close()
  6259  		default:
  6260  			// Reset iterator count to zero and fall through to emit the next point.
  6261  			itr.count = 0
  6262  		}
  6263  	}
  6264  
  6265  	// Increment the counter for every point read.
  6266  	itr.count++
  6267  	return itr.input.Next()
  6268  }
  6269  
  6270  // unsignedCloseInterruptIterator represents a unsigned implementation of CloseInterruptIterator.
  6271  type unsignedCloseInterruptIterator struct {
  6272  	input   UnsignedIterator
  6273  	closing <-chan struct{}
  6274  	done    chan struct{}
  6275  	once    sync.Once
  6276  }
  6277  
  6278  func newUnsignedCloseInterruptIterator(input UnsignedIterator, closing <-chan struct{}) *unsignedCloseInterruptIterator {
  6279  	itr := &unsignedCloseInterruptIterator{
  6280  		input:   input,
  6281  		closing: closing,
  6282  		done:    make(chan struct{}),
  6283  	}
  6284  	go itr.monitor()
  6285  	return itr
  6286  }
  6287  
  6288  func (itr *unsignedCloseInterruptIterator) monitor() {
  6289  	select {
  6290  	case <-itr.closing:
  6291  		itr.Close()
  6292  	case <-itr.done:
  6293  	}
  6294  }
  6295  
  6296  func (itr *unsignedCloseInterruptIterator) Stats() IteratorStats {
  6297  	return itr.input.Stats()
  6298  }
  6299  
  6300  func (itr *unsignedCloseInterruptIterator) Close() error {
  6301  	itr.once.Do(func() {
  6302  		close(itr.done)
  6303  		itr.input.Close()
  6304  	})
  6305  	return nil
  6306  }
  6307  
  6308  func (itr *unsignedCloseInterruptIterator) Next() (*UnsignedPoint, error) {
  6309  	p, err := itr.input.Next()
  6310  	if err != nil {
  6311  		// Check if the iterator was closed.
  6312  		select {
  6313  		case <-itr.done:
  6314  			return nil, nil
  6315  		default:
  6316  			return nil, err
  6317  		}
  6318  	}
  6319  	return p, nil
  6320  }
  6321  
  6322  // unsignedReduceFloatIterator executes a reducer for every interval and buffers the result.
  6323  type unsignedReduceFloatIterator struct {
  6324  	input    *bufUnsignedIterator
  6325  	create   func() (UnsignedPointAggregator, FloatPointEmitter)
  6326  	dims     []string
  6327  	opt      IteratorOptions
  6328  	points   []FloatPoint
  6329  	keepTags bool
  6330  }
  6331  
  6332  func newUnsignedReduceFloatIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, FloatPointEmitter)) *unsignedReduceFloatIterator {
  6333  	return &unsignedReduceFloatIterator{
  6334  		input:  newBufUnsignedIterator(input),
  6335  		create: createFn,
  6336  		dims:   opt.GetDimensions(),
  6337  		opt:    opt,
  6338  	}
  6339  }
  6340  
  6341  // Stats returns stats from the input iterator.
  6342  func (itr *unsignedReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
  6343  
  6344  // Close closes the iterator and all child iterators.
  6345  func (itr *unsignedReduceFloatIterator) Close() error { return itr.input.Close() }
  6346  
  6347  // Next returns the minimum value for the next available interval.
  6348  func (itr *unsignedReduceFloatIterator) Next() (*FloatPoint, error) {
  6349  	// Calculate next window if we have no more points.
  6350  	if len(itr.points) == 0 {
  6351  		var err error
  6352  		itr.points, err = itr.reduce()
  6353  		if len(itr.points) == 0 {
  6354  			return nil, err
  6355  		}
  6356  	}
  6357  
  6358  	// Pop next point off the stack.
  6359  	p := &itr.points[len(itr.points)-1]
  6360  	itr.points = itr.points[:len(itr.points)-1]
  6361  	return p, nil
  6362  }
  6363  
  6364  // unsignedReduceFloatPoint stores the reduced data for a name/tag combination.
  6365  type unsignedReduceFloatPoint struct {
  6366  	Name       string
  6367  	Tags       Tags
  6368  	Aggregator UnsignedPointAggregator
  6369  	Emitter    FloatPointEmitter
  6370  }
  6371  
  6372  // reduce executes fn once for every point in the next window.
  6373  // The previous value for the dimension is passed to fn.
  6374  func (itr *unsignedReduceFloatIterator) reduce() ([]FloatPoint, error) {
  6375  	// Calculate next window.
  6376  	var (
  6377  		startTime, endTime int64
  6378  		window             struct {
  6379  			name string
  6380  			tags string
  6381  		}
  6382  	)
  6383  	for {
  6384  		p, err := itr.input.Next()
  6385  		if err != nil || p == nil {
  6386  			return nil, err
  6387  		} else if p.Nil {
  6388  			continue
  6389  		}
  6390  
  6391  		// Unread the point so it can be processed.
  6392  		itr.input.unread(p)
  6393  		startTime, endTime = itr.opt.Window(p.Time)
  6394  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  6395  		break
  6396  	}
  6397  
  6398  	// Create points by tags.
  6399  	m := make(map[string]*unsignedReduceFloatPoint)
  6400  	for {
  6401  		// Read next point.
  6402  		curr, err := itr.input.NextInWindow(startTime, endTime)
  6403  		if err != nil {
  6404  			return nil, err
  6405  		} else if curr == nil {
  6406  			break
  6407  		} else if curr.Nil {
  6408  			continue
  6409  		} else if curr.Name != window.name {
  6410  			itr.input.unread(curr)
  6411  			break
  6412  		}
  6413  
  6414  		// Ensure this point is within the same final window.
  6415  		if curr.Name != window.name {
  6416  			itr.input.unread(curr)
  6417  			break
  6418  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  6419  			itr.input.unread(curr)
  6420  			break
  6421  		}
  6422  
  6423  		// Retrieve the tags on this point for this level of the query.
  6424  		// This may be different than the bucket dimensions.
  6425  		tags := curr.Tags.Subset(itr.dims)
  6426  		id := tags.ID()
  6427  
  6428  		// Retrieve the aggregator for this name/tag combination or create one.
  6429  		rp := m[id]
  6430  		if rp == nil {
  6431  			aggregator, emitter := itr.create()
  6432  			rp = &unsignedReduceFloatPoint{
  6433  				Name:       curr.Name,
  6434  				Tags:       tags,
  6435  				Aggregator: aggregator,
  6436  				Emitter:    emitter,
  6437  			}
  6438  			m[id] = rp
  6439  		}
  6440  		rp.Aggregator.AggregateUnsigned(curr)
  6441  	}
  6442  
  6443  	keys := make([]string, 0, len(m))
  6444  	for k := range m {
  6445  		keys = append(keys, k)
  6446  	}
  6447  
  6448  	// Reverse sort points by name & tag.
  6449  	// This ensures a consistent order of output.
  6450  	if len(keys) > 0 {
  6451  		var sorted sort.Interface = sort.StringSlice(keys)
  6452  		if itr.opt.Ascending {
  6453  			sorted = sort.Reverse(sorted)
  6454  		}
  6455  		sort.Sort(sorted)
  6456  	}
  6457  
  6458  	// Assume the points are already sorted until proven otherwise.
  6459  	sortedByTime := true
  6460  	// Emit the points for each name & tag combination.
  6461  	a := make([]FloatPoint, 0, len(m))
  6462  	for _, k := range keys {
  6463  		rp := m[k]
  6464  		points := rp.Emitter.Emit()
  6465  		for i := len(points) - 1; i >= 0; i-- {
  6466  			points[i].Name = rp.Name
  6467  			if !itr.keepTags {
  6468  				points[i].Tags = rp.Tags
  6469  			}
  6470  			// Set the points time to the interval time if the reducer didn't provide one.
  6471  			if points[i].Time == ZeroTime {
  6472  				points[i].Time = startTime
  6473  			} else {
  6474  				sortedByTime = false
  6475  			}
  6476  			a = append(a, points[i])
  6477  		}
  6478  	}
  6479  	// Points may be out of order. Perform a stable sort by time if requested.
  6480  	if !sortedByTime && itr.opt.Ordered {
  6481  		var sorted sort.Interface = floatPointsByTime(a)
  6482  		if itr.opt.Ascending {
  6483  			sorted = sort.Reverse(sorted)
  6484  		}
  6485  		sort.Stable(sorted)
  6486  	}
  6487  	return a, nil
  6488  }
  6489  
  6490  // unsignedStreamFloatIterator streams inputs into the iterator and emits points gradually.
  6491  type unsignedStreamFloatIterator struct {
  6492  	input  *bufUnsignedIterator
  6493  	create func() (UnsignedPointAggregator, FloatPointEmitter)
  6494  	dims   []string
  6495  	opt    IteratorOptions
  6496  	m      map[string]*unsignedReduceFloatPoint
  6497  	points []FloatPoint
  6498  }
  6499  
  6500  // newUnsignedStreamFloatIterator returns a new instance of unsignedStreamFloatIterator.
  6501  func newUnsignedStreamFloatIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, FloatPointEmitter), opt IteratorOptions) *unsignedStreamFloatIterator {
  6502  	return &unsignedStreamFloatIterator{
  6503  		input:  newBufUnsignedIterator(input),
  6504  		create: createFn,
  6505  		dims:   opt.GetDimensions(),
  6506  		opt:    opt,
  6507  		m:      make(map[string]*unsignedReduceFloatPoint),
  6508  	}
  6509  }
  6510  
  6511  // Stats returns stats from the input iterator.
  6512  func (itr *unsignedStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
  6513  
  6514  // Close closes the iterator and all child iterators.
  6515  func (itr *unsignedStreamFloatIterator) Close() error { return itr.input.Close() }
  6516  
  6517  // Next returns the next value for the stream iterator.
  6518  func (itr *unsignedStreamFloatIterator) Next() (*FloatPoint, error) {
  6519  	// Calculate next window if we have no more points.
  6520  	if len(itr.points) == 0 {
  6521  		var err error
  6522  		itr.points, err = itr.reduce()
  6523  		if len(itr.points) == 0 {
  6524  			return nil, err
  6525  		}
  6526  	}
  6527  
  6528  	// Pop next point off the stack.
  6529  	p := &itr.points[len(itr.points)-1]
  6530  	itr.points = itr.points[:len(itr.points)-1]
  6531  	return p, nil
  6532  }
  6533  
  6534  // reduce creates and manages aggregators for every point from the input.
  6535  // After aggregating a point, it always tries to emit a value using the emitter.
  6536  func (itr *unsignedStreamFloatIterator) reduce() ([]FloatPoint, error) {
  6537  	// We have already read all of the input points.
  6538  	if itr.m == nil {
  6539  		return nil, nil
  6540  	}
  6541  
  6542  	for {
  6543  		// Read next point.
  6544  		curr, err := itr.input.Next()
  6545  		if err != nil {
  6546  			return nil, err
  6547  		} else if curr == nil {
  6548  			// Close all of the aggregators to flush any remaining points to emit.
  6549  			var points []FloatPoint
  6550  			for _, rp := range itr.m {
  6551  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  6552  					if err := aggregator.Close(); err != nil {
  6553  						return nil, err
  6554  					}
  6555  
  6556  					pts := rp.Emitter.Emit()
  6557  					if len(pts) == 0 {
  6558  						continue
  6559  					}
  6560  
  6561  					for i := range pts {
  6562  						pts[i].Name = rp.Name
  6563  						pts[i].Tags = rp.Tags
  6564  					}
  6565  					points = append(points, pts...)
  6566  				}
  6567  			}
  6568  
  6569  			// Eliminate the aggregators and emitters.
  6570  			itr.m = nil
  6571  			return points, nil
  6572  		} else if curr.Nil {
  6573  			continue
  6574  		}
  6575  		tags := curr.Tags.Subset(itr.dims)
  6576  
  6577  		id := curr.Name
  6578  		if len(tags.m) > 0 {
  6579  			id += "\x00" + tags.ID()
  6580  		}
  6581  
  6582  		// Retrieve the aggregator for this name/tag combination or create one.
  6583  		rp := itr.m[id]
  6584  		if rp == nil {
  6585  			aggregator, emitter := itr.create()
  6586  			rp = &unsignedReduceFloatPoint{
  6587  				Name:       curr.Name,
  6588  				Tags:       tags,
  6589  				Aggregator: aggregator,
  6590  				Emitter:    emitter,
  6591  			}
  6592  			itr.m[id] = rp
  6593  		}
  6594  		rp.Aggregator.AggregateUnsigned(curr)
  6595  
  6596  		// Attempt to emit points from the aggregator.
  6597  		points := rp.Emitter.Emit()
  6598  		if len(points) == 0 {
  6599  			continue
  6600  		}
  6601  
  6602  		for i := range points {
  6603  			points[i].Name = rp.Name
  6604  			points[i].Tags = rp.Tags
  6605  		}
  6606  		return points, nil
  6607  	}
  6608  }
  6609  
  6610  // unsignedReduceIntegerIterator executes a reducer for every interval and buffers the result.
  6611  type unsignedReduceIntegerIterator struct {
  6612  	input    *bufUnsignedIterator
  6613  	create   func() (UnsignedPointAggregator, IntegerPointEmitter)
  6614  	dims     []string
  6615  	opt      IteratorOptions
  6616  	points   []IntegerPoint
  6617  	keepTags bool
  6618  }
  6619  
  6620  func newUnsignedReduceIntegerIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, IntegerPointEmitter)) *unsignedReduceIntegerIterator {
  6621  	return &unsignedReduceIntegerIterator{
  6622  		input:  newBufUnsignedIterator(input),
  6623  		create: createFn,
  6624  		dims:   opt.GetDimensions(),
  6625  		opt:    opt,
  6626  	}
  6627  }
  6628  
  6629  // Stats returns stats from the input iterator.
  6630  func (itr *unsignedReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
  6631  
  6632  // Close closes the iterator and all child iterators.
  6633  func (itr *unsignedReduceIntegerIterator) Close() error { return itr.input.Close() }
  6634  
  6635  // Next returns the minimum value for the next available interval.
  6636  func (itr *unsignedReduceIntegerIterator) Next() (*IntegerPoint, error) {
  6637  	// Calculate next window if we have no more points.
  6638  	if len(itr.points) == 0 {
  6639  		var err error
  6640  		itr.points, err = itr.reduce()
  6641  		if len(itr.points) == 0 {
  6642  			return nil, err
  6643  		}
  6644  	}
  6645  
  6646  	// Pop next point off the stack.
  6647  	p := &itr.points[len(itr.points)-1]
  6648  	itr.points = itr.points[:len(itr.points)-1]
  6649  	return p, nil
  6650  }
  6651  
  6652  // unsignedReduceIntegerPoint stores the reduced data for a name/tag combination.
  6653  type unsignedReduceIntegerPoint struct {
  6654  	Name       string
  6655  	Tags       Tags
  6656  	Aggregator UnsignedPointAggregator
  6657  	Emitter    IntegerPointEmitter
  6658  }
  6659  
  6660  // reduce executes fn once for every point in the next window.
  6661  // The previous value for the dimension is passed to fn.
  6662  func (itr *unsignedReduceIntegerIterator) reduce() ([]IntegerPoint, error) {
  6663  	// Calculate next window.
  6664  	var (
  6665  		startTime, endTime int64
  6666  		window             struct {
  6667  			name string
  6668  			tags string
  6669  		}
  6670  	)
  6671  	for {
  6672  		p, err := itr.input.Next()
  6673  		if err != nil || p == nil {
  6674  			return nil, err
  6675  		} else if p.Nil {
  6676  			continue
  6677  		}
  6678  
  6679  		// Unread the point so it can be processed.
  6680  		itr.input.unread(p)
  6681  		startTime, endTime = itr.opt.Window(p.Time)
  6682  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  6683  		break
  6684  	}
  6685  
  6686  	// Create points by tags.
  6687  	m := make(map[string]*unsignedReduceIntegerPoint)
  6688  	for {
  6689  		// Read next point.
  6690  		curr, err := itr.input.NextInWindow(startTime, endTime)
  6691  		if err != nil {
  6692  			return nil, err
  6693  		} else if curr == nil {
  6694  			break
  6695  		} else if curr.Nil {
  6696  			continue
  6697  		} else if curr.Name != window.name {
  6698  			itr.input.unread(curr)
  6699  			break
  6700  		}
  6701  
  6702  		// Ensure this point is within the same final window.
  6703  		if curr.Name != window.name {
  6704  			itr.input.unread(curr)
  6705  			break
  6706  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  6707  			itr.input.unread(curr)
  6708  			break
  6709  		}
  6710  
  6711  		// Retrieve the tags on this point for this level of the query.
  6712  		// This may be different than the bucket dimensions.
  6713  		tags := curr.Tags.Subset(itr.dims)
  6714  		id := tags.ID()
  6715  
  6716  		// Retrieve the aggregator for this name/tag combination or create one.
  6717  		rp := m[id]
  6718  		if rp == nil {
  6719  			aggregator, emitter := itr.create()
  6720  			rp = &unsignedReduceIntegerPoint{
  6721  				Name:       curr.Name,
  6722  				Tags:       tags,
  6723  				Aggregator: aggregator,
  6724  				Emitter:    emitter,
  6725  			}
  6726  			m[id] = rp
  6727  		}
  6728  		rp.Aggregator.AggregateUnsigned(curr)
  6729  	}
  6730  
  6731  	keys := make([]string, 0, len(m))
  6732  	for k := range m {
  6733  		keys = append(keys, k)
  6734  	}
  6735  
  6736  	// Reverse sort points by name & tag.
  6737  	// This ensures a consistent order of output.
  6738  	if len(keys) > 0 {
  6739  		var sorted sort.Interface = sort.StringSlice(keys)
  6740  		if itr.opt.Ascending {
  6741  			sorted = sort.Reverse(sorted)
  6742  		}
  6743  		sort.Sort(sorted)
  6744  	}
  6745  
  6746  	// Assume the points are already sorted until proven otherwise.
  6747  	sortedByTime := true
  6748  	// Emit the points for each name & tag combination.
  6749  	a := make([]IntegerPoint, 0, len(m))
  6750  	for _, k := range keys {
  6751  		rp := m[k]
  6752  		points := rp.Emitter.Emit()
  6753  		for i := len(points) - 1; i >= 0; i-- {
  6754  			points[i].Name = rp.Name
  6755  			if !itr.keepTags {
  6756  				points[i].Tags = rp.Tags
  6757  			}
  6758  			// Set the points time to the interval time if the reducer didn't provide one.
  6759  			if points[i].Time == ZeroTime {
  6760  				points[i].Time = startTime
  6761  			} else {
  6762  				sortedByTime = false
  6763  			}
  6764  			a = append(a, points[i])
  6765  		}
  6766  	}
  6767  	// Points may be out of order. Perform a stable sort by time if requested.
  6768  	if !sortedByTime && itr.opt.Ordered {
  6769  		var sorted sort.Interface = integerPointsByTime(a)
  6770  		if itr.opt.Ascending {
  6771  			sorted = sort.Reverse(sorted)
  6772  		}
  6773  		sort.Stable(sorted)
  6774  	}
  6775  	return a, nil
  6776  }
  6777  
  6778  // unsignedStreamIntegerIterator streams inputs into the iterator and emits points gradually.
  6779  type unsignedStreamIntegerIterator struct {
  6780  	input  *bufUnsignedIterator
  6781  	create func() (UnsignedPointAggregator, IntegerPointEmitter)
  6782  	dims   []string
  6783  	opt    IteratorOptions
  6784  	m      map[string]*unsignedReduceIntegerPoint
  6785  	points []IntegerPoint
  6786  }
  6787  
  6788  // newUnsignedStreamIntegerIterator returns a new instance of unsignedStreamIntegerIterator.
  6789  func newUnsignedStreamIntegerIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, IntegerPointEmitter), opt IteratorOptions) *unsignedStreamIntegerIterator {
  6790  	return &unsignedStreamIntegerIterator{
  6791  		input:  newBufUnsignedIterator(input),
  6792  		create: createFn,
  6793  		dims:   opt.GetDimensions(),
  6794  		opt:    opt,
  6795  		m:      make(map[string]*unsignedReduceIntegerPoint),
  6796  	}
  6797  }
  6798  
  6799  // Stats returns stats from the input iterator.
  6800  func (itr *unsignedStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
  6801  
  6802  // Close closes the iterator and all child iterators.
  6803  func (itr *unsignedStreamIntegerIterator) Close() error { return itr.input.Close() }
  6804  
  6805  // Next returns the next value for the stream iterator.
  6806  func (itr *unsignedStreamIntegerIterator) Next() (*IntegerPoint, error) {
  6807  	// Calculate next window if we have no more points.
  6808  	if len(itr.points) == 0 {
  6809  		var err error
  6810  		itr.points, err = itr.reduce()
  6811  		if len(itr.points) == 0 {
  6812  			return nil, err
  6813  		}
  6814  	}
  6815  
  6816  	// Pop next point off the stack.
  6817  	p := &itr.points[len(itr.points)-1]
  6818  	itr.points = itr.points[:len(itr.points)-1]
  6819  	return p, nil
  6820  }
  6821  
  6822  // reduce creates and manages aggregators for every point from the input.
  6823  // After aggregating a point, it always tries to emit a value using the emitter.
  6824  func (itr *unsignedStreamIntegerIterator) reduce() ([]IntegerPoint, error) {
  6825  	// We have already read all of the input points.
  6826  	if itr.m == nil {
  6827  		return nil, nil
  6828  	}
  6829  
  6830  	for {
  6831  		// Read next point.
  6832  		curr, err := itr.input.Next()
  6833  		if err != nil {
  6834  			return nil, err
  6835  		} else if curr == nil {
  6836  			// Close all of the aggregators to flush any remaining points to emit.
  6837  			var points []IntegerPoint
  6838  			for _, rp := range itr.m {
  6839  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  6840  					if err := aggregator.Close(); err != nil {
  6841  						return nil, err
  6842  					}
  6843  
  6844  					pts := rp.Emitter.Emit()
  6845  					if len(pts) == 0 {
  6846  						continue
  6847  					}
  6848  
  6849  					for i := range pts {
  6850  						pts[i].Name = rp.Name
  6851  						pts[i].Tags = rp.Tags
  6852  					}
  6853  					points = append(points, pts...)
  6854  				}
  6855  			}
  6856  
  6857  			// Eliminate the aggregators and emitters.
  6858  			itr.m = nil
  6859  			return points, nil
  6860  		} else if curr.Nil {
  6861  			continue
  6862  		}
  6863  		tags := curr.Tags.Subset(itr.dims)
  6864  
  6865  		id := curr.Name
  6866  		if len(tags.m) > 0 {
  6867  			id += "\x00" + tags.ID()
  6868  		}
  6869  
  6870  		// Retrieve the aggregator for this name/tag combination or create one.
  6871  		rp := itr.m[id]
  6872  		if rp == nil {
  6873  			aggregator, emitter := itr.create()
  6874  			rp = &unsignedReduceIntegerPoint{
  6875  				Name:       curr.Name,
  6876  				Tags:       tags,
  6877  				Aggregator: aggregator,
  6878  				Emitter:    emitter,
  6879  			}
  6880  			itr.m[id] = rp
  6881  		}
  6882  		rp.Aggregator.AggregateUnsigned(curr)
  6883  
  6884  		// Attempt to emit points from the aggregator.
  6885  		points := rp.Emitter.Emit()
  6886  		if len(points) == 0 {
  6887  			continue
  6888  		}
  6889  
  6890  		for i := range points {
  6891  			points[i].Name = rp.Name
  6892  			points[i].Tags = rp.Tags
  6893  		}
  6894  		return points, nil
  6895  	}
  6896  }
  6897  
  6898  // unsignedReduceUnsignedIterator executes a reducer for every interval and buffers the result.
  6899  type unsignedReduceUnsignedIterator struct {
  6900  	input    *bufUnsignedIterator
  6901  	create   func() (UnsignedPointAggregator, UnsignedPointEmitter)
  6902  	dims     []string
  6903  	opt      IteratorOptions
  6904  	points   []UnsignedPoint
  6905  	keepTags bool
  6906  }
  6907  
  6908  func newUnsignedReduceUnsignedIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, UnsignedPointEmitter)) *unsignedReduceUnsignedIterator {
  6909  	return &unsignedReduceUnsignedIterator{
  6910  		input:  newBufUnsignedIterator(input),
  6911  		create: createFn,
  6912  		dims:   opt.GetDimensions(),
  6913  		opt:    opt,
  6914  	}
  6915  }
  6916  
  6917  // Stats returns stats from the input iterator.
  6918  func (itr *unsignedReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
  6919  
  6920  // Close closes the iterator and all child iterators.
  6921  func (itr *unsignedReduceUnsignedIterator) Close() error { return itr.input.Close() }
  6922  
  6923  // Next returns the minimum value for the next available interval.
  6924  func (itr *unsignedReduceUnsignedIterator) Next() (*UnsignedPoint, error) {
  6925  	// Calculate next window if we have no more points.
  6926  	if len(itr.points) == 0 {
  6927  		var err error
  6928  		itr.points, err = itr.reduce()
  6929  		if len(itr.points) == 0 {
  6930  			return nil, err
  6931  		}
  6932  	}
  6933  
  6934  	// Pop next point off the stack.
  6935  	p := &itr.points[len(itr.points)-1]
  6936  	itr.points = itr.points[:len(itr.points)-1]
  6937  	return p, nil
  6938  }
  6939  
  6940  // unsignedReduceUnsignedPoint stores the reduced data for a name/tag combination.
  6941  type unsignedReduceUnsignedPoint struct {
  6942  	Name       string
  6943  	Tags       Tags
  6944  	Aggregator UnsignedPointAggregator
  6945  	Emitter    UnsignedPointEmitter
  6946  }
  6947  
  6948  // reduce executes fn once for every point in the next window.
  6949  // The previous value for the dimension is passed to fn.
  6950  func (itr *unsignedReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) {
  6951  	// Calculate next window.
  6952  	var (
  6953  		startTime, endTime int64
  6954  		window             struct {
  6955  			name string
  6956  			tags string
  6957  		}
  6958  	)
  6959  	for {
  6960  		p, err := itr.input.Next()
  6961  		if err != nil || p == nil {
  6962  			return nil, err
  6963  		} else if p.Nil {
  6964  			continue
  6965  		}
  6966  
  6967  		// Unread the point so it can be processed.
  6968  		itr.input.unread(p)
  6969  		startTime, endTime = itr.opt.Window(p.Time)
  6970  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  6971  		break
  6972  	}
  6973  
  6974  	// Create points by tags.
  6975  	m := make(map[string]*unsignedReduceUnsignedPoint)
  6976  	for {
  6977  		// Read next point.
  6978  		curr, err := itr.input.NextInWindow(startTime, endTime)
  6979  		if err != nil {
  6980  			return nil, err
  6981  		} else if curr == nil {
  6982  			break
  6983  		} else if curr.Nil {
  6984  			continue
  6985  		} else if curr.Name != window.name {
  6986  			itr.input.unread(curr)
  6987  			break
  6988  		}
  6989  
  6990  		// Ensure this point is within the same final window.
  6991  		if curr.Name != window.name {
  6992  			itr.input.unread(curr)
  6993  			break
  6994  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  6995  			itr.input.unread(curr)
  6996  			break
  6997  		}
  6998  
  6999  		// Retrieve the tags on this point for this level of the query.
  7000  		// This may be different than the bucket dimensions.
  7001  		tags := curr.Tags.Subset(itr.dims)
  7002  		id := tags.ID()
  7003  
  7004  		// Retrieve the aggregator for this name/tag combination or create one.
  7005  		rp := m[id]
  7006  		if rp == nil {
  7007  			aggregator, emitter := itr.create()
  7008  			rp = &unsignedReduceUnsignedPoint{
  7009  				Name:       curr.Name,
  7010  				Tags:       tags,
  7011  				Aggregator: aggregator,
  7012  				Emitter:    emitter,
  7013  			}
  7014  			m[id] = rp
  7015  		}
  7016  		rp.Aggregator.AggregateUnsigned(curr)
  7017  	}
  7018  
  7019  	keys := make([]string, 0, len(m))
  7020  	for k := range m {
  7021  		keys = append(keys, k)
  7022  	}
  7023  
  7024  	// Reverse sort points by name & tag.
  7025  	// This ensures a consistent order of output.
  7026  	if len(keys) > 0 {
  7027  		var sorted sort.Interface = sort.StringSlice(keys)
  7028  		if itr.opt.Ascending {
  7029  			sorted = sort.Reverse(sorted)
  7030  		}
  7031  		sort.Sort(sorted)
  7032  	}
  7033  
  7034  	// Assume the points are already sorted until proven otherwise.
  7035  	sortedByTime := true
  7036  	// Emit the points for each name & tag combination.
  7037  	a := make([]UnsignedPoint, 0, len(m))
  7038  	for _, k := range keys {
  7039  		rp := m[k]
  7040  		points := rp.Emitter.Emit()
  7041  		for i := len(points) - 1; i >= 0; i-- {
  7042  			points[i].Name = rp.Name
  7043  			if !itr.keepTags {
  7044  				points[i].Tags = rp.Tags
  7045  			}
  7046  			// Set the points time to the interval time if the reducer didn't provide one.
  7047  			if points[i].Time == ZeroTime {
  7048  				points[i].Time = startTime
  7049  			} else {
  7050  				sortedByTime = false
  7051  			}
  7052  			a = append(a, points[i])
  7053  		}
  7054  	}
  7055  	// Points may be out of order. Perform a stable sort by time if requested.
  7056  	if !sortedByTime && itr.opt.Ordered {
  7057  		var sorted sort.Interface = unsignedPointsByTime(a)
  7058  		if itr.opt.Ascending {
  7059  			sorted = sort.Reverse(sorted)
  7060  		}
  7061  		sort.Stable(sorted)
  7062  	}
  7063  	return a, nil
  7064  }
  7065  
  7066  // unsignedStreamUnsignedIterator streams inputs into the iterator and emits points gradually.
  7067  type unsignedStreamUnsignedIterator struct {
  7068  	input  *bufUnsignedIterator
  7069  	create func() (UnsignedPointAggregator, UnsignedPointEmitter)
  7070  	dims   []string
  7071  	opt    IteratorOptions
  7072  	m      map[string]*unsignedReduceUnsignedPoint
  7073  	points []UnsignedPoint
  7074  }
  7075  
  7076  // newUnsignedStreamUnsignedIterator returns a new instance of unsignedStreamUnsignedIterator.
  7077  func newUnsignedStreamUnsignedIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *unsignedStreamUnsignedIterator {
  7078  	return &unsignedStreamUnsignedIterator{
  7079  		input:  newBufUnsignedIterator(input),
  7080  		create: createFn,
  7081  		dims:   opt.GetDimensions(),
  7082  		opt:    opt,
  7083  		m:      make(map[string]*unsignedReduceUnsignedPoint),
  7084  	}
  7085  }
  7086  
  7087  // Stats returns stats from the input iterator.
  7088  func (itr *unsignedStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
  7089  
  7090  // Close closes the iterator and all child iterators.
  7091  func (itr *unsignedStreamUnsignedIterator) Close() error { return itr.input.Close() }
  7092  
  7093  // Next returns the next value for the stream iterator.
  7094  func (itr *unsignedStreamUnsignedIterator) Next() (*UnsignedPoint, error) {
  7095  	// Calculate next window if we have no more points.
  7096  	if len(itr.points) == 0 {
  7097  		var err error
  7098  		itr.points, err = itr.reduce()
  7099  		if len(itr.points) == 0 {
  7100  			return nil, err
  7101  		}
  7102  	}
  7103  
  7104  	// Pop next point off the stack.
  7105  	p := &itr.points[len(itr.points)-1]
  7106  	itr.points = itr.points[:len(itr.points)-1]
  7107  	return p, nil
  7108  }
  7109  
  7110  // reduce creates and manages aggregators for every point from the input.
  7111  // After aggregating a point, it always tries to emit a value using the emitter.
  7112  func (itr *unsignedStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) {
  7113  	// We have already read all of the input points.
  7114  	if itr.m == nil {
  7115  		return nil, nil
  7116  	}
  7117  
  7118  	for {
  7119  		// Read next point.
  7120  		curr, err := itr.input.Next()
  7121  		if err != nil {
  7122  			return nil, err
  7123  		} else if curr == nil {
  7124  			// Close all of the aggregators to flush any remaining points to emit.
  7125  			var points []UnsignedPoint
  7126  			for _, rp := range itr.m {
  7127  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  7128  					if err := aggregator.Close(); err != nil {
  7129  						return nil, err
  7130  					}
  7131  
  7132  					pts := rp.Emitter.Emit()
  7133  					if len(pts) == 0 {
  7134  						continue
  7135  					}
  7136  
  7137  					for i := range pts {
  7138  						pts[i].Name = rp.Name
  7139  						pts[i].Tags = rp.Tags
  7140  					}
  7141  					points = append(points, pts...)
  7142  				}
  7143  			}
  7144  
  7145  			// Eliminate the aggregators and emitters.
  7146  			itr.m = nil
  7147  			return points, nil
  7148  		} else if curr.Nil {
  7149  			continue
  7150  		}
  7151  		tags := curr.Tags.Subset(itr.dims)
  7152  
  7153  		id := curr.Name
  7154  		if len(tags.m) > 0 {
  7155  			id += "\x00" + tags.ID()
  7156  		}
  7157  
  7158  		// Retrieve the aggregator for this name/tag combination or create one.
  7159  		rp := itr.m[id]
  7160  		if rp == nil {
  7161  			aggregator, emitter := itr.create()
  7162  			rp = &unsignedReduceUnsignedPoint{
  7163  				Name:       curr.Name,
  7164  				Tags:       tags,
  7165  				Aggregator: aggregator,
  7166  				Emitter:    emitter,
  7167  			}
  7168  			itr.m[id] = rp
  7169  		}
  7170  		rp.Aggregator.AggregateUnsigned(curr)
  7171  
  7172  		// Attempt to emit points from the aggregator.
  7173  		points := rp.Emitter.Emit()
  7174  		if len(points) == 0 {
  7175  			continue
  7176  		}
  7177  
  7178  		for i := range points {
  7179  			points[i].Name = rp.Name
  7180  			points[i].Tags = rp.Tags
  7181  		}
  7182  		return points, nil
  7183  	}
  7184  }
  7185  
  7186  // unsignedReduceStringIterator executes a reducer for every interval and buffers the result.
  7187  type unsignedReduceStringIterator struct {
  7188  	input    *bufUnsignedIterator
  7189  	create   func() (UnsignedPointAggregator, StringPointEmitter)
  7190  	dims     []string
  7191  	opt      IteratorOptions
  7192  	points   []StringPoint
  7193  	keepTags bool
  7194  }
  7195  
  7196  func newUnsignedReduceStringIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, StringPointEmitter)) *unsignedReduceStringIterator {
  7197  	return &unsignedReduceStringIterator{
  7198  		input:  newBufUnsignedIterator(input),
  7199  		create: createFn,
  7200  		dims:   opt.GetDimensions(),
  7201  		opt:    opt,
  7202  	}
  7203  }
  7204  
  7205  // Stats returns stats from the input iterator.
  7206  func (itr *unsignedReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() }
  7207  
  7208  // Close closes the iterator and all child iterators.
  7209  func (itr *unsignedReduceStringIterator) Close() error { return itr.input.Close() }
  7210  
  7211  // Next returns the minimum value for the next available interval.
  7212  func (itr *unsignedReduceStringIterator) Next() (*StringPoint, error) {
  7213  	// Calculate next window if we have no more points.
  7214  	if len(itr.points) == 0 {
  7215  		var err error
  7216  		itr.points, err = itr.reduce()
  7217  		if len(itr.points) == 0 {
  7218  			return nil, err
  7219  		}
  7220  	}
  7221  
  7222  	// Pop next point off the stack.
  7223  	p := &itr.points[len(itr.points)-1]
  7224  	itr.points = itr.points[:len(itr.points)-1]
  7225  	return p, nil
  7226  }
  7227  
  7228  // unsignedReduceStringPoint stores the reduced data for a name/tag combination.
  7229  type unsignedReduceStringPoint struct {
  7230  	Name       string
  7231  	Tags       Tags
  7232  	Aggregator UnsignedPointAggregator
  7233  	Emitter    StringPointEmitter
  7234  }
  7235  
  7236  // reduce executes fn once for every point in the next window.
  7237  // The previous value for the dimension is passed to fn.
  7238  func (itr *unsignedReduceStringIterator) reduce() ([]StringPoint, error) {
  7239  	// Calculate next window.
  7240  	var (
  7241  		startTime, endTime int64
  7242  		window             struct {
  7243  			name string
  7244  			tags string
  7245  		}
  7246  	)
  7247  	for {
  7248  		p, err := itr.input.Next()
  7249  		if err != nil || p == nil {
  7250  			return nil, err
  7251  		} else if p.Nil {
  7252  			continue
  7253  		}
  7254  
  7255  		// Unread the point so it can be processed.
  7256  		itr.input.unread(p)
  7257  		startTime, endTime = itr.opt.Window(p.Time)
  7258  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  7259  		break
  7260  	}
  7261  
  7262  	// Create points by tags.
  7263  	m := make(map[string]*unsignedReduceStringPoint)
  7264  	for {
  7265  		// Read next point.
  7266  		curr, err := itr.input.NextInWindow(startTime, endTime)
  7267  		if err != nil {
  7268  			return nil, err
  7269  		} else if curr == nil {
  7270  			break
  7271  		} else if curr.Nil {
  7272  			continue
  7273  		} else if curr.Name != window.name {
  7274  			itr.input.unread(curr)
  7275  			break
  7276  		}
  7277  
  7278  		// Ensure this point is within the same final window.
  7279  		if curr.Name != window.name {
  7280  			itr.input.unread(curr)
  7281  			break
  7282  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  7283  			itr.input.unread(curr)
  7284  			break
  7285  		}
  7286  
  7287  		// Retrieve the tags on this point for this level of the query.
  7288  		// This may be different than the bucket dimensions.
  7289  		tags := curr.Tags.Subset(itr.dims)
  7290  		id := tags.ID()
  7291  
  7292  		// Retrieve the aggregator for this name/tag combination or create one.
  7293  		rp := m[id]
  7294  		if rp == nil {
  7295  			aggregator, emitter := itr.create()
  7296  			rp = &unsignedReduceStringPoint{
  7297  				Name:       curr.Name,
  7298  				Tags:       tags,
  7299  				Aggregator: aggregator,
  7300  				Emitter:    emitter,
  7301  			}
  7302  			m[id] = rp
  7303  		}
  7304  		rp.Aggregator.AggregateUnsigned(curr)
  7305  	}
  7306  
  7307  	keys := make([]string, 0, len(m))
  7308  	for k := range m {
  7309  		keys = append(keys, k)
  7310  	}
  7311  
  7312  	// Reverse sort points by name & tag.
  7313  	// This ensures a consistent order of output.
  7314  	if len(keys) > 0 {
  7315  		var sorted sort.Interface = sort.StringSlice(keys)
  7316  		if itr.opt.Ascending {
  7317  			sorted = sort.Reverse(sorted)
  7318  		}
  7319  		sort.Sort(sorted)
  7320  	}
  7321  
  7322  	// Assume the points are already sorted until proven otherwise.
  7323  	sortedByTime := true
  7324  	// Emit the points for each name & tag combination.
  7325  	a := make([]StringPoint, 0, len(m))
  7326  	for _, k := range keys {
  7327  		rp := m[k]
  7328  		points := rp.Emitter.Emit()
  7329  		for i := len(points) - 1; i >= 0; i-- {
  7330  			points[i].Name = rp.Name
  7331  			if !itr.keepTags {
  7332  				points[i].Tags = rp.Tags
  7333  			}
  7334  			// Set the points time to the interval time if the reducer didn't provide one.
  7335  			if points[i].Time == ZeroTime {
  7336  				points[i].Time = startTime
  7337  			} else {
  7338  				sortedByTime = false
  7339  			}
  7340  			a = append(a, points[i])
  7341  		}
  7342  	}
  7343  	// Points may be out of order. Perform a stable sort by time if requested.
  7344  	if !sortedByTime && itr.opt.Ordered {
  7345  		var sorted sort.Interface = stringPointsByTime(a)
  7346  		if itr.opt.Ascending {
  7347  			sorted = sort.Reverse(sorted)
  7348  		}
  7349  		sort.Stable(sorted)
  7350  	}
  7351  	return a, nil
  7352  }
  7353  
  7354  // unsignedStreamStringIterator streams inputs into the iterator and emits points gradually.
  7355  type unsignedStreamStringIterator struct {
  7356  	input  *bufUnsignedIterator
  7357  	create func() (UnsignedPointAggregator, StringPointEmitter)
  7358  	dims   []string
  7359  	opt    IteratorOptions
  7360  	m      map[string]*unsignedReduceStringPoint
  7361  	points []StringPoint
  7362  }
  7363  
  7364  // newUnsignedStreamStringIterator returns a new instance of unsignedStreamStringIterator.
  7365  func newUnsignedStreamStringIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, StringPointEmitter), opt IteratorOptions) *unsignedStreamStringIterator {
  7366  	return &unsignedStreamStringIterator{
  7367  		input:  newBufUnsignedIterator(input),
  7368  		create: createFn,
  7369  		dims:   opt.GetDimensions(),
  7370  		opt:    opt,
  7371  		m:      make(map[string]*unsignedReduceStringPoint),
  7372  	}
  7373  }
  7374  
  7375  // Stats returns stats from the input iterator.
  7376  func (itr *unsignedStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() }
  7377  
  7378  // Close closes the iterator and all child iterators.
  7379  func (itr *unsignedStreamStringIterator) Close() error { return itr.input.Close() }
  7380  
  7381  // Next returns the next value for the stream iterator.
  7382  func (itr *unsignedStreamStringIterator) Next() (*StringPoint, error) {
  7383  	// Calculate next window if we have no more points.
  7384  	if len(itr.points) == 0 {
  7385  		var err error
  7386  		itr.points, err = itr.reduce()
  7387  		if len(itr.points) == 0 {
  7388  			return nil, err
  7389  		}
  7390  	}
  7391  
  7392  	// Pop next point off the stack.
  7393  	p := &itr.points[len(itr.points)-1]
  7394  	itr.points = itr.points[:len(itr.points)-1]
  7395  	return p, nil
  7396  }
  7397  
  7398  // reduce creates and manages aggregators for every point from the input.
  7399  // After aggregating a point, it always tries to emit a value using the emitter.
  7400  func (itr *unsignedStreamStringIterator) reduce() ([]StringPoint, error) {
  7401  	// We have already read all of the input points.
  7402  	if itr.m == nil {
  7403  		return nil, nil
  7404  	}
  7405  
  7406  	for {
  7407  		// Read next point.
  7408  		curr, err := itr.input.Next()
  7409  		if err != nil {
  7410  			return nil, err
  7411  		} else if curr == nil {
  7412  			// Close all of the aggregators to flush any remaining points to emit.
  7413  			var points []StringPoint
  7414  			for _, rp := range itr.m {
  7415  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  7416  					if err := aggregator.Close(); err != nil {
  7417  						return nil, err
  7418  					}
  7419  
  7420  					pts := rp.Emitter.Emit()
  7421  					if len(pts) == 0 {
  7422  						continue
  7423  					}
  7424  
  7425  					for i := range pts {
  7426  						pts[i].Name = rp.Name
  7427  						pts[i].Tags = rp.Tags
  7428  					}
  7429  					points = append(points, pts...)
  7430  				}
  7431  			}
  7432  
  7433  			// Eliminate the aggregators and emitters.
  7434  			itr.m = nil
  7435  			return points, nil
  7436  		} else if curr.Nil {
  7437  			continue
  7438  		}
  7439  		tags := curr.Tags.Subset(itr.dims)
  7440  
  7441  		id := curr.Name
  7442  		if len(tags.m) > 0 {
  7443  			id += "\x00" + tags.ID()
  7444  		}
  7445  
  7446  		// Retrieve the aggregator for this name/tag combination or create one.
  7447  		rp := itr.m[id]
  7448  		if rp == nil {
  7449  			aggregator, emitter := itr.create()
  7450  			rp = &unsignedReduceStringPoint{
  7451  				Name:       curr.Name,
  7452  				Tags:       tags,
  7453  				Aggregator: aggregator,
  7454  				Emitter:    emitter,
  7455  			}
  7456  			itr.m[id] = rp
  7457  		}
  7458  		rp.Aggregator.AggregateUnsigned(curr)
  7459  
  7460  		// Attempt to emit points from the aggregator.
  7461  		points := rp.Emitter.Emit()
  7462  		if len(points) == 0 {
  7463  			continue
  7464  		}
  7465  
  7466  		for i := range points {
  7467  			points[i].Name = rp.Name
  7468  			points[i].Tags = rp.Tags
  7469  		}
  7470  		return points, nil
  7471  	}
  7472  }
  7473  
  7474  // unsignedReduceBooleanIterator executes a reducer for every interval and buffers the result.
  7475  type unsignedReduceBooleanIterator struct {
  7476  	input    *bufUnsignedIterator
  7477  	create   func() (UnsignedPointAggregator, BooleanPointEmitter)
  7478  	dims     []string
  7479  	opt      IteratorOptions
  7480  	points   []BooleanPoint
  7481  	keepTags bool
  7482  }
  7483  
  7484  func newUnsignedReduceBooleanIterator(input UnsignedIterator, opt IteratorOptions, createFn func() (UnsignedPointAggregator, BooleanPointEmitter)) *unsignedReduceBooleanIterator {
  7485  	return &unsignedReduceBooleanIterator{
  7486  		input:  newBufUnsignedIterator(input),
  7487  		create: createFn,
  7488  		dims:   opt.GetDimensions(),
  7489  		opt:    opt,
  7490  	}
  7491  }
  7492  
  7493  // Stats returns stats from the input iterator.
  7494  func (itr *unsignedReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
  7495  
  7496  // Close closes the iterator and all child iterators.
  7497  func (itr *unsignedReduceBooleanIterator) Close() error { return itr.input.Close() }
  7498  
  7499  // Next returns the minimum value for the next available interval.
  7500  func (itr *unsignedReduceBooleanIterator) Next() (*BooleanPoint, error) {
  7501  	// Calculate next window if we have no more points.
  7502  	if len(itr.points) == 0 {
  7503  		var err error
  7504  		itr.points, err = itr.reduce()
  7505  		if len(itr.points) == 0 {
  7506  			return nil, err
  7507  		}
  7508  	}
  7509  
  7510  	// Pop next point off the stack.
  7511  	p := &itr.points[len(itr.points)-1]
  7512  	itr.points = itr.points[:len(itr.points)-1]
  7513  	return p, nil
  7514  }
  7515  
  7516  // unsignedReduceBooleanPoint stores the reduced data for a name/tag combination.
  7517  type unsignedReduceBooleanPoint struct {
  7518  	Name       string
  7519  	Tags       Tags
  7520  	Aggregator UnsignedPointAggregator
  7521  	Emitter    BooleanPointEmitter
  7522  }
  7523  
  7524  // reduce executes fn once for every point in the next window.
  7525  // The previous value for the dimension is passed to fn.
  7526  func (itr *unsignedReduceBooleanIterator) reduce() ([]BooleanPoint, error) {
  7527  	// Calculate next window.
  7528  	var (
  7529  		startTime, endTime int64
  7530  		window             struct {
  7531  			name string
  7532  			tags string
  7533  		}
  7534  	)
  7535  	for {
  7536  		p, err := itr.input.Next()
  7537  		if err != nil || p == nil {
  7538  			return nil, err
  7539  		} else if p.Nil {
  7540  			continue
  7541  		}
  7542  
  7543  		// Unread the point so it can be processed.
  7544  		itr.input.unread(p)
  7545  		startTime, endTime = itr.opt.Window(p.Time)
  7546  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  7547  		break
  7548  	}
  7549  
  7550  	// Create points by tags.
  7551  	m := make(map[string]*unsignedReduceBooleanPoint)
  7552  	for {
  7553  		// Read next point.
  7554  		curr, err := itr.input.NextInWindow(startTime, endTime)
  7555  		if err != nil {
  7556  			return nil, err
  7557  		} else if curr == nil {
  7558  			break
  7559  		} else if curr.Nil {
  7560  			continue
  7561  		} else if curr.Name != window.name {
  7562  			itr.input.unread(curr)
  7563  			break
  7564  		}
  7565  
  7566  		// Ensure this point is within the same final window.
  7567  		if curr.Name != window.name {
  7568  			itr.input.unread(curr)
  7569  			break
  7570  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  7571  			itr.input.unread(curr)
  7572  			break
  7573  		}
  7574  
  7575  		// Retrieve the tags on this point for this level of the query.
  7576  		// This may be different than the bucket dimensions.
  7577  		tags := curr.Tags.Subset(itr.dims)
  7578  		id := tags.ID()
  7579  
  7580  		// Retrieve the aggregator for this name/tag combination or create one.
  7581  		rp := m[id]
  7582  		if rp == nil {
  7583  			aggregator, emitter := itr.create()
  7584  			rp = &unsignedReduceBooleanPoint{
  7585  				Name:       curr.Name,
  7586  				Tags:       tags,
  7587  				Aggregator: aggregator,
  7588  				Emitter:    emitter,
  7589  			}
  7590  			m[id] = rp
  7591  		}
  7592  		rp.Aggregator.AggregateUnsigned(curr)
  7593  	}
  7594  
  7595  	keys := make([]string, 0, len(m))
  7596  	for k := range m {
  7597  		keys = append(keys, k)
  7598  	}
  7599  
  7600  	// Reverse sort points by name & tag.
  7601  	// This ensures a consistent order of output.
  7602  	if len(keys) > 0 {
  7603  		var sorted sort.Interface = sort.StringSlice(keys)
  7604  		if itr.opt.Ascending {
  7605  			sorted = sort.Reverse(sorted)
  7606  		}
  7607  		sort.Sort(sorted)
  7608  	}
  7609  
  7610  	// Assume the points are already sorted until proven otherwise.
  7611  	sortedByTime := true
  7612  	// Emit the points for each name & tag combination.
  7613  	a := make([]BooleanPoint, 0, len(m))
  7614  	for _, k := range keys {
  7615  		rp := m[k]
  7616  		points := rp.Emitter.Emit()
  7617  		for i := len(points) - 1; i >= 0; i-- {
  7618  			points[i].Name = rp.Name
  7619  			if !itr.keepTags {
  7620  				points[i].Tags = rp.Tags
  7621  			}
  7622  			// Set the points time to the interval time if the reducer didn't provide one.
  7623  			if points[i].Time == ZeroTime {
  7624  				points[i].Time = startTime
  7625  			} else {
  7626  				sortedByTime = false
  7627  			}
  7628  			a = append(a, points[i])
  7629  		}
  7630  	}
  7631  	// Points may be out of order. Perform a stable sort by time if requested.
  7632  	if !sortedByTime && itr.opt.Ordered {
  7633  		var sorted sort.Interface = booleanPointsByTime(a)
  7634  		if itr.opt.Ascending {
  7635  			sorted = sort.Reverse(sorted)
  7636  		}
  7637  		sort.Stable(sorted)
  7638  	}
  7639  	return a, nil
  7640  }
  7641  
  7642  // unsignedStreamBooleanIterator streams inputs into the iterator and emits points gradually.
  7643  type unsignedStreamBooleanIterator struct {
  7644  	input  *bufUnsignedIterator
  7645  	create func() (UnsignedPointAggregator, BooleanPointEmitter)
  7646  	dims   []string
  7647  	opt    IteratorOptions
  7648  	m      map[string]*unsignedReduceBooleanPoint
  7649  	points []BooleanPoint
  7650  }
  7651  
  7652  // newUnsignedStreamBooleanIterator returns a new instance of unsignedStreamBooleanIterator.
  7653  func newUnsignedStreamBooleanIterator(input UnsignedIterator, createFn func() (UnsignedPointAggregator, BooleanPointEmitter), opt IteratorOptions) *unsignedStreamBooleanIterator {
  7654  	return &unsignedStreamBooleanIterator{
  7655  		input:  newBufUnsignedIterator(input),
  7656  		create: createFn,
  7657  		dims:   opt.GetDimensions(),
  7658  		opt:    opt,
  7659  		m:      make(map[string]*unsignedReduceBooleanPoint),
  7660  	}
  7661  }
  7662  
  7663  // Stats returns stats from the input iterator.
  7664  func (itr *unsignedStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
  7665  
  7666  // Close closes the iterator and all child iterators.
  7667  func (itr *unsignedStreamBooleanIterator) Close() error { return itr.input.Close() }
  7668  
  7669  // Next returns the next value for the stream iterator.
  7670  func (itr *unsignedStreamBooleanIterator) Next() (*BooleanPoint, error) {
  7671  	// Calculate next window if we have no more points.
  7672  	if len(itr.points) == 0 {
  7673  		var err error
  7674  		itr.points, err = itr.reduce()
  7675  		if len(itr.points) == 0 {
  7676  			return nil, err
  7677  		}
  7678  	}
  7679  
  7680  	// Pop next point off the stack.
  7681  	p := &itr.points[len(itr.points)-1]
  7682  	itr.points = itr.points[:len(itr.points)-1]
  7683  	return p, nil
  7684  }
  7685  
  7686  // reduce creates and manages aggregators for every point from the input.
  7687  // After aggregating a point, it always tries to emit a value using the emitter.
  7688  func (itr *unsignedStreamBooleanIterator) reduce() ([]BooleanPoint, error) {
  7689  	// We have already read all of the input points.
  7690  	if itr.m == nil {
  7691  		return nil, nil
  7692  	}
  7693  
  7694  	for {
  7695  		// Read next point.
  7696  		curr, err := itr.input.Next()
  7697  		if err != nil {
  7698  			return nil, err
  7699  		} else if curr == nil {
  7700  			// Close all of the aggregators to flush any remaining points to emit.
  7701  			var points []BooleanPoint
  7702  			for _, rp := range itr.m {
  7703  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  7704  					if err := aggregator.Close(); err != nil {
  7705  						return nil, err
  7706  					}
  7707  
  7708  					pts := rp.Emitter.Emit()
  7709  					if len(pts) == 0 {
  7710  						continue
  7711  					}
  7712  
  7713  					for i := range pts {
  7714  						pts[i].Name = rp.Name
  7715  						pts[i].Tags = rp.Tags
  7716  					}
  7717  					points = append(points, pts...)
  7718  				}
  7719  			}
  7720  
  7721  			// Eliminate the aggregators and emitters.
  7722  			itr.m = nil
  7723  			return points, nil
  7724  		} else if curr.Nil {
  7725  			continue
  7726  		}
  7727  		tags := curr.Tags.Subset(itr.dims)
  7728  
  7729  		id := curr.Name
  7730  		if len(tags.m) > 0 {
  7731  			id += "\x00" + tags.ID()
  7732  		}
  7733  
  7734  		// Retrieve the aggregator for this name/tag combination or create one.
  7735  		rp := itr.m[id]
  7736  		if rp == nil {
  7737  			aggregator, emitter := itr.create()
  7738  			rp = &unsignedReduceBooleanPoint{
  7739  				Name:       curr.Name,
  7740  				Tags:       tags,
  7741  				Aggregator: aggregator,
  7742  				Emitter:    emitter,
  7743  			}
  7744  			itr.m[id] = rp
  7745  		}
  7746  		rp.Aggregator.AggregateUnsigned(curr)
  7747  
  7748  		// Attempt to emit points from the aggregator.
  7749  		points := rp.Emitter.Emit()
  7750  		if len(points) == 0 {
  7751  			continue
  7752  		}
  7753  
  7754  		for i := range points {
  7755  			points[i].Name = rp.Name
  7756  			points[i].Tags = rp.Tags
  7757  		}
  7758  		return points, nil
  7759  	}
  7760  }
  7761  
  7762  // unsignedDedupeIterator only outputs unique points.
  7763  // This differs from the DistinctIterator in that it compares all aux fields too.
  7764  // This iterator is relatively inefficient and should only be used on small
  7765  // datasets such as meta query results.
  7766  type unsignedDedupeIterator struct {
  7767  	input UnsignedIterator
  7768  	m     map[string]struct{} // lookup of points already sent
  7769  }
  7770  
  7771  type unsignedIteratorMapper struct {
  7772  	cur    Cursor
  7773  	row    Row
  7774  	driver IteratorMap   // which iterator to use for the primary value, can be nil
  7775  	fields []IteratorMap // which iterator to use for an aux field
  7776  	point  UnsignedPoint
  7777  }
  7778  
  7779  func newUnsignedIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *unsignedIteratorMapper {
  7780  	return &unsignedIteratorMapper{
  7781  		cur:    cur,
  7782  		driver: driver,
  7783  		fields: fields,
  7784  		point: UnsignedPoint{
  7785  			Aux: make([]interface{}, len(fields)),
  7786  		},
  7787  	}
  7788  }
  7789  
  7790  func (itr *unsignedIteratorMapper) Next() (*UnsignedPoint, error) {
  7791  	if !itr.cur.Scan(&itr.row) {
  7792  		if err := itr.cur.Err(); err != nil {
  7793  			return nil, err
  7794  		}
  7795  		return nil, nil
  7796  	}
  7797  
  7798  	itr.point.Time = itr.row.Time
  7799  	itr.point.Name = itr.row.Series.Name
  7800  	itr.point.Tags = itr.row.Series.Tags
  7801  
  7802  	if itr.driver != nil {
  7803  		if v := itr.driver.Value(&itr.row); v != nil {
  7804  			if v, ok := castToUnsigned(v); ok {
  7805  				itr.point.Value = v
  7806  				itr.point.Nil = false
  7807  			} else {
  7808  				itr.point.Value = 0
  7809  				itr.point.Nil = true
  7810  			}
  7811  		} else {
  7812  			itr.point.Value = 0
  7813  			itr.point.Nil = true
  7814  		}
  7815  	}
  7816  	for i, f := range itr.fields {
  7817  		itr.point.Aux[i] = f.Value(&itr.row)
  7818  	}
  7819  	return &itr.point, nil
  7820  }
  7821  
  7822  func (itr *unsignedIteratorMapper) Stats() IteratorStats {
  7823  	return itr.cur.Stats()
  7824  }
  7825  
  7826  func (itr *unsignedIteratorMapper) Close() error {
  7827  	return itr.cur.Close()
  7828  }
  7829  
  7830  type unsignedFilterIterator struct {
  7831  	input UnsignedIterator
  7832  	cond  influxql.Expr
  7833  	opt   IteratorOptions
  7834  	m     map[string]interface{}
  7835  }
  7836  
  7837  func newUnsignedFilterIterator(input UnsignedIterator, cond influxql.Expr, opt IteratorOptions) UnsignedIterator {
  7838  	// Strip out time conditions from the WHERE clause.
  7839  	// TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct.
  7840  	n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node {
  7841  		switch n := n.(type) {
  7842  		case *influxql.BinaryExpr:
  7843  			if n.LHS.String() == "time" {
  7844  				return &influxql.BooleanLiteral{Val: true}
  7845  			}
  7846  		}
  7847  		return n
  7848  	})
  7849  
  7850  	cond, _ = n.(influxql.Expr)
  7851  	if cond == nil {
  7852  		return input
  7853  	} else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val {
  7854  		return input
  7855  	}
  7856  
  7857  	return &unsignedFilterIterator{
  7858  		input: input,
  7859  		cond:  cond,
  7860  		opt:   opt,
  7861  		m:     make(map[string]interface{}),
  7862  	}
  7863  }
  7864  
  7865  func (itr *unsignedFilterIterator) Stats() IteratorStats { return itr.input.Stats() }
  7866  func (itr *unsignedFilterIterator) Close() error         { return itr.input.Close() }
  7867  
  7868  func (itr *unsignedFilterIterator) Next() (*UnsignedPoint, error) {
  7869  	for {
  7870  		p, err := itr.input.Next()
  7871  		if err != nil || p == nil {
  7872  			return nil, err
  7873  		}
  7874  
  7875  		for i, ref := range itr.opt.Aux {
  7876  			itr.m[ref.Val] = p.Aux[i]
  7877  		}
  7878  		for k, v := range p.Tags.KeyValues() {
  7879  			itr.m[k] = v
  7880  		}
  7881  
  7882  		if !influxql.EvalBool(itr.cond, itr.m) {
  7883  			continue
  7884  		}
  7885  		return p, nil
  7886  	}
  7887  }
  7888  
  7889  type unsignedTagSubsetIterator struct {
  7890  	input      UnsignedIterator
  7891  	point      UnsignedPoint
  7892  	lastTags   Tags
  7893  	dimensions []string
  7894  }
  7895  
  7896  func newUnsignedTagSubsetIterator(input UnsignedIterator, opt IteratorOptions) *unsignedTagSubsetIterator {
  7897  	return &unsignedTagSubsetIterator{
  7898  		input:      input,
  7899  		dimensions: opt.GetDimensions(),
  7900  	}
  7901  }
  7902  
  7903  func (itr *unsignedTagSubsetIterator) Next() (*UnsignedPoint, error) {
  7904  	p, err := itr.input.Next()
  7905  	if err != nil {
  7906  		return nil, err
  7907  	} else if p == nil {
  7908  		return nil, nil
  7909  	}
  7910  
  7911  	itr.point.Name = p.Name
  7912  	if !p.Tags.Equal(itr.lastTags) {
  7913  		itr.point.Tags = p.Tags.Subset(itr.dimensions)
  7914  		itr.lastTags = p.Tags
  7915  	}
  7916  	itr.point.Time = p.Time
  7917  	itr.point.Value = p.Value
  7918  	itr.point.Aux = p.Aux
  7919  	itr.point.Aggregated = p.Aggregated
  7920  	itr.point.Nil = p.Nil
  7921  	return &itr.point, nil
  7922  }
  7923  
  7924  func (itr *unsignedTagSubsetIterator) Stats() IteratorStats {
  7925  	return itr.input.Stats()
  7926  }
  7927  
  7928  func (itr *unsignedTagSubsetIterator) Close() error {
  7929  	return itr.input.Close()
  7930  }
  7931  
  7932  // newUnsignedDedupeIterator returns a new instance of unsignedDedupeIterator.
  7933  func newUnsignedDedupeIterator(input UnsignedIterator) *unsignedDedupeIterator {
  7934  	return &unsignedDedupeIterator{
  7935  		input: input,
  7936  		m:     make(map[string]struct{}),
  7937  	}
  7938  }
  7939  
  7940  // Stats returns stats from the input iterator.
  7941  func (itr *unsignedDedupeIterator) Stats() IteratorStats { return itr.input.Stats() }
  7942  
  7943  // Close closes the iterator and all child iterators.
  7944  func (itr *unsignedDedupeIterator) Close() error { return itr.input.Close() }
  7945  
  7946  // Next returns the next unique point from the input iterator.
  7947  func (itr *unsignedDedupeIterator) Next() (*UnsignedPoint, error) {
  7948  	for {
  7949  		// Read next point.
  7950  		p, err := itr.input.Next()
  7951  		if p == nil || err != nil {
  7952  			return nil, err
  7953  		}
  7954  
  7955  		// Serialize to bytes to store in lookup.
  7956  		buf, err := proto.Marshal(encodeUnsignedPoint(p))
  7957  		if err != nil {
  7958  			return nil, err
  7959  		}
  7960  
  7961  		// If the point has already been output then move to the next point.
  7962  		if _, ok := itr.m[string(buf)]; ok {
  7963  			continue
  7964  		}
  7965  
  7966  		// Otherwise mark it as emitted and return point.
  7967  		itr.m[string(buf)] = struct{}{}
  7968  		return p, nil
  7969  	}
  7970  }
  7971  
  7972  // unsignedReaderIterator represents an iterator that streams from a reader.
  7973  type unsignedReaderIterator struct {
  7974  	r   io.Reader
  7975  	dec *UnsignedPointDecoder
  7976  }
  7977  
  7978  // newUnsignedReaderIterator returns a new instance of unsignedReaderIterator.
  7979  func newUnsignedReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *unsignedReaderIterator {
  7980  	dec := NewUnsignedPointDecoder(ctx, r)
  7981  	dec.stats = stats
  7982  
  7983  	return &unsignedReaderIterator{
  7984  		r:   r,
  7985  		dec: dec,
  7986  	}
  7987  }
  7988  
  7989  // Stats returns stats about points processed.
  7990  func (itr *unsignedReaderIterator) Stats() IteratorStats { return itr.dec.stats }
  7991  
  7992  // Close closes the underlying reader, if applicable.
  7993  func (itr *unsignedReaderIterator) Close() error {
  7994  	if r, ok := itr.r.(io.ReadCloser); ok {
  7995  		return r.Close()
  7996  	}
  7997  	return nil
  7998  }
  7999  
  8000  // Next returns the next point from the iterator.
  8001  func (itr *unsignedReaderIterator) Next() (*UnsignedPoint, error) {
  8002  	// OPTIMIZE(benbjohnson): Reuse point on iterator.
  8003  
  8004  	// Unmarshal next point.
  8005  	p := &UnsignedPoint{}
  8006  	if err := itr.dec.DecodeUnsignedPoint(p); err == io.EOF {
  8007  		return nil, nil
  8008  	} else if err != nil {
  8009  		return nil, err
  8010  	}
  8011  	return p, nil
  8012  }
  8013  
  8014  // StringIterator represents a stream of string points.
  8015  type StringIterator interface {
  8016  	Iterator
  8017  	Next() (*StringPoint, error)
  8018  }
  8019  
  8020  // newStringIterators converts a slice of Iterator to a slice of StringIterator.
  8021  // Drop and closes any iterator in itrs that is not a StringIterator and cannot
  8022  // be cast to a StringIterator.
  8023  func newStringIterators(itrs []Iterator) []StringIterator {
  8024  	a := make([]StringIterator, 0, len(itrs))
  8025  	for _, itr := range itrs {
  8026  		switch itr := itr.(type) {
  8027  		case StringIterator:
  8028  			a = append(a, itr)
  8029  		default:
  8030  			itr.Close()
  8031  		}
  8032  	}
  8033  	return a
  8034  }
  8035  
  8036  // bufStringIterator represents a buffered StringIterator.
  8037  type bufStringIterator struct {
  8038  	itr StringIterator
  8039  	buf *StringPoint
  8040  }
  8041  
  8042  // newBufStringIterator returns a buffered StringIterator.
  8043  func newBufStringIterator(itr StringIterator) *bufStringIterator {
  8044  	return &bufStringIterator{itr: itr}
  8045  }
  8046  
  8047  // Stats returns statistics from the input iterator.
  8048  func (itr *bufStringIterator) Stats() IteratorStats { return itr.itr.Stats() }
  8049  
  8050  // Close closes the underlying iterator.
  8051  func (itr *bufStringIterator) Close() error { return itr.itr.Close() }
  8052  
  8053  // peek returns the next point without removing it from the iterator.
  8054  func (itr *bufStringIterator) peek() (*StringPoint, error) {
  8055  	p, err := itr.Next()
  8056  	if err != nil {
  8057  		return nil, err
  8058  	}
  8059  	itr.unread(p)
  8060  	return p, nil
  8061  }
  8062  
  8063  // peekTime returns the time of the next point.
  8064  // Returns zero time if no more points available.
  8065  func (itr *bufStringIterator) peekTime() (int64, error) {
  8066  	p, err := itr.peek()
  8067  	if p == nil || err != nil {
  8068  		return ZeroTime, err
  8069  	}
  8070  	return p.Time, nil
  8071  }
  8072  
  8073  // Next returns the current buffer, if exists, or calls the underlying iterator.
  8074  func (itr *bufStringIterator) Next() (*StringPoint, error) {
  8075  	buf := itr.buf
  8076  	if buf != nil {
  8077  		itr.buf = nil
  8078  		return buf, nil
  8079  	}
  8080  	return itr.itr.Next()
  8081  }
  8082  
  8083  // NextInWindow returns the next value if it is between [startTime, endTime).
  8084  // If the next value is outside the range then it is moved to the buffer.
  8085  func (itr *bufStringIterator) NextInWindow(startTime, endTime int64) (*StringPoint, error) {
  8086  	v, err := itr.Next()
  8087  	if v == nil || err != nil {
  8088  		return nil, err
  8089  	} else if t := v.Time; t >= endTime || t < startTime {
  8090  		itr.unread(v)
  8091  		return nil, nil
  8092  	}
  8093  	return v, nil
  8094  }
  8095  
  8096  // unread sets v to the buffer. It is read on the next call to Next().
  8097  func (itr *bufStringIterator) unread(v *StringPoint) { itr.buf = v }
  8098  
  8099  // stringMergeIterator represents an iterator that combines multiple string iterators.
  8100  type stringMergeIterator struct {
  8101  	inputs []StringIterator
  8102  	heap   *stringMergeHeap
  8103  	init   bool
  8104  
  8105  	closed bool
  8106  	mu     sync.RWMutex
  8107  
  8108  	// Current iterator and window.
  8109  	curr   *stringMergeHeapItem
  8110  	window struct {
  8111  		name      string
  8112  		tags      string
  8113  		startTime int64
  8114  		endTime   int64
  8115  	}
  8116  }
  8117  
  8118  // newStringMergeIterator returns a new instance of stringMergeIterator.
  8119  func newStringMergeIterator(inputs []StringIterator, opt IteratorOptions) *stringMergeIterator {
  8120  	itr := &stringMergeIterator{
  8121  		inputs: inputs,
  8122  		heap: &stringMergeHeap{
  8123  			items: make([]*stringMergeHeapItem, 0, len(inputs)),
  8124  			opt:   opt,
  8125  		},
  8126  	}
  8127  
  8128  	// Initialize heap items.
  8129  	for _, input := range inputs {
  8130  		// Wrap in buffer, ignore any inputs without anymore points.
  8131  		bufInput := newBufStringIterator(input)
  8132  
  8133  		// Append to the heap.
  8134  		itr.heap.items = append(itr.heap.items, &stringMergeHeapItem{itr: bufInput})
  8135  	}
  8136  
  8137  	return itr
  8138  }
  8139  
  8140  // Stats returns an aggregation of stats from the underlying iterators.
  8141  func (itr *stringMergeIterator) Stats() IteratorStats {
  8142  	var stats IteratorStats
  8143  	for _, input := range itr.inputs {
  8144  		stats.Add(input.Stats())
  8145  	}
  8146  	return stats
  8147  }
  8148  
  8149  // Close closes the underlying iterators.
  8150  func (itr *stringMergeIterator) Close() error {
  8151  	itr.mu.Lock()
  8152  	defer itr.mu.Unlock()
  8153  
  8154  	for _, input := range itr.inputs {
  8155  		input.Close()
  8156  	}
  8157  	itr.curr = nil
  8158  	itr.inputs = nil
  8159  	itr.heap.items = nil
  8160  	itr.closed = true
  8161  	return nil
  8162  }
  8163  
  8164  // Next returns the next point from the iterator.
  8165  func (itr *stringMergeIterator) Next() (*StringPoint, error) {
  8166  	itr.mu.RLock()
  8167  	defer itr.mu.RUnlock()
  8168  	if itr.closed {
  8169  		return nil, nil
  8170  	}
  8171  
  8172  	// Initialize the heap. This needs to be done lazily on the first call to this iterator
  8173  	// so that iterator initialization done through the Select() call returns quickly.
  8174  	// Queries can only be interrupted after the Select() call completes so any operations
  8175  	// done during iterator creation cannot be interrupted, which is why we do it here
  8176  	// instead so an interrupt can happen while initializing the heap.
  8177  	if !itr.init {
  8178  		items := itr.heap.items
  8179  		itr.heap.items = make([]*stringMergeHeapItem, 0, len(items))
  8180  		for _, item := range items {
  8181  			if p, err := item.itr.peek(); err != nil {
  8182  				return nil, err
  8183  			} else if p == nil {
  8184  				continue
  8185  			}
  8186  			itr.heap.items = append(itr.heap.items, item)
  8187  		}
  8188  		heap.Init(itr.heap)
  8189  		itr.init = true
  8190  	}
  8191  
  8192  	for {
  8193  		// Retrieve the next iterator if we don't have one.
  8194  		if itr.curr == nil {
  8195  			if len(itr.heap.items) == 0 {
  8196  				return nil, nil
  8197  			}
  8198  			itr.curr = heap.Pop(itr.heap).(*stringMergeHeapItem)
  8199  
  8200  			// Read point and set current window.
  8201  			p, err := itr.curr.itr.Next()
  8202  			if err != nil {
  8203  				return nil, err
  8204  			}
  8205  			tags := p.Tags.Subset(itr.heap.opt.Dimensions)
  8206  			itr.window.name, itr.window.tags = p.Name, tags.ID()
  8207  			itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time)
  8208  			return p, nil
  8209  		}
  8210  
  8211  		// Read the next point from the current iterator.
  8212  		p, err := itr.curr.itr.Next()
  8213  		if err != nil {
  8214  			return nil, err
  8215  		}
  8216  
  8217  		// If there are no more points then remove iterator from heap and find next.
  8218  		if p == nil {
  8219  			itr.curr = nil
  8220  			continue
  8221  		}
  8222  
  8223  		// Check if the point is inside of our current window.
  8224  		inWindow := true
  8225  		if window := itr.window; window.name != p.Name {
  8226  			inWindow = false
  8227  		} else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() {
  8228  			inWindow = false
  8229  		} else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime {
  8230  			inWindow = false
  8231  		} else if !opt.Ascending && p.Time < window.startTime {
  8232  			inWindow = false
  8233  		}
  8234  
  8235  		// If it's outside our window then push iterator back on the heap and find new iterator.
  8236  		if !inWindow {
  8237  			itr.curr.itr.unread(p)
  8238  			heap.Push(itr.heap, itr.curr)
  8239  			itr.curr = nil
  8240  			continue
  8241  		}
  8242  
  8243  		return p, nil
  8244  	}
  8245  }
  8246  
  8247  // stringMergeHeap represents a heap of stringMergeHeapItems.
  8248  // Items are sorted by their next window and then by name/tags.
  8249  type stringMergeHeap struct {
  8250  	opt   IteratorOptions
  8251  	items []*stringMergeHeapItem
  8252  }
  8253  
  8254  func (h *stringMergeHeap) Len() int      { return len(h.items) }
  8255  func (h *stringMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
  8256  func (h *stringMergeHeap) Less(i, j int) bool {
  8257  	x, err := h.items[i].itr.peek()
  8258  	if err != nil {
  8259  		return true
  8260  	}
  8261  	y, err := h.items[j].itr.peek()
  8262  	if err != nil {
  8263  		return false
  8264  	}
  8265  
  8266  	if h.opt.Ascending {
  8267  		if x.Name != y.Name {
  8268  			return x.Name < y.Name
  8269  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
  8270  			return xTags.ID() < yTags.ID()
  8271  		}
  8272  	} else {
  8273  		if x.Name != y.Name {
  8274  			return x.Name > y.Name
  8275  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
  8276  			return xTags.ID() > yTags.ID()
  8277  		}
  8278  	}
  8279  
  8280  	xt, _ := h.opt.Window(x.Time)
  8281  	yt, _ := h.opt.Window(y.Time)
  8282  
  8283  	if h.opt.Ascending {
  8284  		return xt < yt
  8285  	}
  8286  	return xt > yt
  8287  }
  8288  
  8289  func (h *stringMergeHeap) Push(x interface{}) {
  8290  	h.items = append(h.items, x.(*stringMergeHeapItem))
  8291  }
  8292  
  8293  func (h *stringMergeHeap) Pop() interface{} {
  8294  	old := h.items
  8295  	n := len(old)
  8296  	item := old[n-1]
  8297  	h.items = old[0 : n-1]
  8298  	return item
  8299  }
  8300  
  8301  type stringMergeHeapItem struct {
  8302  	itr *bufStringIterator
  8303  }
  8304  
  8305  // stringSortedMergeIterator is an iterator that sorts and merges multiple iterators into one.
  8306  type stringSortedMergeIterator struct {
  8307  	inputs []StringIterator
  8308  	heap   *stringSortedMergeHeap
  8309  	init   bool
  8310  }
  8311  
  8312  // newStringSortedMergeIterator returns an instance of stringSortedMergeIterator.
  8313  func newStringSortedMergeIterator(inputs []StringIterator, opt IteratorOptions) Iterator {
  8314  	itr := &stringSortedMergeIterator{
  8315  		inputs: inputs,
  8316  		heap: &stringSortedMergeHeap{
  8317  			items: make([]*stringSortedMergeHeapItem, 0, len(inputs)),
  8318  			opt:   opt,
  8319  		},
  8320  	}
  8321  
  8322  	// Initialize heap items.
  8323  	for _, input := range inputs {
  8324  		// Append to the heap.
  8325  		itr.heap.items = append(itr.heap.items, &stringSortedMergeHeapItem{itr: input})
  8326  	}
  8327  
  8328  	return itr
  8329  }
  8330  
  8331  // Stats returns an aggregation of stats from the underlying iterators.
  8332  func (itr *stringSortedMergeIterator) Stats() IteratorStats {
  8333  	var stats IteratorStats
  8334  	for _, input := range itr.inputs {
  8335  		stats.Add(input.Stats())
  8336  	}
  8337  	return stats
  8338  }
  8339  
  8340  // Close closes the underlying iterators.
  8341  func (itr *stringSortedMergeIterator) Close() error {
  8342  	for _, input := range itr.inputs {
  8343  		input.Close()
  8344  	}
  8345  	return nil
  8346  }
  8347  
  8348  // Next returns the next points from the iterator.
  8349  func (itr *stringSortedMergeIterator) Next() (*StringPoint, error) { return itr.pop() }
  8350  
  8351  // pop returns the next point from the heap.
  8352  // Reads the next point from item's cursor and puts it back on the heap.
  8353  func (itr *stringSortedMergeIterator) pop() (*StringPoint, error) {
  8354  	// Initialize the heap. See the MergeIterator to see why this has to be done lazily.
  8355  	if !itr.init {
  8356  		items := itr.heap.items
  8357  		itr.heap.items = make([]*stringSortedMergeHeapItem, 0, len(items))
  8358  		for _, item := range items {
  8359  			var err error
  8360  			if item.point, err = item.itr.Next(); err != nil {
  8361  				return nil, err
  8362  			} else if item.point == nil {
  8363  				continue
  8364  			}
  8365  			itr.heap.items = append(itr.heap.items, item)
  8366  		}
  8367  		heap.Init(itr.heap)
  8368  		itr.init = true
  8369  	}
  8370  
  8371  	if len(itr.heap.items) == 0 {
  8372  		return nil, nil
  8373  	}
  8374  
  8375  	// Read the next item from the heap.
  8376  	item := heap.Pop(itr.heap).(*stringSortedMergeHeapItem)
  8377  	if item.err != nil {
  8378  		return nil, item.err
  8379  	} else if item.point == nil {
  8380  		return nil, nil
  8381  	}
  8382  
  8383  	// Copy the point for return.
  8384  	p := item.point.Clone()
  8385  
  8386  	// Read the next item from the cursor. Push back to heap if one exists.
  8387  	if item.point, item.err = item.itr.Next(); item.point != nil {
  8388  		heap.Push(itr.heap, item)
  8389  	}
  8390  
  8391  	return p, nil
  8392  }
  8393  
  8394  // stringSortedMergeHeap represents a heap of stringSortedMergeHeapItems.
  8395  // Items are sorted with the following priority:
  8396  //   - By their measurement name;
  8397  //   - By their tag keys/values;
  8398  //   - By time; or
  8399  //   - By their Aux field values.
  8400  type stringSortedMergeHeap struct {
  8401  	opt   IteratorOptions
  8402  	items []*stringSortedMergeHeapItem
  8403  }
  8404  
  8405  func (h *stringSortedMergeHeap) Len() int      { return len(h.items) }
  8406  func (h *stringSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
  8407  func (h *stringSortedMergeHeap) Less(i, j int) bool {
  8408  	x, y := h.items[i].point, h.items[j].point
  8409  
  8410  	if h.opt.Ascending {
  8411  		if x.Name != y.Name {
  8412  			return x.Name < y.Name
  8413  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
  8414  			return xTags.ID() < yTags.ID()
  8415  		}
  8416  
  8417  		if x.Time != y.Time {
  8418  			return x.Time < y.Time
  8419  		}
  8420  
  8421  		if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
  8422  			for i := 0; i < len(x.Aux); i++ {
  8423  				v1, ok1 := x.Aux[i].(string)
  8424  				v2, ok2 := y.Aux[i].(string)
  8425  				if !ok1 || !ok2 {
  8426  					// Unsupported types used in Aux fields. Maybe they
  8427  					// need to be added here?
  8428  					return false
  8429  				} else if v1 == v2 {
  8430  					continue
  8431  				}
  8432  				return v1 < v2
  8433  			}
  8434  		}
  8435  		return false // Times and/or Aux fields are equal.
  8436  	}
  8437  
  8438  	if x.Name != y.Name {
  8439  		return x.Name > y.Name
  8440  	} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
  8441  		return xTags.ID() > yTags.ID()
  8442  	}
  8443  
  8444  	if x.Time != y.Time {
  8445  		return x.Time > y.Time
  8446  	}
  8447  
  8448  	if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
  8449  		for i := 0; i < len(x.Aux); i++ {
  8450  			v1, ok1 := x.Aux[i].(string)
  8451  			v2, ok2 := y.Aux[i].(string)
  8452  			if !ok1 || !ok2 {
  8453  				// Unsupported types used in Aux fields. Maybe they
  8454  				// need to be added here?
  8455  				return false
  8456  			} else if v1 == v2 {
  8457  				continue
  8458  			}
  8459  			return v1 > v2
  8460  		}
  8461  	}
  8462  	return false // Times and/or Aux fields are equal.
  8463  }
  8464  
  8465  func (h *stringSortedMergeHeap) Push(x interface{}) {
  8466  	h.items = append(h.items, x.(*stringSortedMergeHeapItem))
  8467  }
  8468  
  8469  func (h *stringSortedMergeHeap) Pop() interface{} {
  8470  	old := h.items
  8471  	n := len(old)
  8472  	item := old[n-1]
  8473  	h.items = old[0 : n-1]
  8474  	return item
  8475  }
  8476  
  8477  type stringSortedMergeHeapItem struct {
  8478  	point *StringPoint
  8479  	err   error
  8480  	itr   StringIterator
  8481  }
  8482  
  8483  // stringIteratorScanner scans the results of a StringIterator into a map.
  8484  type stringIteratorScanner struct {
  8485  	input        *bufStringIterator
  8486  	err          error
  8487  	keys         []influxql.VarRef
  8488  	defaultValue interface{}
  8489  }
  8490  
  8491  // newStringIteratorScanner creates a new IteratorScanner.
  8492  func newStringIteratorScanner(input StringIterator, keys []influxql.VarRef, defaultValue interface{}) *stringIteratorScanner {
  8493  	return &stringIteratorScanner{
  8494  		input:        newBufStringIterator(input),
  8495  		keys:         keys,
  8496  		defaultValue: defaultValue,
  8497  	}
  8498  }
  8499  
  8500  func (s *stringIteratorScanner) Peek() (int64, string, Tags) {
  8501  	if s.err != nil {
  8502  		return ZeroTime, "", Tags{}
  8503  	}
  8504  
  8505  	p, err := s.input.peek()
  8506  	if err != nil {
  8507  		s.err = err
  8508  		return ZeroTime, "", Tags{}
  8509  	} else if p == nil {
  8510  		return ZeroTime, "", Tags{}
  8511  	}
  8512  	return p.Time, p.Name, p.Tags
  8513  }
  8514  
  8515  func (s *stringIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) {
  8516  	if s.err != nil {
  8517  		return
  8518  	}
  8519  
  8520  	p, err := s.input.Next()
  8521  	if err != nil {
  8522  		s.err = err
  8523  		return
  8524  	} else if p == nil {
  8525  		s.useDefaults(m)
  8526  		return
  8527  	} else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) {
  8528  		s.useDefaults(m)
  8529  		s.input.unread(p)
  8530  		return
  8531  	}
  8532  
  8533  	if k := s.keys[0]; k.Val != "" {
  8534  		if p.Nil {
  8535  			if s.defaultValue != SkipDefault {
  8536  				m[k.Val] = castToType(s.defaultValue, k.Type)
  8537  			}
  8538  		} else {
  8539  			m[k.Val] = p.Value
  8540  		}
  8541  	}
  8542  	for i, v := range p.Aux {
  8543  		k := s.keys[i+1]
  8544  		switch v.(type) {
  8545  		case float64, int64, uint64, string, bool:
  8546  			m[k.Val] = v
  8547  		default:
  8548  			// Insert the fill value if one was specified.
  8549  			if s.defaultValue != SkipDefault {
  8550  				m[k.Val] = castToType(s.defaultValue, k.Type)
  8551  			}
  8552  		}
  8553  	}
  8554  }
  8555  
  8556  func (s *stringIteratorScanner) useDefaults(m map[string]interface{}) {
  8557  	if s.defaultValue == SkipDefault {
  8558  		return
  8559  	}
  8560  	for _, k := range s.keys {
  8561  		if k.Val == "" {
  8562  			continue
  8563  		}
  8564  		m[k.Val] = castToType(s.defaultValue, k.Type)
  8565  	}
  8566  }
  8567  
  8568  func (s *stringIteratorScanner) Stats() IteratorStats { return s.input.Stats() }
  8569  func (s *stringIteratorScanner) Err() error           { return s.err }
  8570  func (s *stringIteratorScanner) Close() error         { return s.input.Close() }
  8571  
  8572  // stringParallelIterator represents an iterator that pulls data in a separate goroutine.
  8573  type stringParallelIterator struct {
  8574  	input StringIterator
  8575  	ch    chan stringPointError
  8576  
  8577  	once    sync.Once
  8578  	closing chan struct{}
  8579  	wg      sync.WaitGroup
  8580  }
  8581  
  8582  // newStringParallelIterator returns a new instance of stringParallelIterator.
  8583  func newStringParallelIterator(input StringIterator) *stringParallelIterator {
  8584  	itr := &stringParallelIterator{
  8585  		input:   input,
  8586  		ch:      make(chan stringPointError, 256),
  8587  		closing: make(chan struct{}),
  8588  	}
  8589  	itr.wg.Add(1)
  8590  	go itr.monitor()
  8591  	return itr
  8592  }
  8593  
  8594  // Stats returns stats from the underlying iterator.
  8595  func (itr *stringParallelIterator) Stats() IteratorStats { return itr.input.Stats() }
  8596  
  8597  // Close closes the underlying iterators.
  8598  func (itr *stringParallelIterator) Close() error {
  8599  	itr.once.Do(func() { close(itr.closing) })
  8600  	itr.wg.Wait()
  8601  	return itr.input.Close()
  8602  }
  8603  
  8604  // Next returns the next point from the iterator.
  8605  func (itr *stringParallelIterator) Next() (*StringPoint, error) {
  8606  	v, ok := <-itr.ch
  8607  	if !ok {
  8608  		return nil, io.EOF
  8609  	}
  8610  	return v.point, v.err
  8611  }
  8612  
  8613  // monitor runs in a separate goroutine and actively pulls the next point.
  8614  func (itr *stringParallelIterator) monitor() {
  8615  	defer close(itr.ch)
  8616  	defer itr.wg.Done()
  8617  
  8618  	for {
  8619  		// Read next point.
  8620  		p, err := itr.input.Next()
  8621  		if p != nil {
  8622  			p = p.Clone()
  8623  		}
  8624  
  8625  		select {
  8626  		case <-itr.closing:
  8627  			return
  8628  		case itr.ch <- stringPointError{point: p, err: err}:
  8629  		}
  8630  	}
  8631  }
  8632  
  8633  type stringPointError struct {
  8634  	point *StringPoint
  8635  	err   error
  8636  }
  8637  
  8638  // stringLimitIterator represents an iterator that limits points per group.
  8639  type stringLimitIterator struct {
  8640  	input StringIterator
  8641  	opt   IteratorOptions
  8642  	n     int
  8643  
  8644  	prev struct {
  8645  		name string
  8646  		tags Tags
  8647  	}
  8648  }
  8649  
  8650  // newStringLimitIterator returns a new instance of stringLimitIterator.
  8651  func newStringLimitIterator(input StringIterator, opt IteratorOptions) *stringLimitIterator {
  8652  	return &stringLimitIterator{
  8653  		input: input,
  8654  		opt:   opt,
  8655  	}
  8656  }
  8657  
  8658  // Stats returns stats from the underlying iterator.
  8659  func (itr *stringLimitIterator) Stats() IteratorStats { return itr.input.Stats() }
  8660  
  8661  // Close closes the underlying iterators.
  8662  func (itr *stringLimitIterator) Close() error { return itr.input.Close() }
  8663  
  8664  // Next returns the next point from the iterator.
  8665  func (itr *stringLimitIterator) Next() (*StringPoint, error) {
  8666  	for {
  8667  		p, err := itr.input.Next()
  8668  		if p == nil || err != nil {
  8669  			return nil, err
  8670  		}
  8671  
  8672  		// Reset window and counter if a new window is encountered.
  8673  		if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) {
  8674  			itr.prev.name = p.Name
  8675  			itr.prev.tags = p.Tags
  8676  			itr.n = 0
  8677  		}
  8678  
  8679  		// Increment counter.
  8680  		itr.n++
  8681  
  8682  		// Read next point if not beyond the offset.
  8683  		if itr.n <= itr.opt.Offset {
  8684  			continue
  8685  		}
  8686  
  8687  		// Read next point if we're beyond the limit.
  8688  		if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit {
  8689  			continue
  8690  		}
  8691  
  8692  		return p, nil
  8693  	}
  8694  }
  8695  
  8696  type stringFillIterator struct {
  8697  	input     *bufStringIterator
  8698  	prev      StringPoint
  8699  	startTime int64
  8700  	endTime   int64
  8701  	auxFields []interface{}
  8702  	init      bool
  8703  	opt       IteratorOptions
  8704  
  8705  	window struct {
  8706  		name   string
  8707  		tags   Tags
  8708  		time   int64
  8709  		offset int64
  8710  	}
  8711  }
  8712  
  8713  func newStringFillIterator(input StringIterator, expr influxql.Expr, opt IteratorOptions) *stringFillIterator {
  8714  	if opt.Fill == influxql.NullFill {
  8715  		if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" {
  8716  			opt.Fill = influxql.NumberFill
  8717  			opt.FillValue = ""
  8718  		}
  8719  	}
  8720  
  8721  	var startTime, endTime int64
  8722  	if opt.Ascending {
  8723  		startTime, _ = opt.Window(opt.StartTime)
  8724  		endTime, _ = opt.Window(opt.EndTime)
  8725  	} else {
  8726  		startTime, _ = opt.Window(opt.EndTime)
  8727  		endTime, _ = opt.Window(opt.StartTime)
  8728  	}
  8729  
  8730  	var auxFields []interface{}
  8731  	if len(opt.Aux) > 0 {
  8732  		auxFields = make([]interface{}, len(opt.Aux))
  8733  	}
  8734  
  8735  	return &stringFillIterator{
  8736  		input:     newBufStringIterator(input),
  8737  		prev:      StringPoint{Nil: true},
  8738  		startTime: startTime,
  8739  		endTime:   endTime,
  8740  		auxFields: auxFields,
  8741  		opt:       opt,
  8742  	}
  8743  }
  8744  
  8745  func (itr *stringFillIterator) Stats() IteratorStats { return itr.input.Stats() }
  8746  func (itr *stringFillIterator) Close() error         { return itr.input.Close() }
  8747  
  8748  func (itr *stringFillIterator) Next() (*StringPoint, error) {
  8749  	if !itr.init {
  8750  		p, err := itr.input.peek()
  8751  		if p == nil || err != nil {
  8752  			return nil, err
  8753  		}
  8754  		itr.window.name, itr.window.tags = p.Name, p.Tags
  8755  		itr.window.time = itr.startTime
  8756  		if itr.startTime == influxql.MinTime {
  8757  			itr.window.time, _ = itr.opt.Window(p.Time)
  8758  		}
  8759  		if itr.opt.Location != nil {
  8760  			_, itr.window.offset = itr.opt.Zone(itr.window.time)
  8761  		}
  8762  		itr.init = true
  8763  	}
  8764  
  8765  	p, err := itr.input.Next()
  8766  	if err != nil {
  8767  		return nil, err
  8768  	}
  8769  
  8770  	// Check if the next point is outside of our window or is nil.
  8771  	if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() {
  8772  		// If we are inside of an interval, unread the point and continue below to
  8773  		// constructing a new point.
  8774  		if itr.opt.Ascending && itr.window.time <= itr.endTime {
  8775  			itr.input.unread(p)
  8776  			p = nil
  8777  			goto CONSTRUCT
  8778  		} else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime {
  8779  			itr.input.unread(p)
  8780  			p = nil
  8781  			goto CONSTRUCT
  8782  		}
  8783  
  8784  		// We are *not* in a current interval. If there is no next point,
  8785  		// we are at the end of all intervals.
  8786  		if p == nil {
  8787  			return nil, nil
  8788  		}
  8789  
  8790  		// Set the new interval.
  8791  		itr.window.name, itr.window.tags = p.Name, p.Tags
  8792  		itr.window.time = itr.startTime
  8793  		if itr.window.time == influxql.MinTime {
  8794  			itr.window.time, _ = itr.opt.Window(p.Time)
  8795  		}
  8796  		if itr.opt.Location != nil {
  8797  			_, itr.window.offset = itr.opt.Zone(itr.window.time)
  8798  		}
  8799  		itr.prev = StringPoint{Nil: true}
  8800  	}
  8801  
  8802  	// Check if the point is our next expected point.
  8803  CONSTRUCT:
  8804  	if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) {
  8805  		if p != nil {
  8806  			itr.input.unread(p)
  8807  		}
  8808  
  8809  		p = &StringPoint{
  8810  			Name: itr.window.name,
  8811  			Tags: itr.window.tags,
  8812  			Time: itr.window.time,
  8813  			Aux:  itr.auxFields,
  8814  		}
  8815  
  8816  		switch itr.opt.Fill {
  8817  		case influxql.LinearFill:
  8818  			fallthrough
  8819  		case influxql.NullFill:
  8820  			p.Nil = true
  8821  		case influxql.NumberFill:
  8822  			p.Value, _ = castToString(itr.opt.FillValue)
  8823  		case influxql.PreviousFill:
  8824  			if !itr.prev.Nil {
  8825  				p.Value = itr.prev.Value
  8826  				p.Nil = itr.prev.Nil
  8827  			} else {
  8828  				p.Nil = true
  8829  			}
  8830  		}
  8831  	} else {
  8832  		itr.prev = *p
  8833  	}
  8834  
  8835  	// Advance the expected time. Do not advance to a new window here
  8836  	// as there may be lingering points with the same timestamp in the previous
  8837  	// window.
  8838  	if itr.opt.Ascending {
  8839  		itr.window.time += int64(itr.opt.Interval.Duration)
  8840  	} else {
  8841  		itr.window.time -= int64(itr.opt.Interval.Duration)
  8842  	}
  8843  
  8844  	// Check to see if we have passed over an offset change and adjust the time
  8845  	// to account for this new offset.
  8846  	if itr.opt.Location != nil {
  8847  		if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset {
  8848  			diff := itr.window.offset - offset
  8849  			if abs(diff) < int64(itr.opt.Interval.Duration) {
  8850  				itr.window.time += diff
  8851  			}
  8852  			itr.window.offset = offset
  8853  		}
  8854  	}
  8855  	return p, nil
  8856  }
  8857  
  8858  // stringIntervalIterator represents a string implementation of IntervalIterator.
  8859  type stringIntervalIterator struct {
  8860  	input StringIterator
  8861  	opt   IteratorOptions
  8862  }
  8863  
  8864  func newStringIntervalIterator(input StringIterator, opt IteratorOptions) *stringIntervalIterator {
  8865  	return &stringIntervalIterator{input: input, opt: opt}
  8866  }
  8867  
  8868  func (itr *stringIntervalIterator) Stats() IteratorStats { return itr.input.Stats() }
  8869  func (itr *stringIntervalIterator) Close() error         { return itr.input.Close() }
  8870  
  8871  func (itr *stringIntervalIterator) Next() (*StringPoint, error) {
  8872  	p, err := itr.input.Next()
  8873  	if p == nil || err != nil {
  8874  		return nil, err
  8875  	}
  8876  	p.Time, _ = itr.opt.Window(p.Time)
  8877  	// If we see the minimum allowable time, set the time to zero so we don't
  8878  	// break the default returned time for aggregate queries without times.
  8879  	if p.Time == influxql.MinTime {
  8880  		p.Time = 0
  8881  	}
  8882  	return p, nil
  8883  }
  8884  
  8885  // stringInterruptIterator represents a string implementation of InterruptIterator.
  8886  type stringInterruptIterator struct {
  8887  	input   StringIterator
  8888  	closing <-chan struct{}
  8889  	count   int
  8890  }
  8891  
  8892  func newStringInterruptIterator(input StringIterator, closing <-chan struct{}) *stringInterruptIterator {
  8893  	return &stringInterruptIterator{input: input, closing: closing}
  8894  }
  8895  
  8896  func (itr *stringInterruptIterator) Stats() IteratorStats { return itr.input.Stats() }
  8897  func (itr *stringInterruptIterator) Close() error         { return itr.input.Close() }
  8898  
  8899  func (itr *stringInterruptIterator) Next() (*StringPoint, error) {
  8900  	// Only check if the channel is closed every N points. This
  8901  	// intentionally checks on both 0 and N so that if the iterator
  8902  	// has been interrupted before the first point is emitted it will
  8903  	// not emit any points.
  8904  	if itr.count&0xFF == 0xFF {
  8905  		select {
  8906  		case <-itr.closing:
  8907  			return nil, itr.Close()
  8908  		default:
  8909  			// Reset iterator count to zero and fall through to emit the next point.
  8910  			itr.count = 0
  8911  		}
  8912  	}
  8913  
  8914  	// Increment the counter for every point read.
  8915  	itr.count++
  8916  	return itr.input.Next()
  8917  }
  8918  
  8919  // stringCloseInterruptIterator represents a string implementation of CloseInterruptIterator.
  8920  type stringCloseInterruptIterator struct {
  8921  	input   StringIterator
  8922  	closing <-chan struct{}
  8923  	done    chan struct{}
  8924  	once    sync.Once
  8925  }
  8926  
  8927  func newStringCloseInterruptIterator(input StringIterator, closing <-chan struct{}) *stringCloseInterruptIterator {
  8928  	itr := &stringCloseInterruptIterator{
  8929  		input:   input,
  8930  		closing: closing,
  8931  		done:    make(chan struct{}),
  8932  	}
  8933  	go itr.monitor()
  8934  	return itr
  8935  }
  8936  
  8937  func (itr *stringCloseInterruptIterator) monitor() {
  8938  	select {
  8939  	case <-itr.closing:
  8940  		itr.Close()
  8941  	case <-itr.done:
  8942  	}
  8943  }
  8944  
  8945  func (itr *stringCloseInterruptIterator) Stats() IteratorStats {
  8946  	return itr.input.Stats()
  8947  }
  8948  
  8949  func (itr *stringCloseInterruptIterator) Close() error {
  8950  	itr.once.Do(func() {
  8951  		close(itr.done)
  8952  		itr.input.Close()
  8953  	})
  8954  	return nil
  8955  }
  8956  
  8957  func (itr *stringCloseInterruptIterator) Next() (*StringPoint, error) {
  8958  	p, err := itr.input.Next()
  8959  	if err != nil {
  8960  		// Check if the iterator was closed.
  8961  		select {
  8962  		case <-itr.done:
  8963  			return nil, nil
  8964  		default:
  8965  			return nil, err
  8966  		}
  8967  	}
  8968  	return p, nil
  8969  }
  8970  
  8971  // stringReduceFloatIterator executes a reducer for every interval and buffers the result.
  8972  type stringReduceFloatIterator struct {
  8973  	input    *bufStringIterator
  8974  	create   func() (StringPointAggregator, FloatPointEmitter)
  8975  	dims     []string
  8976  	opt      IteratorOptions
  8977  	points   []FloatPoint
  8978  	keepTags bool
  8979  }
  8980  
  8981  func newStringReduceFloatIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, FloatPointEmitter)) *stringReduceFloatIterator {
  8982  	return &stringReduceFloatIterator{
  8983  		input:  newBufStringIterator(input),
  8984  		create: createFn,
  8985  		dims:   opt.GetDimensions(),
  8986  		opt:    opt,
  8987  	}
  8988  }
  8989  
  8990  // Stats returns stats from the input iterator.
  8991  func (itr *stringReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
  8992  
  8993  // Close closes the iterator and all child iterators.
  8994  func (itr *stringReduceFloatIterator) Close() error { return itr.input.Close() }
  8995  
  8996  // Next returns the minimum value for the next available interval.
  8997  func (itr *stringReduceFloatIterator) Next() (*FloatPoint, error) {
  8998  	// Calculate next window if we have no more points.
  8999  	if len(itr.points) == 0 {
  9000  		var err error
  9001  		itr.points, err = itr.reduce()
  9002  		if len(itr.points) == 0 {
  9003  			return nil, err
  9004  		}
  9005  	}
  9006  
  9007  	// Pop next point off the stack.
  9008  	p := &itr.points[len(itr.points)-1]
  9009  	itr.points = itr.points[:len(itr.points)-1]
  9010  	return p, nil
  9011  }
  9012  
  9013  // stringReduceFloatPoint stores the reduced data for a name/tag combination.
  9014  type stringReduceFloatPoint struct {
  9015  	Name       string
  9016  	Tags       Tags
  9017  	Aggregator StringPointAggregator
  9018  	Emitter    FloatPointEmitter
  9019  }
  9020  
  9021  // reduce executes fn once for every point in the next window.
  9022  // The previous value for the dimension is passed to fn.
  9023  func (itr *stringReduceFloatIterator) reduce() ([]FloatPoint, error) {
  9024  	// Calculate next window.
  9025  	var (
  9026  		startTime, endTime int64
  9027  		window             struct {
  9028  			name string
  9029  			tags string
  9030  		}
  9031  	)
  9032  	for {
  9033  		p, err := itr.input.Next()
  9034  		if err != nil || p == nil {
  9035  			return nil, err
  9036  		} else if p.Nil {
  9037  			continue
  9038  		}
  9039  
  9040  		// Unread the point so it can be processed.
  9041  		itr.input.unread(p)
  9042  		startTime, endTime = itr.opt.Window(p.Time)
  9043  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  9044  		break
  9045  	}
  9046  
  9047  	// Create points by tags.
  9048  	m := make(map[string]*stringReduceFloatPoint)
  9049  	for {
  9050  		// Read next point.
  9051  		curr, err := itr.input.NextInWindow(startTime, endTime)
  9052  		if err != nil {
  9053  			return nil, err
  9054  		} else if curr == nil {
  9055  			break
  9056  		} else if curr.Nil {
  9057  			continue
  9058  		} else if curr.Name != window.name {
  9059  			itr.input.unread(curr)
  9060  			break
  9061  		}
  9062  
  9063  		// Ensure this point is within the same final window.
  9064  		if curr.Name != window.name {
  9065  			itr.input.unread(curr)
  9066  			break
  9067  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  9068  			itr.input.unread(curr)
  9069  			break
  9070  		}
  9071  
  9072  		// Retrieve the tags on this point for this level of the query.
  9073  		// This may be different than the bucket dimensions.
  9074  		tags := curr.Tags.Subset(itr.dims)
  9075  		id := tags.ID()
  9076  
  9077  		// Retrieve the aggregator for this name/tag combination or create one.
  9078  		rp := m[id]
  9079  		if rp == nil {
  9080  			aggregator, emitter := itr.create()
  9081  			rp = &stringReduceFloatPoint{
  9082  				Name:       curr.Name,
  9083  				Tags:       tags,
  9084  				Aggregator: aggregator,
  9085  				Emitter:    emitter,
  9086  			}
  9087  			m[id] = rp
  9088  		}
  9089  		rp.Aggregator.AggregateString(curr)
  9090  	}
  9091  
  9092  	keys := make([]string, 0, len(m))
  9093  	for k := range m {
  9094  		keys = append(keys, k)
  9095  	}
  9096  
  9097  	// Reverse sort points by name & tag.
  9098  	// This ensures a consistent order of output.
  9099  	if len(keys) > 0 {
  9100  		var sorted sort.Interface = sort.StringSlice(keys)
  9101  		if itr.opt.Ascending {
  9102  			sorted = sort.Reverse(sorted)
  9103  		}
  9104  		sort.Sort(sorted)
  9105  	}
  9106  
  9107  	// Assume the points are already sorted until proven otherwise.
  9108  	sortedByTime := true
  9109  	// Emit the points for each name & tag combination.
  9110  	a := make([]FloatPoint, 0, len(m))
  9111  	for _, k := range keys {
  9112  		rp := m[k]
  9113  		points := rp.Emitter.Emit()
  9114  		for i := len(points) - 1; i >= 0; i-- {
  9115  			points[i].Name = rp.Name
  9116  			if !itr.keepTags {
  9117  				points[i].Tags = rp.Tags
  9118  			}
  9119  			// Set the points time to the interval time if the reducer didn't provide one.
  9120  			if points[i].Time == ZeroTime {
  9121  				points[i].Time = startTime
  9122  			} else {
  9123  				sortedByTime = false
  9124  			}
  9125  			a = append(a, points[i])
  9126  		}
  9127  	}
  9128  	// Points may be out of order. Perform a stable sort by time if requested.
  9129  	if !sortedByTime && itr.opt.Ordered {
  9130  		var sorted sort.Interface = floatPointsByTime(a)
  9131  		if itr.opt.Ascending {
  9132  			sorted = sort.Reverse(sorted)
  9133  		}
  9134  		sort.Stable(sorted)
  9135  	}
  9136  	return a, nil
  9137  }
  9138  
  9139  // stringStreamFloatIterator streams inputs into the iterator and emits points gradually.
  9140  type stringStreamFloatIterator struct {
  9141  	input  *bufStringIterator
  9142  	create func() (StringPointAggregator, FloatPointEmitter)
  9143  	dims   []string
  9144  	opt    IteratorOptions
  9145  	m      map[string]*stringReduceFloatPoint
  9146  	points []FloatPoint
  9147  }
  9148  
  9149  // newStringStreamFloatIterator returns a new instance of stringStreamFloatIterator.
  9150  func newStringStreamFloatIterator(input StringIterator, createFn func() (StringPointAggregator, FloatPointEmitter), opt IteratorOptions) *stringStreamFloatIterator {
  9151  	return &stringStreamFloatIterator{
  9152  		input:  newBufStringIterator(input),
  9153  		create: createFn,
  9154  		dims:   opt.GetDimensions(),
  9155  		opt:    opt,
  9156  		m:      make(map[string]*stringReduceFloatPoint),
  9157  	}
  9158  }
  9159  
  9160  // Stats returns stats from the input iterator.
  9161  func (itr *stringStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
  9162  
  9163  // Close closes the iterator and all child iterators.
  9164  func (itr *stringStreamFloatIterator) Close() error { return itr.input.Close() }
  9165  
  9166  // Next returns the next value for the stream iterator.
  9167  func (itr *stringStreamFloatIterator) Next() (*FloatPoint, error) {
  9168  	// Calculate next window if we have no more points.
  9169  	if len(itr.points) == 0 {
  9170  		var err error
  9171  		itr.points, err = itr.reduce()
  9172  		if len(itr.points) == 0 {
  9173  			return nil, err
  9174  		}
  9175  	}
  9176  
  9177  	// Pop next point off the stack.
  9178  	p := &itr.points[len(itr.points)-1]
  9179  	itr.points = itr.points[:len(itr.points)-1]
  9180  	return p, nil
  9181  }
  9182  
  9183  // reduce creates and manages aggregators for every point from the input.
  9184  // After aggregating a point, it always tries to emit a value using the emitter.
  9185  func (itr *stringStreamFloatIterator) reduce() ([]FloatPoint, error) {
  9186  	// We have already read all of the input points.
  9187  	if itr.m == nil {
  9188  		return nil, nil
  9189  	}
  9190  
  9191  	for {
  9192  		// Read next point.
  9193  		curr, err := itr.input.Next()
  9194  		if err != nil {
  9195  			return nil, err
  9196  		} else if curr == nil {
  9197  			// Close all of the aggregators to flush any remaining points to emit.
  9198  			var points []FloatPoint
  9199  			for _, rp := range itr.m {
  9200  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  9201  					if err := aggregator.Close(); err != nil {
  9202  						return nil, err
  9203  					}
  9204  
  9205  					pts := rp.Emitter.Emit()
  9206  					if len(pts) == 0 {
  9207  						continue
  9208  					}
  9209  
  9210  					for i := range pts {
  9211  						pts[i].Name = rp.Name
  9212  						pts[i].Tags = rp.Tags
  9213  					}
  9214  					points = append(points, pts...)
  9215  				}
  9216  			}
  9217  
  9218  			// Eliminate the aggregators and emitters.
  9219  			itr.m = nil
  9220  			return points, nil
  9221  		} else if curr.Nil {
  9222  			continue
  9223  		}
  9224  		tags := curr.Tags.Subset(itr.dims)
  9225  
  9226  		id := curr.Name
  9227  		if len(tags.m) > 0 {
  9228  			id += "\x00" + tags.ID()
  9229  		}
  9230  
  9231  		// Retrieve the aggregator for this name/tag combination or create one.
  9232  		rp := itr.m[id]
  9233  		if rp == nil {
  9234  			aggregator, emitter := itr.create()
  9235  			rp = &stringReduceFloatPoint{
  9236  				Name:       curr.Name,
  9237  				Tags:       tags,
  9238  				Aggregator: aggregator,
  9239  				Emitter:    emitter,
  9240  			}
  9241  			itr.m[id] = rp
  9242  		}
  9243  		rp.Aggregator.AggregateString(curr)
  9244  
  9245  		// Attempt to emit points from the aggregator.
  9246  		points := rp.Emitter.Emit()
  9247  		if len(points) == 0 {
  9248  			continue
  9249  		}
  9250  
  9251  		for i := range points {
  9252  			points[i].Name = rp.Name
  9253  			points[i].Tags = rp.Tags
  9254  		}
  9255  		return points, nil
  9256  	}
  9257  }
  9258  
  9259  // stringReduceIntegerIterator executes a reducer for every interval and buffers the result.
  9260  type stringReduceIntegerIterator struct {
  9261  	input    *bufStringIterator
  9262  	create   func() (StringPointAggregator, IntegerPointEmitter)
  9263  	dims     []string
  9264  	opt      IteratorOptions
  9265  	points   []IntegerPoint
  9266  	keepTags bool
  9267  }
  9268  
  9269  func newStringReduceIntegerIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, IntegerPointEmitter)) *stringReduceIntegerIterator {
  9270  	return &stringReduceIntegerIterator{
  9271  		input:  newBufStringIterator(input),
  9272  		create: createFn,
  9273  		dims:   opt.GetDimensions(),
  9274  		opt:    opt,
  9275  	}
  9276  }
  9277  
  9278  // Stats returns stats from the input iterator.
  9279  func (itr *stringReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
  9280  
  9281  // Close closes the iterator and all child iterators.
  9282  func (itr *stringReduceIntegerIterator) Close() error { return itr.input.Close() }
  9283  
  9284  // Next returns the minimum value for the next available interval.
  9285  func (itr *stringReduceIntegerIterator) Next() (*IntegerPoint, error) {
  9286  	// Calculate next window if we have no more points.
  9287  	if len(itr.points) == 0 {
  9288  		var err error
  9289  		itr.points, err = itr.reduce()
  9290  		if len(itr.points) == 0 {
  9291  			return nil, err
  9292  		}
  9293  	}
  9294  
  9295  	// Pop next point off the stack.
  9296  	p := &itr.points[len(itr.points)-1]
  9297  	itr.points = itr.points[:len(itr.points)-1]
  9298  	return p, nil
  9299  }
  9300  
  9301  // stringReduceIntegerPoint stores the reduced data for a name/tag combination.
  9302  type stringReduceIntegerPoint struct {
  9303  	Name       string
  9304  	Tags       Tags
  9305  	Aggregator StringPointAggregator
  9306  	Emitter    IntegerPointEmitter
  9307  }
  9308  
  9309  // reduce executes fn once for every point in the next window.
  9310  // The previous value for the dimension is passed to fn.
  9311  func (itr *stringReduceIntegerIterator) reduce() ([]IntegerPoint, error) {
  9312  	// Calculate next window.
  9313  	var (
  9314  		startTime, endTime int64
  9315  		window             struct {
  9316  			name string
  9317  			tags string
  9318  		}
  9319  	)
  9320  	for {
  9321  		p, err := itr.input.Next()
  9322  		if err != nil || p == nil {
  9323  			return nil, err
  9324  		} else if p.Nil {
  9325  			continue
  9326  		}
  9327  
  9328  		// Unread the point so it can be processed.
  9329  		itr.input.unread(p)
  9330  		startTime, endTime = itr.opt.Window(p.Time)
  9331  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  9332  		break
  9333  	}
  9334  
  9335  	// Create points by tags.
  9336  	m := make(map[string]*stringReduceIntegerPoint)
  9337  	for {
  9338  		// Read next point.
  9339  		curr, err := itr.input.NextInWindow(startTime, endTime)
  9340  		if err != nil {
  9341  			return nil, err
  9342  		} else if curr == nil {
  9343  			break
  9344  		} else if curr.Nil {
  9345  			continue
  9346  		} else if curr.Name != window.name {
  9347  			itr.input.unread(curr)
  9348  			break
  9349  		}
  9350  
  9351  		// Ensure this point is within the same final window.
  9352  		if curr.Name != window.name {
  9353  			itr.input.unread(curr)
  9354  			break
  9355  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  9356  			itr.input.unread(curr)
  9357  			break
  9358  		}
  9359  
  9360  		// Retrieve the tags on this point for this level of the query.
  9361  		// This may be different than the bucket dimensions.
  9362  		tags := curr.Tags.Subset(itr.dims)
  9363  		id := tags.ID()
  9364  
  9365  		// Retrieve the aggregator for this name/tag combination or create one.
  9366  		rp := m[id]
  9367  		if rp == nil {
  9368  			aggregator, emitter := itr.create()
  9369  			rp = &stringReduceIntegerPoint{
  9370  				Name:       curr.Name,
  9371  				Tags:       tags,
  9372  				Aggregator: aggregator,
  9373  				Emitter:    emitter,
  9374  			}
  9375  			m[id] = rp
  9376  		}
  9377  		rp.Aggregator.AggregateString(curr)
  9378  	}
  9379  
  9380  	keys := make([]string, 0, len(m))
  9381  	for k := range m {
  9382  		keys = append(keys, k)
  9383  	}
  9384  
  9385  	// Reverse sort points by name & tag.
  9386  	// This ensures a consistent order of output.
  9387  	if len(keys) > 0 {
  9388  		var sorted sort.Interface = sort.StringSlice(keys)
  9389  		if itr.opt.Ascending {
  9390  			sorted = sort.Reverse(sorted)
  9391  		}
  9392  		sort.Sort(sorted)
  9393  	}
  9394  
  9395  	// Assume the points are already sorted until proven otherwise.
  9396  	sortedByTime := true
  9397  	// Emit the points for each name & tag combination.
  9398  	a := make([]IntegerPoint, 0, len(m))
  9399  	for _, k := range keys {
  9400  		rp := m[k]
  9401  		points := rp.Emitter.Emit()
  9402  		for i := len(points) - 1; i >= 0; i-- {
  9403  			points[i].Name = rp.Name
  9404  			if !itr.keepTags {
  9405  				points[i].Tags = rp.Tags
  9406  			}
  9407  			// Set the points time to the interval time if the reducer didn't provide one.
  9408  			if points[i].Time == ZeroTime {
  9409  				points[i].Time = startTime
  9410  			} else {
  9411  				sortedByTime = false
  9412  			}
  9413  			a = append(a, points[i])
  9414  		}
  9415  	}
  9416  	// Points may be out of order. Perform a stable sort by time if requested.
  9417  	if !sortedByTime && itr.opt.Ordered {
  9418  		var sorted sort.Interface = integerPointsByTime(a)
  9419  		if itr.opt.Ascending {
  9420  			sorted = sort.Reverse(sorted)
  9421  		}
  9422  		sort.Stable(sorted)
  9423  	}
  9424  	return a, nil
  9425  }
  9426  
  9427  // stringStreamIntegerIterator streams inputs into the iterator and emits points gradually.
  9428  type stringStreamIntegerIterator struct {
  9429  	input  *bufStringIterator
  9430  	create func() (StringPointAggregator, IntegerPointEmitter)
  9431  	dims   []string
  9432  	opt    IteratorOptions
  9433  	m      map[string]*stringReduceIntegerPoint
  9434  	points []IntegerPoint
  9435  }
  9436  
  9437  // newStringStreamIntegerIterator returns a new instance of stringStreamIntegerIterator.
  9438  func newStringStreamIntegerIterator(input StringIterator, createFn func() (StringPointAggregator, IntegerPointEmitter), opt IteratorOptions) *stringStreamIntegerIterator {
  9439  	return &stringStreamIntegerIterator{
  9440  		input:  newBufStringIterator(input),
  9441  		create: createFn,
  9442  		dims:   opt.GetDimensions(),
  9443  		opt:    opt,
  9444  		m:      make(map[string]*stringReduceIntegerPoint),
  9445  	}
  9446  }
  9447  
  9448  // Stats returns stats from the input iterator.
  9449  func (itr *stringStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
  9450  
  9451  // Close closes the iterator and all child iterators.
  9452  func (itr *stringStreamIntegerIterator) Close() error { return itr.input.Close() }
  9453  
  9454  // Next returns the next value for the stream iterator.
  9455  func (itr *stringStreamIntegerIterator) Next() (*IntegerPoint, error) {
  9456  	// Calculate next window if we have no more points.
  9457  	if len(itr.points) == 0 {
  9458  		var err error
  9459  		itr.points, err = itr.reduce()
  9460  		if len(itr.points) == 0 {
  9461  			return nil, err
  9462  		}
  9463  	}
  9464  
  9465  	// Pop next point off the stack.
  9466  	p := &itr.points[len(itr.points)-1]
  9467  	itr.points = itr.points[:len(itr.points)-1]
  9468  	return p, nil
  9469  }
  9470  
  9471  // reduce creates and manages aggregators for every point from the input.
  9472  // After aggregating a point, it always tries to emit a value using the emitter.
  9473  func (itr *stringStreamIntegerIterator) reduce() ([]IntegerPoint, error) {
  9474  	// We have already read all of the input points.
  9475  	if itr.m == nil {
  9476  		return nil, nil
  9477  	}
  9478  
  9479  	for {
  9480  		// Read next point.
  9481  		curr, err := itr.input.Next()
  9482  		if err != nil {
  9483  			return nil, err
  9484  		} else if curr == nil {
  9485  			// Close all of the aggregators to flush any remaining points to emit.
  9486  			var points []IntegerPoint
  9487  			for _, rp := range itr.m {
  9488  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  9489  					if err := aggregator.Close(); err != nil {
  9490  						return nil, err
  9491  					}
  9492  
  9493  					pts := rp.Emitter.Emit()
  9494  					if len(pts) == 0 {
  9495  						continue
  9496  					}
  9497  
  9498  					for i := range pts {
  9499  						pts[i].Name = rp.Name
  9500  						pts[i].Tags = rp.Tags
  9501  					}
  9502  					points = append(points, pts...)
  9503  				}
  9504  			}
  9505  
  9506  			// Eliminate the aggregators and emitters.
  9507  			itr.m = nil
  9508  			return points, nil
  9509  		} else if curr.Nil {
  9510  			continue
  9511  		}
  9512  		tags := curr.Tags.Subset(itr.dims)
  9513  
  9514  		id := curr.Name
  9515  		if len(tags.m) > 0 {
  9516  			id += "\x00" + tags.ID()
  9517  		}
  9518  
  9519  		// Retrieve the aggregator for this name/tag combination or create one.
  9520  		rp := itr.m[id]
  9521  		if rp == nil {
  9522  			aggregator, emitter := itr.create()
  9523  			rp = &stringReduceIntegerPoint{
  9524  				Name:       curr.Name,
  9525  				Tags:       tags,
  9526  				Aggregator: aggregator,
  9527  				Emitter:    emitter,
  9528  			}
  9529  			itr.m[id] = rp
  9530  		}
  9531  		rp.Aggregator.AggregateString(curr)
  9532  
  9533  		// Attempt to emit points from the aggregator.
  9534  		points := rp.Emitter.Emit()
  9535  		if len(points) == 0 {
  9536  			continue
  9537  		}
  9538  
  9539  		for i := range points {
  9540  			points[i].Name = rp.Name
  9541  			points[i].Tags = rp.Tags
  9542  		}
  9543  		return points, nil
  9544  	}
  9545  }
  9546  
  9547  // stringReduceUnsignedIterator executes a reducer for every interval and buffers the result.
  9548  type stringReduceUnsignedIterator struct {
  9549  	input    *bufStringIterator
  9550  	create   func() (StringPointAggregator, UnsignedPointEmitter)
  9551  	dims     []string
  9552  	opt      IteratorOptions
  9553  	points   []UnsignedPoint
  9554  	keepTags bool
  9555  }
  9556  
  9557  func newStringReduceUnsignedIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, UnsignedPointEmitter)) *stringReduceUnsignedIterator {
  9558  	return &stringReduceUnsignedIterator{
  9559  		input:  newBufStringIterator(input),
  9560  		create: createFn,
  9561  		dims:   opt.GetDimensions(),
  9562  		opt:    opt,
  9563  	}
  9564  }
  9565  
  9566  // Stats returns stats from the input iterator.
  9567  func (itr *stringReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
  9568  
  9569  // Close closes the iterator and all child iterators.
  9570  func (itr *stringReduceUnsignedIterator) Close() error { return itr.input.Close() }
  9571  
  9572  // Next returns the minimum value for the next available interval.
  9573  func (itr *stringReduceUnsignedIterator) Next() (*UnsignedPoint, error) {
  9574  	// Calculate next window if we have no more points.
  9575  	if len(itr.points) == 0 {
  9576  		var err error
  9577  		itr.points, err = itr.reduce()
  9578  		if len(itr.points) == 0 {
  9579  			return nil, err
  9580  		}
  9581  	}
  9582  
  9583  	// Pop next point off the stack.
  9584  	p := &itr.points[len(itr.points)-1]
  9585  	itr.points = itr.points[:len(itr.points)-1]
  9586  	return p, nil
  9587  }
  9588  
  9589  // stringReduceUnsignedPoint stores the reduced data for a name/tag combination.
  9590  type stringReduceUnsignedPoint struct {
  9591  	Name       string
  9592  	Tags       Tags
  9593  	Aggregator StringPointAggregator
  9594  	Emitter    UnsignedPointEmitter
  9595  }
  9596  
  9597  // reduce executes fn once for every point in the next window.
  9598  // The previous value for the dimension is passed to fn.
  9599  func (itr *stringReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) {
  9600  	// Calculate next window.
  9601  	var (
  9602  		startTime, endTime int64
  9603  		window             struct {
  9604  			name string
  9605  			tags string
  9606  		}
  9607  	)
  9608  	for {
  9609  		p, err := itr.input.Next()
  9610  		if err != nil || p == nil {
  9611  			return nil, err
  9612  		} else if p.Nil {
  9613  			continue
  9614  		}
  9615  
  9616  		// Unread the point so it can be processed.
  9617  		itr.input.unread(p)
  9618  		startTime, endTime = itr.opt.Window(p.Time)
  9619  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  9620  		break
  9621  	}
  9622  
  9623  	// Create points by tags.
  9624  	m := make(map[string]*stringReduceUnsignedPoint)
  9625  	for {
  9626  		// Read next point.
  9627  		curr, err := itr.input.NextInWindow(startTime, endTime)
  9628  		if err != nil {
  9629  			return nil, err
  9630  		} else if curr == nil {
  9631  			break
  9632  		} else if curr.Nil {
  9633  			continue
  9634  		} else if curr.Name != window.name {
  9635  			itr.input.unread(curr)
  9636  			break
  9637  		}
  9638  
  9639  		// Ensure this point is within the same final window.
  9640  		if curr.Name != window.name {
  9641  			itr.input.unread(curr)
  9642  			break
  9643  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  9644  			itr.input.unread(curr)
  9645  			break
  9646  		}
  9647  
  9648  		// Retrieve the tags on this point for this level of the query.
  9649  		// This may be different than the bucket dimensions.
  9650  		tags := curr.Tags.Subset(itr.dims)
  9651  		id := tags.ID()
  9652  
  9653  		// Retrieve the aggregator for this name/tag combination or create one.
  9654  		rp := m[id]
  9655  		if rp == nil {
  9656  			aggregator, emitter := itr.create()
  9657  			rp = &stringReduceUnsignedPoint{
  9658  				Name:       curr.Name,
  9659  				Tags:       tags,
  9660  				Aggregator: aggregator,
  9661  				Emitter:    emitter,
  9662  			}
  9663  			m[id] = rp
  9664  		}
  9665  		rp.Aggregator.AggregateString(curr)
  9666  	}
  9667  
  9668  	keys := make([]string, 0, len(m))
  9669  	for k := range m {
  9670  		keys = append(keys, k)
  9671  	}
  9672  
  9673  	// Reverse sort points by name & tag.
  9674  	// This ensures a consistent order of output.
  9675  	if len(keys) > 0 {
  9676  		var sorted sort.Interface = sort.StringSlice(keys)
  9677  		if itr.opt.Ascending {
  9678  			sorted = sort.Reverse(sorted)
  9679  		}
  9680  		sort.Sort(sorted)
  9681  	}
  9682  
  9683  	// Assume the points are already sorted until proven otherwise.
  9684  	sortedByTime := true
  9685  	// Emit the points for each name & tag combination.
  9686  	a := make([]UnsignedPoint, 0, len(m))
  9687  	for _, k := range keys {
  9688  		rp := m[k]
  9689  		points := rp.Emitter.Emit()
  9690  		for i := len(points) - 1; i >= 0; i-- {
  9691  			points[i].Name = rp.Name
  9692  			if !itr.keepTags {
  9693  				points[i].Tags = rp.Tags
  9694  			}
  9695  			// Set the points time to the interval time if the reducer didn't provide one.
  9696  			if points[i].Time == ZeroTime {
  9697  				points[i].Time = startTime
  9698  			} else {
  9699  				sortedByTime = false
  9700  			}
  9701  			a = append(a, points[i])
  9702  		}
  9703  	}
  9704  	// Points may be out of order. Perform a stable sort by time if requested.
  9705  	if !sortedByTime && itr.opt.Ordered {
  9706  		var sorted sort.Interface = unsignedPointsByTime(a)
  9707  		if itr.opt.Ascending {
  9708  			sorted = sort.Reverse(sorted)
  9709  		}
  9710  		sort.Stable(sorted)
  9711  	}
  9712  	return a, nil
  9713  }
  9714  
  9715  // stringStreamUnsignedIterator streams inputs into the iterator and emits points gradually.
  9716  type stringStreamUnsignedIterator struct {
  9717  	input  *bufStringIterator
  9718  	create func() (StringPointAggregator, UnsignedPointEmitter)
  9719  	dims   []string
  9720  	opt    IteratorOptions
  9721  	m      map[string]*stringReduceUnsignedPoint
  9722  	points []UnsignedPoint
  9723  }
  9724  
  9725  // newStringStreamUnsignedIterator returns a new instance of stringStreamUnsignedIterator.
  9726  func newStringStreamUnsignedIterator(input StringIterator, createFn func() (StringPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *stringStreamUnsignedIterator {
  9727  	return &stringStreamUnsignedIterator{
  9728  		input:  newBufStringIterator(input),
  9729  		create: createFn,
  9730  		dims:   opt.GetDimensions(),
  9731  		opt:    opt,
  9732  		m:      make(map[string]*stringReduceUnsignedPoint),
  9733  	}
  9734  }
  9735  
  9736  // Stats returns stats from the input iterator.
  9737  func (itr *stringStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
  9738  
  9739  // Close closes the iterator and all child iterators.
  9740  func (itr *stringStreamUnsignedIterator) Close() error { return itr.input.Close() }
  9741  
  9742  // Next returns the next value for the stream iterator.
  9743  func (itr *stringStreamUnsignedIterator) Next() (*UnsignedPoint, error) {
  9744  	// Calculate next window if we have no more points.
  9745  	if len(itr.points) == 0 {
  9746  		var err error
  9747  		itr.points, err = itr.reduce()
  9748  		if len(itr.points) == 0 {
  9749  			return nil, err
  9750  		}
  9751  	}
  9752  
  9753  	// Pop next point off the stack.
  9754  	p := &itr.points[len(itr.points)-1]
  9755  	itr.points = itr.points[:len(itr.points)-1]
  9756  	return p, nil
  9757  }
  9758  
  9759  // reduce creates and manages aggregators for every point from the input.
  9760  // After aggregating a point, it always tries to emit a value using the emitter.
  9761  func (itr *stringStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) {
  9762  	// We have already read all of the input points.
  9763  	if itr.m == nil {
  9764  		return nil, nil
  9765  	}
  9766  
  9767  	for {
  9768  		// Read next point.
  9769  		curr, err := itr.input.Next()
  9770  		if err != nil {
  9771  			return nil, err
  9772  		} else if curr == nil {
  9773  			// Close all of the aggregators to flush any remaining points to emit.
  9774  			var points []UnsignedPoint
  9775  			for _, rp := range itr.m {
  9776  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
  9777  					if err := aggregator.Close(); err != nil {
  9778  						return nil, err
  9779  					}
  9780  
  9781  					pts := rp.Emitter.Emit()
  9782  					if len(pts) == 0 {
  9783  						continue
  9784  					}
  9785  
  9786  					for i := range pts {
  9787  						pts[i].Name = rp.Name
  9788  						pts[i].Tags = rp.Tags
  9789  					}
  9790  					points = append(points, pts...)
  9791  				}
  9792  			}
  9793  
  9794  			// Eliminate the aggregators and emitters.
  9795  			itr.m = nil
  9796  			return points, nil
  9797  		} else if curr.Nil {
  9798  			continue
  9799  		}
  9800  		tags := curr.Tags.Subset(itr.dims)
  9801  
  9802  		id := curr.Name
  9803  		if len(tags.m) > 0 {
  9804  			id += "\x00" + tags.ID()
  9805  		}
  9806  
  9807  		// Retrieve the aggregator for this name/tag combination or create one.
  9808  		rp := itr.m[id]
  9809  		if rp == nil {
  9810  			aggregator, emitter := itr.create()
  9811  			rp = &stringReduceUnsignedPoint{
  9812  				Name:       curr.Name,
  9813  				Tags:       tags,
  9814  				Aggregator: aggregator,
  9815  				Emitter:    emitter,
  9816  			}
  9817  			itr.m[id] = rp
  9818  		}
  9819  		rp.Aggregator.AggregateString(curr)
  9820  
  9821  		// Attempt to emit points from the aggregator.
  9822  		points := rp.Emitter.Emit()
  9823  		if len(points) == 0 {
  9824  			continue
  9825  		}
  9826  
  9827  		for i := range points {
  9828  			points[i].Name = rp.Name
  9829  			points[i].Tags = rp.Tags
  9830  		}
  9831  		return points, nil
  9832  	}
  9833  }
  9834  
  9835  // stringReduceStringIterator executes a reducer for every interval and buffers the result.
  9836  type stringReduceStringIterator struct {
  9837  	input    *bufStringIterator
  9838  	create   func() (StringPointAggregator, StringPointEmitter)
  9839  	dims     []string
  9840  	opt      IteratorOptions
  9841  	points   []StringPoint
  9842  	keepTags bool
  9843  }
  9844  
  9845  func newStringReduceStringIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, StringPointEmitter)) *stringReduceStringIterator {
  9846  	return &stringReduceStringIterator{
  9847  		input:  newBufStringIterator(input),
  9848  		create: createFn,
  9849  		dims:   opt.GetDimensions(),
  9850  		opt:    opt,
  9851  	}
  9852  }
  9853  
  9854  // Stats returns stats from the input iterator.
  9855  func (itr *stringReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() }
  9856  
  9857  // Close closes the iterator and all child iterators.
  9858  func (itr *stringReduceStringIterator) Close() error { return itr.input.Close() }
  9859  
  9860  // Next returns the minimum value for the next available interval.
  9861  func (itr *stringReduceStringIterator) Next() (*StringPoint, error) {
  9862  	// Calculate next window if we have no more points.
  9863  	if len(itr.points) == 0 {
  9864  		var err error
  9865  		itr.points, err = itr.reduce()
  9866  		if len(itr.points) == 0 {
  9867  			return nil, err
  9868  		}
  9869  	}
  9870  
  9871  	// Pop next point off the stack.
  9872  	p := &itr.points[len(itr.points)-1]
  9873  	itr.points = itr.points[:len(itr.points)-1]
  9874  	return p, nil
  9875  }
  9876  
  9877  // stringReduceStringPoint stores the reduced data for a name/tag combination.
  9878  type stringReduceStringPoint struct {
  9879  	Name       string
  9880  	Tags       Tags
  9881  	Aggregator StringPointAggregator
  9882  	Emitter    StringPointEmitter
  9883  }
  9884  
  9885  // reduce executes fn once for every point in the next window.
  9886  // The previous value for the dimension is passed to fn.
  9887  func (itr *stringReduceStringIterator) reduce() ([]StringPoint, error) {
  9888  	// Calculate next window.
  9889  	var (
  9890  		startTime, endTime int64
  9891  		window             struct {
  9892  			name string
  9893  			tags string
  9894  		}
  9895  	)
  9896  	for {
  9897  		p, err := itr.input.Next()
  9898  		if err != nil || p == nil {
  9899  			return nil, err
  9900  		} else if p.Nil {
  9901  			continue
  9902  		}
  9903  
  9904  		// Unread the point so it can be processed.
  9905  		itr.input.unread(p)
  9906  		startTime, endTime = itr.opt.Window(p.Time)
  9907  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
  9908  		break
  9909  	}
  9910  
  9911  	// Create points by tags.
  9912  	m := make(map[string]*stringReduceStringPoint)
  9913  	for {
  9914  		// Read next point.
  9915  		curr, err := itr.input.NextInWindow(startTime, endTime)
  9916  		if err != nil {
  9917  			return nil, err
  9918  		} else if curr == nil {
  9919  			break
  9920  		} else if curr.Nil {
  9921  			continue
  9922  		} else if curr.Name != window.name {
  9923  			itr.input.unread(curr)
  9924  			break
  9925  		}
  9926  
  9927  		// Ensure this point is within the same final window.
  9928  		if curr.Name != window.name {
  9929  			itr.input.unread(curr)
  9930  			break
  9931  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
  9932  			itr.input.unread(curr)
  9933  			break
  9934  		}
  9935  
  9936  		// Retrieve the tags on this point for this level of the query.
  9937  		// This may be different than the bucket dimensions.
  9938  		tags := curr.Tags.Subset(itr.dims)
  9939  		id := tags.ID()
  9940  
  9941  		// Retrieve the aggregator for this name/tag combination or create one.
  9942  		rp := m[id]
  9943  		if rp == nil {
  9944  			aggregator, emitter := itr.create()
  9945  			rp = &stringReduceStringPoint{
  9946  				Name:       curr.Name,
  9947  				Tags:       tags,
  9948  				Aggregator: aggregator,
  9949  				Emitter:    emitter,
  9950  			}
  9951  			m[id] = rp
  9952  		}
  9953  		rp.Aggregator.AggregateString(curr)
  9954  	}
  9955  
  9956  	keys := make([]string, 0, len(m))
  9957  	for k := range m {
  9958  		keys = append(keys, k)
  9959  	}
  9960  
  9961  	// Reverse sort points by name & tag.
  9962  	// This ensures a consistent order of output.
  9963  	if len(keys) > 0 {
  9964  		var sorted sort.Interface = sort.StringSlice(keys)
  9965  		if itr.opt.Ascending {
  9966  			sorted = sort.Reverse(sorted)
  9967  		}
  9968  		sort.Sort(sorted)
  9969  	}
  9970  
  9971  	// Assume the points are already sorted until proven otherwise.
  9972  	sortedByTime := true
  9973  	// Emit the points for each name & tag combination.
  9974  	a := make([]StringPoint, 0, len(m))
  9975  	for _, k := range keys {
  9976  		rp := m[k]
  9977  		points := rp.Emitter.Emit()
  9978  		for i := len(points) - 1; i >= 0; i-- {
  9979  			points[i].Name = rp.Name
  9980  			if !itr.keepTags {
  9981  				points[i].Tags = rp.Tags
  9982  			}
  9983  			// Set the points time to the interval time if the reducer didn't provide one.
  9984  			if points[i].Time == ZeroTime {
  9985  				points[i].Time = startTime
  9986  			} else {
  9987  				sortedByTime = false
  9988  			}
  9989  			a = append(a, points[i])
  9990  		}
  9991  	}
  9992  	// Points may be out of order. Perform a stable sort by time if requested.
  9993  	if !sortedByTime && itr.opt.Ordered {
  9994  		var sorted sort.Interface = stringPointsByTime(a)
  9995  		if itr.opt.Ascending {
  9996  			sorted = sort.Reverse(sorted)
  9997  		}
  9998  		sort.Stable(sorted)
  9999  	}
 10000  	return a, nil
 10001  }
 10002  
 10003  // stringStreamStringIterator streams inputs into the iterator and emits points gradually.
 10004  type stringStreamStringIterator struct {
 10005  	input  *bufStringIterator
 10006  	create func() (StringPointAggregator, StringPointEmitter)
 10007  	dims   []string
 10008  	opt    IteratorOptions
 10009  	m      map[string]*stringReduceStringPoint
 10010  	points []StringPoint
 10011  }
 10012  
 10013  // newStringStreamStringIterator returns a new instance of stringStreamStringIterator.
 10014  func newStringStreamStringIterator(input StringIterator, createFn func() (StringPointAggregator, StringPointEmitter), opt IteratorOptions) *stringStreamStringIterator {
 10015  	return &stringStreamStringIterator{
 10016  		input:  newBufStringIterator(input),
 10017  		create: createFn,
 10018  		dims:   opt.GetDimensions(),
 10019  		opt:    opt,
 10020  		m:      make(map[string]*stringReduceStringPoint),
 10021  	}
 10022  }
 10023  
 10024  // Stats returns stats from the input iterator.
 10025  func (itr *stringStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() }
 10026  
 10027  // Close closes the iterator and all child iterators.
 10028  func (itr *stringStreamStringIterator) Close() error { return itr.input.Close() }
 10029  
 10030  // Next returns the next value for the stream iterator.
 10031  func (itr *stringStreamStringIterator) Next() (*StringPoint, error) {
 10032  	// Calculate next window if we have no more points.
 10033  	if len(itr.points) == 0 {
 10034  		var err error
 10035  		itr.points, err = itr.reduce()
 10036  		if len(itr.points) == 0 {
 10037  			return nil, err
 10038  		}
 10039  	}
 10040  
 10041  	// Pop next point off the stack.
 10042  	p := &itr.points[len(itr.points)-1]
 10043  	itr.points = itr.points[:len(itr.points)-1]
 10044  	return p, nil
 10045  }
 10046  
 10047  // reduce creates and manages aggregators for every point from the input.
 10048  // After aggregating a point, it always tries to emit a value using the emitter.
 10049  func (itr *stringStreamStringIterator) reduce() ([]StringPoint, error) {
 10050  	// We have already read all of the input points.
 10051  	if itr.m == nil {
 10052  		return nil, nil
 10053  	}
 10054  
 10055  	for {
 10056  		// Read next point.
 10057  		curr, err := itr.input.Next()
 10058  		if err != nil {
 10059  			return nil, err
 10060  		} else if curr == nil {
 10061  			// Close all of the aggregators to flush any remaining points to emit.
 10062  			var points []StringPoint
 10063  			for _, rp := range itr.m {
 10064  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
 10065  					if err := aggregator.Close(); err != nil {
 10066  						return nil, err
 10067  					}
 10068  
 10069  					pts := rp.Emitter.Emit()
 10070  					if len(pts) == 0 {
 10071  						continue
 10072  					}
 10073  
 10074  					for i := range pts {
 10075  						pts[i].Name = rp.Name
 10076  						pts[i].Tags = rp.Tags
 10077  					}
 10078  					points = append(points, pts...)
 10079  				}
 10080  			}
 10081  
 10082  			// Eliminate the aggregators and emitters.
 10083  			itr.m = nil
 10084  			return points, nil
 10085  		} else if curr.Nil {
 10086  			continue
 10087  		}
 10088  		tags := curr.Tags.Subset(itr.dims)
 10089  
 10090  		id := curr.Name
 10091  		if len(tags.m) > 0 {
 10092  			id += "\x00" + tags.ID()
 10093  		}
 10094  
 10095  		// Retrieve the aggregator for this name/tag combination or create one.
 10096  		rp := itr.m[id]
 10097  		if rp == nil {
 10098  			aggregator, emitter := itr.create()
 10099  			rp = &stringReduceStringPoint{
 10100  				Name:       curr.Name,
 10101  				Tags:       tags,
 10102  				Aggregator: aggregator,
 10103  				Emitter:    emitter,
 10104  			}
 10105  			itr.m[id] = rp
 10106  		}
 10107  		rp.Aggregator.AggregateString(curr)
 10108  
 10109  		// Attempt to emit points from the aggregator.
 10110  		points := rp.Emitter.Emit()
 10111  		if len(points) == 0 {
 10112  			continue
 10113  		}
 10114  
 10115  		for i := range points {
 10116  			points[i].Name = rp.Name
 10117  			points[i].Tags = rp.Tags
 10118  		}
 10119  		return points, nil
 10120  	}
 10121  }
 10122  
 10123  // stringReduceBooleanIterator executes a reducer for every interval and buffers the result.
 10124  type stringReduceBooleanIterator struct {
 10125  	input    *bufStringIterator
 10126  	create   func() (StringPointAggregator, BooleanPointEmitter)
 10127  	dims     []string
 10128  	opt      IteratorOptions
 10129  	points   []BooleanPoint
 10130  	keepTags bool
 10131  }
 10132  
 10133  func newStringReduceBooleanIterator(input StringIterator, opt IteratorOptions, createFn func() (StringPointAggregator, BooleanPointEmitter)) *stringReduceBooleanIterator {
 10134  	return &stringReduceBooleanIterator{
 10135  		input:  newBufStringIterator(input),
 10136  		create: createFn,
 10137  		dims:   opt.GetDimensions(),
 10138  		opt:    opt,
 10139  	}
 10140  }
 10141  
 10142  // Stats returns stats from the input iterator.
 10143  func (itr *stringReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
 10144  
 10145  // Close closes the iterator and all child iterators.
 10146  func (itr *stringReduceBooleanIterator) Close() error { return itr.input.Close() }
 10147  
 10148  // Next returns the minimum value for the next available interval.
 10149  func (itr *stringReduceBooleanIterator) Next() (*BooleanPoint, error) {
 10150  	// Calculate next window if we have no more points.
 10151  	if len(itr.points) == 0 {
 10152  		var err error
 10153  		itr.points, err = itr.reduce()
 10154  		if len(itr.points) == 0 {
 10155  			return nil, err
 10156  		}
 10157  	}
 10158  
 10159  	// Pop next point off the stack.
 10160  	p := &itr.points[len(itr.points)-1]
 10161  	itr.points = itr.points[:len(itr.points)-1]
 10162  	return p, nil
 10163  }
 10164  
 10165  // stringReduceBooleanPoint stores the reduced data for a name/tag combination.
 10166  type stringReduceBooleanPoint struct {
 10167  	Name       string
 10168  	Tags       Tags
 10169  	Aggregator StringPointAggregator
 10170  	Emitter    BooleanPointEmitter
 10171  }
 10172  
 10173  // reduce executes fn once for every point in the next window.
 10174  // The previous value for the dimension is passed to fn.
 10175  func (itr *stringReduceBooleanIterator) reduce() ([]BooleanPoint, error) {
 10176  	// Calculate next window.
 10177  	var (
 10178  		startTime, endTime int64
 10179  		window             struct {
 10180  			name string
 10181  			tags string
 10182  		}
 10183  	)
 10184  	for {
 10185  		p, err := itr.input.Next()
 10186  		if err != nil || p == nil {
 10187  			return nil, err
 10188  		} else if p.Nil {
 10189  			continue
 10190  		}
 10191  
 10192  		// Unread the point so it can be processed.
 10193  		itr.input.unread(p)
 10194  		startTime, endTime = itr.opt.Window(p.Time)
 10195  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
 10196  		break
 10197  	}
 10198  
 10199  	// Create points by tags.
 10200  	m := make(map[string]*stringReduceBooleanPoint)
 10201  	for {
 10202  		// Read next point.
 10203  		curr, err := itr.input.NextInWindow(startTime, endTime)
 10204  		if err != nil {
 10205  			return nil, err
 10206  		} else if curr == nil {
 10207  			break
 10208  		} else if curr.Nil {
 10209  			continue
 10210  		} else if curr.Name != window.name {
 10211  			itr.input.unread(curr)
 10212  			break
 10213  		}
 10214  
 10215  		// Ensure this point is within the same final window.
 10216  		if curr.Name != window.name {
 10217  			itr.input.unread(curr)
 10218  			break
 10219  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
 10220  			itr.input.unread(curr)
 10221  			break
 10222  		}
 10223  
 10224  		// Retrieve the tags on this point for this level of the query.
 10225  		// This may be different than the bucket dimensions.
 10226  		tags := curr.Tags.Subset(itr.dims)
 10227  		id := tags.ID()
 10228  
 10229  		// Retrieve the aggregator for this name/tag combination or create one.
 10230  		rp := m[id]
 10231  		if rp == nil {
 10232  			aggregator, emitter := itr.create()
 10233  			rp = &stringReduceBooleanPoint{
 10234  				Name:       curr.Name,
 10235  				Tags:       tags,
 10236  				Aggregator: aggregator,
 10237  				Emitter:    emitter,
 10238  			}
 10239  			m[id] = rp
 10240  		}
 10241  		rp.Aggregator.AggregateString(curr)
 10242  	}
 10243  
 10244  	keys := make([]string, 0, len(m))
 10245  	for k := range m {
 10246  		keys = append(keys, k)
 10247  	}
 10248  
 10249  	// Reverse sort points by name & tag.
 10250  	// This ensures a consistent order of output.
 10251  	if len(keys) > 0 {
 10252  		var sorted sort.Interface = sort.StringSlice(keys)
 10253  		if itr.opt.Ascending {
 10254  			sorted = sort.Reverse(sorted)
 10255  		}
 10256  		sort.Sort(sorted)
 10257  	}
 10258  
 10259  	// Assume the points are already sorted until proven otherwise.
 10260  	sortedByTime := true
 10261  	// Emit the points for each name & tag combination.
 10262  	a := make([]BooleanPoint, 0, len(m))
 10263  	for _, k := range keys {
 10264  		rp := m[k]
 10265  		points := rp.Emitter.Emit()
 10266  		for i := len(points) - 1; i >= 0; i-- {
 10267  			points[i].Name = rp.Name
 10268  			if !itr.keepTags {
 10269  				points[i].Tags = rp.Tags
 10270  			}
 10271  			// Set the points time to the interval time if the reducer didn't provide one.
 10272  			if points[i].Time == ZeroTime {
 10273  				points[i].Time = startTime
 10274  			} else {
 10275  				sortedByTime = false
 10276  			}
 10277  			a = append(a, points[i])
 10278  		}
 10279  	}
 10280  	// Points may be out of order. Perform a stable sort by time if requested.
 10281  	if !sortedByTime && itr.opt.Ordered {
 10282  		var sorted sort.Interface = booleanPointsByTime(a)
 10283  		if itr.opt.Ascending {
 10284  			sorted = sort.Reverse(sorted)
 10285  		}
 10286  		sort.Stable(sorted)
 10287  	}
 10288  	return a, nil
 10289  }
 10290  
 10291  // stringStreamBooleanIterator streams inputs into the iterator and emits points gradually.
 10292  type stringStreamBooleanIterator struct {
 10293  	input  *bufStringIterator
 10294  	create func() (StringPointAggregator, BooleanPointEmitter)
 10295  	dims   []string
 10296  	opt    IteratorOptions
 10297  	m      map[string]*stringReduceBooleanPoint
 10298  	points []BooleanPoint
 10299  }
 10300  
 10301  // newStringStreamBooleanIterator returns a new instance of stringStreamBooleanIterator.
 10302  func newStringStreamBooleanIterator(input StringIterator, createFn func() (StringPointAggregator, BooleanPointEmitter), opt IteratorOptions) *stringStreamBooleanIterator {
 10303  	return &stringStreamBooleanIterator{
 10304  		input:  newBufStringIterator(input),
 10305  		create: createFn,
 10306  		dims:   opt.GetDimensions(),
 10307  		opt:    opt,
 10308  		m:      make(map[string]*stringReduceBooleanPoint),
 10309  	}
 10310  }
 10311  
 10312  // Stats returns stats from the input iterator.
 10313  func (itr *stringStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
 10314  
 10315  // Close closes the iterator and all child iterators.
 10316  func (itr *stringStreamBooleanIterator) Close() error { return itr.input.Close() }
 10317  
 10318  // Next returns the next value for the stream iterator.
 10319  func (itr *stringStreamBooleanIterator) Next() (*BooleanPoint, error) {
 10320  	// Calculate next window if we have no more points.
 10321  	if len(itr.points) == 0 {
 10322  		var err error
 10323  		itr.points, err = itr.reduce()
 10324  		if len(itr.points) == 0 {
 10325  			return nil, err
 10326  		}
 10327  	}
 10328  
 10329  	// Pop next point off the stack.
 10330  	p := &itr.points[len(itr.points)-1]
 10331  	itr.points = itr.points[:len(itr.points)-1]
 10332  	return p, nil
 10333  }
 10334  
 10335  // reduce creates and manages aggregators for every point from the input.
 10336  // After aggregating a point, it always tries to emit a value using the emitter.
 10337  func (itr *stringStreamBooleanIterator) reduce() ([]BooleanPoint, error) {
 10338  	// We have already read all of the input points.
 10339  	if itr.m == nil {
 10340  		return nil, nil
 10341  	}
 10342  
 10343  	for {
 10344  		// Read next point.
 10345  		curr, err := itr.input.Next()
 10346  		if err != nil {
 10347  			return nil, err
 10348  		} else if curr == nil {
 10349  			// Close all of the aggregators to flush any remaining points to emit.
 10350  			var points []BooleanPoint
 10351  			for _, rp := range itr.m {
 10352  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
 10353  					if err := aggregator.Close(); err != nil {
 10354  						return nil, err
 10355  					}
 10356  
 10357  					pts := rp.Emitter.Emit()
 10358  					if len(pts) == 0 {
 10359  						continue
 10360  					}
 10361  
 10362  					for i := range pts {
 10363  						pts[i].Name = rp.Name
 10364  						pts[i].Tags = rp.Tags
 10365  					}
 10366  					points = append(points, pts...)
 10367  				}
 10368  			}
 10369  
 10370  			// Eliminate the aggregators and emitters.
 10371  			itr.m = nil
 10372  			return points, nil
 10373  		} else if curr.Nil {
 10374  			continue
 10375  		}
 10376  		tags := curr.Tags.Subset(itr.dims)
 10377  
 10378  		id := curr.Name
 10379  		if len(tags.m) > 0 {
 10380  			id += "\x00" + tags.ID()
 10381  		}
 10382  
 10383  		// Retrieve the aggregator for this name/tag combination or create one.
 10384  		rp := itr.m[id]
 10385  		if rp == nil {
 10386  			aggregator, emitter := itr.create()
 10387  			rp = &stringReduceBooleanPoint{
 10388  				Name:       curr.Name,
 10389  				Tags:       tags,
 10390  				Aggregator: aggregator,
 10391  				Emitter:    emitter,
 10392  			}
 10393  			itr.m[id] = rp
 10394  		}
 10395  		rp.Aggregator.AggregateString(curr)
 10396  
 10397  		// Attempt to emit points from the aggregator.
 10398  		points := rp.Emitter.Emit()
 10399  		if len(points) == 0 {
 10400  			continue
 10401  		}
 10402  
 10403  		for i := range points {
 10404  			points[i].Name = rp.Name
 10405  			points[i].Tags = rp.Tags
 10406  		}
 10407  		return points, nil
 10408  	}
 10409  }
 10410  
 10411  // stringDedupeIterator only outputs unique points.
 10412  // This differs from the DistinctIterator in that it compares all aux fields too.
 10413  // This iterator is relatively inefficient and should only be used on small
 10414  // datasets such as meta query results.
 10415  type stringDedupeIterator struct {
 10416  	input StringIterator
 10417  	m     map[string]struct{} // lookup of points already sent
 10418  }
 10419  
 10420  type stringIteratorMapper struct {
 10421  	cur    Cursor
 10422  	row    Row
 10423  	driver IteratorMap   // which iterator to use for the primary value, can be nil
 10424  	fields []IteratorMap // which iterator to use for an aux field
 10425  	point  StringPoint
 10426  }
 10427  
 10428  func newStringIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *stringIteratorMapper {
 10429  	return &stringIteratorMapper{
 10430  		cur:    cur,
 10431  		driver: driver,
 10432  		fields: fields,
 10433  		point: StringPoint{
 10434  			Aux: make([]interface{}, len(fields)),
 10435  		},
 10436  	}
 10437  }
 10438  
 10439  func (itr *stringIteratorMapper) Next() (*StringPoint, error) {
 10440  	if !itr.cur.Scan(&itr.row) {
 10441  		if err := itr.cur.Err(); err != nil {
 10442  			return nil, err
 10443  		}
 10444  		return nil, nil
 10445  	}
 10446  
 10447  	itr.point.Time = itr.row.Time
 10448  	itr.point.Name = itr.row.Series.Name
 10449  	itr.point.Tags = itr.row.Series.Tags
 10450  
 10451  	if itr.driver != nil {
 10452  		if v := itr.driver.Value(&itr.row); v != nil {
 10453  			if v, ok := castToString(v); ok {
 10454  				itr.point.Value = v
 10455  				itr.point.Nil = false
 10456  			} else {
 10457  				itr.point.Value = ""
 10458  				itr.point.Nil = true
 10459  			}
 10460  		} else {
 10461  			itr.point.Value = ""
 10462  			itr.point.Nil = true
 10463  		}
 10464  	}
 10465  	for i, f := range itr.fields {
 10466  		itr.point.Aux[i] = f.Value(&itr.row)
 10467  	}
 10468  	return &itr.point, nil
 10469  }
 10470  
 10471  func (itr *stringIteratorMapper) Stats() IteratorStats {
 10472  	return itr.cur.Stats()
 10473  }
 10474  
 10475  func (itr *stringIteratorMapper) Close() error {
 10476  	return itr.cur.Close()
 10477  }
 10478  
 10479  type stringFilterIterator struct {
 10480  	input StringIterator
 10481  	cond  influxql.Expr
 10482  	opt   IteratorOptions
 10483  	m     map[string]interface{}
 10484  }
 10485  
 10486  func newStringFilterIterator(input StringIterator, cond influxql.Expr, opt IteratorOptions) StringIterator {
 10487  	// Strip out time conditions from the WHERE clause.
 10488  	// TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct.
 10489  	n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node {
 10490  		switch n := n.(type) {
 10491  		case *influxql.BinaryExpr:
 10492  			if n.LHS.String() == "time" {
 10493  				return &influxql.BooleanLiteral{Val: true}
 10494  			}
 10495  		}
 10496  		return n
 10497  	})
 10498  
 10499  	cond, _ = n.(influxql.Expr)
 10500  	if cond == nil {
 10501  		return input
 10502  	} else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val {
 10503  		return input
 10504  	}
 10505  
 10506  	return &stringFilterIterator{
 10507  		input: input,
 10508  		cond:  cond,
 10509  		opt:   opt,
 10510  		m:     make(map[string]interface{}),
 10511  	}
 10512  }
 10513  
 10514  func (itr *stringFilterIterator) Stats() IteratorStats { return itr.input.Stats() }
 10515  func (itr *stringFilterIterator) Close() error         { return itr.input.Close() }
 10516  
 10517  func (itr *stringFilterIterator) Next() (*StringPoint, error) {
 10518  	for {
 10519  		p, err := itr.input.Next()
 10520  		if err != nil || p == nil {
 10521  			return nil, err
 10522  		}
 10523  
 10524  		for i, ref := range itr.opt.Aux {
 10525  			itr.m[ref.Val] = p.Aux[i]
 10526  		}
 10527  		for k, v := range p.Tags.KeyValues() {
 10528  			itr.m[k] = v
 10529  		}
 10530  
 10531  		if !influxql.EvalBool(itr.cond, itr.m) {
 10532  			continue
 10533  		}
 10534  		return p, nil
 10535  	}
 10536  }
 10537  
 10538  type stringTagSubsetIterator struct {
 10539  	input      StringIterator
 10540  	point      StringPoint
 10541  	lastTags   Tags
 10542  	dimensions []string
 10543  }
 10544  
 10545  func newStringTagSubsetIterator(input StringIterator, opt IteratorOptions) *stringTagSubsetIterator {
 10546  	return &stringTagSubsetIterator{
 10547  		input:      input,
 10548  		dimensions: opt.GetDimensions(),
 10549  	}
 10550  }
 10551  
 10552  func (itr *stringTagSubsetIterator) Next() (*StringPoint, error) {
 10553  	p, err := itr.input.Next()
 10554  	if err != nil {
 10555  		return nil, err
 10556  	} else if p == nil {
 10557  		return nil, nil
 10558  	}
 10559  
 10560  	itr.point.Name = p.Name
 10561  	if !p.Tags.Equal(itr.lastTags) {
 10562  		itr.point.Tags = p.Tags.Subset(itr.dimensions)
 10563  		itr.lastTags = p.Tags
 10564  	}
 10565  	itr.point.Time = p.Time
 10566  	itr.point.Value = p.Value
 10567  	itr.point.Aux = p.Aux
 10568  	itr.point.Aggregated = p.Aggregated
 10569  	itr.point.Nil = p.Nil
 10570  	return &itr.point, nil
 10571  }
 10572  
 10573  func (itr *stringTagSubsetIterator) Stats() IteratorStats {
 10574  	return itr.input.Stats()
 10575  }
 10576  
 10577  func (itr *stringTagSubsetIterator) Close() error {
 10578  	return itr.input.Close()
 10579  }
 10580  
 10581  // newStringDedupeIterator returns a new instance of stringDedupeIterator.
 10582  func newStringDedupeIterator(input StringIterator) *stringDedupeIterator {
 10583  	return &stringDedupeIterator{
 10584  		input: input,
 10585  		m:     make(map[string]struct{}),
 10586  	}
 10587  }
 10588  
 10589  // Stats returns stats from the input iterator.
 10590  func (itr *stringDedupeIterator) Stats() IteratorStats { return itr.input.Stats() }
 10591  
 10592  // Close closes the iterator and all child iterators.
 10593  func (itr *stringDedupeIterator) Close() error { return itr.input.Close() }
 10594  
 10595  // Next returns the next unique point from the input iterator.
 10596  func (itr *stringDedupeIterator) Next() (*StringPoint, error) {
 10597  	for {
 10598  		// Read next point.
 10599  		p, err := itr.input.Next()
 10600  		if p == nil || err != nil {
 10601  			return nil, err
 10602  		}
 10603  
 10604  		// Serialize to bytes to store in lookup.
 10605  		buf, err := proto.Marshal(encodeStringPoint(p))
 10606  		if err != nil {
 10607  			return nil, err
 10608  		}
 10609  
 10610  		// If the point has already been output then move to the next point.
 10611  		if _, ok := itr.m[string(buf)]; ok {
 10612  			continue
 10613  		}
 10614  
 10615  		// Otherwise mark it as emitted and return point.
 10616  		itr.m[string(buf)] = struct{}{}
 10617  		return p, nil
 10618  	}
 10619  }
 10620  
 10621  // stringReaderIterator represents an iterator that streams from a reader.
 10622  type stringReaderIterator struct {
 10623  	r   io.Reader
 10624  	dec *StringPointDecoder
 10625  }
 10626  
 10627  // newStringReaderIterator returns a new instance of stringReaderIterator.
 10628  func newStringReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *stringReaderIterator {
 10629  	dec := NewStringPointDecoder(ctx, r)
 10630  	dec.stats = stats
 10631  
 10632  	return &stringReaderIterator{
 10633  		r:   r,
 10634  		dec: dec,
 10635  	}
 10636  }
 10637  
 10638  // Stats returns stats about points processed.
 10639  func (itr *stringReaderIterator) Stats() IteratorStats { return itr.dec.stats }
 10640  
 10641  // Close closes the underlying reader, if applicable.
 10642  func (itr *stringReaderIterator) Close() error {
 10643  	if r, ok := itr.r.(io.ReadCloser); ok {
 10644  		return r.Close()
 10645  	}
 10646  	return nil
 10647  }
 10648  
 10649  // Next returns the next point from the iterator.
 10650  func (itr *stringReaderIterator) Next() (*StringPoint, error) {
 10651  	// OPTIMIZE(benbjohnson): Reuse point on iterator.
 10652  
 10653  	// Unmarshal next point.
 10654  	p := &StringPoint{}
 10655  	if err := itr.dec.DecodeStringPoint(p); err == io.EOF {
 10656  		return nil, nil
 10657  	} else if err != nil {
 10658  		return nil, err
 10659  	}
 10660  	return p, nil
 10661  }
 10662  
 10663  // BooleanIterator represents a stream of boolean points.
 10664  type BooleanIterator interface {
 10665  	Iterator
 10666  	Next() (*BooleanPoint, error)
 10667  }
 10668  
 10669  // newBooleanIterators converts a slice of Iterator to a slice of BooleanIterator.
 10670  // Drop and closes any iterator in itrs that is not a BooleanIterator and cannot
 10671  // be cast to a BooleanIterator.
 10672  func newBooleanIterators(itrs []Iterator) []BooleanIterator {
 10673  	a := make([]BooleanIterator, 0, len(itrs))
 10674  	for _, itr := range itrs {
 10675  		switch itr := itr.(type) {
 10676  		case BooleanIterator:
 10677  			a = append(a, itr)
 10678  		default:
 10679  			itr.Close()
 10680  		}
 10681  	}
 10682  	return a
 10683  }
 10684  
 10685  // bufBooleanIterator represents a buffered BooleanIterator.
 10686  type bufBooleanIterator struct {
 10687  	itr BooleanIterator
 10688  	buf *BooleanPoint
 10689  }
 10690  
 10691  // newBufBooleanIterator returns a buffered BooleanIterator.
 10692  func newBufBooleanIterator(itr BooleanIterator) *bufBooleanIterator {
 10693  	return &bufBooleanIterator{itr: itr}
 10694  }
 10695  
 10696  // Stats returns statistics from the input iterator.
 10697  func (itr *bufBooleanIterator) Stats() IteratorStats { return itr.itr.Stats() }
 10698  
 10699  // Close closes the underlying iterator.
 10700  func (itr *bufBooleanIterator) Close() error { return itr.itr.Close() }
 10701  
 10702  // peek returns the next point without removing it from the iterator.
 10703  func (itr *bufBooleanIterator) peek() (*BooleanPoint, error) {
 10704  	p, err := itr.Next()
 10705  	if err != nil {
 10706  		return nil, err
 10707  	}
 10708  	itr.unread(p)
 10709  	return p, nil
 10710  }
 10711  
 10712  // peekTime returns the time of the next point.
 10713  // Returns zero time if no more points available.
 10714  func (itr *bufBooleanIterator) peekTime() (int64, error) {
 10715  	p, err := itr.peek()
 10716  	if p == nil || err != nil {
 10717  		return ZeroTime, err
 10718  	}
 10719  	return p.Time, nil
 10720  }
 10721  
 10722  // Next returns the current buffer, if exists, or calls the underlying iterator.
 10723  func (itr *bufBooleanIterator) Next() (*BooleanPoint, error) {
 10724  	buf := itr.buf
 10725  	if buf != nil {
 10726  		itr.buf = nil
 10727  		return buf, nil
 10728  	}
 10729  	return itr.itr.Next()
 10730  }
 10731  
 10732  // NextInWindow returns the next value if it is between [startTime, endTime).
 10733  // If the next value is outside the range then it is moved to the buffer.
 10734  func (itr *bufBooleanIterator) NextInWindow(startTime, endTime int64) (*BooleanPoint, error) {
 10735  	v, err := itr.Next()
 10736  	if v == nil || err != nil {
 10737  		return nil, err
 10738  	} else if t := v.Time; t >= endTime || t < startTime {
 10739  		itr.unread(v)
 10740  		return nil, nil
 10741  	}
 10742  	return v, nil
 10743  }
 10744  
 10745  // unread sets v to the buffer. It is read on the next call to Next().
 10746  func (itr *bufBooleanIterator) unread(v *BooleanPoint) { itr.buf = v }
 10747  
 10748  // booleanMergeIterator represents an iterator that combines multiple boolean iterators.
 10749  type booleanMergeIterator struct {
 10750  	inputs []BooleanIterator
 10751  	heap   *booleanMergeHeap
 10752  	init   bool
 10753  
 10754  	closed bool
 10755  	mu     sync.RWMutex
 10756  
 10757  	// Current iterator and window.
 10758  	curr   *booleanMergeHeapItem
 10759  	window struct {
 10760  		name      string
 10761  		tags      string
 10762  		startTime int64
 10763  		endTime   int64
 10764  	}
 10765  }
 10766  
 10767  // newBooleanMergeIterator returns a new instance of booleanMergeIterator.
 10768  func newBooleanMergeIterator(inputs []BooleanIterator, opt IteratorOptions) *booleanMergeIterator {
 10769  	itr := &booleanMergeIterator{
 10770  		inputs: inputs,
 10771  		heap: &booleanMergeHeap{
 10772  			items: make([]*booleanMergeHeapItem, 0, len(inputs)),
 10773  			opt:   opt,
 10774  		},
 10775  	}
 10776  
 10777  	// Initialize heap items.
 10778  	for _, input := range inputs {
 10779  		// Wrap in buffer, ignore any inputs without anymore points.
 10780  		bufInput := newBufBooleanIterator(input)
 10781  
 10782  		// Append to the heap.
 10783  		itr.heap.items = append(itr.heap.items, &booleanMergeHeapItem{itr: bufInput})
 10784  	}
 10785  
 10786  	return itr
 10787  }
 10788  
 10789  // Stats returns an aggregation of stats from the underlying iterators.
 10790  func (itr *booleanMergeIterator) Stats() IteratorStats {
 10791  	var stats IteratorStats
 10792  	for _, input := range itr.inputs {
 10793  		stats.Add(input.Stats())
 10794  	}
 10795  	return stats
 10796  }
 10797  
 10798  // Close closes the underlying iterators.
 10799  func (itr *booleanMergeIterator) Close() error {
 10800  	itr.mu.Lock()
 10801  	defer itr.mu.Unlock()
 10802  
 10803  	for _, input := range itr.inputs {
 10804  		input.Close()
 10805  	}
 10806  	itr.curr = nil
 10807  	itr.inputs = nil
 10808  	itr.heap.items = nil
 10809  	itr.closed = true
 10810  	return nil
 10811  }
 10812  
 10813  // Next returns the next point from the iterator.
 10814  func (itr *booleanMergeIterator) Next() (*BooleanPoint, error) {
 10815  	itr.mu.RLock()
 10816  	defer itr.mu.RUnlock()
 10817  	if itr.closed {
 10818  		return nil, nil
 10819  	}
 10820  
 10821  	// Initialize the heap. This needs to be done lazily on the first call to this iterator
 10822  	// so that iterator initialization done through the Select() call returns quickly.
 10823  	// Queries can only be interrupted after the Select() call completes so any operations
 10824  	// done during iterator creation cannot be interrupted, which is why we do it here
 10825  	// instead so an interrupt can happen while initializing the heap.
 10826  	if !itr.init {
 10827  		items := itr.heap.items
 10828  		itr.heap.items = make([]*booleanMergeHeapItem, 0, len(items))
 10829  		for _, item := range items {
 10830  			if p, err := item.itr.peek(); err != nil {
 10831  				return nil, err
 10832  			} else if p == nil {
 10833  				continue
 10834  			}
 10835  			itr.heap.items = append(itr.heap.items, item)
 10836  		}
 10837  		heap.Init(itr.heap)
 10838  		itr.init = true
 10839  	}
 10840  
 10841  	for {
 10842  		// Retrieve the next iterator if we don't have one.
 10843  		if itr.curr == nil {
 10844  			if len(itr.heap.items) == 0 {
 10845  				return nil, nil
 10846  			}
 10847  			itr.curr = heap.Pop(itr.heap).(*booleanMergeHeapItem)
 10848  
 10849  			// Read point and set current window.
 10850  			p, err := itr.curr.itr.Next()
 10851  			if err != nil {
 10852  				return nil, err
 10853  			}
 10854  			tags := p.Tags.Subset(itr.heap.opt.Dimensions)
 10855  			itr.window.name, itr.window.tags = p.Name, tags.ID()
 10856  			itr.window.startTime, itr.window.endTime = itr.heap.opt.Window(p.Time)
 10857  			return p, nil
 10858  		}
 10859  
 10860  		// Read the next point from the current iterator.
 10861  		p, err := itr.curr.itr.Next()
 10862  		if err != nil {
 10863  			return nil, err
 10864  		}
 10865  
 10866  		// If there are no more points then remove iterator from heap and find next.
 10867  		if p == nil {
 10868  			itr.curr = nil
 10869  			continue
 10870  		}
 10871  
 10872  		// Check if the point is inside of our current window.
 10873  		inWindow := true
 10874  		if window := itr.window; window.name != p.Name {
 10875  			inWindow = false
 10876  		} else if tags := p.Tags.Subset(itr.heap.opt.Dimensions); window.tags != tags.ID() {
 10877  			inWindow = false
 10878  		} else if opt := itr.heap.opt; opt.Ascending && p.Time >= window.endTime {
 10879  			inWindow = false
 10880  		} else if !opt.Ascending && p.Time < window.startTime {
 10881  			inWindow = false
 10882  		}
 10883  
 10884  		// If it's outside our window then push iterator back on the heap and find new iterator.
 10885  		if !inWindow {
 10886  			itr.curr.itr.unread(p)
 10887  			heap.Push(itr.heap, itr.curr)
 10888  			itr.curr = nil
 10889  			continue
 10890  		}
 10891  
 10892  		return p, nil
 10893  	}
 10894  }
 10895  
 10896  // booleanMergeHeap represents a heap of booleanMergeHeapItems.
 10897  // Items are sorted by their next window and then by name/tags.
 10898  type booleanMergeHeap struct {
 10899  	opt   IteratorOptions
 10900  	items []*booleanMergeHeapItem
 10901  }
 10902  
 10903  func (h *booleanMergeHeap) Len() int      { return len(h.items) }
 10904  func (h *booleanMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
 10905  func (h *booleanMergeHeap) Less(i, j int) bool {
 10906  	x, err := h.items[i].itr.peek()
 10907  	if err != nil {
 10908  		return true
 10909  	}
 10910  	y, err := h.items[j].itr.peek()
 10911  	if err != nil {
 10912  		return false
 10913  	}
 10914  
 10915  	if h.opt.Ascending {
 10916  		if x.Name != y.Name {
 10917  			return x.Name < y.Name
 10918  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
 10919  			return xTags.ID() < yTags.ID()
 10920  		}
 10921  	} else {
 10922  		if x.Name != y.Name {
 10923  			return x.Name > y.Name
 10924  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); xTags.ID() != yTags.ID() {
 10925  			return xTags.ID() > yTags.ID()
 10926  		}
 10927  	}
 10928  
 10929  	xt, _ := h.opt.Window(x.Time)
 10930  	yt, _ := h.opt.Window(y.Time)
 10931  
 10932  	if h.opt.Ascending {
 10933  		return xt < yt
 10934  	}
 10935  	return xt > yt
 10936  }
 10937  
 10938  func (h *booleanMergeHeap) Push(x interface{}) {
 10939  	h.items = append(h.items, x.(*booleanMergeHeapItem))
 10940  }
 10941  
 10942  func (h *booleanMergeHeap) Pop() interface{} {
 10943  	old := h.items
 10944  	n := len(old)
 10945  	item := old[n-1]
 10946  	h.items = old[0 : n-1]
 10947  	return item
 10948  }
 10949  
 10950  type booleanMergeHeapItem struct {
 10951  	itr *bufBooleanIterator
 10952  }
 10953  
 10954  // booleanSortedMergeIterator is an iterator that sorts and merges multiple iterators into one.
 10955  type booleanSortedMergeIterator struct {
 10956  	inputs []BooleanIterator
 10957  	heap   *booleanSortedMergeHeap
 10958  	init   bool
 10959  }
 10960  
 10961  // newBooleanSortedMergeIterator returns an instance of booleanSortedMergeIterator.
 10962  func newBooleanSortedMergeIterator(inputs []BooleanIterator, opt IteratorOptions) Iterator {
 10963  	itr := &booleanSortedMergeIterator{
 10964  		inputs: inputs,
 10965  		heap: &booleanSortedMergeHeap{
 10966  			items: make([]*booleanSortedMergeHeapItem, 0, len(inputs)),
 10967  			opt:   opt,
 10968  		},
 10969  	}
 10970  
 10971  	// Initialize heap items.
 10972  	for _, input := range inputs {
 10973  		// Append to the heap.
 10974  		itr.heap.items = append(itr.heap.items, &booleanSortedMergeHeapItem{itr: input})
 10975  	}
 10976  
 10977  	return itr
 10978  }
 10979  
 10980  // Stats returns an aggregation of stats from the underlying iterators.
 10981  func (itr *booleanSortedMergeIterator) Stats() IteratorStats {
 10982  	var stats IteratorStats
 10983  	for _, input := range itr.inputs {
 10984  		stats.Add(input.Stats())
 10985  	}
 10986  	return stats
 10987  }
 10988  
 10989  // Close closes the underlying iterators.
 10990  func (itr *booleanSortedMergeIterator) Close() error {
 10991  	for _, input := range itr.inputs {
 10992  		input.Close()
 10993  	}
 10994  	return nil
 10995  }
 10996  
 10997  // Next returns the next points from the iterator.
 10998  func (itr *booleanSortedMergeIterator) Next() (*BooleanPoint, error) { return itr.pop() }
 10999  
 11000  // pop returns the next point from the heap.
 11001  // Reads the next point from item's cursor and puts it back on the heap.
 11002  func (itr *booleanSortedMergeIterator) pop() (*BooleanPoint, error) {
 11003  	// Initialize the heap. See the MergeIterator to see why this has to be done lazily.
 11004  	if !itr.init {
 11005  		items := itr.heap.items
 11006  		itr.heap.items = make([]*booleanSortedMergeHeapItem, 0, len(items))
 11007  		for _, item := range items {
 11008  			var err error
 11009  			if item.point, err = item.itr.Next(); err != nil {
 11010  				return nil, err
 11011  			} else if item.point == nil {
 11012  				continue
 11013  			}
 11014  			itr.heap.items = append(itr.heap.items, item)
 11015  		}
 11016  		heap.Init(itr.heap)
 11017  		itr.init = true
 11018  	}
 11019  
 11020  	if len(itr.heap.items) == 0 {
 11021  		return nil, nil
 11022  	}
 11023  
 11024  	// Read the next item from the heap.
 11025  	item := heap.Pop(itr.heap).(*booleanSortedMergeHeapItem)
 11026  	if item.err != nil {
 11027  		return nil, item.err
 11028  	} else if item.point == nil {
 11029  		return nil, nil
 11030  	}
 11031  
 11032  	// Copy the point for return.
 11033  	p := item.point.Clone()
 11034  
 11035  	// Read the next item from the cursor. Push back to heap if one exists.
 11036  	if item.point, item.err = item.itr.Next(); item.point != nil {
 11037  		heap.Push(itr.heap, item)
 11038  	}
 11039  
 11040  	return p, nil
 11041  }
 11042  
 11043  // booleanSortedMergeHeap represents a heap of booleanSortedMergeHeapItems.
 11044  // Items are sorted with the following priority:
 11045  //   - By their measurement name;
 11046  //   - By their tag keys/values;
 11047  //   - By time; or
 11048  //   - By their Aux field values.
 11049  type booleanSortedMergeHeap struct {
 11050  	opt   IteratorOptions
 11051  	items []*booleanSortedMergeHeapItem
 11052  }
 11053  
 11054  func (h *booleanSortedMergeHeap) Len() int      { return len(h.items) }
 11055  func (h *booleanSortedMergeHeap) Swap(i, j int) { h.items[i], h.items[j] = h.items[j], h.items[i] }
 11056  func (h *booleanSortedMergeHeap) Less(i, j int) bool {
 11057  	x, y := h.items[i].point, h.items[j].point
 11058  
 11059  	if h.opt.Ascending {
 11060  		if x.Name != y.Name {
 11061  			return x.Name < y.Name
 11062  		} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
 11063  			return xTags.ID() < yTags.ID()
 11064  		}
 11065  
 11066  		if x.Time != y.Time {
 11067  			return x.Time < y.Time
 11068  		}
 11069  
 11070  		if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
 11071  			for i := 0; i < len(x.Aux); i++ {
 11072  				v1, ok1 := x.Aux[i].(string)
 11073  				v2, ok2 := y.Aux[i].(string)
 11074  				if !ok1 || !ok2 {
 11075  					// Unsupported types used in Aux fields. Maybe they
 11076  					// need to be added here?
 11077  					return false
 11078  				} else if v1 == v2 {
 11079  					continue
 11080  				}
 11081  				return v1 < v2
 11082  			}
 11083  		}
 11084  		return false // Times and/or Aux fields are equal.
 11085  	}
 11086  
 11087  	if x.Name != y.Name {
 11088  		return x.Name > y.Name
 11089  	} else if xTags, yTags := x.Tags.Subset(h.opt.Dimensions), y.Tags.Subset(h.opt.Dimensions); !xTags.Equals(&yTags) {
 11090  		return xTags.ID() > yTags.ID()
 11091  	}
 11092  
 11093  	if x.Time != y.Time {
 11094  		return x.Time > y.Time
 11095  	}
 11096  
 11097  	if len(x.Aux) > 0 && len(x.Aux) == len(y.Aux) {
 11098  		for i := 0; i < len(x.Aux); i++ {
 11099  			v1, ok1 := x.Aux[i].(string)
 11100  			v2, ok2 := y.Aux[i].(string)
 11101  			if !ok1 || !ok2 {
 11102  				// Unsupported types used in Aux fields. Maybe they
 11103  				// need to be added here?
 11104  				return false
 11105  			} else if v1 == v2 {
 11106  				continue
 11107  			}
 11108  			return v1 > v2
 11109  		}
 11110  	}
 11111  	return false // Times and/or Aux fields are equal.
 11112  }
 11113  
 11114  func (h *booleanSortedMergeHeap) Push(x interface{}) {
 11115  	h.items = append(h.items, x.(*booleanSortedMergeHeapItem))
 11116  }
 11117  
 11118  func (h *booleanSortedMergeHeap) Pop() interface{} {
 11119  	old := h.items
 11120  	n := len(old)
 11121  	item := old[n-1]
 11122  	h.items = old[0 : n-1]
 11123  	return item
 11124  }
 11125  
 11126  type booleanSortedMergeHeapItem struct {
 11127  	point *BooleanPoint
 11128  	err   error
 11129  	itr   BooleanIterator
 11130  }
 11131  
 11132  // booleanIteratorScanner scans the results of a BooleanIterator into a map.
 11133  type booleanIteratorScanner struct {
 11134  	input        *bufBooleanIterator
 11135  	err          error
 11136  	keys         []influxql.VarRef
 11137  	defaultValue interface{}
 11138  }
 11139  
 11140  // newBooleanIteratorScanner creates a new IteratorScanner.
 11141  func newBooleanIteratorScanner(input BooleanIterator, keys []influxql.VarRef, defaultValue interface{}) *booleanIteratorScanner {
 11142  	return &booleanIteratorScanner{
 11143  		input:        newBufBooleanIterator(input),
 11144  		keys:         keys,
 11145  		defaultValue: defaultValue,
 11146  	}
 11147  }
 11148  
 11149  func (s *booleanIteratorScanner) Peek() (int64, string, Tags) {
 11150  	if s.err != nil {
 11151  		return ZeroTime, "", Tags{}
 11152  	}
 11153  
 11154  	p, err := s.input.peek()
 11155  	if err != nil {
 11156  		s.err = err
 11157  		return ZeroTime, "", Tags{}
 11158  	} else if p == nil {
 11159  		return ZeroTime, "", Tags{}
 11160  	}
 11161  	return p.Time, p.Name, p.Tags
 11162  }
 11163  
 11164  func (s *booleanIteratorScanner) ScanAt(ts int64, name string, tags Tags, m map[string]interface{}) {
 11165  	if s.err != nil {
 11166  		return
 11167  	}
 11168  
 11169  	p, err := s.input.Next()
 11170  	if err != nil {
 11171  		s.err = err
 11172  		return
 11173  	} else if p == nil {
 11174  		s.useDefaults(m)
 11175  		return
 11176  	} else if p.Time != ts || p.Name != name || !p.Tags.Equals(&tags) {
 11177  		s.useDefaults(m)
 11178  		s.input.unread(p)
 11179  		return
 11180  	}
 11181  
 11182  	if k := s.keys[0]; k.Val != "" {
 11183  		if p.Nil {
 11184  			if s.defaultValue != SkipDefault {
 11185  				m[k.Val] = castToType(s.defaultValue, k.Type)
 11186  			}
 11187  		} else {
 11188  			m[k.Val] = p.Value
 11189  		}
 11190  	}
 11191  	for i, v := range p.Aux {
 11192  		k := s.keys[i+1]
 11193  		switch v.(type) {
 11194  		case float64, int64, uint64, string, bool:
 11195  			m[k.Val] = v
 11196  		default:
 11197  			// Insert the fill value if one was specified.
 11198  			if s.defaultValue != SkipDefault {
 11199  				m[k.Val] = castToType(s.defaultValue, k.Type)
 11200  			}
 11201  		}
 11202  	}
 11203  }
 11204  
 11205  func (s *booleanIteratorScanner) useDefaults(m map[string]interface{}) {
 11206  	if s.defaultValue == SkipDefault {
 11207  		return
 11208  	}
 11209  	for _, k := range s.keys {
 11210  		if k.Val == "" {
 11211  			continue
 11212  		}
 11213  		m[k.Val] = castToType(s.defaultValue, k.Type)
 11214  	}
 11215  }
 11216  
 11217  func (s *booleanIteratorScanner) Stats() IteratorStats { return s.input.Stats() }
 11218  func (s *booleanIteratorScanner) Err() error           { return s.err }
 11219  func (s *booleanIteratorScanner) Close() error         { return s.input.Close() }
 11220  
 11221  // booleanParallelIterator represents an iterator that pulls data in a separate goroutine.
 11222  type booleanParallelIterator struct {
 11223  	input BooleanIterator
 11224  	ch    chan booleanPointError
 11225  
 11226  	once    sync.Once
 11227  	closing chan struct{}
 11228  	wg      sync.WaitGroup
 11229  }
 11230  
 11231  // newBooleanParallelIterator returns a new instance of booleanParallelIterator.
 11232  func newBooleanParallelIterator(input BooleanIterator) *booleanParallelIterator {
 11233  	itr := &booleanParallelIterator{
 11234  		input:   input,
 11235  		ch:      make(chan booleanPointError, 256),
 11236  		closing: make(chan struct{}),
 11237  	}
 11238  	itr.wg.Add(1)
 11239  	go itr.monitor()
 11240  	return itr
 11241  }
 11242  
 11243  // Stats returns stats from the underlying iterator.
 11244  func (itr *booleanParallelIterator) Stats() IteratorStats { return itr.input.Stats() }
 11245  
 11246  // Close closes the underlying iterators.
 11247  func (itr *booleanParallelIterator) Close() error {
 11248  	itr.once.Do(func() { close(itr.closing) })
 11249  	itr.wg.Wait()
 11250  	return itr.input.Close()
 11251  }
 11252  
 11253  // Next returns the next point from the iterator.
 11254  func (itr *booleanParallelIterator) Next() (*BooleanPoint, error) {
 11255  	v, ok := <-itr.ch
 11256  	if !ok {
 11257  		return nil, io.EOF
 11258  	}
 11259  	return v.point, v.err
 11260  }
 11261  
 11262  // monitor runs in a separate goroutine and actively pulls the next point.
 11263  func (itr *booleanParallelIterator) monitor() {
 11264  	defer close(itr.ch)
 11265  	defer itr.wg.Done()
 11266  
 11267  	for {
 11268  		// Read next point.
 11269  		p, err := itr.input.Next()
 11270  		if p != nil {
 11271  			p = p.Clone()
 11272  		}
 11273  
 11274  		select {
 11275  		case <-itr.closing:
 11276  			return
 11277  		case itr.ch <- booleanPointError{point: p, err: err}:
 11278  		}
 11279  	}
 11280  }
 11281  
 11282  type booleanPointError struct {
 11283  	point *BooleanPoint
 11284  	err   error
 11285  }
 11286  
 11287  // booleanLimitIterator represents an iterator that limits points per group.
 11288  type booleanLimitIterator struct {
 11289  	input BooleanIterator
 11290  	opt   IteratorOptions
 11291  	n     int
 11292  
 11293  	prev struct {
 11294  		name string
 11295  		tags Tags
 11296  	}
 11297  }
 11298  
 11299  // newBooleanLimitIterator returns a new instance of booleanLimitIterator.
 11300  func newBooleanLimitIterator(input BooleanIterator, opt IteratorOptions) *booleanLimitIterator {
 11301  	return &booleanLimitIterator{
 11302  		input: input,
 11303  		opt:   opt,
 11304  	}
 11305  }
 11306  
 11307  // Stats returns stats from the underlying iterator.
 11308  func (itr *booleanLimitIterator) Stats() IteratorStats { return itr.input.Stats() }
 11309  
 11310  // Close closes the underlying iterators.
 11311  func (itr *booleanLimitIterator) Close() error { return itr.input.Close() }
 11312  
 11313  // Next returns the next point from the iterator.
 11314  func (itr *booleanLimitIterator) Next() (*BooleanPoint, error) {
 11315  	for {
 11316  		p, err := itr.input.Next()
 11317  		if p == nil || err != nil {
 11318  			return nil, err
 11319  		}
 11320  
 11321  		// Reset window and counter if a new window is encountered.
 11322  		if p.Name != itr.prev.name || !p.Tags.Equals(&itr.prev.tags) {
 11323  			itr.prev.name = p.Name
 11324  			itr.prev.tags = p.Tags
 11325  			itr.n = 0
 11326  		}
 11327  
 11328  		// Increment counter.
 11329  		itr.n++
 11330  
 11331  		// Read next point if not beyond the offset.
 11332  		if itr.n <= itr.opt.Offset {
 11333  			continue
 11334  		}
 11335  
 11336  		// Read next point if we're beyond the limit.
 11337  		if itr.opt.Limit > 0 && (itr.n-itr.opt.Offset) > itr.opt.Limit {
 11338  			continue
 11339  		}
 11340  
 11341  		return p, nil
 11342  	}
 11343  }
 11344  
 11345  type booleanFillIterator struct {
 11346  	input     *bufBooleanIterator
 11347  	prev      BooleanPoint
 11348  	startTime int64
 11349  	endTime   int64
 11350  	auxFields []interface{}
 11351  	init      bool
 11352  	opt       IteratorOptions
 11353  
 11354  	window struct {
 11355  		name   string
 11356  		tags   Tags
 11357  		time   int64
 11358  		offset int64
 11359  	}
 11360  }
 11361  
 11362  func newBooleanFillIterator(input BooleanIterator, expr influxql.Expr, opt IteratorOptions) *booleanFillIterator {
 11363  	if opt.Fill == influxql.NullFill {
 11364  		if expr, ok := expr.(*influxql.Call); ok && expr.Name == "count" {
 11365  			opt.Fill = influxql.NumberFill
 11366  			opt.FillValue = false
 11367  		}
 11368  	}
 11369  
 11370  	var startTime, endTime int64
 11371  	if opt.Ascending {
 11372  		startTime, _ = opt.Window(opt.StartTime)
 11373  		endTime, _ = opt.Window(opt.EndTime)
 11374  	} else {
 11375  		startTime, _ = opt.Window(opt.EndTime)
 11376  		endTime, _ = opt.Window(opt.StartTime)
 11377  	}
 11378  
 11379  	var auxFields []interface{}
 11380  	if len(opt.Aux) > 0 {
 11381  		auxFields = make([]interface{}, len(opt.Aux))
 11382  	}
 11383  
 11384  	return &booleanFillIterator{
 11385  		input:     newBufBooleanIterator(input),
 11386  		prev:      BooleanPoint{Nil: true},
 11387  		startTime: startTime,
 11388  		endTime:   endTime,
 11389  		auxFields: auxFields,
 11390  		opt:       opt,
 11391  	}
 11392  }
 11393  
 11394  func (itr *booleanFillIterator) Stats() IteratorStats { return itr.input.Stats() }
 11395  func (itr *booleanFillIterator) Close() error         { return itr.input.Close() }
 11396  
 11397  func (itr *booleanFillIterator) Next() (*BooleanPoint, error) {
 11398  	if !itr.init {
 11399  		p, err := itr.input.peek()
 11400  		if p == nil || err != nil {
 11401  			return nil, err
 11402  		}
 11403  		itr.window.name, itr.window.tags = p.Name, p.Tags
 11404  		itr.window.time = itr.startTime
 11405  		if itr.startTime == influxql.MinTime {
 11406  			itr.window.time, _ = itr.opt.Window(p.Time)
 11407  		}
 11408  		if itr.opt.Location != nil {
 11409  			_, itr.window.offset = itr.opt.Zone(itr.window.time)
 11410  		}
 11411  		itr.init = true
 11412  	}
 11413  
 11414  	p, err := itr.input.Next()
 11415  	if err != nil {
 11416  		return nil, err
 11417  	}
 11418  
 11419  	// Check if the next point is outside of our window or is nil.
 11420  	if p == nil || p.Name != itr.window.name || p.Tags.ID() != itr.window.tags.ID() {
 11421  		// If we are inside of an interval, unread the point and continue below to
 11422  		// constructing a new point.
 11423  		if itr.opt.Ascending && itr.window.time <= itr.endTime {
 11424  			itr.input.unread(p)
 11425  			p = nil
 11426  			goto CONSTRUCT
 11427  		} else if !itr.opt.Ascending && itr.window.time >= itr.endTime && itr.endTime != influxql.MinTime {
 11428  			itr.input.unread(p)
 11429  			p = nil
 11430  			goto CONSTRUCT
 11431  		}
 11432  
 11433  		// We are *not* in a current interval. If there is no next point,
 11434  		// we are at the end of all intervals.
 11435  		if p == nil {
 11436  			return nil, nil
 11437  		}
 11438  
 11439  		// Set the new interval.
 11440  		itr.window.name, itr.window.tags = p.Name, p.Tags
 11441  		itr.window.time = itr.startTime
 11442  		if itr.window.time == influxql.MinTime {
 11443  			itr.window.time, _ = itr.opt.Window(p.Time)
 11444  		}
 11445  		if itr.opt.Location != nil {
 11446  			_, itr.window.offset = itr.opt.Zone(itr.window.time)
 11447  		}
 11448  		itr.prev = BooleanPoint{Nil: true}
 11449  	}
 11450  
 11451  	// Check if the point is our next expected point.
 11452  CONSTRUCT:
 11453  	if p == nil || (itr.opt.Ascending && p.Time > itr.window.time) || (!itr.opt.Ascending && p.Time < itr.window.time) {
 11454  		if p != nil {
 11455  			itr.input.unread(p)
 11456  		}
 11457  
 11458  		p = &BooleanPoint{
 11459  			Name: itr.window.name,
 11460  			Tags: itr.window.tags,
 11461  			Time: itr.window.time,
 11462  			Aux:  itr.auxFields,
 11463  		}
 11464  
 11465  		switch itr.opt.Fill {
 11466  		case influxql.LinearFill:
 11467  			fallthrough
 11468  		case influxql.NullFill:
 11469  			p.Nil = true
 11470  		case influxql.NumberFill:
 11471  			p.Value, _ = castToBoolean(itr.opt.FillValue)
 11472  		case influxql.PreviousFill:
 11473  			if !itr.prev.Nil {
 11474  				p.Value = itr.prev.Value
 11475  				p.Nil = itr.prev.Nil
 11476  			} else {
 11477  				p.Nil = true
 11478  			}
 11479  		}
 11480  	} else {
 11481  		itr.prev = *p
 11482  	}
 11483  
 11484  	// Advance the expected time. Do not advance to a new window here
 11485  	// as there may be lingering points with the same timestamp in the previous
 11486  	// window.
 11487  	if itr.opt.Ascending {
 11488  		itr.window.time += int64(itr.opt.Interval.Duration)
 11489  	} else {
 11490  		itr.window.time -= int64(itr.opt.Interval.Duration)
 11491  	}
 11492  
 11493  	// Check to see if we have passed over an offset change and adjust the time
 11494  	// to account for this new offset.
 11495  	if itr.opt.Location != nil {
 11496  		if _, offset := itr.opt.Zone(itr.window.time - 1); offset != itr.window.offset {
 11497  			diff := itr.window.offset - offset
 11498  			if abs(diff) < int64(itr.opt.Interval.Duration) {
 11499  				itr.window.time += diff
 11500  			}
 11501  			itr.window.offset = offset
 11502  		}
 11503  	}
 11504  	return p, nil
 11505  }
 11506  
 11507  // booleanIntervalIterator represents a boolean implementation of IntervalIterator.
 11508  type booleanIntervalIterator struct {
 11509  	input BooleanIterator
 11510  	opt   IteratorOptions
 11511  }
 11512  
 11513  func newBooleanIntervalIterator(input BooleanIterator, opt IteratorOptions) *booleanIntervalIterator {
 11514  	return &booleanIntervalIterator{input: input, opt: opt}
 11515  }
 11516  
 11517  func (itr *booleanIntervalIterator) Stats() IteratorStats { return itr.input.Stats() }
 11518  func (itr *booleanIntervalIterator) Close() error         { return itr.input.Close() }
 11519  
 11520  func (itr *booleanIntervalIterator) Next() (*BooleanPoint, error) {
 11521  	p, err := itr.input.Next()
 11522  	if p == nil || err != nil {
 11523  		return nil, err
 11524  	}
 11525  	p.Time, _ = itr.opt.Window(p.Time)
 11526  	// If we see the minimum allowable time, set the time to zero so we don't
 11527  	// break the default returned time for aggregate queries without times.
 11528  	if p.Time == influxql.MinTime {
 11529  		p.Time = 0
 11530  	}
 11531  	return p, nil
 11532  }
 11533  
 11534  // booleanInterruptIterator represents a boolean implementation of InterruptIterator.
 11535  type booleanInterruptIterator struct {
 11536  	input   BooleanIterator
 11537  	closing <-chan struct{}
 11538  	count   int
 11539  }
 11540  
 11541  func newBooleanInterruptIterator(input BooleanIterator, closing <-chan struct{}) *booleanInterruptIterator {
 11542  	return &booleanInterruptIterator{input: input, closing: closing}
 11543  }
 11544  
 11545  func (itr *booleanInterruptIterator) Stats() IteratorStats { return itr.input.Stats() }
 11546  func (itr *booleanInterruptIterator) Close() error         { return itr.input.Close() }
 11547  
 11548  func (itr *booleanInterruptIterator) Next() (*BooleanPoint, error) {
 11549  	// Only check if the channel is closed every N points. This
 11550  	// intentionally checks on both 0 and N so that if the iterator
 11551  	// has been interrupted before the first point is emitted it will
 11552  	// not emit any points.
 11553  	if itr.count&0xFF == 0xFF {
 11554  		select {
 11555  		case <-itr.closing:
 11556  			return nil, itr.Close()
 11557  		default:
 11558  			// Reset iterator count to zero and fall through to emit the next point.
 11559  			itr.count = 0
 11560  		}
 11561  	}
 11562  
 11563  	// Increment the counter for every point read.
 11564  	itr.count++
 11565  	return itr.input.Next()
 11566  }
 11567  
 11568  // booleanCloseInterruptIterator represents a boolean implementation of CloseInterruptIterator.
 11569  type booleanCloseInterruptIterator struct {
 11570  	input   BooleanIterator
 11571  	closing <-chan struct{}
 11572  	done    chan struct{}
 11573  	once    sync.Once
 11574  }
 11575  
 11576  func newBooleanCloseInterruptIterator(input BooleanIterator, closing <-chan struct{}) *booleanCloseInterruptIterator {
 11577  	itr := &booleanCloseInterruptIterator{
 11578  		input:   input,
 11579  		closing: closing,
 11580  		done:    make(chan struct{}),
 11581  	}
 11582  	go itr.monitor()
 11583  	return itr
 11584  }
 11585  
 11586  func (itr *booleanCloseInterruptIterator) monitor() {
 11587  	select {
 11588  	case <-itr.closing:
 11589  		itr.Close()
 11590  	case <-itr.done:
 11591  	}
 11592  }
 11593  
 11594  func (itr *booleanCloseInterruptIterator) Stats() IteratorStats {
 11595  	return itr.input.Stats()
 11596  }
 11597  
 11598  func (itr *booleanCloseInterruptIterator) Close() error {
 11599  	itr.once.Do(func() {
 11600  		close(itr.done)
 11601  		itr.input.Close()
 11602  	})
 11603  	return nil
 11604  }
 11605  
 11606  func (itr *booleanCloseInterruptIterator) Next() (*BooleanPoint, error) {
 11607  	p, err := itr.input.Next()
 11608  	if err != nil {
 11609  		// Check if the iterator was closed.
 11610  		select {
 11611  		case <-itr.done:
 11612  			return nil, nil
 11613  		default:
 11614  			return nil, err
 11615  		}
 11616  	}
 11617  	return p, nil
 11618  }
 11619  
 11620  // booleanReduceFloatIterator executes a reducer for every interval and buffers the result.
 11621  type booleanReduceFloatIterator struct {
 11622  	input    *bufBooleanIterator
 11623  	create   func() (BooleanPointAggregator, FloatPointEmitter)
 11624  	dims     []string
 11625  	opt      IteratorOptions
 11626  	points   []FloatPoint
 11627  	keepTags bool
 11628  }
 11629  
 11630  func newBooleanReduceFloatIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, FloatPointEmitter)) *booleanReduceFloatIterator {
 11631  	return &booleanReduceFloatIterator{
 11632  		input:  newBufBooleanIterator(input),
 11633  		create: createFn,
 11634  		dims:   opt.GetDimensions(),
 11635  		opt:    opt,
 11636  	}
 11637  }
 11638  
 11639  // Stats returns stats from the input iterator.
 11640  func (itr *booleanReduceFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
 11641  
 11642  // Close closes the iterator and all child iterators.
 11643  func (itr *booleanReduceFloatIterator) Close() error { return itr.input.Close() }
 11644  
 11645  // Next returns the minimum value for the next available interval.
 11646  func (itr *booleanReduceFloatIterator) Next() (*FloatPoint, error) {
 11647  	// Calculate next window if we have no more points.
 11648  	if len(itr.points) == 0 {
 11649  		var err error
 11650  		itr.points, err = itr.reduce()
 11651  		if len(itr.points) == 0 {
 11652  			return nil, err
 11653  		}
 11654  	}
 11655  
 11656  	// Pop next point off the stack.
 11657  	p := &itr.points[len(itr.points)-1]
 11658  	itr.points = itr.points[:len(itr.points)-1]
 11659  	return p, nil
 11660  }
 11661  
 11662  // booleanReduceFloatPoint stores the reduced data for a name/tag combination.
 11663  type booleanReduceFloatPoint struct {
 11664  	Name       string
 11665  	Tags       Tags
 11666  	Aggregator BooleanPointAggregator
 11667  	Emitter    FloatPointEmitter
 11668  }
 11669  
 11670  // reduce executes fn once for every point in the next window.
 11671  // The previous value for the dimension is passed to fn.
 11672  func (itr *booleanReduceFloatIterator) reduce() ([]FloatPoint, error) {
 11673  	// Calculate next window.
 11674  	var (
 11675  		startTime, endTime int64
 11676  		window             struct {
 11677  			name string
 11678  			tags string
 11679  		}
 11680  	)
 11681  	for {
 11682  		p, err := itr.input.Next()
 11683  		if err != nil || p == nil {
 11684  			return nil, err
 11685  		} else if p.Nil {
 11686  			continue
 11687  		}
 11688  
 11689  		// Unread the point so it can be processed.
 11690  		itr.input.unread(p)
 11691  		startTime, endTime = itr.opt.Window(p.Time)
 11692  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
 11693  		break
 11694  	}
 11695  
 11696  	// Create points by tags.
 11697  	m := make(map[string]*booleanReduceFloatPoint)
 11698  	for {
 11699  		// Read next point.
 11700  		curr, err := itr.input.NextInWindow(startTime, endTime)
 11701  		if err != nil {
 11702  			return nil, err
 11703  		} else if curr == nil {
 11704  			break
 11705  		} else if curr.Nil {
 11706  			continue
 11707  		} else if curr.Name != window.name {
 11708  			itr.input.unread(curr)
 11709  			break
 11710  		}
 11711  
 11712  		// Ensure this point is within the same final window.
 11713  		if curr.Name != window.name {
 11714  			itr.input.unread(curr)
 11715  			break
 11716  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
 11717  			itr.input.unread(curr)
 11718  			break
 11719  		}
 11720  
 11721  		// Retrieve the tags on this point for this level of the query.
 11722  		// This may be different than the bucket dimensions.
 11723  		tags := curr.Tags.Subset(itr.dims)
 11724  		id := tags.ID()
 11725  
 11726  		// Retrieve the aggregator for this name/tag combination or create one.
 11727  		rp := m[id]
 11728  		if rp == nil {
 11729  			aggregator, emitter := itr.create()
 11730  			rp = &booleanReduceFloatPoint{
 11731  				Name:       curr.Name,
 11732  				Tags:       tags,
 11733  				Aggregator: aggregator,
 11734  				Emitter:    emitter,
 11735  			}
 11736  			m[id] = rp
 11737  		}
 11738  		rp.Aggregator.AggregateBoolean(curr)
 11739  	}
 11740  
 11741  	keys := make([]string, 0, len(m))
 11742  	for k := range m {
 11743  		keys = append(keys, k)
 11744  	}
 11745  
 11746  	// Reverse sort points by name & tag.
 11747  	// This ensures a consistent order of output.
 11748  	if len(keys) > 0 {
 11749  		var sorted sort.Interface = sort.StringSlice(keys)
 11750  		if itr.opt.Ascending {
 11751  			sorted = sort.Reverse(sorted)
 11752  		}
 11753  		sort.Sort(sorted)
 11754  	}
 11755  
 11756  	// Assume the points are already sorted until proven otherwise.
 11757  	sortedByTime := true
 11758  	// Emit the points for each name & tag combination.
 11759  	a := make([]FloatPoint, 0, len(m))
 11760  	for _, k := range keys {
 11761  		rp := m[k]
 11762  		points := rp.Emitter.Emit()
 11763  		for i := len(points) - 1; i >= 0; i-- {
 11764  			points[i].Name = rp.Name
 11765  			if !itr.keepTags {
 11766  				points[i].Tags = rp.Tags
 11767  			}
 11768  			// Set the points time to the interval time if the reducer didn't provide one.
 11769  			if points[i].Time == ZeroTime {
 11770  				points[i].Time = startTime
 11771  			} else {
 11772  				sortedByTime = false
 11773  			}
 11774  			a = append(a, points[i])
 11775  		}
 11776  	}
 11777  	// Points may be out of order. Perform a stable sort by time if requested.
 11778  	if !sortedByTime && itr.opt.Ordered {
 11779  		var sorted sort.Interface = floatPointsByTime(a)
 11780  		if itr.opt.Ascending {
 11781  			sorted = sort.Reverse(sorted)
 11782  		}
 11783  		sort.Stable(sorted)
 11784  	}
 11785  	return a, nil
 11786  }
 11787  
 11788  // booleanStreamFloatIterator streams inputs into the iterator and emits points gradually.
 11789  type booleanStreamFloatIterator struct {
 11790  	input  *bufBooleanIterator
 11791  	create func() (BooleanPointAggregator, FloatPointEmitter)
 11792  	dims   []string
 11793  	opt    IteratorOptions
 11794  	m      map[string]*booleanReduceFloatPoint
 11795  	points []FloatPoint
 11796  }
 11797  
 11798  // newBooleanStreamFloatIterator returns a new instance of booleanStreamFloatIterator.
 11799  func newBooleanStreamFloatIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, FloatPointEmitter), opt IteratorOptions) *booleanStreamFloatIterator {
 11800  	return &booleanStreamFloatIterator{
 11801  		input:  newBufBooleanIterator(input),
 11802  		create: createFn,
 11803  		dims:   opt.GetDimensions(),
 11804  		opt:    opt,
 11805  		m:      make(map[string]*booleanReduceFloatPoint),
 11806  	}
 11807  }
 11808  
 11809  // Stats returns stats from the input iterator.
 11810  func (itr *booleanStreamFloatIterator) Stats() IteratorStats { return itr.input.Stats() }
 11811  
 11812  // Close closes the iterator and all child iterators.
 11813  func (itr *booleanStreamFloatIterator) Close() error { return itr.input.Close() }
 11814  
 11815  // Next returns the next value for the stream iterator.
 11816  func (itr *booleanStreamFloatIterator) Next() (*FloatPoint, error) {
 11817  	// Calculate next window if we have no more points.
 11818  	if len(itr.points) == 0 {
 11819  		var err error
 11820  		itr.points, err = itr.reduce()
 11821  		if len(itr.points) == 0 {
 11822  			return nil, err
 11823  		}
 11824  	}
 11825  
 11826  	// Pop next point off the stack.
 11827  	p := &itr.points[len(itr.points)-1]
 11828  	itr.points = itr.points[:len(itr.points)-1]
 11829  	return p, nil
 11830  }
 11831  
 11832  // reduce creates and manages aggregators for every point from the input.
 11833  // After aggregating a point, it always tries to emit a value using the emitter.
 11834  func (itr *booleanStreamFloatIterator) reduce() ([]FloatPoint, error) {
 11835  	// We have already read all of the input points.
 11836  	if itr.m == nil {
 11837  		return nil, nil
 11838  	}
 11839  
 11840  	for {
 11841  		// Read next point.
 11842  		curr, err := itr.input.Next()
 11843  		if err != nil {
 11844  			return nil, err
 11845  		} else if curr == nil {
 11846  			// Close all of the aggregators to flush any remaining points to emit.
 11847  			var points []FloatPoint
 11848  			for _, rp := range itr.m {
 11849  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
 11850  					if err := aggregator.Close(); err != nil {
 11851  						return nil, err
 11852  					}
 11853  
 11854  					pts := rp.Emitter.Emit()
 11855  					if len(pts) == 0 {
 11856  						continue
 11857  					}
 11858  
 11859  					for i := range pts {
 11860  						pts[i].Name = rp.Name
 11861  						pts[i].Tags = rp.Tags
 11862  					}
 11863  					points = append(points, pts...)
 11864  				}
 11865  			}
 11866  
 11867  			// Eliminate the aggregators and emitters.
 11868  			itr.m = nil
 11869  			return points, nil
 11870  		} else if curr.Nil {
 11871  			continue
 11872  		}
 11873  		tags := curr.Tags.Subset(itr.dims)
 11874  
 11875  		id := curr.Name
 11876  		if len(tags.m) > 0 {
 11877  			id += "\x00" + tags.ID()
 11878  		}
 11879  
 11880  		// Retrieve the aggregator for this name/tag combination or create one.
 11881  		rp := itr.m[id]
 11882  		if rp == nil {
 11883  			aggregator, emitter := itr.create()
 11884  			rp = &booleanReduceFloatPoint{
 11885  				Name:       curr.Name,
 11886  				Tags:       tags,
 11887  				Aggregator: aggregator,
 11888  				Emitter:    emitter,
 11889  			}
 11890  			itr.m[id] = rp
 11891  		}
 11892  		rp.Aggregator.AggregateBoolean(curr)
 11893  
 11894  		// Attempt to emit points from the aggregator.
 11895  		points := rp.Emitter.Emit()
 11896  		if len(points) == 0 {
 11897  			continue
 11898  		}
 11899  
 11900  		for i := range points {
 11901  			points[i].Name = rp.Name
 11902  			points[i].Tags = rp.Tags
 11903  		}
 11904  		return points, nil
 11905  	}
 11906  }
 11907  
 11908  // booleanReduceIntegerIterator executes a reducer for every interval and buffers the result.
 11909  type booleanReduceIntegerIterator struct {
 11910  	input    *bufBooleanIterator
 11911  	create   func() (BooleanPointAggregator, IntegerPointEmitter)
 11912  	dims     []string
 11913  	opt      IteratorOptions
 11914  	points   []IntegerPoint
 11915  	keepTags bool
 11916  }
 11917  
 11918  func newBooleanReduceIntegerIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, IntegerPointEmitter)) *booleanReduceIntegerIterator {
 11919  	return &booleanReduceIntegerIterator{
 11920  		input:  newBufBooleanIterator(input),
 11921  		create: createFn,
 11922  		dims:   opt.GetDimensions(),
 11923  		opt:    opt,
 11924  	}
 11925  }
 11926  
 11927  // Stats returns stats from the input iterator.
 11928  func (itr *booleanReduceIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
 11929  
 11930  // Close closes the iterator and all child iterators.
 11931  func (itr *booleanReduceIntegerIterator) Close() error { return itr.input.Close() }
 11932  
 11933  // Next returns the minimum value for the next available interval.
 11934  func (itr *booleanReduceIntegerIterator) Next() (*IntegerPoint, error) {
 11935  	// Calculate next window if we have no more points.
 11936  	if len(itr.points) == 0 {
 11937  		var err error
 11938  		itr.points, err = itr.reduce()
 11939  		if len(itr.points) == 0 {
 11940  			return nil, err
 11941  		}
 11942  	}
 11943  
 11944  	// Pop next point off the stack.
 11945  	p := &itr.points[len(itr.points)-1]
 11946  	itr.points = itr.points[:len(itr.points)-1]
 11947  	return p, nil
 11948  }
 11949  
 11950  // booleanReduceIntegerPoint stores the reduced data for a name/tag combination.
 11951  type booleanReduceIntegerPoint struct {
 11952  	Name       string
 11953  	Tags       Tags
 11954  	Aggregator BooleanPointAggregator
 11955  	Emitter    IntegerPointEmitter
 11956  }
 11957  
 11958  // reduce executes fn once for every point in the next window.
 11959  // The previous value for the dimension is passed to fn.
 11960  func (itr *booleanReduceIntegerIterator) reduce() ([]IntegerPoint, error) {
 11961  	// Calculate next window.
 11962  	var (
 11963  		startTime, endTime int64
 11964  		window             struct {
 11965  			name string
 11966  			tags string
 11967  		}
 11968  	)
 11969  	for {
 11970  		p, err := itr.input.Next()
 11971  		if err != nil || p == nil {
 11972  			return nil, err
 11973  		} else if p.Nil {
 11974  			continue
 11975  		}
 11976  
 11977  		// Unread the point so it can be processed.
 11978  		itr.input.unread(p)
 11979  		startTime, endTime = itr.opt.Window(p.Time)
 11980  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
 11981  		break
 11982  	}
 11983  
 11984  	// Create points by tags.
 11985  	m := make(map[string]*booleanReduceIntegerPoint)
 11986  	for {
 11987  		// Read next point.
 11988  		curr, err := itr.input.NextInWindow(startTime, endTime)
 11989  		if err != nil {
 11990  			return nil, err
 11991  		} else if curr == nil {
 11992  			break
 11993  		} else if curr.Nil {
 11994  			continue
 11995  		} else if curr.Name != window.name {
 11996  			itr.input.unread(curr)
 11997  			break
 11998  		}
 11999  
 12000  		// Ensure this point is within the same final window.
 12001  		if curr.Name != window.name {
 12002  			itr.input.unread(curr)
 12003  			break
 12004  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
 12005  			itr.input.unread(curr)
 12006  			break
 12007  		}
 12008  
 12009  		// Retrieve the tags on this point for this level of the query.
 12010  		// This may be different than the bucket dimensions.
 12011  		tags := curr.Tags.Subset(itr.dims)
 12012  		id := tags.ID()
 12013  
 12014  		// Retrieve the aggregator for this name/tag combination or create one.
 12015  		rp := m[id]
 12016  		if rp == nil {
 12017  			aggregator, emitter := itr.create()
 12018  			rp = &booleanReduceIntegerPoint{
 12019  				Name:       curr.Name,
 12020  				Tags:       tags,
 12021  				Aggregator: aggregator,
 12022  				Emitter:    emitter,
 12023  			}
 12024  			m[id] = rp
 12025  		}
 12026  		rp.Aggregator.AggregateBoolean(curr)
 12027  	}
 12028  
 12029  	keys := make([]string, 0, len(m))
 12030  	for k := range m {
 12031  		keys = append(keys, k)
 12032  	}
 12033  
 12034  	// Reverse sort points by name & tag.
 12035  	// This ensures a consistent order of output.
 12036  	if len(keys) > 0 {
 12037  		var sorted sort.Interface = sort.StringSlice(keys)
 12038  		if itr.opt.Ascending {
 12039  			sorted = sort.Reverse(sorted)
 12040  		}
 12041  		sort.Sort(sorted)
 12042  	}
 12043  
 12044  	// Assume the points are already sorted until proven otherwise.
 12045  	sortedByTime := true
 12046  	// Emit the points for each name & tag combination.
 12047  	a := make([]IntegerPoint, 0, len(m))
 12048  	for _, k := range keys {
 12049  		rp := m[k]
 12050  		points := rp.Emitter.Emit()
 12051  		for i := len(points) - 1; i >= 0; i-- {
 12052  			points[i].Name = rp.Name
 12053  			if !itr.keepTags {
 12054  				points[i].Tags = rp.Tags
 12055  			}
 12056  			// Set the points time to the interval time if the reducer didn't provide one.
 12057  			if points[i].Time == ZeroTime {
 12058  				points[i].Time = startTime
 12059  			} else {
 12060  				sortedByTime = false
 12061  			}
 12062  			a = append(a, points[i])
 12063  		}
 12064  	}
 12065  	// Points may be out of order. Perform a stable sort by time if requested.
 12066  	if !sortedByTime && itr.opt.Ordered {
 12067  		var sorted sort.Interface = integerPointsByTime(a)
 12068  		if itr.opt.Ascending {
 12069  			sorted = sort.Reverse(sorted)
 12070  		}
 12071  		sort.Stable(sorted)
 12072  	}
 12073  	return a, nil
 12074  }
 12075  
 12076  // booleanStreamIntegerIterator streams inputs into the iterator and emits points gradually.
 12077  type booleanStreamIntegerIterator struct {
 12078  	input  *bufBooleanIterator
 12079  	create func() (BooleanPointAggregator, IntegerPointEmitter)
 12080  	dims   []string
 12081  	opt    IteratorOptions
 12082  	m      map[string]*booleanReduceIntegerPoint
 12083  	points []IntegerPoint
 12084  }
 12085  
 12086  // newBooleanStreamIntegerIterator returns a new instance of booleanStreamIntegerIterator.
 12087  func newBooleanStreamIntegerIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, IntegerPointEmitter), opt IteratorOptions) *booleanStreamIntegerIterator {
 12088  	return &booleanStreamIntegerIterator{
 12089  		input:  newBufBooleanIterator(input),
 12090  		create: createFn,
 12091  		dims:   opt.GetDimensions(),
 12092  		opt:    opt,
 12093  		m:      make(map[string]*booleanReduceIntegerPoint),
 12094  	}
 12095  }
 12096  
 12097  // Stats returns stats from the input iterator.
 12098  func (itr *booleanStreamIntegerIterator) Stats() IteratorStats { return itr.input.Stats() }
 12099  
 12100  // Close closes the iterator and all child iterators.
 12101  func (itr *booleanStreamIntegerIterator) Close() error { return itr.input.Close() }
 12102  
 12103  // Next returns the next value for the stream iterator.
 12104  func (itr *booleanStreamIntegerIterator) Next() (*IntegerPoint, error) {
 12105  	// Calculate next window if we have no more points.
 12106  	if len(itr.points) == 0 {
 12107  		var err error
 12108  		itr.points, err = itr.reduce()
 12109  		if len(itr.points) == 0 {
 12110  			return nil, err
 12111  		}
 12112  	}
 12113  
 12114  	// Pop next point off the stack.
 12115  	p := &itr.points[len(itr.points)-1]
 12116  	itr.points = itr.points[:len(itr.points)-1]
 12117  	return p, nil
 12118  }
 12119  
 12120  // reduce creates and manages aggregators for every point from the input.
 12121  // After aggregating a point, it always tries to emit a value using the emitter.
 12122  func (itr *booleanStreamIntegerIterator) reduce() ([]IntegerPoint, error) {
 12123  	// We have already read all of the input points.
 12124  	if itr.m == nil {
 12125  		return nil, nil
 12126  	}
 12127  
 12128  	for {
 12129  		// Read next point.
 12130  		curr, err := itr.input.Next()
 12131  		if err != nil {
 12132  			return nil, err
 12133  		} else if curr == nil {
 12134  			// Close all of the aggregators to flush any remaining points to emit.
 12135  			var points []IntegerPoint
 12136  			for _, rp := range itr.m {
 12137  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
 12138  					if err := aggregator.Close(); err != nil {
 12139  						return nil, err
 12140  					}
 12141  
 12142  					pts := rp.Emitter.Emit()
 12143  					if len(pts) == 0 {
 12144  						continue
 12145  					}
 12146  
 12147  					for i := range pts {
 12148  						pts[i].Name = rp.Name
 12149  						pts[i].Tags = rp.Tags
 12150  					}
 12151  					points = append(points, pts...)
 12152  				}
 12153  			}
 12154  
 12155  			// Eliminate the aggregators and emitters.
 12156  			itr.m = nil
 12157  			return points, nil
 12158  		} else if curr.Nil {
 12159  			continue
 12160  		}
 12161  		tags := curr.Tags.Subset(itr.dims)
 12162  
 12163  		id := curr.Name
 12164  		if len(tags.m) > 0 {
 12165  			id += "\x00" + tags.ID()
 12166  		}
 12167  
 12168  		// Retrieve the aggregator for this name/tag combination or create one.
 12169  		rp := itr.m[id]
 12170  		if rp == nil {
 12171  			aggregator, emitter := itr.create()
 12172  			rp = &booleanReduceIntegerPoint{
 12173  				Name:       curr.Name,
 12174  				Tags:       tags,
 12175  				Aggregator: aggregator,
 12176  				Emitter:    emitter,
 12177  			}
 12178  			itr.m[id] = rp
 12179  		}
 12180  		rp.Aggregator.AggregateBoolean(curr)
 12181  
 12182  		// Attempt to emit points from the aggregator.
 12183  		points := rp.Emitter.Emit()
 12184  		if len(points) == 0 {
 12185  			continue
 12186  		}
 12187  
 12188  		for i := range points {
 12189  			points[i].Name = rp.Name
 12190  			points[i].Tags = rp.Tags
 12191  		}
 12192  		return points, nil
 12193  	}
 12194  }
 12195  
 12196  // booleanReduceUnsignedIterator executes a reducer for every interval and buffers the result.
 12197  type booleanReduceUnsignedIterator struct {
 12198  	input    *bufBooleanIterator
 12199  	create   func() (BooleanPointAggregator, UnsignedPointEmitter)
 12200  	dims     []string
 12201  	opt      IteratorOptions
 12202  	points   []UnsignedPoint
 12203  	keepTags bool
 12204  }
 12205  
 12206  func newBooleanReduceUnsignedIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, UnsignedPointEmitter)) *booleanReduceUnsignedIterator {
 12207  	return &booleanReduceUnsignedIterator{
 12208  		input:  newBufBooleanIterator(input),
 12209  		create: createFn,
 12210  		dims:   opt.GetDimensions(),
 12211  		opt:    opt,
 12212  	}
 12213  }
 12214  
 12215  // Stats returns stats from the input iterator.
 12216  func (itr *booleanReduceUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
 12217  
 12218  // Close closes the iterator and all child iterators.
 12219  func (itr *booleanReduceUnsignedIterator) Close() error { return itr.input.Close() }
 12220  
 12221  // Next returns the minimum value for the next available interval.
 12222  func (itr *booleanReduceUnsignedIterator) Next() (*UnsignedPoint, error) {
 12223  	// Calculate next window if we have no more points.
 12224  	if len(itr.points) == 0 {
 12225  		var err error
 12226  		itr.points, err = itr.reduce()
 12227  		if len(itr.points) == 0 {
 12228  			return nil, err
 12229  		}
 12230  	}
 12231  
 12232  	// Pop next point off the stack.
 12233  	p := &itr.points[len(itr.points)-1]
 12234  	itr.points = itr.points[:len(itr.points)-1]
 12235  	return p, nil
 12236  }
 12237  
 12238  // booleanReduceUnsignedPoint stores the reduced data for a name/tag combination.
 12239  type booleanReduceUnsignedPoint struct {
 12240  	Name       string
 12241  	Tags       Tags
 12242  	Aggregator BooleanPointAggregator
 12243  	Emitter    UnsignedPointEmitter
 12244  }
 12245  
 12246  // reduce executes fn once for every point in the next window.
 12247  // The previous value for the dimension is passed to fn.
 12248  func (itr *booleanReduceUnsignedIterator) reduce() ([]UnsignedPoint, error) {
 12249  	// Calculate next window.
 12250  	var (
 12251  		startTime, endTime int64
 12252  		window             struct {
 12253  			name string
 12254  			tags string
 12255  		}
 12256  	)
 12257  	for {
 12258  		p, err := itr.input.Next()
 12259  		if err != nil || p == nil {
 12260  			return nil, err
 12261  		} else if p.Nil {
 12262  			continue
 12263  		}
 12264  
 12265  		// Unread the point so it can be processed.
 12266  		itr.input.unread(p)
 12267  		startTime, endTime = itr.opt.Window(p.Time)
 12268  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
 12269  		break
 12270  	}
 12271  
 12272  	// Create points by tags.
 12273  	m := make(map[string]*booleanReduceUnsignedPoint)
 12274  	for {
 12275  		// Read next point.
 12276  		curr, err := itr.input.NextInWindow(startTime, endTime)
 12277  		if err != nil {
 12278  			return nil, err
 12279  		} else if curr == nil {
 12280  			break
 12281  		} else if curr.Nil {
 12282  			continue
 12283  		} else if curr.Name != window.name {
 12284  			itr.input.unread(curr)
 12285  			break
 12286  		}
 12287  
 12288  		// Ensure this point is within the same final window.
 12289  		if curr.Name != window.name {
 12290  			itr.input.unread(curr)
 12291  			break
 12292  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
 12293  			itr.input.unread(curr)
 12294  			break
 12295  		}
 12296  
 12297  		// Retrieve the tags on this point for this level of the query.
 12298  		// This may be different than the bucket dimensions.
 12299  		tags := curr.Tags.Subset(itr.dims)
 12300  		id := tags.ID()
 12301  
 12302  		// Retrieve the aggregator for this name/tag combination or create one.
 12303  		rp := m[id]
 12304  		if rp == nil {
 12305  			aggregator, emitter := itr.create()
 12306  			rp = &booleanReduceUnsignedPoint{
 12307  				Name:       curr.Name,
 12308  				Tags:       tags,
 12309  				Aggregator: aggregator,
 12310  				Emitter:    emitter,
 12311  			}
 12312  			m[id] = rp
 12313  		}
 12314  		rp.Aggregator.AggregateBoolean(curr)
 12315  	}
 12316  
 12317  	keys := make([]string, 0, len(m))
 12318  	for k := range m {
 12319  		keys = append(keys, k)
 12320  	}
 12321  
 12322  	// Reverse sort points by name & tag.
 12323  	// This ensures a consistent order of output.
 12324  	if len(keys) > 0 {
 12325  		var sorted sort.Interface = sort.StringSlice(keys)
 12326  		if itr.opt.Ascending {
 12327  			sorted = sort.Reverse(sorted)
 12328  		}
 12329  		sort.Sort(sorted)
 12330  	}
 12331  
 12332  	// Assume the points are already sorted until proven otherwise.
 12333  	sortedByTime := true
 12334  	// Emit the points for each name & tag combination.
 12335  	a := make([]UnsignedPoint, 0, len(m))
 12336  	for _, k := range keys {
 12337  		rp := m[k]
 12338  		points := rp.Emitter.Emit()
 12339  		for i := len(points) - 1; i >= 0; i-- {
 12340  			points[i].Name = rp.Name
 12341  			if !itr.keepTags {
 12342  				points[i].Tags = rp.Tags
 12343  			}
 12344  			// Set the points time to the interval time if the reducer didn't provide one.
 12345  			if points[i].Time == ZeroTime {
 12346  				points[i].Time = startTime
 12347  			} else {
 12348  				sortedByTime = false
 12349  			}
 12350  			a = append(a, points[i])
 12351  		}
 12352  	}
 12353  	// Points may be out of order. Perform a stable sort by time if requested.
 12354  	if !sortedByTime && itr.opt.Ordered {
 12355  		var sorted sort.Interface = unsignedPointsByTime(a)
 12356  		if itr.opt.Ascending {
 12357  			sorted = sort.Reverse(sorted)
 12358  		}
 12359  		sort.Stable(sorted)
 12360  	}
 12361  	return a, nil
 12362  }
 12363  
 12364  // booleanStreamUnsignedIterator streams inputs into the iterator and emits points gradually.
 12365  type booleanStreamUnsignedIterator struct {
 12366  	input  *bufBooleanIterator
 12367  	create func() (BooleanPointAggregator, UnsignedPointEmitter)
 12368  	dims   []string
 12369  	opt    IteratorOptions
 12370  	m      map[string]*booleanReduceUnsignedPoint
 12371  	points []UnsignedPoint
 12372  }
 12373  
 12374  // newBooleanStreamUnsignedIterator returns a new instance of booleanStreamUnsignedIterator.
 12375  func newBooleanStreamUnsignedIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, UnsignedPointEmitter), opt IteratorOptions) *booleanStreamUnsignedIterator {
 12376  	return &booleanStreamUnsignedIterator{
 12377  		input:  newBufBooleanIterator(input),
 12378  		create: createFn,
 12379  		dims:   opt.GetDimensions(),
 12380  		opt:    opt,
 12381  		m:      make(map[string]*booleanReduceUnsignedPoint),
 12382  	}
 12383  }
 12384  
 12385  // Stats returns stats from the input iterator.
 12386  func (itr *booleanStreamUnsignedIterator) Stats() IteratorStats { return itr.input.Stats() }
 12387  
 12388  // Close closes the iterator and all child iterators.
 12389  func (itr *booleanStreamUnsignedIterator) Close() error { return itr.input.Close() }
 12390  
 12391  // Next returns the next value for the stream iterator.
 12392  func (itr *booleanStreamUnsignedIterator) Next() (*UnsignedPoint, error) {
 12393  	// Calculate next window if we have no more points.
 12394  	if len(itr.points) == 0 {
 12395  		var err error
 12396  		itr.points, err = itr.reduce()
 12397  		if len(itr.points) == 0 {
 12398  			return nil, err
 12399  		}
 12400  	}
 12401  
 12402  	// Pop next point off the stack.
 12403  	p := &itr.points[len(itr.points)-1]
 12404  	itr.points = itr.points[:len(itr.points)-1]
 12405  	return p, nil
 12406  }
 12407  
 12408  // reduce creates and manages aggregators for every point from the input.
 12409  // After aggregating a point, it always tries to emit a value using the emitter.
 12410  func (itr *booleanStreamUnsignedIterator) reduce() ([]UnsignedPoint, error) {
 12411  	// We have already read all of the input points.
 12412  	if itr.m == nil {
 12413  		return nil, nil
 12414  	}
 12415  
 12416  	for {
 12417  		// Read next point.
 12418  		curr, err := itr.input.Next()
 12419  		if err != nil {
 12420  			return nil, err
 12421  		} else if curr == nil {
 12422  			// Close all of the aggregators to flush any remaining points to emit.
 12423  			var points []UnsignedPoint
 12424  			for _, rp := range itr.m {
 12425  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
 12426  					if err := aggregator.Close(); err != nil {
 12427  						return nil, err
 12428  					}
 12429  
 12430  					pts := rp.Emitter.Emit()
 12431  					if len(pts) == 0 {
 12432  						continue
 12433  					}
 12434  
 12435  					for i := range pts {
 12436  						pts[i].Name = rp.Name
 12437  						pts[i].Tags = rp.Tags
 12438  					}
 12439  					points = append(points, pts...)
 12440  				}
 12441  			}
 12442  
 12443  			// Eliminate the aggregators and emitters.
 12444  			itr.m = nil
 12445  			return points, nil
 12446  		} else if curr.Nil {
 12447  			continue
 12448  		}
 12449  		tags := curr.Tags.Subset(itr.dims)
 12450  
 12451  		id := curr.Name
 12452  		if len(tags.m) > 0 {
 12453  			id += "\x00" + tags.ID()
 12454  		}
 12455  
 12456  		// Retrieve the aggregator for this name/tag combination or create one.
 12457  		rp := itr.m[id]
 12458  		if rp == nil {
 12459  			aggregator, emitter := itr.create()
 12460  			rp = &booleanReduceUnsignedPoint{
 12461  				Name:       curr.Name,
 12462  				Tags:       tags,
 12463  				Aggregator: aggregator,
 12464  				Emitter:    emitter,
 12465  			}
 12466  			itr.m[id] = rp
 12467  		}
 12468  		rp.Aggregator.AggregateBoolean(curr)
 12469  
 12470  		// Attempt to emit points from the aggregator.
 12471  		points := rp.Emitter.Emit()
 12472  		if len(points) == 0 {
 12473  			continue
 12474  		}
 12475  
 12476  		for i := range points {
 12477  			points[i].Name = rp.Name
 12478  			points[i].Tags = rp.Tags
 12479  		}
 12480  		return points, nil
 12481  	}
 12482  }
 12483  
 12484  // booleanReduceStringIterator executes a reducer for every interval and buffers the result.
 12485  type booleanReduceStringIterator struct {
 12486  	input    *bufBooleanIterator
 12487  	create   func() (BooleanPointAggregator, StringPointEmitter)
 12488  	dims     []string
 12489  	opt      IteratorOptions
 12490  	points   []StringPoint
 12491  	keepTags bool
 12492  }
 12493  
 12494  func newBooleanReduceStringIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, StringPointEmitter)) *booleanReduceStringIterator {
 12495  	return &booleanReduceStringIterator{
 12496  		input:  newBufBooleanIterator(input),
 12497  		create: createFn,
 12498  		dims:   opt.GetDimensions(),
 12499  		opt:    opt,
 12500  	}
 12501  }
 12502  
 12503  // Stats returns stats from the input iterator.
 12504  func (itr *booleanReduceStringIterator) Stats() IteratorStats { return itr.input.Stats() }
 12505  
 12506  // Close closes the iterator and all child iterators.
 12507  func (itr *booleanReduceStringIterator) Close() error { return itr.input.Close() }
 12508  
 12509  // Next returns the minimum value for the next available interval.
 12510  func (itr *booleanReduceStringIterator) Next() (*StringPoint, error) {
 12511  	// Calculate next window if we have no more points.
 12512  	if len(itr.points) == 0 {
 12513  		var err error
 12514  		itr.points, err = itr.reduce()
 12515  		if len(itr.points) == 0 {
 12516  			return nil, err
 12517  		}
 12518  	}
 12519  
 12520  	// Pop next point off the stack.
 12521  	p := &itr.points[len(itr.points)-1]
 12522  	itr.points = itr.points[:len(itr.points)-1]
 12523  	return p, nil
 12524  }
 12525  
 12526  // booleanReduceStringPoint stores the reduced data for a name/tag combination.
 12527  type booleanReduceStringPoint struct {
 12528  	Name       string
 12529  	Tags       Tags
 12530  	Aggregator BooleanPointAggregator
 12531  	Emitter    StringPointEmitter
 12532  }
 12533  
 12534  // reduce executes fn once for every point in the next window.
 12535  // The previous value for the dimension is passed to fn.
 12536  func (itr *booleanReduceStringIterator) reduce() ([]StringPoint, error) {
 12537  	// Calculate next window.
 12538  	var (
 12539  		startTime, endTime int64
 12540  		window             struct {
 12541  			name string
 12542  			tags string
 12543  		}
 12544  	)
 12545  	for {
 12546  		p, err := itr.input.Next()
 12547  		if err != nil || p == nil {
 12548  			return nil, err
 12549  		} else if p.Nil {
 12550  			continue
 12551  		}
 12552  
 12553  		// Unread the point so it can be processed.
 12554  		itr.input.unread(p)
 12555  		startTime, endTime = itr.opt.Window(p.Time)
 12556  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
 12557  		break
 12558  	}
 12559  
 12560  	// Create points by tags.
 12561  	m := make(map[string]*booleanReduceStringPoint)
 12562  	for {
 12563  		// Read next point.
 12564  		curr, err := itr.input.NextInWindow(startTime, endTime)
 12565  		if err != nil {
 12566  			return nil, err
 12567  		} else if curr == nil {
 12568  			break
 12569  		} else if curr.Nil {
 12570  			continue
 12571  		} else if curr.Name != window.name {
 12572  			itr.input.unread(curr)
 12573  			break
 12574  		}
 12575  
 12576  		// Ensure this point is within the same final window.
 12577  		if curr.Name != window.name {
 12578  			itr.input.unread(curr)
 12579  			break
 12580  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
 12581  			itr.input.unread(curr)
 12582  			break
 12583  		}
 12584  
 12585  		// Retrieve the tags on this point for this level of the query.
 12586  		// This may be different than the bucket dimensions.
 12587  		tags := curr.Tags.Subset(itr.dims)
 12588  		id := tags.ID()
 12589  
 12590  		// Retrieve the aggregator for this name/tag combination or create one.
 12591  		rp := m[id]
 12592  		if rp == nil {
 12593  			aggregator, emitter := itr.create()
 12594  			rp = &booleanReduceStringPoint{
 12595  				Name:       curr.Name,
 12596  				Tags:       tags,
 12597  				Aggregator: aggregator,
 12598  				Emitter:    emitter,
 12599  			}
 12600  			m[id] = rp
 12601  		}
 12602  		rp.Aggregator.AggregateBoolean(curr)
 12603  	}
 12604  
 12605  	keys := make([]string, 0, len(m))
 12606  	for k := range m {
 12607  		keys = append(keys, k)
 12608  	}
 12609  
 12610  	// Reverse sort points by name & tag.
 12611  	// This ensures a consistent order of output.
 12612  	if len(keys) > 0 {
 12613  		var sorted sort.Interface = sort.StringSlice(keys)
 12614  		if itr.opt.Ascending {
 12615  			sorted = sort.Reverse(sorted)
 12616  		}
 12617  		sort.Sort(sorted)
 12618  	}
 12619  
 12620  	// Assume the points are already sorted until proven otherwise.
 12621  	sortedByTime := true
 12622  	// Emit the points for each name & tag combination.
 12623  	a := make([]StringPoint, 0, len(m))
 12624  	for _, k := range keys {
 12625  		rp := m[k]
 12626  		points := rp.Emitter.Emit()
 12627  		for i := len(points) - 1; i >= 0; i-- {
 12628  			points[i].Name = rp.Name
 12629  			if !itr.keepTags {
 12630  				points[i].Tags = rp.Tags
 12631  			}
 12632  			// Set the points time to the interval time if the reducer didn't provide one.
 12633  			if points[i].Time == ZeroTime {
 12634  				points[i].Time = startTime
 12635  			} else {
 12636  				sortedByTime = false
 12637  			}
 12638  			a = append(a, points[i])
 12639  		}
 12640  	}
 12641  	// Points may be out of order. Perform a stable sort by time if requested.
 12642  	if !sortedByTime && itr.opt.Ordered {
 12643  		var sorted sort.Interface = stringPointsByTime(a)
 12644  		if itr.opt.Ascending {
 12645  			sorted = sort.Reverse(sorted)
 12646  		}
 12647  		sort.Stable(sorted)
 12648  	}
 12649  	return a, nil
 12650  }
 12651  
 12652  // booleanStreamStringIterator streams inputs into the iterator and emits points gradually.
 12653  type booleanStreamStringIterator struct {
 12654  	input  *bufBooleanIterator
 12655  	create func() (BooleanPointAggregator, StringPointEmitter)
 12656  	dims   []string
 12657  	opt    IteratorOptions
 12658  	m      map[string]*booleanReduceStringPoint
 12659  	points []StringPoint
 12660  }
 12661  
 12662  // newBooleanStreamStringIterator returns a new instance of booleanStreamStringIterator.
 12663  func newBooleanStreamStringIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, StringPointEmitter), opt IteratorOptions) *booleanStreamStringIterator {
 12664  	return &booleanStreamStringIterator{
 12665  		input:  newBufBooleanIterator(input),
 12666  		create: createFn,
 12667  		dims:   opt.GetDimensions(),
 12668  		opt:    opt,
 12669  		m:      make(map[string]*booleanReduceStringPoint),
 12670  	}
 12671  }
 12672  
 12673  // Stats returns stats from the input iterator.
 12674  func (itr *booleanStreamStringIterator) Stats() IteratorStats { return itr.input.Stats() }
 12675  
 12676  // Close closes the iterator and all child iterators.
 12677  func (itr *booleanStreamStringIterator) Close() error { return itr.input.Close() }
 12678  
 12679  // Next returns the next value for the stream iterator.
 12680  func (itr *booleanStreamStringIterator) Next() (*StringPoint, error) {
 12681  	// Calculate next window if we have no more points.
 12682  	if len(itr.points) == 0 {
 12683  		var err error
 12684  		itr.points, err = itr.reduce()
 12685  		if len(itr.points) == 0 {
 12686  			return nil, err
 12687  		}
 12688  	}
 12689  
 12690  	// Pop next point off the stack.
 12691  	p := &itr.points[len(itr.points)-1]
 12692  	itr.points = itr.points[:len(itr.points)-1]
 12693  	return p, nil
 12694  }
 12695  
 12696  // reduce creates and manages aggregators for every point from the input.
 12697  // After aggregating a point, it always tries to emit a value using the emitter.
 12698  func (itr *booleanStreamStringIterator) reduce() ([]StringPoint, error) {
 12699  	// We have already read all of the input points.
 12700  	if itr.m == nil {
 12701  		return nil, nil
 12702  	}
 12703  
 12704  	for {
 12705  		// Read next point.
 12706  		curr, err := itr.input.Next()
 12707  		if err != nil {
 12708  			return nil, err
 12709  		} else if curr == nil {
 12710  			// Close all of the aggregators to flush any remaining points to emit.
 12711  			var points []StringPoint
 12712  			for _, rp := range itr.m {
 12713  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
 12714  					if err := aggregator.Close(); err != nil {
 12715  						return nil, err
 12716  					}
 12717  
 12718  					pts := rp.Emitter.Emit()
 12719  					if len(pts) == 0 {
 12720  						continue
 12721  					}
 12722  
 12723  					for i := range pts {
 12724  						pts[i].Name = rp.Name
 12725  						pts[i].Tags = rp.Tags
 12726  					}
 12727  					points = append(points, pts...)
 12728  				}
 12729  			}
 12730  
 12731  			// Eliminate the aggregators and emitters.
 12732  			itr.m = nil
 12733  			return points, nil
 12734  		} else if curr.Nil {
 12735  			continue
 12736  		}
 12737  		tags := curr.Tags.Subset(itr.dims)
 12738  
 12739  		id := curr.Name
 12740  		if len(tags.m) > 0 {
 12741  			id += "\x00" + tags.ID()
 12742  		}
 12743  
 12744  		// Retrieve the aggregator for this name/tag combination or create one.
 12745  		rp := itr.m[id]
 12746  		if rp == nil {
 12747  			aggregator, emitter := itr.create()
 12748  			rp = &booleanReduceStringPoint{
 12749  				Name:       curr.Name,
 12750  				Tags:       tags,
 12751  				Aggregator: aggregator,
 12752  				Emitter:    emitter,
 12753  			}
 12754  			itr.m[id] = rp
 12755  		}
 12756  		rp.Aggregator.AggregateBoolean(curr)
 12757  
 12758  		// Attempt to emit points from the aggregator.
 12759  		points := rp.Emitter.Emit()
 12760  		if len(points) == 0 {
 12761  			continue
 12762  		}
 12763  
 12764  		for i := range points {
 12765  			points[i].Name = rp.Name
 12766  			points[i].Tags = rp.Tags
 12767  		}
 12768  		return points, nil
 12769  	}
 12770  }
 12771  
 12772  // booleanReduceBooleanIterator executes a reducer for every interval and buffers the result.
 12773  type booleanReduceBooleanIterator struct {
 12774  	input    *bufBooleanIterator
 12775  	create   func() (BooleanPointAggregator, BooleanPointEmitter)
 12776  	dims     []string
 12777  	opt      IteratorOptions
 12778  	points   []BooleanPoint
 12779  	keepTags bool
 12780  }
 12781  
 12782  func newBooleanReduceBooleanIterator(input BooleanIterator, opt IteratorOptions, createFn func() (BooleanPointAggregator, BooleanPointEmitter)) *booleanReduceBooleanIterator {
 12783  	return &booleanReduceBooleanIterator{
 12784  		input:  newBufBooleanIterator(input),
 12785  		create: createFn,
 12786  		dims:   opt.GetDimensions(),
 12787  		opt:    opt,
 12788  	}
 12789  }
 12790  
 12791  // Stats returns stats from the input iterator.
 12792  func (itr *booleanReduceBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
 12793  
 12794  // Close closes the iterator and all child iterators.
 12795  func (itr *booleanReduceBooleanIterator) Close() error { return itr.input.Close() }
 12796  
 12797  // Next returns the minimum value for the next available interval.
 12798  func (itr *booleanReduceBooleanIterator) Next() (*BooleanPoint, error) {
 12799  	// Calculate next window if we have no more points.
 12800  	if len(itr.points) == 0 {
 12801  		var err error
 12802  		itr.points, err = itr.reduce()
 12803  		if len(itr.points) == 0 {
 12804  			return nil, err
 12805  		}
 12806  	}
 12807  
 12808  	// Pop next point off the stack.
 12809  	p := &itr.points[len(itr.points)-1]
 12810  	itr.points = itr.points[:len(itr.points)-1]
 12811  	return p, nil
 12812  }
 12813  
 12814  // booleanReduceBooleanPoint stores the reduced data for a name/tag combination.
 12815  type booleanReduceBooleanPoint struct {
 12816  	Name       string
 12817  	Tags       Tags
 12818  	Aggregator BooleanPointAggregator
 12819  	Emitter    BooleanPointEmitter
 12820  }
 12821  
 12822  // reduce executes fn once for every point in the next window.
 12823  // The previous value for the dimension is passed to fn.
 12824  func (itr *booleanReduceBooleanIterator) reduce() ([]BooleanPoint, error) {
 12825  	// Calculate next window.
 12826  	var (
 12827  		startTime, endTime int64
 12828  		window             struct {
 12829  			name string
 12830  			tags string
 12831  		}
 12832  	)
 12833  	for {
 12834  		p, err := itr.input.Next()
 12835  		if err != nil || p == nil {
 12836  			return nil, err
 12837  		} else if p.Nil {
 12838  			continue
 12839  		}
 12840  
 12841  		// Unread the point so it can be processed.
 12842  		itr.input.unread(p)
 12843  		startTime, endTime = itr.opt.Window(p.Time)
 12844  		window.name, window.tags = p.Name, p.Tags.Subset(itr.opt.Dimensions).ID()
 12845  		break
 12846  	}
 12847  
 12848  	// Create points by tags.
 12849  	m := make(map[string]*booleanReduceBooleanPoint)
 12850  	for {
 12851  		// Read next point.
 12852  		curr, err := itr.input.NextInWindow(startTime, endTime)
 12853  		if err != nil {
 12854  			return nil, err
 12855  		} else if curr == nil {
 12856  			break
 12857  		} else if curr.Nil {
 12858  			continue
 12859  		} else if curr.Name != window.name {
 12860  			itr.input.unread(curr)
 12861  			break
 12862  		}
 12863  
 12864  		// Ensure this point is within the same final window.
 12865  		if curr.Name != window.name {
 12866  			itr.input.unread(curr)
 12867  			break
 12868  		} else if tags := curr.Tags.Subset(itr.opt.Dimensions); tags.ID() != window.tags {
 12869  			itr.input.unread(curr)
 12870  			break
 12871  		}
 12872  
 12873  		// Retrieve the tags on this point for this level of the query.
 12874  		// This may be different than the bucket dimensions.
 12875  		tags := curr.Tags.Subset(itr.dims)
 12876  		id := tags.ID()
 12877  
 12878  		// Retrieve the aggregator for this name/tag combination or create one.
 12879  		rp := m[id]
 12880  		if rp == nil {
 12881  			aggregator, emitter := itr.create()
 12882  			rp = &booleanReduceBooleanPoint{
 12883  				Name:       curr.Name,
 12884  				Tags:       tags,
 12885  				Aggregator: aggregator,
 12886  				Emitter:    emitter,
 12887  			}
 12888  			m[id] = rp
 12889  		}
 12890  		rp.Aggregator.AggregateBoolean(curr)
 12891  	}
 12892  
 12893  	keys := make([]string, 0, len(m))
 12894  	for k := range m {
 12895  		keys = append(keys, k)
 12896  	}
 12897  
 12898  	// Reverse sort points by name & tag.
 12899  	// This ensures a consistent order of output.
 12900  	if len(keys) > 0 {
 12901  		var sorted sort.Interface = sort.StringSlice(keys)
 12902  		if itr.opt.Ascending {
 12903  			sorted = sort.Reverse(sorted)
 12904  		}
 12905  		sort.Sort(sorted)
 12906  	}
 12907  
 12908  	// Assume the points are already sorted until proven otherwise.
 12909  	sortedByTime := true
 12910  	// Emit the points for each name & tag combination.
 12911  	a := make([]BooleanPoint, 0, len(m))
 12912  	for _, k := range keys {
 12913  		rp := m[k]
 12914  		points := rp.Emitter.Emit()
 12915  		for i := len(points) - 1; i >= 0; i-- {
 12916  			points[i].Name = rp.Name
 12917  			if !itr.keepTags {
 12918  				points[i].Tags = rp.Tags
 12919  			}
 12920  			// Set the points time to the interval time if the reducer didn't provide one.
 12921  			if points[i].Time == ZeroTime {
 12922  				points[i].Time = startTime
 12923  			} else {
 12924  				sortedByTime = false
 12925  			}
 12926  			a = append(a, points[i])
 12927  		}
 12928  	}
 12929  	// Points may be out of order. Perform a stable sort by time if requested.
 12930  	if !sortedByTime && itr.opt.Ordered {
 12931  		var sorted sort.Interface = booleanPointsByTime(a)
 12932  		if itr.opt.Ascending {
 12933  			sorted = sort.Reverse(sorted)
 12934  		}
 12935  		sort.Stable(sorted)
 12936  	}
 12937  	return a, nil
 12938  }
 12939  
 12940  // booleanStreamBooleanIterator streams inputs into the iterator and emits points gradually.
 12941  type booleanStreamBooleanIterator struct {
 12942  	input  *bufBooleanIterator
 12943  	create func() (BooleanPointAggregator, BooleanPointEmitter)
 12944  	dims   []string
 12945  	opt    IteratorOptions
 12946  	m      map[string]*booleanReduceBooleanPoint
 12947  	points []BooleanPoint
 12948  }
 12949  
 12950  // newBooleanStreamBooleanIterator returns a new instance of booleanStreamBooleanIterator.
 12951  func newBooleanStreamBooleanIterator(input BooleanIterator, createFn func() (BooleanPointAggregator, BooleanPointEmitter), opt IteratorOptions) *booleanStreamBooleanIterator {
 12952  	return &booleanStreamBooleanIterator{
 12953  		input:  newBufBooleanIterator(input),
 12954  		create: createFn,
 12955  		dims:   opt.GetDimensions(),
 12956  		opt:    opt,
 12957  		m:      make(map[string]*booleanReduceBooleanPoint),
 12958  	}
 12959  }
 12960  
 12961  // Stats returns stats from the input iterator.
 12962  func (itr *booleanStreamBooleanIterator) Stats() IteratorStats { return itr.input.Stats() }
 12963  
 12964  // Close closes the iterator and all child iterators.
 12965  func (itr *booleanStreamBooleanIterator) Close() error { return itr.input.Close() }
 12966  
 12967  // Next returns the next value for the stream iterator.
 12968  func (itr *booleanStreamBooleanIterator) Next() (*BooleanPoint, error) {
 12969  	// Calculate next window if we have no more points.
 12970  	if len(itr.points) == 0 {
 12971  		var err error
 12972  		itr.points, err = itr.reduce()
 12973  		if len(itr.points) == 0 {
 12974  			return nil, err
 12975  		}
 12976  	}
 12977  
 12978  	// Pop next point off the stack.
 12979  	p := &itr.points[len(itr.points)-1]
 12980  	itr.points = itr.points[:len(itr.points)-1]
 12981  	return p, nil
 12982  }
 12983  
 12984  // reduce creates and manages aggregators for every point from the input.
 12985  // After aggregating a point, it always tries to emit a value using the emitter.
 12986  func (itr *booleanStreamBooleanIterator) reduce() ([]BooleanPoint, error) {
 12987  	// We have already read all of the input points.
 12988  	if itr.m == nil {
 12989  		return nil, nil
 12990  	}
 12991  
 12992  	for {
 12993  		// Read next point.
 12994  		curr, err := itr.input.Next()
 12995  		if err != nil {
 12996  			return nil, err
 12997  		} else if curr == nil {
 12998  			// Close all of the aggregators to flush any remaining points to emit.
 12999  			var points []BooleanPoint
 13000  			for _, rp := range itr.m {
 13001  				if aggregator, ok := rp.Aggregator.(io.Closer); ok {
 13002  					if err := aggregator.Close(); err != nil {
 13003  						return nil, err
 13004  					}
 13005  
 13006  					pts := rp.Emitter.Emit()
 13007  					if len(pts) == 0 {
 13008  						continue
 13009  					}
 13010  
 13011  					for i := range pts {
 13012  						pts[i].Name = rp.Name
 13013  						pts[i].Tags = rp.Tags
 13014  					}
 13015  					points = append(points, pts...)
 13016  				}
 13017  			}
 13018  
 13019  			// Eliminate the aggregators and emitters.
 13020  			itr.m = nil
 13021  			return points, nil
 13022  		} else if curr.Nil {
 13023  			continue
 13024  		}
 13025  		tags := curr.Tags.Subset(itr.dims)
 13026  
 13027  		id := curr.Name
 13028  		if len(tags.m) > 0 {
 13029  			id += "\x00" + tags.ID()
 13030  		}
 13031  
 13032  		// Retrieve the aggregator for this name/tag combination or create one.
 13033  		rp := itr.m[id]
 13034  		if rp == nil {
 13035  			aggregator, emitter := itr.create()
 13036  			rp = &booleanReduceBooleanPoint{
 13037  				Name:       curr.Name,
 13038  				Tags:       tags,
 13039  				Aggregator: aggregator,
 13040  				Emitter:    emitter,
 13041  			}
 13042  			itr.m[id] = rp
 13043  		}
 13044  		rp.Aggregator.AggregateBoolean(curr)
 13045  
 13046  		// Attempt to emit points from the aggregator.
 13047  		points := rp.Emitter.Emit()
 13048  		if len(points) == 0 {
 13049  			continue
 13050  		}
 13051  
 13052  		for i := range points {
 13053  			points[i].Name = rp.Name
 13054  			points[i].Tags = rp.Tags
 13055  		}
 13056  		return points, nil
 13057  	}
 13058  }
 13059  
 13060  // booleanDedupeIterator only outputs unique points.
 13061  // This differs from the DistinctIterator in that it compares all aux fields too.
 13062  // This iterator is relatively inefficient and should only be used on small
 13063  // datasets such as meta query results.
 13064  type booleanDedupeIterator struct {
 13065  	input BooleanIterator
 13066  	m     map[string]struct{} // lookup of points already sent
 13067  }
 13068  
 13069  type booleanIteratorMapper struct {
 13070  	cur    Cursor
 13071  	row    Row
 13072  	driver IteratorMap   // which iterator to use for the primary value, can be nil
 13073  	fields []IteratorMap // which iterator to use for an aux field
 13074  	point  BooleanPoint
 13075  }
 13076  
 13077  func newBooleanIteratorMapper(cur Cursor, driver IteratorMap, fields []IteratorMap, opt IteratorOptions) *booleanIteratorMapper {
 13078  	return &booleanIteratorMapper{
 13079  		cur:    cur,
 13080  		driver: driver,
 13081  		fields: fields,
 13082  		point: BooleanPoint{
 13083  			Aux: make([]interface{}, len(fields)),
 13084  		},
 13085  	}
 13086  }
 13087  
 13088  func (itr *booleanIteratorMapper) Next() (*BooleanPoint, error) {
 13089  	if !itr.cur.Scan(&itr.row) {
 13090  		if err := itr.cur.Err(); err != nil {
 13091  			return nil, err
 13092  		}
 13093  		return nil, nil
 13094  	}
 13095  
 13096  	itr.point.Time = itr.row.Time
 13097  	itr.point.Name = itr.row.Series.Name
 13098  	itr.point.Tags = itr.row.Series.Tags
 13099  
 13100  	if itr.driver != nil {
 13101  		if v := itr.driver.Value(&itr.row); v != nil {
 13102  			if v, ok := castToBoolean(v); ok {
 13103  				itr.point.Value = v
 13104  				itr.point.Nil = false
 13105  			} else {
 13106  				itr.point.Value = false
 13107  				itr.point.Nil = true
 13108  			}
 13109  		} else {
 13110  			itr.point.Value = false
 13111  			itr.point.Nil = true
 13112  		}
 13113  	}
 13114  	for i, f := range itr.fields {
 13115  		itr.point.Aux[i] = f.Value(&itr.row)
 13116  	}
 13117  	return &itr.point, nil
 13118  }
 13119  
 13120  func (itr *booleanIteratorMapper) Stats() IteratorStats {
 13121  	return itr.cur.Stats()
 13122  }
 13123  
 13124  func (itr *booleanIteratorMapper) Close() error {
 13125  	return itr.cur.Close()
 13126  }
 13127  
 13128  type booleanFilterIterator struct {
 13129  	input BooleanIterator
 13130  	cond  influxql.Expr
 13131  	opt   IteratorOptions
 13132  	m     map[string]interface{}
 13133  }
 13134  
 13135  func newBooleanFilterIterator(input BooleanIterator, cond influxql.Expr, opt IteratorOptions) BooleanIterator {
 13136  	// Strip out time conditions from the WHERE clause.
 13137  	// TODO(jsternberg): This should really be done for us when creating the IteratorOptions struct.
 13138  	n := influxql.RewriteFunc(influxql.CloneExpr(cond), func(n influxql.Node) influxql.Node {
 13139  		switch n := n.(type) {
 13140  		case *influxql.BinaryExpr:
 13141  			if n.LHS.String() == "time" {
 13142  				return &influxql.BooleanLiteral{Val: true}
 13143  			}
 13144  		}
 13145  		return n
 13146  	})
 13147  
 13148  	cond, _ = n.(influxql.Expr)
 13149  	if cond == nil {
 13150  		return input
 13151  	} else if n, ok := cond.(*influxql.BooleanLiteral); ok && n.Val {
 13152  		return input
 13153  	}
 13154  
 13155  	return &booleanFilterIterator{
 13156  		input: input,
 13157  		cond:  cond,
 13158  		opt:   opt,
 13159  		m:     make(map[string]interface{}),
 13160  	}
 13161  }
 13162  
 13163  func (itr *booleanFilterIterator) Stats() IteratorStats { return itr.input.Stats() }
 13164  func (itr *booleanFilterIterator) Close() error         { return itr.input.Close() }
 13165  
 13166  func (itr *booleanFilterIterator) Next() (*BooleanPoint, error) {
 13167  	for {
 13168  		p, err := itr.input.Next()
 13169  		if err != nil || p == nil {
 13170  			return nil, err
 13171  		}
 13172  
 13173  		for i, ref := range itr.opt.Aux {
 13174  			itr.m[ref.Val] = p.Aux[i]
 13175  		}
 13176  		for k, v := range p.Tags.KeyValues() {
 13177  			itr.m[k] = v
 13178  		}
 13179  
 13180  		if !influxql.EvalBool(itr.cond, itr.m) {
 13181  			continue
 13182  		}
 13183  		return p, nil
 13184  	}
 13185  }
 13186  
 13187  type booleanTagSubsetIterator struct {
 13188  	input      BooleanIterator
 13189  	point      BooleanPoint
 13190  	lastTags   Tags
 13191  	dimensions []string
 13192  }
 13193  
 13194  func newBooleanTagSubsetIterator(input BooleanIterator, opt IteratorOptions) *booleanTagSubsetIterator {
 13195  	return &booleanTagSubsetIterator{
 13196  		input:      input,
 13197  		dimensions: opt.GetDimensions(),
 13198  	}
 13199  }
 13200  
 13201  func (itr *booleanTagSubsetIterator) Next() (*BooleanPoint, error) {
 13202  	p, err := itr.input.Next()
 13203  	if err != nil {
 13204  		return nil, err
 13205  	} else if p == nil {
 13206  		return nil, nil
 13207  	}
 13208  
 13209  	itr.point.Name = p.Name
 13210  	if !p.Tags.Equal(itr.lastTags) {
 13211  		itr.point.Tags = p.Tags.Subset(itr.dimensions)
 13212  		itr.lastTags = p.Tags
 13213  	}
 13214  	itr.point.Time = p.Time
 13215  	itr.point.Value = p.Value
 13216  	itr.point.Aux = p.Aux
 13217  	itr.point.Aggregated = p.Aggregated
 13218  	itr.point.Nil = p.Nil
 13219  	return &itr.point, nil
 13220  }
 13221  
 13222  func (itr *booleanTagSubsetIterator) Stats() IteratorStats {
 13223  	return itr.input.Stats()
 13224  }
 13225  
 13226  func (itr *booleanTagSubsetIterator) Close() error {
 13227  	return itr.input.Close()
 13228  }
 13229  
 13230  // newBooleanDedupeIterator returns a new instance of booleanDedupeIterator.
 13231  func newBooleanDedupeIterator(input BooleanIterator) *booleanDedupeIterator {
 13232  	return &booleanDedupeIterator{
 13233  		input: input,
 13234  		m:     make(map[string]struct{}),
 13235  	}
 13236  }
 13237  
 13238  // Stats returns stats from the input iterator.
 13239  func (itr *booleanDedupeIterator) Stats() IteratorStats { return itr.input.Stats() }
 13240  
 13241  // Close closes the iterator and all child iterators.
 13242  func (itr *booleanDedupeIterator) Close() error { return itr.input.Close() }
 13243  
 13244  // Next returns the next unique point from the input iterator.
 13245  func (itr *booleanDedupeIterator) Next() (*BooleanPoint, error) {
 13246  	for {
 13247  		// Read next point.
 13248  		p, err := itr.input.Next()
 13249  		if p == nil || err != nil {
 13250  			return nil, err
 13251  		}
 13252  
 13253  		// Serialize to bytes to store in lookup.
 13254  		buf, err := proto.Marshal(encodeBooleanPoint(p))
 13255  		if err != nil {
 13256  			return nil, err
 13257  		}
 13258  
 13259  		// If the point has already been output then move to the next point.
 13260  		if _, ok := itr.m[string(buf)]; ok {
 13261  			continue
 13262  		}
 13263  
 13264  		// Otherwise mark it as emitted and return point.
 13265  		itr.m[string(buf)] = struct{}{}
 13266  		return p, nil
 13267  	}
 13268  }
 13269  
 13270  // booleanReaderIterator represents an iterator that streams from a reader.
 13271  type booleanReaderIterator struct {
 13272  	r   io.Reader
 13273  	dec *BooleanPointDecoder
 13274  }
 13275  
 13276  // newBooleanReaderIterator returns a new instance of booleanReaderIterator.
 13277  func newBooleanReaderIterator(ctx context.Context, r io.Reader, stats IteratorStats) *booleanReaderIterator {
 13278  	dec := NewBooleanPointDecoder(ctx, r)
 13279  	dec.stats = stats
 13280  
 13281  	return &booleanReaderIterator{
 13282  		r:   r,
 13283  		dec: dec,
 13284  	}
 13285  }
 13286  
 13287  // Stats returns stats about points processed.
 13288  func (itr *booleanReaderIterator) Stats() IteratorStats { return itr.dec.stats }
 13289  
 13290  // Close closes the underlying reader, if applicable.
 13291  func (itr *booleanReaderIterator) Close() error {
 13292  	if r, ok := itr.r.(io.ReadCloser); ok {
 13293  		return r.Close()
 13294  	}
 13295  	return nil
 13296  }
 13297  
 13298  // Next returns the next point from the iterator.
 13299  func (itr *booleanReaderIterator) Next() (*BooleanPoint, error) {
 13300  	// OPTIMIZE(benbjohnson): Reuse point on iterator.
 13301  
 13302  	// Unmarshal next point.
 13303  	p := &BooleanPoint{}
 13304  	if err := itr.dec.DecodeBooleanPoint(p); err == io.EOF {
 13305  		return nil, nil
 13306  	} else if err != nil {
 13307  		return nil, err
 13308  	}
 13309  	return p, nil
 13310  }
 13311  
 13312  // encodeFloatIterator encodes all points from itr to the underlying writer.
 13313  func (enc *IteratorEncoder) encodeFloatIterator(itr FloatIterator) error {
 13314  	ticker := time.NewTicker(enc.StatsInterval)
 13315  	defer ticker.Stop()
 13316  
 13317  	// Emit initial stats.
 13318  	if err := enc.encodeStats(itr.Stats()); err != nil {
 13319  		return err
 13320  	}
 13321  
 13322  	// Continually stream points from the iterator into the encoder.
 13323  	penc := NewFloatPointEncoder(enc.w)
 13324  	for {
 13325  		// Emit stats periodically.
 13326  		select {
 13327  		case <-ticker.C:
 13328  			if err := enc.encodeStats(itr.Stats()); err != nil {
 13329  				return err
 13330  			}
 13331  		default:
 13332  		}
 13333  
 13334  		// Retrieve the next point from the iterator.
 13335  		p, err := itr.Next()
 13336  		if err != nil {
 13337  			return err
 13338  		} else if p == nil {
 13339  			break
 13340  		}
 13341  
 13342  		// Write the point to the point encoder.
 13343  		if err := penc.EncodeFloatPoint(p); err != nil {
 13344  			return err
 13345  		}
 13346  	}
 13347  
 13348  	// Emit final stats.
 13349  	if err := enc.encodeStats(itr.Stats()); err != nil {
 13350  		return err
 13351  	}
 13352  	return nil
 13353  }
 13354  
 13355  // encodeIntegerIterator encodes all points from itr to the underlying writer.
 13356  func (enc *IteratorEncoder) encodeIntegerIterator(itr IntegerIterator) error {
 13357  	ticker := time.NewTicker(enc.StatsInterval)
 13358  	defer ticker.Stop()
 13359  
 13360  	// Emit initial stats.
 13361  	if err := enc.encodeStats(itr.Stats()); err != nil {
 13362  		return err
 13363  	}
 13364  
 13365  	// Continually stream points from the iterator into the encoder.
 13366  	penc := NewIntegerPointEncoder(enc.w)
 13367  	for {
 13368  		// Emit stats periodically.
 13369  		select {
 13370  		case <-ticker.C:
 13371  			if err := enc.encodeStats(itr.Stats()); err != nil {
 13372  				return err
 13373  			}
 13374  		default:
 13375  		}
 13376  
 13377  		// Retrieve the next point from the iterator.
 13378  		p, err := itr.Next()
 13379  		if err != nil {
 13380  			return err
 13381  		} else if p == nil {
 13382  			break
 13383  		}
 13384  
 13385  		// Write the point to the point encoder.
 13386  		if err := penc.EncodeIntegerPoint(p); err != nil {
 13387  			return err
 13388  		}
 13389  	}
 13390  
 13391  	// Emit final stats.
 13392  	if err := enc.encodeStats(itr.Stats()); err != nil {
 13393  		return err
 13394  	}
 13395  	return nil
 13396  }
 13397  
 13398  // encodeUnsignedIterator encodes all points from itr to the underlying writer.
 13399  func (enc *IteratorEncoder) encodeUnsignedIterator(itr UnsignedIterator) error {
 13400  	ticker := time.NewTicker(enc.StatsInterval)
 13401  	defer ticker.Stop()
 13402  
 13403  	// Emit initial stats.
 13404  	if err := enc.encodeStats(itr.Stats()); err != nil {
 13405  		return err
 13406  	}
 13407  
 13408  	// Continually stream points from the iterator into the encoder.
 13409  	penc := NewUnsignedPointEncoder(enc.w)
 13410  	for {
 13411  		// Emit stats periodically.
 13412  		select {
 13413  		case <-ticker.C:
 13414  			if err := enc.encodeStats(itr.Stats()); err != nil {
 13415  				return err
 13416  			}
 13417  		default:
 13418  		}
 13419  
 13420  		// Retrieve the next point from the iterator.
 13421  		p, err := itr.Next()
 13422  		if err != nil {
 13423  			return err
 13424  		} else if p == nil {
 13425  			break
 13426  		}
 13427  
 13428  		// Write the point to the point encoder.
 13429  		if err := penc.EncodeUnsignedPoint(p); err != nil {
 13430  			return err
 13431  		}
 13432  	}
 13433  
 13434  	// Emit final stats.
 13435  	if err := enc.encodeStats(itr.Stats()); err != nil {
 13436  		return err
 13437  	}
 13438  	return nil
 13439  }
 13440  
 13441  // encodeStringIterator encodes all points from itr to the underlying writer.
 13442  func (enc *IteratorEncoder) encodeStringIterator(itr StringIterator) error {
 13443  	ticker := time.NewTicker(enc.StatsInterval)
 13444  	defer ticker.Stop()
 13445  
 13446  	// Emit initial stats.
 13447  	if err := enc.encodeStats(itr.Stats()); err != nil {
 13448  		return err
 13449  	}
 13450  
 13451  	// Continually stream points from the iterator into the encoder.
 13452  	penc := NewStringPointEncoder(enc.w)
 13453  	for {
 13454  		// Emit stats periodically.
 13455  		select {
 13456  		case <-ticker.C:
 13457  			if err := enc.encodeStats(itr.Stats()); err != nil {
 13458  				return err
 13459  			}
 13460  		default:
 13461  		}
 13462  
 13463  		// Retrieve the next point from the iterator.
 13464  		p, err := itr.Next()
 13465  		if err != nil {
 13466  			return err
 13467  		} else if p == nil {
 13468  			break
 13469  		}
 13470  
 13471  		// Write the point to the point encoder.
 13472  		if err := penc.EncodeStringPoint(p); err != nil {
 13473  			return err
 13474  		}
 13475  	}
 13476  
 13477  	// Emit final stats.
 13478  	if err := enc.encodeStats(itr.Stats()); err != nil {
 13479  		return err
 13480  	}
 13481  	return nil
 13482  }
 13483  
 13484  // encodeBooleanIterator encodes all points from itr to the underlying writer.
 13485  func (enc *IteratorEncoder) encodeBooleanIterator(itr BooleanIterator) error {
 13486  	ticker := time.NewTicker(enc.StatsInterval)
 13487  	defer ticker.Stop()
 13488  
 13489  	// Emit initial stats.
 13490  	if err := enc.encodeStats(itr.Stats()); err != nil {
 13491  		return err
 13492  	}
 13493  
 13494  	// Continually stream points from the iterator into the encoder.
 13495  	penc := NewBooleanPointEncoder(enc.w)
 13496  	for {
 13497  		// Emit stats periodically.
 13498  		select {
 13499  		case <-ticker.C:
 13500  			if err := enc.encodeStats(itr.Stats()); err != nil {
 13501  				return err
 13502  			}
 13503  		default:
 13504  		}
 13505  
 13506  		// Retrieve the next point from the iterator.
 13507  		p, err := itr.Next()
 13508  		if err != nil {
 13509  			return err
 13510  		} else if p == nil {
 13511  			break
 13512  		}
 13513  
 13514  		// Write the point to the point encoder.
 13515  		if err := penc.EncodeBooleanPoint(p); err != nil {
 13516  			return err
 13517  		}
 13518  	}
 13519  
 13520  	// Emit final stats.
 13521  	if err := enc.encodeStats(itr.Stats()); err != nil {
 13522  		return err
 13523  	}
 13524  	return nil
 13525  }