optimize sequence of structurepaths to not add additional overhead by coercing to structurevalspath

This commit is contained in:
Nathan Marz 2015-05-11 11:44:42 -04:00
parent 0767afca61
commit 060e61218a

View file

@ -88,11 +88,11 @@
selector (:select* pimpl) selector (:select* pimpl)
updater (:update* pimpl)] updater (:update* pimpl)]
(->TransformFunctions (->TransformFunctions
StructureValsPathExecutor StructurePathExecutor
(fn [vals structure next-fn] (fn [structure next-fn]
(selector this structure (fn [structure] (next-fn vals structure)))) (selector this structure next-fn))
(fn [vals structure next-fn] (fn [structure next-fn]
(updater this structure (fn [structure] (next-fn vals structure)))) (updater this structure next-fn))
))) )))
(defn obj-extends? [prot obj] (defn obj-extends? [prot obj]
@ -117,39 +117,70 @@
))) )))
(defn extype [^TransformFunctions f]
(let [^ExecutorFunctions exs (.executors f)]
(.type exs)
))
(defn- combine-same-types [[^TransformFunctions f & _ :as all]]
(let [^ExecutorFunctions exs (.executors f)
t (.type exs)
combiner
(if (= t :svalspath)
(fn [curr next]
(fn [vals structure next-fn]
(curr vals structure
(fn [vals-next structure-next]
(next vals-next structure-next next-fn)
))))
(fn [curr next]
(fn [structure next-fn]
(curr structure (fn [structure] (next structure next-fn)))))
)]
(reduce (fn [^TransformFunctions curr ^TransformFunctions next]
(->TransformFunctions
exs
(combiner (.selector curr) (.selector next))
(combiner (.updater curr) (.updater next))
))
all)))
(defn coerce-structure-vals [^TransformFunctions tfns]
(condp = (extype tfns)
:svalspath
tfns
:spath
(let [selector (.selector tfns)
updater (.updater tfns)]
(->TransformFunctions
StructureValsPathExecutor
(fn [vals structure next-fn]
(selector structure (fn [structure] (next-fn vals structure))))
(fn [vals structure next-fn]
(updater structure (fn [structure] (next-fn vals structure))))
))))
(extend-protocol StructureValsPathComposer (extend-protocol StructureValsPathComposer
Object Object
(comp-paths* [sp] (comp-paths* [sp]
(coerce-path sp)) (coerce-path sp))
java.util.List java.util.List
(comp-paths* [structure-paths] (comp-paths* [structure-paths]
;;TODO: need to get smart here (let [combined (->> structure-paths
;; - select/update become stupid and just run execute-select / execute-update (map coerce-path)
;; - coerce-path doesn't go all the way to structurevalspath interface but actually keeps things as is (partition-by extype)
;; (except for collector) (map combine-same-types)
;; - compose together consecutive structurepaths and consecutive structurevalspath )]
;; - if only one structurepath remaining, return that (if (= 1 (count combined))
;; - otherwise coerce structurepath to structurevalspath and finish combining (first combined)
(reduce (fn [^TransformFunctions sp-curr ^TransformFunctions sp] (->> combined
(let [curr-selector (.selector sp-curr) (map coerce-structure-vals)
selector (.selector sp) combine-same-types)
curr-updater (.updater sp-curr) ))))
updater (.updater sp)]
(->TransformFunctions
StructureValsPathExecutor
(fn [vals structure next-fn]
(curr-selector vals structure
(fn [vals-next structure-next]
(selector vals-next structure-next next-fn)
)))
(fn [vals structure next-fn]
(curr-updater vals structure
(fn [vals-next structure-next]
(updater vals-next structure-next next-fn)
)))
)))
(map coerce-path structure-paths))
))
;; cell implementation idea taken from prismatic schema library ;; cell implementation idea taken from prismatic schema library
(definterface PMutableCell (definterface PMutableCell