influxdb/storage/reads/response_writer.gen.go.tmpl

113 lines
3.4 KiB
Cheetah

package reads
import (
"github.com/influxdata/influxdb/storage/reads/datatypes"
"github.com/influxdata/influxdb/tsdb/cursors"
)
{{range .}}
func (w *ResponseWriter) get{{.Name}}PointsFrame() *datatypes.ReadResponse_Frame_{{.Name}}Points {
var res *datatypes.ReadResponse_Frame_{{.Name}}Points
if len(w.buffer.{{.Name}}) > 0 {
i := len(w.buffer.{{.Name}}) - 1
res = w.buffer.{{.Name}}[i]
w.buffer.{{.Name}}[i] = nil
w.buffer.{{.Name}} = w.buffer.{{.Name}}[:i]
} else {
res = &datatypes.ReadResponse_Frame_{{.Name}}Points{
{{.Name}}Points: &datatypes.ReadResponse_{{.Name}}PointsFrame{
Timestamps: make([]int64, 0, batchSize),
Values: make([]{{.Type}}, 0, batchSize),
},
}
}
return res
}
func (w *ResponseWriter) put{{.Name}}PointsFrame(f *datatypes.ReadResponse_Frame_{{.Name}}Points) {
f.{{.Name}}Points.Timestamps = f.{{.Name}}Points.Timestamps[:0]
f.{{.Name}}Points.Values = f.{{.Name}}Points.Values[:0]
w.buffer.{{.Name}} = append(w.buffer.{{.Name}}, f)
}
func (w *ResponseWriter) stream{{.Name}}ArraySeries(cur cursors.{{.Name}}ArrayCursor) {
w.sf.DataType = datatypes.DataType{{.Name}}
ss := len(w.res.Frames) - 1
a := cur.Next()
if len(a.Timestamps) == 0 {
w.sz -= w.sf.Size()
w.putSeriesFrame(w.res.Frames[ss].Data.(*datatypes.ReadResponse_Frame_Series))
w.res.Frames = w.res.Frames[:ss]
} else if w.sz > writeSize {
w.Flush()
}
}
func (w *ResponseWriter) stream{{.Name}}ArrayPoints(cur cursors.{{.Name}}ArrayCursor) {
w.sf.DataType = datatypes.DataType{{.Name}}
ss := len(w.res.Frames) - 1
p := w.get{{.Name}}PointsFrame()
frame := p.{{.Name}}Points
w.res.Frames = append(w.res.Frames, datatypes.ReadResponse_Frame{Data: p})
var seriesValueCount = 0
for {
// If the number of values produced by cur > 1000,
// cur.Next() will produce batches of values that are of
// length ≤ 1000.
// We attempt to limit the frame Timestamps / Values lengths
// the same to avoid allocations. These frames are recycled
// after flushing so that on repeated use there should be enough space
// to append values from a into frame without additional allocations.
a := cur.Next()
if len(a.Timestamps) == 0 {
break
}
seriesValueCount += a.Len()
// As specified in the struct definition, w.sz is an estimated
// size (in bytes) of the buffered data. It is therefore a
// deliberate choice to accumulate using the array Size, which is
// cheap to calculate. Calling frame.Size() can be expensive
// when using varint encoding for numbers.
w.sz += a.Size()
frame.Timestamps = append(frame.Timestamps, a.Timestamps...)
frame.Values = append(frame.Values, a.Values...)
// given the expectation of cur.Next, we attempt to limit
// the number of values appended to the frame to batchSize (1000)
needsFrame := len(frame.Timestamps) >= batchSize
if w.sz >= writeSize {
needsFrame = true
w.Flush()
if w.err != nil {
break
}
}
if needsFrame {
// new frames are returned with Timestamps and Values preallocated
// to a minimum of batchSize length to reduce further allocations.
p = w.get{{.Name}}PointsFrame()
frame = p.{{.Name}}Points
w.res.Frames = append(w.res.Frames, datatypes.ReadResponse_Frame{Data: p})
}
}
w.vc += seriesValueCount
if seriesValueCount == 0 {
w.sz -= w.sf.Size()
w.putSeriesFrame(w.res.Frames[ss].Data.(*datatypes.ReadResponse_Frame_Series))
w.res.Frames = w.res.Frames[:ss]
} else if w.sz > writeSize {
w.Flush()
}
}
{{end}}