prepare for optimized execution of pure structurepaths
This commit is contained in:
parent
a22df528f0
commit
0767afca61
2 changed files with 59 additions and 25 deletions
|
|
@ -13,10 +13,10 @@
|
||||||
|
|
||||||
(defn compiled-select
|
(defn compiled-select
|
||||||
"Version of select that takes in a selector pre-compiled with comp-paths"
|
"Version of select that takes in a selector pre-compiled with comp-paths"
|
||||||
[^com.rpl.specter.impl.StructureValsPathFunctions selfns structure]
|
[^com.rpl.specter.impl.TransformFunctions tfns structure]
|
||||||
((.selector selfns) [] structure
|
(let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)]
|
||||||
(fn [vals structure]
|
((.select-executor ex) (.selector tfns) structure)
|
||||||
(if-not (empty? vals) [(conj vals structure)] [structure]))))
|
))
|
||||||
|
|
||||||
(defn select
|
(defn select
|
||||||
"Navigates to and returns a sequence of all the elements specified by the selector."
|
"Navigates to and returns a sequence of all the elements specified by the selector."
|
||||||
|
|
@ -65,13 +65,10 @@
|
||||||
|
|
||||||
(defn compiled-update
|
(defn compiled-update
|
||||||
"Version of update that takes in a selector pre-compiled with comp-paths"
|
"Version of update that takes in a selector pre-compiled with comp-paths"
|
||||||
[^com.rpl.specter.impl.StructureValsPathFunctions selfns update-fn structure]
|
[^com.rpl.specter.impl.TransformFunctions tfns update-fn structure]
|
||||||
((.updater selfns) [] structure
|
(let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)]
|
||||||
(fn [vals structure]
|
((.update-executor ex) (.updater tfns) update-fn structure)
|
||||||
(if (empty? vals)
|
))
|
||||||
(update-fn structure)
|
|
||||||
(apply update-fn (conj vals structure)))
|
|
||||||
)))
|
|
||||||
|
|
||||||
(defn update
|
(defn update
|
||||||
"Navigates to each value specified by the selector and replaces it by the result of running
|
"Navigates to each value specified by the selector and replaces it by the result of running
|
||||||
|
|
@ -162,10 +159,11 @@
|
||||||
|
|
||||||
(extend-type clojure.lang.Keyword
|
(extend-type clojure.lang.Keyword
|
||||||
StructurePath
|
StructurePath
|
||||||
(select* [kw structure next-fn]
|
;; faster to invoke keyword directly on structure rather than reuse key-select and key-update functions
|
||||||
(key-select kw structure next-fn))
|
(select* [^clojure.lang.Keyword kw structure next-fn]
|
||||||
(update* [kw structure next-fn]
|
(next-fn (kw structure)))
|
||||||
(key-update kw structure next-fn)
|
(update* [^clojure.lang.Keyword kw structure next-fn]
|
||||||
|
(assoc structure kw (next-fn (kw structure)))
|
||||||
))
|
))
|
||||||
|
|
||||||
(extend-type clojure.lang.AFn
|
(extend-type clojure.lang.AFn
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,36 @@
|
||||||
(dotimes [_ iters]
|
(dotimes [_ iters]
|
||||||
(afn))))
|
(afn))))
|
||||||
|
|
||||||
(deftype StructureValsPathFunctions [selector updater])
|
(deftype ExecutorFunctions [type select-executor update-executor])
|
||||||
|
|
||||||
(defprotocol CoerceStructureValsPathFunctions
|
(def StructureValsPathExecutor
|
||||||
|
(->ExecutorFunctions
|
||||||
|
:svalspath
|
||||||
|
(fn [selector structure]
|
||||||
|
(selector [] structure
|
||||||
|
(fn [vals structure]
|
||||||
|
(if-not (empty? vals) [(conj vals structure)] [structure]))))
|
||||||
|
(fn [updater update-fn structure]
|
||||||
|
(updater [] structure
|
||||||
|
(fn [vals structure]
|
||||||
|
(if (empty? vals)
|
||||||
|
(update-fn structure)
|
||||||
|
(apply update-fn (conj vals structure))))))
|
||||||
|
))
|
||||||
|
|
||||||
|
(def StructurePathExecutor
|
||||||
|
(->ExecutorFunctions
|
||||||
|
:spath
|
||||||
|
(fn [selector structure]
|
||||||
|
(selector structure (fn [structure] [structure])))
|
||||||
|
(fn [updater update-fn structure]
|
||||||
|
(updater structure update-fn))
|
||||||
|
))
|
||||||
|
|
||||||
|
(deftype TransformFunctions [executors selector updater])
|
||||||
|
|
||||||
|
|
||||||
|
(defprotocol CoerceTransformFunctions
|
||||||
(coerce-path [this]))
|
(coerce-path [this]))
|
||||||
|
|
||||||
(defn no-prot-error-str [obj]
|
(defn no-prot-error-str [obj]
|
||||||
|
|
@ -38,7 +65,8 @@
|
||||||
(let [pimpl (find-protocol-impl! StructureValsPath this)
|
(let [pimpl (find-protocol-impl! StructureValsPath this)
|
||||||
selector (:select-full* pimpl)
|
selector (:select-full* pimpl)
|
||||||
updater (:update-full* pimpl)]
|
updater (:update-full* pimpl)]
|
||||||
(->StructureValsPathFunctions
|
(->TransformFunctions
|
||||||
|
StructureValsPathExecutor
|
||||||
(fn [vals structure next-fn]
|
(fn [vals structure next-fn]
|
||||||
(selector this vals structure next-fn))
|
(selector this vals structure next-fn))
|
||||||
(fn [vals structure next-fn]
|
(fn [vals structure next-fn]
|
||||||
|
|
@ -53,13 +81,14 @@
|
||||||
afn (fn [vals structure next-fn]
|
afn (fn [vals structure next-fn]
|
||||||
(next-fn (conj vals (cfn this structure)) structure)
|
(next-fn (conj vals (cfn this structure)) structure)
|
||||||
)]
|
)]
|
||||||
(->StructureValsPathFunctions afn afn)))
|
(->TransformFunctions StructureValsPathExecutor afn afn)))
|
||||||
|
|
||||||
(defn coerce-structure-path [this]
|
(defn coerce-structure-path [this]
|
||||||
(let [pimpl (find-protocol-impl! StructurePath this)
|
(let [pimpl (find-protocol-impl! StructurePath this)
|
||||||
selector (:select* pimpl)
|
selector (:select* pimpl)
|
||||||
updater (:update* pimpl)]
|
updater (:update* pimpl)]
|
||||||
(->StructureValsPathFunctions
|
(->TransformFunctions
|
||||||
|
StructureValsPathExecutor
|
||||||
(fn [vals structure next-fn]
|
(fn [vals structure next-fn]
|
||||||
(selector this structure (fn [structure] (next-fn vals structure))))
|
(selector this structure (fn [structure] (next-fn vals structure))))
|
||||||
(fn [vals structure next-fn]
|
(fn [vals structure next-fn]
|
||||||
|
|
@ -69,9 +98,9 @@
|
||||||
(defn obj-extends? [prot obj]
|
(defn obj-extends? [prot obj]
|
||||||
(->> obj (find-protocol-impl prot) nil? not))
|
(->> obj (find-protocol-impl prot) nil? not))
|
||||||
|
|
||||||
(extend-protocol CoerceStructureValsPathFunctions
|
(extend-protocol CoerceTransformFunctions
|
||||||
|
|
||||||
StructureValsPathFunctions
|
TransformFunctions
|
||||||
(coerce-path [this]
|
(coerce-path [this]
|
||||||
this)
|
this)
|
||||||
|
|
||||||
|
|
@ -94,12 +123,20 @@
|
||||||
(coerce-path sp))
|
(coerce-path sp))
|
||||||
java.util.List
|
java.util.List
|
||||||
(comp-paths* [structure-paths]
|
(comp-paths* [structure-paths]
|
||||||
(reduce (fn [^StructureValsPathFunctions sp-curr ^StructureValsPathFunctions sp]
|
;;TODO: need to get smart here
|
||||||
|
;; - select/update become stupid and just run execute-select / execute-update
|
||||||
|
;; - coerce-path doesn't go all the way to structurevalspath interface but actually keeps things as is
|
||||||
|
;; (except for collector)
|
||||||
|
;; - compose together consecutive structurepaths and consecutive structurevalspath
|
||||||
|
;; - if only one structurepath remaining, return that
|
||||||
|
;; - otherwise coerce structurepath to structurevalspath and finish combining
|
||||||
|
(reduce (fn [^TransformFunctions sp-curr ^TransformFunctions sp]
|
||||||
(let [curr-selector (.selector sp-curr)
|
(let [curr-selector (.selector sp-curr)
|
||||||
selector (.selector sp)
|
selector (.selector sp)
|
||||||
curr-updater (.updater sp-curr)
|
curr-updater (.updater sp-curr)
|
||||||
updater (.updater sp)]
|
updater (.updater sp)]
|
||||||
(->StructureValsPathFunctions
|
(->TransformFunctions
|
||||||
|
StructureValsPathExecutor
|
||||||
(fn [vals structure next-fn]
|
(fn [vals structure next-fn]
|
||||||
(curr-selector vals structure
|
(curr-selector vals structure
|
||||||
(fn [vals-next structure-next]
|
(fn [vals-next structure-next]
|
||||||
|
|
@ -296,7 +333,6 @@
|
||||||
|
|
||||||
(deftype KeyPath [akey])
|
(deftype KeyPath [akey])
|
||||||
|
|
||||||
|
|
||||||
(extend-protocol StructurePath
|
(extend-protocol StructurePath
|
||||||
KeyPath
|
KeyPath
|
||||||
(select* [^KeyPath this structure next-fn]
|
(select* [^KeyPath this structure next-fn]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue