mirror of
https://github.com/prometheus/prometheus.git
synced 2025-08-06 06:07:11 +02:00
Merge 75b72c2e42
into 25aee26a57
This commit is contained in:
commit
4d38d56c94
@ -660,6 +660,15 @@ func BenchmarkParser(b *testing.B) {
|
||||
}
|
||||
})
|
||||
}
|
||||
for _, c := range cases {
|
||||
b.Run("preprocess "+c, func(b *testing.B) {
|
||||
expr, _ := parser.ParseExpr(c)
|
||||
start, end := time.Now().Add(-time.Hour), time.Now()
|
||||
for i := 0; i < b.N; i++ {
|
||||
promql.PreprocessExpr(expr, start, end, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
for _, c := range errCases {
|
||||
name := fmt.Sprintf("%s (should fail)", c)
|
||||
b.Run(name, func(b *testing.B) {
|
||||
|
@ -334,10 +334,13 @@ func Walk(v Visitor, node Node, path []Node) error {
|
||||
if v, err = v.Visit(node, path); v == nil || err != nil {
|
||||
return err
|
||||
}
|
||||
path = append(path, node)
|
||||
var pathToHere []Node // Initialized only when needed.
|
||||
|
||||
for _, e := range Children(node) {
|
||||
if err := Walk(v, e, path); err != nil {
|
||||
for e := range ChildrenIter(node) {
|
||||
if pathToHere == nil {
|
||||
pathToHere = append(path, node)
|
||||
}
|
||||
if err := Walk(v, e, pathToHere); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -371,61 +374,71 @@ func (f inspector) Visit(node Node, path []Node) (Visitor, error) {
|
||||
// Inspect traverses an AST in depth-first order: It starts by calling
|
||||
// f(node, path); node must not be nil. If f returns a nil error, Inspect invokes f
|
||||
// for all the non-nil children of node, recursively.
|
||||
// Note: path may be overwritten after f returns; copy path if you need to retain it.
|
||||
func Inspect(node Node, f inspector) {
|
||||
Walk(f, node, nil) //nolint:errcheck
|
||||
var pathBuf [4]Node // To reduce allocations during recursion.
|
||||
Walk(f, node, pathBuf[:0]) //nolint:errcheck
|
||||
}
|
||||
|
||||
// ChildrenIter returns an iterator over all child nodes of a syntax tree node.
|
||||
func ChildrenIter(node Node) func(func(Node) bool) {
|
||||
return func(yield func(Node) bool) {
|
||||
// According to lore, these switches have significantly better performance than interfaces
|
||||
switch n := node.(type) {
|
||||
case *EvalStmt:
|
||||
yield(n.Expr)
|
||||
case Expressions:
|
||||
for _, e := range n {
|
||||
if !yield(e) {
|
||||
return
|
||||
}
|
||||
}
|
||||
case *AggregateExpr:
|
||||
if n.Expr != nil {
|
||||
if !yield(n.Expr) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if n.Param != nil {
|
||||
yield(n.Param)
|
||||
}
|
||||
case *BinaryExpr:
|
||||
if !yield(n.LHS) {
|
||||
return
|
||||
}
|
||||
yield(n.RHS)
|
||||
case *Call:
|
||||
for _, e := range n.Args {
|
||||
if !yield(e) {
|
||||
return
|
||||
}
|
||||
}
|
||||
case *SubqueryExpr:
|
||||
yield(n.Expr)
|
||||
case *ParenExpr:
|
||||
yield(n.Expr)
|
||||
case *UnaryExpr:
|
||||
yield(n.Expr)
|
||||
case *MatrixSelector:
|
||||
yield(n.VectorSelector)
|
||||
case *StepInvariantExpr:
|
||||
yield(n.Expr)
|
||||
case *NumberLiteral, *StringLiteral, *VectorSelector:
|
||||
// nothing to do
|
||||
default:
|
||||
panic(fmt.Errorf("promql.ChildrenIter: unhandled node type %T", node))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Children returns a list of all child nodes of a syntax tree node.
|
||||
// Implemented for backwards-compatibility; prefer ChildrenIter().
|
||||
func Children(node Node) []Node {
|
||||
// For some reasons these switches have significantly better performance than interfaces
|
||||
switch n := node.(type) {
|
||||
case *EvalStmt:
|
||||
return []Node{n.Expr}
|
||||
case Expressions:
|
||||
// golang cannot convert slices of interfaces
|
||||
ret := make([]Node, len(n))
|
||||
for i, e := range n {
|
||||
ret[i] = e
|
||||
}
|
||||
return ret
|
||||
case *AggregateExpr:
|
||||
// While this does not look nice, it should avoid unnecessary allocations
|
||||
// caused by slice resizing
|
||||
switch {
|
||||
case n.Expr == nil && n.Param == nil:
|
||||
return nil
|
||||
case n.Expr == nil:
|
||||
return []Node{n.Param}
|
||||
case n.Param == nil:
|
||||
return []Node{n.Expr}
|
||||
default:
|
||||
return []Node{n.Expr, n.Param}
|
||||
}
|
||||
case *BinaryExpr:
|
||||
return []Node{n.LHS, n.RHS}
|
||||
case *Call:
|
||||
// golang cannot convert slices of interfaces
|
||||
ret := make([]Node, len(n.Args))
|
||||
for i, e := range n.Args {
|
||||
ret[i] = e
|
||||
}
|
||||
return ret
|
||||
case *SubqueryExpr:
|
||||
return []Node{n.Expr}
|
||||
case *ParenExpr:
|
||||
return []Node{n.Expr}
|
||||
case *UnaryExpr:
|
||||
return []Node{n.Expr}
|
||||
case *MatrixSelector:
|
||||
return []Node{n.VectorSelector}
|
||||
case *StepInvariantExpr:
|
||||
return []Node{n.Expr}
|
||||
case *NumberLiteral, *StringLiteral, *VectorSelector:
|
||||
// nothing to do
|
||||
return []Node{}
|
||||
default:
|
||||
panic(fmt.Errorf("promql.Children: unhandled node type %T", node))
|
||||
ret := []Node{}
|
||||
for e := range ChildrenIter(node) {
|
||||
ret = append(ret, e)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// mergeRanges is a helper function to merge the PositionRanges of two Nodes.
|
||||
|
@ -41,7 +41,7 @@ func tree(node Node, level string) string {
|
||||
|
||||
level += " · · ·"
|
||||
|
||||
for _, e := range Children(node) {
|
||||
for e := range ChildrenIter(node) {
|
||||
t += tree(e, level)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user