Add object pooling for parser expressions
This commit is contained in:
parent
340dea242d
commit
6b90b94e07
|
@ -0,0 +1,7 @@
|
|||
goos: darwin
|
||||
goarch: amd64
|
||||
pkg: github.com/dosco/super-graph/psql
|
||||
BenchmarkCompile-8 100000 15728 ns/op 3000 B/op 60 allocs/op
|
||||
BenchmarkCompileParallel-8 300000 5077 ns/op 3023 B/op 60 allocs/op
|
||||
PASS
|
||||
ok github.com/dosco/super-graph/psql 3.318s
|
|
@ -657,10 +657,12 @@ func (c *compilerContext) renderWhere(sel *qcode.Select, ti *DBTableInfo) error
|
|||
st.Push(val.Op)
|
||||
}
|
||||
}
|
||||
qcode.FreeExp(val)
|
||||
continue
|
||||
case qcode.OpNot:
|
||||
st.Push(val.Children[0])
|
||||
st.Push(qcode.OpNot)
|
||||
qcode.FreeExp(val)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -669,6 +671,7 @@ func (c *compilerContext) renderWhere(sel *qcode.Select, ti *DBTableInfo) error
|
|||
c.w.WriteString(`(("`)
|
||||
c.w.WriteString(val.Col)
|
||||
c.w.WriteString(`") `)
|
||||
|
||||
} else if len(val.Col) != 0 {
|
||||
//fmt.Fprintf(w, `(("%s"."%s") `, c.sel.Table, val.Col)
|
||||
c.w.WriteString(`((`)
|
||||
|
@ -757,9 +760,12 @@ func (c *compilerContext) renderWhere(sel *qcode.Select, ti *DBTableInfo) error
|
|||
c.w.WriteString(`)`)
|
||||
}
|
||||
|
||||
qcode.FreeExp(val)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("12: unexpected value %v (%t)", intf, intf)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -523,6 +523,6 @@ func (t parserType) String() string {
|
|||
return fmt.Sprintf("<%s>", v)
|
||||
}
|
||||
|
||||
func PutNode(n *Node) {
|
||||
func FreeNode(n *Node) {
|
||||
nodePool.Put(n)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/dosco/super-graph/util"
|
||||
"github.com/gobuffalo/flect"
|
||||
|
@ -51,6 +52,13 @@ type Exp struct {
|
|||
ListVal []string
|
||||
Children []*Exp
|
||||
childrenA [5]*Exp
|
||||
doFree bool
|
||||
}
|
||||
|
||||
var zeroExp = Exp{doFree: true}
|
||||
|
||||
func (ex *Exp) Reset() {
|
||||
*ex = zeroExp
|
||||
}
|
||||
|
||||
type OrderBy struct {
|
||||
|
@ -141,6 +149,10 @@ type Compiler struct {
|
|||
ka bool
|
||||
}
|
||||
|
||||
var expPool = sync.Pool{
|
||||
New: func() interface{} { return new(Exp) },
|
||||
}
|
||||
|
||||
func NewCompiler(c Config) (*Compiler, error) {
|
||||
bl := make(map[string]struct{}, len(c.Blacklist))
|
||||
|
||||
|
@ -385,10 +397,10 @@ func (com *Compiler) compileArgObj(arg *Arg) (*Exp, error) {
|
|||
return nil, fmt.Errorf("expecting an object")
|
||||
}
|
||||
|
||||
return com.compileArgNode(arg.Val)
|
||||
return com.compileArgNode(arg.Val, true)
|
||||
}
|
||||
|
||||
func (com *Compiler) compileArgNode(node *Node) (*Exp, error) {
|
||||
func (com *Compiler) compileArgNode(node *Node, usePool bool) (*Exp, error) {
|
||||
st := util.NewStack()
|
||||
var root *Exp
|
||||
|
||||
|
@ -415,8 +427,7 @@ func (com *Compiler) compileArgNode(node *Node) (*Exp, error) {
|
|||
}
|
||||
}
|
||||
|
||||
ex, err := newExp(st, eT)
|
||||
|
||||
ex, err := newExp(st, eT, usePool)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -459,7 +470,11 @@ func (com *Compiler) compileArgID(sel *Select, arg *Arg) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
ex := &Exp{Op: OpEqID, Val: arg.Val.Val}
|
||||
ex := expPool.Get().(*Exp)
|
||||
ex.Reset()
|
||||
|
||||
ex.Op = OpEqID
|
||||
ex.Val = arg.Val.Val
|
||||
|
||||
switch arg.Val.Type {
|
||||
case nodeStr:
|
||||
|
@ -479,11 +494,12 @@ func (com *Compiler) compileArgID(sel *Select, arg *Arg) error {
|
|||
}
|
||||
|
||||
func (com *Compiler) compileArgSearch(sel *Select, arg *Arg) error {
|
||||
ex := &Exp{
|
||||
Op: OpTsQuery,
|
||||
Type: ValStr,
|
||||
Val: arg.Val.Val,
|
||||
}
|
||||
ex := expPool.Get().(*Exp)
|
||||
ex.Reset()
|
||||
|
||||
ex.Op = OpTsQuery
|
||||
ex.Type = ValStr
|
||||
ex.Val = arg.Val.Val
|
||||
|
||||
if sel.Where != nil {
|
||||
ow := sel.Where
|
||||
|
@ -643,7 +659,7 @@ func compileSub() (*Query, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func newExp(st *util.Stack, eT *expT) (*Exp, error) {
|
||||
func newExp(st *util.Stack, eT *expT, usePool bool) (*Exp, error) {
|
||||
node := eT.node
|
||||
|
||||
if len(node.Name) == 0 {
|
||||
|
@ -656,7 +672,15 @@ func newExp(st *util.Stack, eT *expT) (*Exp, error) {
|
|||
name = name[1:]
|
||||
}
|
||||
|
||||
ex := &Exp{}
|
||||
var ex *Exp
|
||||
|
||||
if usePool {
|
||||
ex = expPool.Get().(*Exp)
|
||||
ex.Reset()
|
||||
} else {
|
||||
ex = &Exp{}
|
||||
}
|
||||
ex.Children = ex.childrenA[:0]
|
||||
|
||||
switch name {
|
||||
case "and":
|
||||
|
@ -831,7 +855,7 @@ func compileFilter(filter []string) (*Exp, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, err := com.compileArgNode(node)
|
||||
f, err := com.compileArgNode(node, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -926,3 +950,9 @@ func (t ExpOp) String() string {
|
|||
}
|
||||
return fmt.Sprintf("<%s>", v)
|
||||
}
|
||||
|
||||
func FreeExp(ex *Exp) {
|
||||
if ex.doFree {
|
||||
expPool.Put(ex)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue