forked from couchbaselabs/gojsonsm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpressionstats.go
105 lines (97 loc) · 2.62 KB
/
expressionstats.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2018 Couchbase, Inc. All rights reserved.
package gojsonsm
import "fmt"
type ExpressionStats struct {
NumLoops int
NumNestedLoops int
MaxLoopDepth int
NumAnds int
NumOrs int
NumFields int
NumValues int
}
func (stats ExpressionStats) String() string {
var out string
out += fmt.Sprintf("num loops: %d\n", stats.NumLoops)
out += fmt.Sprintf("num nested loops: %d\n", stats.NumNestedLoops)
out += fmt.Sprintf("max loop depth: %d\n", stats.MaxLoopDepth)
out += fmt.Sprintf("num ands: %d\n", stats.NumAnds)
out += fmt.Sprintf("num ors: %d\n", stats.NumOrs)
out += fmt.Sprintf("num fields: %d\n", stats.NumFields)
out += fmt.Sprintf("num values: %d", stats.NumValues)
return out
}
func (stats *ExpressionStats) scanOne(expr Expression, loopDepth int) error {
if loopDepth > stats.MaxLoopDepth {
stats.MaxLoopDepth = loopDepth
}
switch expr := expr.(type) {
case FieldExpr:
stats.NumFields++
case ValueExpr:
stats.NumValues++
case FuncExpr:
for _, subexpr := range expr.Params {
stats.scanOne(subexpr, loopDepth)
}
case AndExpr:
stats.NumAnds++
for _, subexpr := range expr {
stats.scanOne(subexpr, loopDepth)
}
case OrExpr:
stats.NumOrs++
for _, subexpr := range expr {
stats.scanOne(subexpr, loopDepth)
}
case AnyInExpr:
stats.NumLoops++
if loopDepth == 1 {
stats.NumNestedLoops++
}
stats.scanOne(expr.InExpr, loopDepth)
stats.scanOne(expr.SubExpr, loopDepth+1)
case EveryInExpr:
stats.NumLoops++
if loopDepth == 1 {
stats.NumNestedLoops++
}
stats.scanOne(expr.InExpr, loopDepth)
stats.scanOne(expr.SubExpr, loopDepth+1)
case AnyEveryInExpr:
stats.NumLoops++
if loopDepth == 1 {
stats.NumNestedLoops++
}
stats.scanOne(expr.InExpr, loopDepth)
stats.scanOne(expr.SubExpr, loopDepth+1)
case ExistsExpr:
stats.scanOne(expr.SubExpr, loopDepth)
case NotExistsExpr:
stats.scanOne(expr.SubExpr, loopDepth)
case EqualsExpr:
stats.scanOne(expr.Lhs, loopDepth)
stats.scanOne(expr.Rhs, loopDepth)
case NotEqualsExpr:
stats.scanOne(expr.Lhs, loopDepth)
stats.scanOne(expr.Rhs, loopDepth)
case LessThanExpr:
stats.scanOne(expr.Lhs, loopDepth)
stats.scanOne(expr.Rhs, loopDepth)
case LessEqualsExpr:
stats.scanOne(expr.Lhs, loopDepth)
stats.scanOne(expr.Rhs, loopDepth)
case GreaterThanExpr:
stats.scanOne(expr.Lhs, loopDepth)
stats.scanOne(expr.Rhs, loopDepth)
case GreaterEqualsExpr:
stats.scanOne(expr.Lhs, loopDepth)
stats.scanOne(expr.Rhs, loopDepth)
default:
panic("unexpected expression type")
}
return nil
}
func (stats *ExpressionStats) Scan(expr Expression) error {
return stats.scanOne(expr, 0)
}