Skip to content

Commit d0699bf

Browse files
author
Paula Gearon
committed
Added outer product support to the optimizer.
1 parent 6caac84 commit d0699bf

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

src/naga/storage/memory/core.clj

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
(s/defn paths :- [[EPVPattern]]
2828
"Returns a seq of all paths through the constraints. A path is defined
2929
by new patterns containing at least one variable common to the patterns
30-
that appeared before it. This prevents cross products in a join."
30+
that appeared before it. Patterns must form a group."
3131
([patterns :- [EPVPattern]]
3232
(let [all-paths (paths #{} patterns)]
3333
(assert (every? (partial = (count patterns)) (map count all-paths))
@@ -75,18 +75,44 @@
7575
(recur (into plan nxt-filters) bound patterns remaining-filters)
7676
(recur (conj plan np) (into bound (get-vars np)) rp filters)))))))
7777

78+
(s/defn first-group :- [(s/one [Pattern] "group") (s/one [Pattern] "remainder")]
79+
"Finds a group from a sequence of patterns. A group is defined by every pattern
80+
sharing at least one var with at least one other pattern. Returns a pair.
81+
The first returned element is the Patterns in the group, the second is what was left over."
82+
[[fp & rp] :- [Pattern]]
83+
(letfn [;; Define a reduction step.
84+
;; Accumulates a triple of: known vars; patterns that are part of the group;
85+
;; patterns that are not in the group. Each step looks at a pattern for
86+
;; inclusion or exclusion
87+
(step [[vs included excluded] next-pattern]
88+
(let [new-vars (get-vars next-pattern)]
89+
(if (seq (set/intersection vs new-vars))
90+
[(into vs new-vars) (conj included next-pattern) excluded]
91+
[vs included (conj excluded next-pattern)])))
92+
;; apply the reduction steps, with a given set of known vars, and
93+
;; included patterns. Previously excluded patterns are being scanned
94+
;; again using the new known vars.
95+
(groups [[v i e]] (reduce step [v i []] e))]
96+
;; scan for everything that matches the first pattern, and then iterate until
97+
;; everything that matches the resulting patterns has also been found.
98+
;; Drop the set of vars before returning.
99+
(rest (u/fixpoint groups [(get-vars fp) [fp] rp]))))
100+
78101
(s/defn min-join-path :- [EPVPattern]
79102
"Calculates a plan based on no outer joins (a cross product), and minimized joins.
80103
A plan is the order in which to evaluate constraints and join them to the accumulated
81104
evaluated data. If it is not possible to create a path without a cross product,
82105
then return a plan of the patterns in the provided order."
83106
[patterns :- [Pattern]
84107
count-map :- {EPVPattern s/Num}]
85-
(or
86-
(->> (paths patterns)
87-
(sort-by (partial mapv count-map))
88-
first)
89-
patterns)) ;; TODO: longest paths with minimized cross products
108+
(loop [[grp rmdr] (first-group patterns) ordered []]
109+
(let [all-ordered (->> (paths grp)
110+
(sort-by (partial mapv count-map))
111+
first
112+
(concat ordered))]
113+
(if (empty? rmdr)
114+
all-ordered
115+
(recur (first-group rmdr) all-ordered)))))
90116

91117
(s/defn user-plan :- [EPVPattern]
92118
"Returns the original path specified by the user"

0 commit comments

Comments
 (0)