forked from influxdata/influxdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
emitter.go
81 lines (73 loc) · 1.96 KB
/
emitter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package query
import (
"github.com/influxdata/influxdb/models"
)
// Emitter reads from a cursor into rows.
type Emitter struct {
cur Cursor
chunkSize int
series Series
row *models.Row
columns []string
}
// NewEmitter returns a new instance of Emitter that pulls from itrs.
func NewEmitter(cur Cursor, chunkSize int) *Emitter {
columns := make([]string, len(cur.Columns()))
for i, col := range cur.Columns() {
columns[i] = col.Val
}
return &Emitter{
cur: cur,
chunkSize: chunkSize,
columns: columns,
}
}
// Close closes the underlying iterators.
func (e *Emitter) Close() error {
return e.cur.Close()
}
// Emit returns the next row from the iterators.
func (e *Emitter) Emit() (*models.Row, bool, error) {
// Continually read from the cursor until it is exhausted.
for {
// Scan the next row. If there are no rows left, return the current row.
var row Row
if !e.cur.Scan(&row) {
if err := e.cur.Err(); err != nil {
return nil, false, err
}
r := e.row
e.row = nil
return r, false, nil
}
// If there's no row yet then create one.
// If the name and tags match the existing row, append to that row if
// the number of values doesn't exceed the chunk size.
// Otherwise return existing row and add values to next emitted row.
if e.row == nil {
e.createRow(row.Series, row.Values)
} else if e.series.SameSeries(row.Series) {
if e.chunkSize > 0 && len(e.row.Values) >= e.chunkSize {
r := e.row
r.Partial = true
e.createRow(row.Series, row.Values)
return r, true, nil
}
e.row.Values = append(e.row.Values, row.Values)
} else {
r := e.row
e.createRow(row.Series, row.Values)
return r, true, nil
}
}
}
// createRow creates a new row attached to the emitter.
func (e *Emitter) createRow(series Series, values []interface{}) {
e.series = series
e.row = &models.Row{
Name: series.Name,
Tags: series.Tags.KeyValues(),
Columns: e.columns,
Values: [][]interface{}{values},
}
}