func (c *integerAscendingBatchCursor) Close() {
	c.tsm.keyCursor.Close()
	c.tsm.keyCursor = nil
	c.cache.values = nil
	c.tsm.values = nil
}
close closes the cursor and any dependent cursors.
package tsm1
import (
	"context"
	"sort"
	"github.com/influxdata/influxdb/query"
	"github.com/influxdata/influxdb/tsdb"
)
func (e *Engine) buildFloatCursor(ctx context.Context, measurement, seriesKey, field string, opt query.IteratorOptions) floatCursor {
	key := SeriesFieldKeyBytes(seriesKey, field)
	cacheValues := e.Cache.Values(key)
	keyCursor := e.KeyCursor(ctx, key, opt.SeekTime(), opt.Ascending)
	return newFloatCursor(opt.SeekTime(), opt.Ascending, cacheValues, keyCursor)
}
func (e *Engine) buildFloatBatchCursor(ctx context.Context, measurement, seriesKey, field string, opt query.IteratorOptions) tsdb.FloatBatchCursor {
	key := SeriesFieldKeyBytes(seriesKey, field)
	cacheValues := e.Cache.Values(key)
	keyCursor := e.KeyCursor(ctx, key, opt.SeekTime(), opt.Ascending)
	return newFloatBatchCursor(seriesKey, opt.SeekTime(), opt.Ascending, cacheValues, keyCursor)
}
func (e *Engine) buildIntegerCursor(ctx context.Context, measurement, seriesKey, field string, opt query.IteratorOptions) integerCursor {
	key := SeriesFieldKeyBytes(seriesKey, field)
	cacheValues := e.Cache.Values(key)
	keyCursor := e.KeyCursor(ctx, key, opt.SeekTime(), opt.Ascending)
	return newIntegerCursor(opt.SeekTime(), opt.Ascending, cacheValues, keyCursor)
}
func (e *Engine) buildIntegerBatchCursor(ctx context.Context, measurement, seriesKey, field string, opt query.IteratorOptions) tsdb.IntegerBatchCursor {
	key := SeriesFieldKeyBytes(seriesKey, field)
	cacheValues := e.Cache.Values(key)
	keyCursor := e.KeyCursor(ctx, key, opt.SeekTime(), opt.Ascending)
	return newIntegerBatchCursor(seriesKey, opt.SeekTime(), opt.Ascending, cacheValues, keyCursor)
}
func (e *Engine) buildUnsignedCursor(ctx context.Context, measurement, seriesKey, field string, opt query.IteratorOptions) unsignedCursor {
	key := SeriesFieldKeyBytes(seriesKey, field)
	cacheValues := e.Cache.Values(key)
	keyCursor := e.KeyCursor(ctx, key, opt.SeekTime(), opt.Ascending)
	return newUnsignedCursor(opt.SeekTime(), opt.Ascending, cacheValues, keyCursor)
}
func (e *Engine) buildUnsignedBatchCursor(ctx context.Context, measurement, seriesKey, field string, opt query.IteratorOptions) tsdb.UnsignedBatchCursor {
	key := SeriesFieldKeyBytes(seriesKey, field)
	cacheValues := e.Cache.Values(key)
	keyCursor := e.KeyCursor(ctx, key, opt.SeekTime(), opt.Ascending)
	return newUnsignedBatchCursor(seriesKey, opt.SeekTime(), opt.Ascending, cacheValues, keyCursor)
}
func (e *Engine) buildStringCursor(ctx context.Context, measurement, seriesKey, field string, opt query.IteratorOptions) stringCursor {
	key := SeriesFieldKeyBytes(seriesKey, field)
	cacheValues := e.Cache.Values(key)
	keyCursor := e.KeyCursor(ctx, key, opt.SeekTime(), opt.Ascending)
	return newStringCursor(opt.SeekTime(), opt.Ascending, cacheValues, keyCursor)
}
func (e *Engine) buildStringBatchCursor(ctx context.Context, measurement, seriesKey, field string, opt query.IteratorOptions) tsdb.StringBatchCursor {
	key := SeriesFieldKeyBytes(seriesKey, field)
	cacheValues := e.Cache.Values(key)
	keyCursor := e.KeyCursor(ctx, key, opt.SeekTime(), opt.Ascending)
	return newStringBatchCursor(seriesKey, opt.SeekTime(), opt.Ascending, cacheValues, keyCursor)
}
func (e *Engine) buildBooleanCursor(ctx context.Context, measurement, seriesKey, field string, opt query.IteratorOptions) booleanCursor {
	key := SeriesFieldKeyBytes(seriesKey, field)
	cacheValues := e.Cache.Values(key)
	keyCursor := e.KeyCursor(ctx, key, opt.SeekTime(), opt.Ascending)
	return newBooleanCursor(opt.SeekTime(), opt.Ascending, cacheValues, keyCursor)
}
func (e *Engine) buildBooleanBatchCursor(ctx context.Context, measurement, seriesKey, field string, opt query.IteratorOptions) tsdb.BooleanBatchCursor {
	key := SeriesFieldKeyBytes(seriesKey, field)
	cacheValues := e.Cache.Values(key)
	keyCursor := e.KeyCursor(ctx, key, opt.SeekTime(), opt.Ascending)
	return newBooleanBatchCursor(seriesKey, opt.SeekTime(), opt.Ascending, cacheValues, keyCursor)
}
func newFloatBatchCursor(key string, seek int64, ascending bool, cacheValues Values, tsmKeyCursor *KeyCursor) tsdb.FloatBatchCursor {
	if ascending {
		return newFloatAscendingBatchCursor(key, seek, cacheValues, tsmKeyCursor)
	}
	return newFloatDescendingBatchCursor(key, seek, cacheValues, tsmKeyCursor)
}
type floatAscendingBatchCursor struct {
	cache struct {
		values Values
		pos    int
	}
	tsm struct {
		values    []FloatValue
		pos       int
		keyCursor *KeyCursor
	}
	key string
	t   []int64
	v   []float64
}
func newFloatAscendingBatchCursor(key string, seek int64, cacheValues Values, tsmKeyCursor *KeyCursor) *floatAscendingBatchCursor {
	c := &floatAscendingBatchCursor{key: key}
	c.cache.values = cacheValues
	c.cache.pos = sort.Search(len(c.cache.values), func(i int) bool {
		return c.cache.values[i].UnixNano() >= seek
	})
	c.tsm.keyCursor = tsmKeyCursor
	c.tsm.values, _ = c.tsm.keyCursor.ReadFloatBlock(&c.tsm.values)
	c.tsm.pos = sort.Search(len(c.tsm.values), func(i int) bool {
		return c.tsm.values[i].UnixNano() >= seek
	})
	c.t = make([]int64, tsdb.DefaultMaxPointsPerBlock)
	c.v = make([]float64, tsdb.DefaultMaxPointsPerBlock)
	return c
}
func (c *floatAscendingBatchCursor) Err() error        { return nil }
func (c *floatAscendingBatchCursor) SeriesKey() string { return c.key }
func (c *floatAscendingBatchCursor) Close() {
	c.tsm.keyCursor.Close()
	c.tsm.keyCursor = nil
	c.cache.values = nil
	c.tsm.values = nil
}
func (c *floatAscendingBatchCursor) Next() ([]int64, []float64) {
	var ckey, tkey int64
	var cvalue, tvalue float64
	pos := 0
	for ; pos < cap(c.t); pos++ {
		tkey, tvalue = c.peekTSM()
		if c.cache.pos < len(c.cache.values) {
			ckey, cvalue = c.peekCache()
			var cache, tsm bool
			if ckey == tkey {
				cache, tsm = true, true
				tkey = ckey
				tvalue = cvalue
			} else if ckey < tkey || tkey == tsdb.EOF {
				cache = true
				tkey = ckey
				tvalue = cvalue
			} else {
				tsm = true
			}
			if cache {
				c.nextCache()
			}
			if tsm {
				c.nextTSM()
			}
		} else {
			if tkey == tsdb.EOF {
				break
			}
			c.nextTSM()
		}
		c.t[pos] = tkey
		c.v[pos] = tvalue
	}
	return c.t[:pos], c.v[:pos]
}
func (c *floatAscendingBatchCursor) peekCache() (t int64, v float64) {
	item := c.cache.values[c.cache.pos]
	return item.UnixNano(), item.(FloatValue).value
}
func (c *floatAscendingBatchCursor) nextCache() {
	if c.cache.pos < len(c.cache.values) {
		c.cache.pos++
	}
}
func (c *floatAscendingBatchCursor) peekTSM() (t int64, v float64) {
	if c.tsm.pos >= len(c.tsm.values) {
		return tsdb.EOF, 0
	}
	item := c.tsm.values[c.tsm.pos]
	return item.UnixNano(), item.value
}
func (c *floatAscendingBatchCursor) nextTSM() {
	c.tsm.pos++
	if c.tsm.pos >= len(c.tsm.values) {
		c.tsm.keyCursor.Next()
		c.tsm.values, _ = c.tsm.keyCursor.ReadFloatBlock(&c.tsm.values)
		c.tsm.pos = 0
	}
}
type floatDescendingBatchCursor struct {
	cache struct {
		values Values
		pos    int
	}
	tsm struct {
		values    []FloatValue
		pos       int
		keyCursor *KeyCursor
	}
	key string
	t   []int64
	v   []float64
}
func newFloatDescendingBatchCursor(key string, seek int64, cacheValues Values, tsmKeyCursor *KeyCursor) *floatDescendingBatchCursor {
	c := &floatDescendingBatchCursor{key: key}
	c.cache.values = cacheValues
	if len(c.cache.values) > 0 {
		c.cache.pos = sort.Search(len(c.cache.values), func(i int) bool {
			return c.cache.values[i].UnixNano() >= seek
		})
		if c.cache.pos == len(c.cache.values) {
			c.cache.pos--
		} else if t, _ := c.peekCache(); t != seek {
			c.cache.pos--
		}
	} else {
		c.cache.pos = -1
	}
	c.tsm.keyCursor = tsmKeyCursor
	c.tsm.values, _ = c.tsm.keyCursor.ReadFloatBlock(&c.tsm.values)
	c.tsm.pos = sort.Search(len(c.tsm.values), func(i int) bool {
		return c.tsm.values[i].UnixNano() >= seek
	})
	if len(c.tsm.values) > 0 {
		if c.tsm.pos == len(c.tsm.values) {
			c.tsm.pos--
		} else if t, _ := c.peekTSM(); t != seek {
			c.tsm.pos--
		}
	} else {
		c.tsm.pos = -1
	}
	c.t = make([]int64, tsdb.DefaultMaxPointsPerBlock)
	c.v = make([]float64, tsdb.DefaultMaxPointsPerBlock)
	return c
}
func (c *floatDescendingBatchCursor) Err() error        { return nil }
func (c *floatDescendingBatchCursor) SeriesKey() string { return c.key }
func (c *floatDescendingBatchCursor) Close() {
	c.tsm.keyCursor.Close()
	c.tsm.keyCursor = nil
	c.cache.values = nil
	c.tsm.values = nil
}
func (c *floatDescendingBatchCursor) Next() ([]int64, []float64) {
	var ckey, tkey int64
	var cvalue, tvalue float64
	pos := 0
	for ; pos < cap(c.t); pos++ {
		tkey, tvalue = c.peekTSM()
		if c.cache.pos >= 0 {
			ckey, cvalue = c.peekCache()
			var cache, tsm bool
			if ckey == tkey {
				cache, tsm = true, true
				tkey = ckey
				tvalue = cvalue
			} else if ckey > tkey || tkey == tsdb.EOF {
				cache = true
				tkey = ckey
				tvalue = cvalue
			} else {
				tsm = true
			}
			if cache {
				c.nextCache()
			}
			if tsm {
				c.nextTSM()
			}
		} else {
			if tkey == tsdb.EOF {
				break
			}
			c.nextTSM()
		}
		c.t[pos] = tkey
		c.v[pos] = tvalue
	}
	return c.t[:pos], c.v[:pos]
}
func (c *floatDescendingBatchCursor) peekCache() (t int64, v float64) {
	item := c.cache.values[c.cache.pos]
	return item.UnixNano(), item.(FloatValue).value
}
func (c *floatDescendingBatchCursor) nextCache() {
	if c.cache.pos >= 0 {
		c.cache.pos--
	}
}
func (c *floatDescendingBatchCursor) peekTSM() (t int64, v float64) {
	if c.tsm.pos < 0 {
		return tsdb.EOF, 0
	}
	item := c.tsm.values[c.tsm.pos]
	return item.UnixNano(), item.value
}
func (c *floatDescendingBatchCursor) nextTSM() {
	c.tsm.pos--
	if c.tsm.pos < 0 {
		c.tsm.keyCursor.Next()
		c.tsm.values, _ = c.tsm.keyCursor.ReadFloatBlock(&c.tsm.values)
		c.tsm.pos = len(c.tsm.values) - 1
	}
}
func newFloatRangeBatchCursor(time int64, asc bool, cur tsdb.FloatBatchCursor) tsdb.FloatBatchCursor {
	if asc {
		return &floatAscendingRangeBatchCursor{FloatBatchCursor: cur, t: time}
	}
	return &floatDescendingRangeBatchCursor{FloatBatchCursor: cur, t: time}
}
type floatAscendingRangeBatchCursor struct {
	tsdb.FloatBatchCursor
	t int64
}
func (l *floatAscendingRangeBatchCursor) Next() ([]int64, []float64) {
	k, v := l.FloatBatchCursor.Next()
	if len(k) > 0 && k[len(k)-1] > l.t {
		i := len(k) - 2
		for i >= 0 && k[i] > l.t {
			i--
		}
		k = k[:i+1]
		v = v[:i+1]
	}
	return k, v
}
type floatDescendingRangeBatchCursor struct {
	tsdb.FloatBatchCursor
	t int64
}
func (l *floatDescendingRangeBatchCursor) Next() ([]int64, []float64) {
	k, v := l.FloatBatchCursor.Next()
	if len(k) > 0 && k[len(k)-1] < l.t {
		i := len(k) - 2
		for i >= 0 && k[i] < l.t {
			i--
		}
		k = k[:i+1]
		v = v[:i+1]
	}
	return k, v
}
func newIntegerBatchCursor(key string, seek int64, ascending bool, cacheValues Values, tsmKeyCursor *KeyCursor) tsdb.IntegerBatchCursor {
	if ascending {
		return newIntegerAscendingBatchCursor(key, seek, cacheValues, tsmKeyCursor)
	}
	return newIntegerDescendingBatchCursor(key, seek, cacheValues, tsmKeyCursor)
}
type integerAscendingBatchCursor struct {
	cache struct {
		values Values
		pos    int
	}
	tsm struct {
		values    []IntegerValue
		pos       int
		keyCursor *KeyCursor
	}
	key string
	t   []int64
	v   []int64
}
func newIntegerAscendingBatchCursor(key string, seek int64, cacheValues Values, tsmKeyCursor *KeyCursor) *integerAscendingBatchCursor {
	c := &integerAscendingBatchCursor{key: key}
	c.cache.values = cacheValues
	c.cache.pos = sort.Search(len(c.cache.values), func(i int) bool {
		return c.cache.values[i].UnixNano() >= seek
	})
	c.tsm.keyCursor = tsmKeyCursor
	c.tsm.values, _ = c.tsm.keyCursor.ReadIntegerBlock(&c.tsm.values)
	c.tsm.pos = sort.Search(len(c.tsm.values), func(i int) bool {
		return c.tsm.values[i].UnixNano() >= seek
	})
	c.t = make([]int64, tsdb.DefaultMaxPointsPerBlock)
	c.v = make([]int64, tsdb.DefaultMaxPointsPerBlock)
	return c
}
func (c *integerAscendingBatchCursor) Err() error        { return nil }
func (c *integerAscendingBatchCursor) SeriesKey() string { return c.key }