mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-31 15:06:26 +00:00
89 lines
2.1 KiB
Go
89 lines
2.1 KiB
Go
package logstorage
|
|
|
|
import (
|
|
"fmt"
|
|
"slices"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
|
)
|
|
|
|
type pipeFields struct {
|
|
// fields contains list of fields to fetch
|
|
fields []string
|
|
|
|
// whether fields contains star
|
|
containsStar bool
|
|
}
|
|
|
|
func (pf *pipeFields) String() string {
|
|
if len(pf.fields) == 0 {
|
|
logger.Panicf("BUG: pipeFields must contain at least a single field")
|
|
}
|
|
return "fields " + fieldNamesString(pf.fields)
|
|
}
|
|
|
|
func (pf *pipeFields) newPipeProcessor(_ int, _ <-chan struct{}, _ func(), ppBase pipeProcessor) pipeProcessor {
|
|
return &pipeFieldsProcessor{
|
|
pf: pf,
|
|
ppBase: ppBase,
|
|
}
|
|
}
|
|
|
|
type pipeFieldsProcessor struct {
|
|
pf *pipeFields
|
|
ppBase pipeProcessor
|
|
}
|
|
|
|
func (fpp *pipeFieldsProcessor) writeBlock(workerID uint, timestamps []int64, columns []BlockColumn) {
|
|
if fpp.pf.containsStar || areSameBlockColumns(columns, fpp.pf.fields) {
|
|
// Fast path - there is no need in additional transformations before writing the block to ppBase.
|
|
fpp.ppBase.writeBlock(workerID, timestamps, columns)
|
|
return
|
|
}
|
|
|
|
// Slow path - construct columns for fpp.pf.fields before writing them to ppBase.
|
|
brs := getBlockRows()
|
|
cs := brs.cs
|
|
for _, f := range fpp.pf.fields {
|
|
values := getBlockColumnValues(columns, f, len(timestamps))
|
|
cs = append(cs, BlockColumn{
|
|
Name: f,
|
|
Values: values,
|
|
})
|
|
}
|
|
fpp.ppBase.writeBlock(workerID, timestamps, cs)
|
|
brs.cs = cs
|
|
putBlockRows(brs)
|
|
}
|
|
|
|
func (fpp *pipeFieldsProcessor) flush() error {
|
|
return nil
|
|
}
|
|
|
|
func parsePipeFields(lex *lexer) (*pipeFields, error) {
|
|
var fields []string
|
|
for {
|
|
if !lex.mustNextToken() {
|
|
return nil, fmt.Errorf("missing field name")
|
|
}
|
|
if lex.isKeyword(",") {
|
|
return nil, fmt.Errorf("unexpected ','; expecting field name")
|
|
}
|
|
field, err := parseFieldName(lex)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot parse field name: %w", err)
|
|
}
|
|
fields = append(fields, field)
|
|
switch {
|
|
case lex.isKeyword("|", ")", ""):
|
|
pf := &pipeFields{
|
|
fields: fields,
|
|
containsStar: slices.Contains(fields, "*"),
|
|
}
|
|
return pf, nil
|
|
case lex.isKeyword(","):
|
|
default:
|
|
return nil, fmt.Errorf("unexpected token: %q; expecting ',', '|' or ')'", lex.token)
|
|
}
|
|
}
|
|
}
|