influxdb/tsdb/engine/tsm1/file_store.gen.go.tmpl

278 lines
7.8 KiB
Cheetah

package tsm1
import (
"github.com/influxdata/influxdb/v2/tsdb"
)
{{$isArray := .D.isArray}}
{{$isNotArray := not $isArray}}
{{range .In}}
{{if $isArray -}}
// Read{{.Name}}ArrayBlock reads the next block as a set of {{.name}} values.
func (c *KeyCursor) Read{{.Name}}ArrayBlock(values *tsdb.{{.Name}}Array) (*tsdb.{{.Name}}Array, error) {
LOOP:
// No matching blocks to decode
if len(c.current) == 0 {
values.Timestamps = values.Timestamps[:0]
values.Values = values.Values[:0]
return values, nil
}
{{else}}
// Read{{.Name}}Block reads the next block as a set of {{.name}} values.
func (c *KeyCursor) Read{{.Name}}Block(buf *[]{{.Name}}Value) ([]{{.Name}}Value, error) {
LOOP:
// No matching blocks to decode
if len(c.current) == 0 {
return nil, nil
}
{{end}}
// First block is the oldest block containing the points we're searching for.
first := c.current[0]
{{if $isArray -}}
err := first.r.Read{{.Name}}ArrayBlockAt(&first.entry, values)
{{else -}}
*buf = (*buf)[:0]
var values {{.Name}}Values
values, err := first.r.Read{{.Name}}BlockAt(&first.entry, buf)
{{end -}}
if err != nil {
return nil, err
}
if c.col != nil {
c.col.GetCounter({{.name}}BlocksDecodedCounter).Add(1)
c.col.GetCounter({{.name}}BlocksSizeCounter).Add(int64(first.entry.Size))
}
// Remove values we already read
{{if $isArray -}}
values.Exclude(first.readMin, first.readMax)
{{else -}}
values = values.Exclude(first.readMin, first.readMax)
{{end}}
// Remove any tombstones
tombstones := first.r.TombstoneRange(c.key)
{{if $isArray -}}
excludeTombstones{{.Name}}Array(tombstones, values)
{{else -}}
values = excludeTombstones{{.Name}}Values(tombstones, values)
{{end -}}
// If there are no values in this first block (all tombstoned or previously read) and
// we have more potential blocks too search. Try again.
if values.Len() == 0 && len(c.current) > 0 {
c.current = c.current[1:]
goto LOOP
}
// Only one block with this key and time range so return it
if len(c.current) == 1 {
if values.Len() > 0 {
first.markRead(values.MinTime(), values.MaxTime())
}
return values, nil
}
// Use the current block time range as our overlapping window
minT, maxT := first.readMin, first.readMax
if values.Len() > 0 {
minT, maxT = values.MinTime(), values.MaxTime()
}
if c.ascending {
// Blocks are ordered by generation, we may have values in the past in later blocks, if so,
// expand the window to include the min time range to ensure values are returned in ascending
// order
for i := 1; i < len(c.current); i++ {
cur := c.current[i]
if cur.entry.MinTime < minT && !cur.read() {
minT = cur.entry.MinTime
}
}
// Find first block that overlaps our window
for i := 1; i < len(c.current); i++ {
cur := c.current[i]
if cur.entry.OverlapsTimeRange(minT, maxT) && !cur.read() {
// Shrink our window so it's the intersection of the first overlapping block and the
// first block. We do this to minimize the region that overlaps and needs to
// be merged.
if cur.entry.MaxTime > maxT {
maxT = cur.entry.MaxTime
}
{{if $isArray -}}
values.Include(minT, maxT)
{{else -}}
values = values.Include(minT, maxT)
{{end -}}
break
}
}
// Search the remaining blocks that overlap our window and append their values so we can
// merge them.
for i := 1; i < len(c.current); i++ {
cur := c.current[i]
// Skip this block if it doesn't contain points we looking for or they have already been read
if !cur.entry.OverlapsTimeRange(minT, maxT) || cur.read() {
cur.markRead(minT, maxT)
continue
}
{{if $isArray -}}
v := &tsdb.{{.Name}}Array{}
err := cur.r.Read{{.Name}}ArrayBlockAt(&cur.entry, v)
{{else -}}
var a []{{.Name}}Value
var v {{.Name}}Values
v, err := cur.r.Read{{.Name}}BlockAt(&cur.entry, &a)
{{end -}}
if err != nil {
return nil, err
}
if c.col != nil {
c.col.GetCounter({{.name}}BlocksDecodedCounter).Add(1)
c.col.GetCounter({{.name}}BlocksSizeCounter).Add(int64(cur.entry.Size))
}
tombstones := cur.r.TombstoneRange(c.key)
{{if $isArray -}}
// Remove any tombstoned values
excludeTombstones{{.Name}}Array(tombstones, v)
// Remove values we already read
v.Exclude(cur.readMin, cur.readMax)
if v.Len() > 0 {
// Only use values in the overlapping window
v.Include(minT, maxT)
// Merge the remaining values with the existing
values.Merge(v)
}
{{else -}}
// Remove any tombstoned values
v = excludeTombstones{{.Name}}Values(tombstones, v)
// Remove values we already read
v = v.Exclude(cur.readMin, cur.readMax)
if v.Len() > 0 {
// Only use values in the overlapping window
v = v.Include(minT, maxT)
// Merge the remaining values with the existing
values = values.Merge(v)
}
{{end -}}
cur.markRead(minT, maxT)
}
} else {
// Blocks are ordered by generation, we may have values in the past in later blocks, if so,
// expand the window to include the max time range to ensure values are returned in descending
// order
for i := 1; i < len(c.current); i++ {
cur := c.current[i]
if cur.entry.MaxTime > maxT && !cur.read() {
maxT = cur.entry.MaxTime
}
}
// Find first block that overlaps our window
for i := 1; i < len(c.current); i++ {
cur := c.current[i]
if cur.entry.OverlapsTimeRange(minT, maxT) && !cur.read() {
// Shrink our window so it's the intersection of the first overlapping block and the
// first block. We do this to minimize the region that overlaps and needs to
// be merged.
if cur.entry.MinTime < minT {
minT = cur.entry.MinTime
}
{{if $isArray -}}
values.Include(minT, maxT)
{{else -}}
values = values.Include(minT, maxT)
{{end -}}
break
}
}
// Search the remaining blocks that overlap our window and append their values so we can
// merge them.
for i := 1; i < len(c.current); i++ {
cur := c.current[i]
// Skip this block if it doesn't contain points we looking for or they have already been read
if !cur.entry.OverlapsTimeRange(minT, maxT) || cur.read() {
cur.markRead(minT, maxT)
continue
}
{{if $isArray -}}
v := &tsdb.{{.Name}}Array{}
err := cur.r.Read{{.Name}}ArrayBlockAt(&cur.entry, v)
{{else -}}
var a []{{.Name}}Value
var v {{.Name}}Values
v, err := cur.r.Read{{.Name}}BlockAt(&cur.entry, &a)
{{end -}}
if err != nil {
return nil, err
}
if c.col != nil {
c.col.GetCounter({{.name}}BlocksDecodedCounter).Add(1)
c.col.GetCounter({{.name}}BlocksSizeCounter).Add(int64(cur.entry.Size))
}
tombstones := cur.r.TombstoneRange(c.key)
{{if $isArray -}}
// Remove any tombstoned values
excludeTombstones{{.Name}}Array(tombstones, v)
// Remove values we already read
v.Exclude(cur.readMin, cur.readMax)
// If the block we decoded should have all of it's values included, mark it as read so we
// don't use it again.
if v.Len() > 0 {
v.Include(minT, maxT)
// Merge the remaining values with the existing
v.Merge(values)
*values = *v
}
{{else -}}
// Remove any tombstoned values
v = excludeTombstones{{.Name}}Values(tombstones, v)
// Remove values we already read
v = v.Exclude(cur.readMin, cur.readMax)
// If the block we decoded should have all of it's values included, mark it as read so we
// don't use it again.
if v.Len() > 0 {
v = v.Include(minT, maxT)
// Merge the remaining values with the existing
values = v.Merge(values)
}
{{end -}}
cur.markRead(minT, maxT)
}
}
first.markRead(minT, maxT)
return values, err
}
{{if $isArray -}}
func excludeTombstones{{.Name}}Array(t []TimeRange, values *tsdb.{{.Name}}Array) {
for i := range t {
values.Exclude(t[i].Min, t[i].Max)
}
}
{{else -}}
func excludeTombstones{{.Name}}Values(t []TimeRange, values {{.Name}}Values) {{.Name}}Values {
for i := range t {
values = values.Exclude(t[i].Min, t[i].Max)
}
return values
}
{{end -}}
{{ end }}