@@ -119,9 +119,17 @@ type eval struct {
119119 defined bool
120120}
121121
122- type evp struct {
123- pool sync.Pool
124- }
122+ type (
123+ evp struct {
124+ pool sync.Pool
125+ }
126+ evfp struct {
127+ pool sync.Pool
128+ }
129+ evbp struct {
130+ pool sync.Pool
131+ }
132+ )
125133
126134func (ep * evp ) Put (e * eval ) {
127135 ep .pool .Put (e )
@@ -131,14 +139,52 @@ func (ep *evp) Get() *eval {
131139 return ep .pool .Get ().(* eval )
132140}
133141
134- var evalPool = evp {
135- pool : sync.Pool {
136- New : func () any {
137- return & eval {}
138- },
139- },
142+ func (ep * evfp ) Put (e * evalFunc ) {
143+ if e != nil {
144+ e .e , e .terms , e .ir = nil , nil , nil
145+ ep .pool .Put (e )
146+ }
147+ }
148+
149+ func (ep * evfp ) Get () * evalFunc {
150+ return ep .pool .Get ().(* evalFunc )
151+ }
152+
153+ func (ep * evbp ) Put (e * evalBuiltin ) {
154+ if e != nil {
155+ e .e , e .bi , e .bctx , e .f , e .terms = nil , nil , nil , nil , nil
156+ ep .pool .Put (e )
157+ }
158+ }
159+
160+ func (ep * evbp ) Get () * evalBuiltin {
161+ return ep .pool .Get ().(* evalBuiltin )
140162}
141163
164+ var (
165+ evalPool = & evp {
166+ pool : sync.Pool {
167+ New : func () any {
168+ return & eval {}
169+ },
170+ },
171+ }
172+ evalFuncPool = & evfp {
173+ pool : sync.Pool {
174+ New : func () any {
175+ return & evalFunc {}
176+ },
177+ },
178+ }
179+ evalBuiltinPool = & evbp {
180+ pool : sync.Pool {
181+ New : func () any {
182+ return & evalBuiltin {}
183+ },
184+ },
185+ }
186+ )
187+
142188func (e * eval ) Run (iter evalIterator ) error {
143189 if ! e .traceEnabled {
144190 // avoid function literal escaping to heap if we don't need the trace
@@ -401,9 +447,11 @@ func (e *eval) evalExpr(iter evalIterator) error {
401447 }
402448 return nil
403449 }
404- expr := e .query [e .index ]
405450
406- e .traceEval (expr )
451+ expr := e .query [e .index ]
452+ if e .traceEnabled {
453+ e .traceEval (expr )
454+ }
407455
408456 if len (expr .With ) > 0 {
409457 return e .evalWith (iter )
@@ -521,7 +569,7 @@ func (e *eval) evalStep(iter evalIterator) error {
521569 // generateVar inlined here to avoid extra allocations in hot path
522570 rterm := ast .VarTerm (e .fmtVarTerm ())
523571 err = e .unify (terms , rterm , func () error {
524- if e .saveSet .Contains (rterm , e .bindings ) {
572+ if e .saveSet != nil && e . saveSet .Contains (rterm , e .bindings ) {
525573 return e .saveExpr (ast .NewExpr (rterm ), e .bindings , func () error {
526574 return iter (e )
527575 })
@@ -888,7 +936,6 @@ func (e *eval) evalNotPartialSupport(negationID uint64, expr *ast.Expr, unknowns
888936}
889937
890938func (e * eval ) evalCall (terms []* ast.Term , iter unifyIterator ) error {
891-
892939 ref := terms [0 ].Value .(ast.Ref )
893940
894941 mock , mocked := e .functionMocks .Get (ref )
@@ -912,8 +959,8 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error {
912959
913960 if ref [0 ].Equal (ast .DefaultRootDocument ) {
914961 if mocked {
915- f := e .compiler .TypeEnv .Get (ref ).(* types.Function )
916- return e .evalCallValue (f . Arity () , terms , mock , iter )
962+ arity := e .compiler .TypeEnv .GetByRef (ref ).(* types.Function ). Arity ( )
963+ return e .evalCallValue (arity , terms , mock , iter )
917964 }
918965
919966 var ir * ast.IndexResult
@@ -928,11 +975,13 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error {
928975 return err
929976 }
930977
931- eval := evalFunc {
932- e : e ,
933- terms : terms ,
934- ir : ir ,
935- }
978+ eval := evalFuncPool .Get ()
979+ defer evalFuncPool .Put (eval )
980+
981+ eval .e = e
982+ eval .terms = terms
983+ eval .ir = ir
984+
936985 return eval .eval (iter )
937986 }
938987
@@ -991,13 +1040,14 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error {
9911040 }
9921041 }
9931042
994- eval := evalBuiltin {
995- e : e ,
996- bi : bi ,
997- bctx : bctx ,
998- f : f ,
999- terms : terms [1 :],
1000- }
1043+ eval := evalBuiltinPool .Get ()
1044+ defer evalBuiltinPool .Put (eval )
1045+
1046+ eval .e = e
1047+ eval .bi = bi
1048+ eval .bctx = bctx
1049+ eval .f = f
1050+ eval .terms = terms [1 :]
10011051
10021052 return eval .eval (iter )
10031053}
@@ -1054,7 +1104,9 @@ func (e *eval) biunify(a, b *ast.Term, b1, b2 *bindings, iter unifyIterator) err
10541104 case ast.Var , ast.Ref , * ast.ArrayComprehension :
10551105 return e .biunifyValues (a , b , b1 , b2 , iter )
10561106 case * ast.Array :
1057- return e .biunifyArrays (vA , vB , b1 , b2 , iter )
1107+ if vA .Len () == vB .Len () {
1108+ return e .biunifyArraysRec (vA , vB , b1 , b2 , iter , 0 )
1109+ }
10581110 }
10591111 case ast.Object :
10601112 switch vB := b .Value .(type ) {
@@ -1069,13 +1121,6 @@ func (e *eval) biunify(a, b *ast.Term, b1, b2 *bindings, iter unifyIterator) err
10691121 return nil
10701122}
10711123
1072- func (e * eval ) biunifyArrays (a , b * ast.Array , b1 , b2 * bindings , iter unifyIterator ) error {
1073- if a .Len () != b .Len () {
1074- return nil
1075- }
1076- return e .biunifyArraysRec (a , b , b1 , b2 , iter , 0 )
1077- }
1078-
10791124func (e * eval ) biunifyArraysRec (a , b * ast.Array , b1 , b2 * bindings , iter unifyIterator , idx int ) error {
10801125 if idx == a .Len () {
10811126 return iter ()
@@ -2052,8 +2097,7 @@ type evalFunc struct {
20522097 terms []* ast.Term
20532098}
20542099
2055- func (e evalFunc ) eval (iter unifyIterator ) error {
2056-
2100+ func (e * evalFunc ) eval (iter unifyIterator ) error {
20572101 if e .ir .Empty () {
20582102 return nil
20592103 }
@@ -2065,13 +2109,13 @@ func (e evalFunc) eval(iter unifyIterator) error {
20652109 argCount = len (e .ir .Default .Head .Args )
20662110 }
20672111
2068- if len (e .ir .Else ) > 0 && e .e .unknown (e .e .query [e .e .index ], e .e .bindings ) {
2069- // Partial evaluation of ordered rules is not supported currently. Save the
2070- // expression and continue. This could be revisited in the future.
2071- return e .e .saveCall (argCount , e .terms , iter )
2072- }
2073-
20742112 if e .e .partial () {
2113+ if len (e .ir .Else ) > 0 && e .e .unknown (e .e .query [e .e .index ], e .e .bindings ) {
2114+ // Partial evaluation of ordered rules is not supported currently. Save the
2115+ // expression and continue. This could be revisited in the future.
2116+ return e .e .saveCall (argCount , e .terms , iter )
2117+ }
2118+
20752119 var mustGenerateSupport bool
20762120
20772121 if defRule := e .ir .Default ; defRule != nil {
@@ -2109,7 +2153,7 @@ func (e evalFunc) eval(iter unifyIterator) error {
21092153 return e .evalValue (iter , argCount , e .ir .EarlyExit )
21102154}
21112155
2112- func (e evalFunc ) evalValue (iter unifyIterator , argCount int , findOne bool ) error {
2156+ func (e * evalFunc ) evalValue (iter unifyIterator , argCount int , findOne bool ) error {
21132157 var cacheKey ast.Ref
21142158 if ! e .e .partial () {
21152159 var hit bool
@@ -2194,7 +2238,7 @@ func (e evalFunc) evalValue(iter unifyIterator, argCount int, findOne bool) erro
21942238 })
21952239}
21962240
2197- func (e evalFunc ) evalCache (argCount int , iter unifyIterator ) (ast.Ref , bool , error ) {
2241+ func (e * evalFunc ) evalCache (argCount int , iter unifyIterator ) (ast.Ref , bool , error ) {
21982242 plen := len (e .terms )
21992243 if plen == argCount + 2 { // func name + output = 2
22002244 plen -= 1
@@ -2226,7 +2270,7 @@ func (e evalFunc) evalCache(argCount int, iter unifyIterator) (ast.Ref, bool, er
22262270 return cacheKey , false , nil
22272271}
22282272
2229- func (e evalFunc ) evalOneRule (iter unifyIterator , rule * ast.Rule , args []* ast.Term , cacheKey ast.Ref , prev * ast.Term , findOne bool ) (* ast.Term , error ) {
2273+ func (e * evalFunc ) evalOneRule (iter unifyIterator , rule * ast.Rule , args []* ast.Term , cacheKey ast.Ref , prev * ast.Term , findOne bool ) (* ast.Term , error ) {
22302274 child := evalPool .Get ()
22312275 defer evalPool .Put (child )
22322276
@@ -2288,7 +2332,7 @@ func (e evalFunc) evalOneRule(iter unifyIterator, rule *ast.Rule, args []*ast.Te
22882332 return result , err
22892333}
22902334
2291- func (e evalFunc ) partialEvalSupport (declArgsLen int , iter unifyIterator ) error {
2335+ func (e * evalFunc ) partialEvalSupport (declArgsLen int , iter unifyIterator ) error {
22922336 path := e .e .namespaceRef (e .terms [0 ].Value .(ast.Ref ))
22932337
22942338 if ! e .e .saveSupport .Exists (path ) {
@@ -2316,7 +2360,7 @@ func (e evalFunc) partialEvalSupport(declArgsLen int, iter unifyIterator) error
23162360 return e .e .saveCall (declArgsLen , append ([]* ast.Term {term }, e .terms [1 :]... ), iter )
23172361}
23182362
2319- func (e evalFunc ) partialEvalSupportRule (rule * ast.Rule , path ast.Ref ) error {
2363+ func (e * evalFunc ) partialEvalSupportRule (rule * ast.Rule , path ast.Ref ) error {
23202364 child := evalPool .Get ()
23212365 defer evalPool .Put (child )
23222366
0 commit comments