-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Expose Compile alongside Parse with CEL compilers
- Loading branch information
Showing
8 changed files
with
148 additions
and
163 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package expr | ||
|
||
import ( | ||
"sync/atomic" | ||
"time" | ||
|
||
"github.com/google/cel-go/cel" | ||
"github.com/karlseguin/ccache/v2" | ||
) | ||
|
||
var ( | ||
CacheTime = time.Hour | ||
) | ||
|
||
// NewCachingCompiler returns a CELCompiler which lifts quoted literals out of the expression | ||
// as variables and uses caching to cache expression parsing, resulting in improved | ||
// performance when parsing expressions. | ||
func NewCachingCompiler(env *cel.Env, cache *ccache.Cache) CELCompiler { | ||
return &cachingCompiler{ | ||
cache: cache, | ||
env: env, | ||
} | ||
} | ||
|
||
type cachingCompiler struct { | ||
// cache is a global cache of precompiled expressions. | ||
cache *ccache.Cache | ||
|
||
env *cel.Env | ||
|
||
hits int64 | ||
misses int64 | ||
} | ||
|
||
// Parse calls | ||
func (c *cachingCompiler) Parse(expr string) (*cel.Ast, *cel.Issues, LiftedArgs) { | ||
if c.cache == nil { | ||
c.cache = ccache.New(ccache.Configure()) | ||
} | ||
|
||
expr, vars := liftLiterals(expr) | ||
|
||
if cached := c.cache.Get("cc:" + expr); cached != nil { | ||
cached.Extend(CacheTime) | ||
p := cached.Value().(parsedCELExpr) | ||
atomic.AddInt64(&c.hits, 1) | ||
return p.AST, p.ParseIssues, vars | ||
} | ||
|
||
ast, issues := c.env.Parse(expr) | ||
|
||
c.cache.Set("cc:"+expr, parsedCELExpr{ | ||
Expr: expr, | ||
AST: ast, | ||
ParseIssues: issues, | ||
}, CacheTime) | ||
|
||
atomic.AddInt64(&c.misses, 1) | ||
return ast, issues, vars | ||
} | ||
|
||
func (c *cachingCompiler) Compile(expr string) (*cel.Ast, *cel.Issues, LiftedArgs) { | ||
ast, issues, args := c.Parse(expr) | ||
if issues != nil { | ||
return ast, issues, args | ||
} | ||
ast, issues = c.env.Check(ast) | ||
return ast, issues, args | ||
} | ||
|
||
func (c *cachingCompiler) Hits() int64 { | ||
return atomic.LoadInt64(&c.hits) | ||
} | ||
|
||
func (c *cachingCompiler) Misses() int64 { | ||
return atomic.LoadInt64(&c.misses) | ||
} | ||
|
||
type parsedCELExpr struct { | ||
Expr string | ||
AST *cel.Ast | ||
ParseIssues *cel.Issues | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package expr | ||
|
||
// Evaluable represents an evaluable expression with a unique identifier. | ||
type Evaluable interface { | ||
// GetID returns a unique identifier for the evaluable item. If there are | ||
// two instances of the same expression, the identifier should return a unique | ||
// string for each instance of the expression (eg. for two pauses). | ||
// | ||
// It has the Get prefix to reduce collisions with implementations who expose an | ||
// ID member. | ||
GetID() string | ||
|
||
// GetExpression returns an expression as a raw string. | ||
// | ||
// It has the Get prefix to reduce collisions with implementations who expose an | ||
// Expression member. | ||
GetExpression() string | ||
} | ||
|
||
// StringExpression is a string type that implements Evaluable, useful for basic | ||
// ephemeral expressions that have no lifetime. | ||
type StringExpression string | ||
|
||
func (s StringExpression) GetID() string { return string(s) } | ||
func (s StringExpression) GetExpression() string { return string(s) } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.