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
|
||||
"Version of select that takes in a selector pre-compiled with comp-paths"
|
||||
[^com.rpl.specter.impl.StructureValsPathFunctions selfns structure]
|
||||
((.selector selfns) [] structure
|
||||
(fn [vals structure]
|
||||
(if-not (empty? vals) [(conj vals structure)] [structure]))))
|
||||
[^com.rpl.specter.impl.TransformFunctions tfns structure]
|
||||
(let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)]
|
||||
((.select-executor ex) (.selector tfns) structure)
|
||||
))
|
||||
|
||||
(defn select
|
||||
"Navigates to and returns a sequence of all the elements specified by the selector."
|
||||
|
|
@ -65,13 +65,10 @@
|
|||
|
||||
(defn compiled-update
|
||||
"Version of update that takes in a selector pre-compiled with comp-paths"
|
||||
[^com.rpl.specter.impl.StructureValsPathFunctions selfns update-fn structure]
|
||||
((.updater selfns) [] structure
|
||||
(fn [vals structure]
|
||||
(if (empty? vals)
|
||||
(update-fn structure)
|
||||
(apply update-fn (conj vals structure)))
|
||||
)))
|
||||
[^com.rpl.specter.impl.TransformFunctions tfns update-fn structure]
|
||||
(let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)]
|
||||
((.update-executor ex) (.updater tfns) update-fn structure)
|
||||
))
|
||||
|
||||
(defn update
|
||||
"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
|
||||
StructurePath
|
||||
(select* [kw structure next-fn]
|
||||
(key-select kw structure next-fn))
|
||||
(update* [kw structure next-fn]
|
||||
(key-update kw structure next-fn)
|
||||
;; faster to invoke keyword directly on structure rather than reuse key-select and key-update functions
|
||||
(select* [^clojure.lang.Keyword kw structure next-fn]
|
||||
(next-fn (kw structure)))
|
||||
(update* [^clojure.lang.Keyword kw structure next-fn]
|
||||
(assoc structure kw (next-fn (kw structure)))
|
||||
))
|
||||
|
||||
(extend-type clojure.lang.AFn
|
||||
|
|
|
|||
|
|
@ -15,9 +15,36 @@
|
|||
(dotimes [_ iters]
|
||||
(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]))
|
||||
|
||||
(defn no-prot-error-str [obj]
|
||||
|
|
@ -38,7 +65,8 @@
|
|||
(let [pimpl (find-protocol-impl! StructureValsPath this)
|
||||
selector (:select-full* pimpl)
|
||||
updater (:update-full* pimpl)]
|
||||
(->StructureValsPathFunctions
|
||||
(->TransformFunctions
|
||||
StructureValsPathExecutor
|
||||
(fn [vals structure next-fn]
|
||||
(selector this vals structure next-fn))
|
||||
(fn [vals structure next-fn]
|
||||
|
|
@ -53,13 +81,14 @@
|
|||
afn (fn [vals structure next-fn]
|
||||
(next-fn (conj vals (cfn this structure)) structure)
|
||||
)]
|
||||
(->StructureValsPathFunctions afn afn)))
|
||||
(->TransformFunctions StructureValsPathExecutor afn afn)))
|
||||
|
||||
(defn coerce-structure-path [this]
|
||||
(let [pimpl (find-protocol-impl! StructurePath this)
|
||||
selector (:select* pimpl)
|
||||
updater (:update* pimpl)]
|
||||
(->StructureValsPathFunctions
|
||||
(->TransformFunctions
|
||||
StructureValsPathExecutor
|
||||
(fn [vals structure next-fn]
|
||||
(selector this structure (fn [structure] (next-fn vals structure))))
|
||||
(fn [vals structure next-fn]
|
||||
|
|
@ -69,9 +98,9 @@
|
|||
(defn obj-extends? [prot obj]
|
||||
(->> obj (find-protocol-impl prot) nil? not))
|
||||
|
||||
(extend-protocol CoerceStructureValsPathFunctions
|
||||
(extend-protocol CoerceTransformFunctions
|
||||
|
||||
StructureValsPathFunctions
|
||||
TransformFunctions
|
||||
(coerce-path [this]
|
||||
this)
|
||||
|
||||
|
|
@ -94,12 +123,20 @@
|
|||
(coerce-path sp))
|
||||
java.util.List
|
||||
(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)
|
||||
selector (.selector sp)
|
||||
curr-updater (.updater sp-curr)
|
||||
updater (.updater sp)]
|
||||
(->StructureValsPathFunctions
|
||||
(->TransformFunctions
|
||||
StructureValsPathExecutor
|
||||
(fn [vals structure next-fn]
|
||||
(curr-selector vals structure
|
||||
(fn [vals-next structure-next]
|
||||
|
|
@ -295,7 +332,6 @@
|
|||
ancestry))))
|
||||
|
||||
(deftype KeyPath [akey])
|
||||
|
||||
|
||||
(extend-protocol StructurePath
|
||||
KeyPath
|
||||
|
|
|
|||
Loading…
Reference in a new issue