influxdb/tsdb/tsm1/array_cursor.gen.go.tmpl

339 lines
7.6 KiB
Cheetah

package tsm1
import (
"sort"
"github.com/influxdata/influxdb/tsdb"
"github.com/influxdata/influxdb/tsdb/cursors"
)
// Array Cursors
{{range .}}
{{$arrayType := print "*tsdb." .Name "Array"}}
{{$type := print .name "ArrayAscendingCursor"}}
{{$Type := print .Name "ArrayAscendingCursor"}}
type {{$type}} struct {
cache struct {
values Values
pos int
}
tsm struct {
buf {{$arrayType}}
values {{$arrayType}}
pos int
keyCursor *KeyCursor
}
end int64
res {{$arrayType}}
stats cursors.CursorStats
}
func new{{$Type}}() *{{$type}} {
c := &{{$type}}{
res: tsdb.New{{.Name}}ArrayLen(MaxPointsPerBlock),
}
c.tsm.buf = tsdb.New{{.Name}}ArrayLen(MaxPointsPerBlock)
return c
}
func (c *{{$type}}) reset(seek, end int64, cacheValues Values, tsmKeyCursor *KeyCursor) {
c.end = end
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.readArrayBlock()
c.tsm.pos = sort.Search(c.tsm.values.Len(), func(i int) bool {
return c.tsm.values.Timestamps[i] >= seek
})
}
func (c *{{$type}}) Err() error { return nil }
// close closes the cursor and any dependent cursors.
func (c *{{$type}}) Close() {
if c.tsm.keyCursor != nil {
c.tsm.keyCursor.Close()
c.tsm.keyCursor = nil
}
c.cache.values = nil
c.tsm.values = nil
}
func (c *{{$type}}) Stats() cursors.CursorStats { return c.stats }
// Next returns the next key/value for the cursor.
func (c *{{$type}}) Next() {{$arrayType}} {
pos := 0
cvals := c.cache.values
tvals := c.tsm.values
c.res.Timestamps = c.res.Timestamps[:cap(c.res.Timestamps)]
c.res.Values = c.res.Values[:cap(c.res.Values)]
for pos < len(c.res.Timestamps) && c.tsm.pos < len(tvals.Timestamps) && c.cache.pos < len(cvals) {
ckey := cvals[c.cache.pos].UnixNano()
tkey := tvals.Timestamps[c.tsm.pos]
if ckey == tkey {
c.res.Timestamps[pos] = ckey
c.res.Values[pos] = cvals[c.cache.pos].({{.Name}}Value).RawValue()
c.cache.pos++
c.tsm.pos++
} else if ckey < tkey {
c.res.Timestamps[pos] = ckey
c.res.Values[pos] = cvals[c.cache.pos].({{.Name}}Value).RawValue()
c.cache.pos++
} else {
c.res.Timestamps[pos] = tkey
c.res.Values[pos] = tvals.Values[c.tsm.pos]
c.tsm.pos++
}
pos++
if c.tsm.pos >= len(tvals.Timestamps) {
tvals = c.nextTSM()
}
}
if pos < len(c.res.Timestamps) {
if c.tsm.pos < len(tvals.Timestamps) {
if pos == 0 {
// optimization: all points served from TSM data
copy(c.res.Timestamps, tvals.Timestamps)
pos += copy(c.res.Values, tvals.Values)
c.nextTSM()
} else {
// copy as much as we can
n := copy(c.res.Timestamps[pos:], tvals.Timestamps[c.tsm.pos:])
copy(c.res.Values[pos:], tvals.Values[c.tsm.pos:])
pos += n
c.tsm.pos += n
if c.tsm.pos >= len(tvals.Timestamps) {
c.nextTSM()
}
}
}
if c.cache.pos < len(cvals) {
// TSM was exhausted
for pos < len(c.res.Timestamps) && c.cache.pos < len(cvals) {
c.res.Timestamps[pos] = cvals[c.cache.pos].UnixNano()
c.res.Values[pos] = cvals[c.cache.pos].({{.Name}}Value).RawValue()
pos++
c.cache.pos++
}
}
}
if pos > 0 && c.res.Timestamps[pos-1] > c.end {
pos -= 2
for pos >= 0 && c.res.Timestamps[pos] > c.end {
pos--
}
pos++
}
c.res.Timestamps = c.res.Timestamps[:pos]
c.res.Values = c.res.Values[:pos]
c.stats.ScannedValues += len(c.res.Values)
{{if eq .Name "String" }}
for _, v := range c.res.Values {
c.stats.ScannedBytes += len(v)
}
{{else}}
c.stats.ScannedBytes += len(c.res.Values) * {{.Size}}
{{end}}
return c.res
}
func (c *{{$type}}) nextTSM() {{$arrayType}} {
c.tsm.keyCursor.Next()
c.tsm.values = c.readArrayBlock()
c.tsm.pos = 0
return c.tsm.values
}
func (c *{{$type}}) readArrayBlock() {{$arrayType}} {
values, _ := c.tsm.keyCursor.Read{{.Name}}ArrayBlock(c.tsm.buf)
return values
}
{{$type := print .name "ArrayDescendingCursor"}}
{{$Type := print .Name "ArrayDescendingCursor"}}
type {{$type}} struct {
cache struct {
values Values
pos int
}
tsm struct {
buf {{$arrayType}}
values {{$arrayType}}
pos int
keyCursor *KeyCursor
}
end int64
res {{$arrayType}}
stats cursors.CursorStats
}
func new{{$Type}}() *{{$type}} {
c := &{{$type}}{
res: tsdb.New{{.Name}}ArrayLen(MaxPointsPerBlock),
}
c.tsm.buf = tsdb.New{{.Name}}ArrayLen(MaxPointsPerBlock)
return c
}
func (c *{{$type}}) reset(seek, end int64, cacheValues Values, tsmKeyCursor *KeyCursor) {
c.end = end
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 c.cache.values[c.cache.pos].UnixNano() != seek {
c.cache.pos--
}
} else {
c.cache.pos = -1
}
c.tsm.keyCursor = tsmKeyCursor
c.tsm.values = c.readArrayBlock()
c.tsm.pos = sort.Search(c.tsm.values.Len(), func(i int) bool {
return c.tsm.values.Timestamps[i] >= seek
})
if c.tsm.values.Len() > 0 {
if c.tsm.pos == c.tsm.values.Len() {
c.tsm.pos--
} else if c.tsm.values.Timestamps[c.tsm.pos] != seek {
c.tsm.pos--
}
} else {
c.tsm.pos = -1
}
}
func (c *{{$type}}) Err() error { return nil }
func (c *{{$type}}) Close() {
if c.tsm.keyCursor != nil {
c.tsm.keyCursor.Close()
c.tsm.keyCursor = nil
}
c.cache.values = nil
c.tsm.values = nil
}
func (c *{{$type}}) Stats() cursors.CursorStats { return c.stats }
func (c *{{$type}}) Next() {{$arrayType}} {
pos := 0
cvals := c.cache.values
tvals := c.tsm.values
c.res.Timestamps = c.res.Timestamps[:cap(c.res.Timestamps)]
c.res.Values = c.res.Values[:cap(c.res.Values)]
for pos < len(c.res.Timestamps) && c.tsm.pos >= 0 && c.cache.pos >= 0 {
ckey := cvals[c.cache.pos].UnixNano()
tkey := tvals.Timestamps[c.tsm.pos]
if ckey == tkey {
c.res.Timestamps[pos] = ckey
c.res.Values[pos] = cvals[c.cache.pos].({{.Name}}Value).RawValue()
c.cache.pos--
c.tsm.pos--
} else if ckey > tkey {
c.res.Timestamps[pos] = ckey
c.res.Values[pos] = cvals[c.cache.pos].({{.Name}}Value).RawValue()
c.cache.pos--
} else {
c.res.Timestamps[pos] = tkey
c.res.Values[pos] = tvals.Values[c.tsm.pos]
c.tsm.pos--
}
pos++
if c.tsm.pos < 0 {
tvals = c.nextTSM()
}
}
if pos < len(c.res.Timestamps) {
// cache was exhausted
if c.tsm.pos >= 0 {
for pos < len(c.res.Timestamps) && c.tsm.pos >= 0 {
c.res.Timestamps[pos] = tvals.Timestamps[c.tsm.pos]
c.res.Values[pos] = tvals.Values[c.tsm.pos]
pos++
c.tsm.pos--
if c.tsm.pos < 0 {
tvals = c.nextTSM()
}
}
}
if c.cache.pos >= 0 {
// TSM was exhausted
for pos < len(c.res.Timestamps) && c.cache.pos >= 0 {
c.res.Timestamps[pos] = cvals[c.cache.pos].UnixNano()
c.res.Values[pos] = cvals[c.cache.pos].({{.Name}}Value).RawValue()
pos++
c.cache.pos--
}
}
}
if pos > 0 && c.res.Timestamps[pos-1] < c.end {
pos -= 2
for pos >= 0 && c.res.Timestamps[pos] < c.end {
pos--
}
pos++
}
c.res.Timestamps = c.res.Timestamps[:pos]
c.res.Values = c.res.Values[:pos]
return c.res
}
func (c *{{$type}}) nextTSM() {{$arrayType}} {
c.tsm.keyCursor.Next()
c.tsm.values = c.readArrayBlock()
c.tsm.pos = len(c.tsm.values.Timestamps) - 1
return c.tsm.values
}
func (c *{{$type}}) readArrayBlock() {{$arrayType}} {
values, _ := c.tsm.keyCursor.Read{{.Name}}ArrayBlock(c.tsm.buf)
c.stats.ScannedValues += len(values.Values)
{{if eq .Name "String" }}
for _, v := range values.Values {
c.stats.ScannedBytes += len(v)
}
{{else}}
c.stats.ScannedBytes += len(values.Values) * {{.Size}}
{{end}}
return values
}
{{end}}