implement traverse
This commit is contained in:
parent
3af11575d7
commit
f605167a53
4 changed files with 44 additions and 0 deletions
|
|
@ -52,6 +52,15 @@
|
||||||
(println "\n********************************\n")
|
(println "\n********************************\n")
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
(let [data (range 1000)]
|
||||||
|
(run-benchmark "Traverse into a set" 5000
|
||||||
|
(set data)
|
||||||
|
(set (select ALL data))
|
||||||
|
(persistent!
|
||||||
|
(reduce conj! (transient #{}) (traverse ALL data)))
|
||||||
|
(reduce conj #{} (traverse ALL data))
|
||||||
|
))
|
||||||
|
|
||||||
(let [data {:a {:b {:c 1}}}
|
(let [data {:a {:b {:c 1}}}
|
||||||
p (comp-paths :a :b :c)]
|
p (comp-paths :a :b :c)]
|
||||||
(run-benchmark "get value in nested map" 5000000
|
(run-benchmark "get value in nested map" 5000000
|
||||||
|
|
@ -243,3 +252,4 @@
|
||||||
2000000
|
2000000
|
||||||
(vary-meta data assoc :y 2)
|
(vary-meta data assoc :y 2)
|
||||||
(setval [META :y] 2 data)))
|
(setval [META :y] 2 data)))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,17 @@
|
||||||
[path structure]
|
[path structure]
|
||||||
(compiled-selected-any? (i/comp-paths* path) structure))
|
(compiled-selected-any? (i/comp-paths* path) structure))
|
||||||
|
|
||||||
|
;; Reducible traverse functions
|
||||||
|
|
||||||
|
(def ^{:doc "Version of traverse that takes in a path pre-compiled with comp-paths"}
|
||||||
|
compiled-traverse i/do-compiled-traverse)
|
||||||
|
|
||||||
|
(defn traverse*
|
||||||
|
"Return a reducible object that traverses over `structure` to every element
|
||||||
|
specified by the path"
|
||||||
|
[apath structure]
|
||||||
|
(compiled-traverse (i/comp-paths* apath) structure))
|
||||||
|
|
||||||
;; Transformation functions
|
;; Transformation functions
|
||||||
|
|
||||||
(def ^{:doc "Version of transform that takes in a path pre-compiled with comp-paths"}
|
(def ^{:doc "Version of transform that takes in a path pre-compiled with comp-paths"}
|
||||||
|
|
|
||||||
|
|
@ -653,6 +653,20 @@
|
||||||
structure)
|
structure)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
(defn do-compiled-traverse [apath structure]
|
||||||
|
(reify clojure.lang.IReduceInit
|
||||||
|
(reduce [this afn start]
|
||||||
|
(let [cell (mutable-cell start)]
|
||||||
|
(compiled-traverse*
|
||||||
|
apath
|
||||||
|
(fn [elem]
|
||||||
|
(let [curr (get-cell cell)]
|
||||||
|
(set-cell! cell (afn curr elem))
|
||||||
|
))
|
||||||
|
structure
|
||||||
|
)
|
||||||
|
(get-cell cell)
|
||||||
|
))))
|
||||||
|
|
||||||
(defn compiled-select* [path structure]
|
(defn compiled-select* [path structure]
|
||||||
(let [res (mutable-cell (transient []))
|
(let [res (mutable-cell (transient []))
|
||||||
|
|
|
||||||
|
|
@ -599,6 +599,15 @@
|
||||||
[apath aval structure]
|
[apath aval structure]
|
||||||
`(i/compiled-setval* (path ~apath) ~aval ~structure))
|
`(i/compiled-setval* (path ~apath) ~aval ~structure))
|
||||||
|
|
||||||
|
(defmacro traverse
|
||||||
|
"Return a reducible object that traverses over `structure` to every element
|
||||||
|
specified by the path.
|
||||||
|
This macro will attempt to do inline factoring and caching of the path, falling
|
||||||
|
back to compiling the path on every invocation it it's not possible to
|
||||||
|
factor/cache the path."
|
||||||
|
[apath structure]
|
||||||
|
`(i/do-compiled-traverse (path ~apath) ~structure))
|
||||||
|
|
||||||
(defmacro replace-in
|
(defmacro replace-in
|
||||||
"Similar to transform, except returns a pair of [transformed-structure sequence-of-user-ret].
|
"Similar to transform, except returns a pair of [transformed-structure sequence-of-user-ret].
|
||||||
The transform-fn in this case is expected to return [ret user-ret]. ret is
|
The transform-fn in this case is expected to return [ret user-ret]. ret is
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue