aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/query/optimizer.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/query/optimizer.go')
-rw-r--r--pkg/query/optimizer.go38
1 files changed, 38 insertions, 0 deletions
diff --git a/pkg/query/optimizer.go b/pkg/query/optimizer.go
index c203b9c..cdb2455 100644
--- a/pkg/query/optimizer.go
+++ b/pkg/query/optimizer.go
@@ -47,6 +47,38 @@ func NewOptimizer(root *Clause, workers uint) Optimizer {
}
}
+// Optimize clause according to level.
+// level 0 is automatic and levels < 0 do nothing.
+func (o Optimizer) Optimize(level int) {
+ o.Simplify()
+ if level < 0 {
+ return
+ } else if level == 0 {
+ // TODO: determine smarter level determination strategy
+ level = o.root.Depth()
+ }
+
+ oldDepth := o.root.Depth()
+ for range level {
+ // clause level parallel
+ o.Compact()
+ o.StrictEquality()
+ o.Tighten()
+ o.Contradictions()
+ // parallel + serial
+ o.Tidy()
+ // purely serial
+ o.Flatten()
+
+ depth := o.root.Depth()
+ if depth == oldDepth {
+ break
+ } else {
+ oldDepth = depth
+ }
+ }
+}
+
// Perform optimizations in parallel. They should **NOT** mutate the tree
func (o Optimizer) parallel(optimize func(*Clause)) {
jobs := make(chan *Clause, o.workers)
@@ -131,6 +163,12 @@ func (o *Optimizer) Flatten() {
})
}
+// Remove multiples of equivalent statements within the same clause
+//
+// Examples
+//
+// (and a="Fred Flinstone" a="Fred Flinstone") --> (and a="Fred Flinstone")
+// (or a=Shaggy -a!=Shaggy) --> (or a=Shaggy)
func (o *Optimizer) Compact() {
o.parallel(func(c *Clause) {
c.Statements = slices.CompactFunc(c.Statements, StatementEq)