implement traverse

This commit is contained in:
Nathan Marz 2016-06-09 16:36:20 -04:00
parent 3af11575d7
commit f605167a53
4 changed files with 44 additions and 0 deletions

View file

@ -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)))

View file

@ -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"}

View file

@ -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 []))

View file

@ -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