Refactor InfluxDB listener (#6974)

Use streaming parser in InfluxDB listener
This commit is contained in:
reimda
2020-03-04 11:13:44 -07:00
committed by GitHub
parent ab8438dcc6
commit a0276385b1
21 changed files with 19898 additions and 18303 deletions

View File

@@ -2,6 +2,7 @@ package influx
import (
"errors"
"io"
)
var (
@@ -70,8 +71,8 @@ action goto_align {
fgoto align;
}
action found_metric {
foundMetric = true
action begin_metric {
m.beginMetric = true
}
action name {
@@ -84,11 +85,11 @@ action name {
}
action tagkey {
key = m.text()
m.key = m.text()
}
action tagvalue {
err = m.handler.AddTag(key, m.text())
err = m.handler.AddTag(m.key, m.text())
if err != nil {
fhold;
fnext discard_line;
@@ -97,11 +98,11 @@ action tagvalue {
}
action fieldkey {
key = m.text()
m.key = m.text()
}
action integer {
err = m.handler.AddInt(key, m.text())
err = m.handler.AddInt(m.key, m.text())
if err != nil {
fhold;
fnext discard_line;
@@ -110,7 +111,7 @@ action integer {
}
action unsigned {
err = m.handler.AddUint(key, m.text())
err = m.handler.AddUint(m.key, m.text())
if err != nil {
fhold;
fnext discard_line;
@@ -119,7 +120,7 @@ action unsigned {
}
action float {
err = m.handler.AddFloat(key, m.text())
err = m.handler.AddFloat(m.key, m.text())
if err != nil {
fhold;
fnext discard_line;
@@ -128,7 +129,7 @@ action float {
}
action bool {
err = m.handler.AddBool(key, m.text())
err = m.handler.AddBool(m.key, m.text())
if err != nil {
fhold;
fnext discard_line;
@@ -137,7 +138,7 @@ action bool {
}
action string {
err = m.handler.AddString(key, m.text())
err = m.handler.AddString(m.key, m.text())
if err != nil {
fhold;
fnext discard_line;
@@ -161,15 +162,20 @@ action incr_newline {
}
action eol {
m.finishMetric = true
fnext align;
fbreak;
}
action finish_metric {
m.finishMetric = true
}
ws =
[\t\v\f ];
newline =
'\r'? '\n' %to(incr_newline);
'\r'? '\n' >incr_newline;
non_zero_digit =
[1-9];
@@ -273,7 +279,7 @@ line_without_term =
main :=
(line_with_term*
(line_with_term | line_without_term?)
) >found_metric
) >begin_metric %eof(finish_metric)
;
# The discard_line machine discards the current line. Useful for recovering
@@ -299,7 +305,7 @@ align :=
# Series is a machine for matching measurement+tagset
series :=
(measurement >err(name_error) tagset eol_break?)
>found_metric
>begin_metric
;
}%%
@@ -317,14 +323,17 @@ type Handler interface {
}
type machine struct {
data []byte
cs int
p, pe, eof int
pb int
lineno int
sol int
handler Handler
initState int
data []byte
cs int
p, pe, eof int
pb int
lineno int
sol int
handler Handler
initState int
key []byte
beginMetric bool
finishMetric bool
}
func NewMachine(handler Handler) *machine {
@@ -368,6 +377,9 @@ func (m *machine) SetData(data []byte) {
m.sol = 0
m.pe = len(data)
m.eof = len(data)
m.key = nil
m.beginMetric = false
m.finishMetric = false
%% write init;
m.cs = m.initState
@@ -382,10 +394,15 @@ func (m *machine) Next() error {
return EOF
}
var err error
var key []byte
foundMetric := false
m.key = nil
m.beginMetric = false
m.finishMetric = false
return m.exec()
}
func (m *machine) exec() error {
var err error
%% write exec;
if err != nil {
@@ -405,7 +422,7 @@ func (m *machine) Next() error {
//
// Otherwise we have successfully parsed a metric line, so if we are at
// the EOF we will report it the next call.
if !foundMetric && m.p == m.pe && m.pe == m.eof {
if !m.beginMetric && m.p == m.pe && m.pe == m.eof {
return EOF
}
@@ -437,3 +454,96 @@ func (m *machine) Column() int {
func (m *machine) text() []byte {
return m.data[m.pb:m.p]
}
type streamMachine struct {
machine *machine
reader io.Reader
}
func NewStreamMachine(r io.Reader, handler Handler) *streamMachine {
m := &streamMachine{
machine: NewMachine(handler),
reader: r,
}
m.machine.SetData(make([]byte, 1024))
m.machine.pe = 0
m.machine.eof = -1
return m
}
func (m *streamMachine) Next() error {
// Check if we are already at EOF, this should only happen if called again
// after already returning EOF.
if m.machine.p == m.machine.pe && m.machine.pe == m.machine.eof {
return EOF
}
copy(m.machine.data, m.machine.data[m.machine.p:])
m.machine.pe = m.machine.pe - m.machine.p
m.machine.sol = m.machine.sol - m.machine.p
m.machine.pb = 0
m.machine.p = 0
m.machine.eof = -1
m.machine.key = nil
m.machine.beginMetric = false
m.machine.finishMetric = false
for {
// Expand the buffer if it is full
if m.machine.pe == len(m.machine.data) {
expanded := make([]byte, 2 * len(m.machine.data))
copy(expanded, m.machine.data)
m.machine.data = expanded
}
n, err := m.reader.Read(m.machine.data[m.machine.pe:])
if n == 0 && err == io.EOF {
m.machine.eof = m.machine.pe
} else if err != nil && err != io.EOF {
return err
}
m.machine.pe += n
err = m.machine.exec()
if err != nil {
return err
}
// If we have successfully parsed a full metric line break out
if m.machine.finishMetric {
break
}
}
return nil
}
// Position returns the current byte offset into the data.
func (m *streamMachine) Position() int {
return m.machine.Position()
}
// LineOffset returns the byte offset of the current line.
func (m *streamMachine) LineOffset() int {
return m.machine.LineOffset()
}
// LineNumber returns the current line number. Lines are counted based on the
// regular expression `\r?\n`.
func (m *streamMachine) LineNumber() int {
return m.machine.LineNumber()
}
// Column returns the current column.
func (m *streamMachine) Column() int {
return m.machine.Column()
}
// LineText returns the text of the current line that has been parsed so far.
func (m *streamMachine) LineText() string {
return string(m.machine.data[0:m.machine.p])
}