add specialized MAP-VALS navigator to circumvent the unavoidable overhead of [ALL LAST]
This commit is contained in:
parent
9a9f425b7f
commit
ae98aa48ba
4 changed files with 59 additions and 4 deletions
|
|
@ -106,6 +106,7 @@
|
|||
(reduce-kv (fn [m k v] (assoc m k (inc v))) {} data)
|
||||
(manual-similar-reduce-kv data)
|
||||
(transform [ALL LAST] inc data)
|
||||
(transform MAP-VALS inc data)
|
||||
))
|
||||
|
||||
(let [data (->> (for [i (range 1000)] [i i]) (into {}))]
|
||||
|
|
@ -114,6 +115,7 @@
|
|||
(reduce-kv (fn [m k v] (assoc m k (inc v))) {} data)
|
||||
(manual-similar-reduce-kv data)
|
||||
(transform [ALL LAST] inc data)
|
||||
(transform MAP-VALS inc data)
|
||||
))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -163,6 +163,14 @@
|
|||
ALL
|
||||
(comp-paths (i/->AllNavigator)))
|
||||
|
||||
(defnav MAP-VALS []
|
||||
(select* [this structure next-fn]
|
||||
(doall (mapcat next-fn (vals structure))))
|
||||
(transform* [this structure next-fn]
|
||||
(i/map-vals-transform structure next-fn)
|
||||
))
|
||||
|
||||
|
||||
(def VAL (i/->ValCollect))
|
||||
|
||||
(def
|
||||
|
|
|
|||
|
|
@ -702,6 +702,49 @@
|
|||
(transform* [this structure next-fn]
|
||||
(all-transform structure next-fn)))
|
||||
|
||||
(defprotocol MapValsTransformProtocol
|
||||
(map-vals-transform [structure next-fn]))
|
||||
|
||||
(defn map-vals-non-transient-transform [structure empty-map next-fn]
|
||||
(reduce-kv
|
||||
(fn [m k v]
|
||||
(assoc m k (next-fn v)))
|
||||
empty-map
|
||||
structure))
|
||||
|
||||
(extend-protocol MapValsTransformProtocol
|
||||
#+clj clojure.lang.PersistentArrayMap #+cljs cljs.core/PersistentArrayMap
|
||||
(map-vals-transform [structure next-fn]
|
||||
(map-vals-non-transient-transform structure {} next-fn)
|
||||
)
|
||||
|
||||
#+clj clojure.lang.PersistentTreeMap #+cljs cljs.core/PersistentTreeMap
|
||||
(map-vals-transform [structure next-fn]
|
||||
(map-vals-non-transient-transform structure (sorted-map) next-fn)
|
||||
)
|
||||
|
||||
#+clj clojure.lang.PersistentHashMap #+cljs cljs.core/PersistentHashMap
|
||||
(map-vals-transform [structure next-fn]
|
||||
(persistent!
|
||||
(reduce-kv
|
||||
(fn [m k v]
|
||||
(assoc! m k (next-fn v)))
|
||||
(transient
|
||||
#+clj clojure.lang.PersistentHashMap/EMPTY #+cljs cljs.core.PersistentHashMap.EMPTY
|
||||
)
|
||||
structure
|
||||
)))
|
||||
|
||||
#+clj Object #+cljs default
|
||||
(map-vals-transform [structure next-fn]
|
||||
(reduce-kv
|
||||
(fn [m k v]
|
||||
(assoc m k (next-fn v)))
|
||||
(empty structure)
|
||||
structure))
|
||||
)
|
||||
|
||||
|
||||
(deftype ValCollect [])
|
||||
|
||||
(extend-protocol p/Collector
|
||||
|
|
|
|||
|
|
@ -64,8 +64,9 @@
|
|||
|
||||
(defspec select-all-on-map
|
||||
(for-all+
|
||||
[m (limit-size 5 (gen/map gen/keyword gen/int))]
|
||||
(= (select [s/ALL s/LAST] m)
|
||||
[m (limit-size 5 (gen/map gen/keyword gen/int))
|
||||
p (gen/elements [s/MAP-VALS [s/ALL s/LAST]])]
|
||||
(= (select p m)
|
||||
(for [[k v] m] v))
|
||||
))
|
||||
|
||||
|
|
@ -81,8 +82,9 @@
|
|||
|
||||
(defspec transform-all-on-map
|
||||
(for-all+
|
||||
[m (limit-size 5 (gen/map gen/keyword gen/int))]
|
||||
(= (transform [s/ALL s/LAST] inc m)
|
||||
[m (limit-size 5 (gen/map gen/keyword gen/int))
|
||||
p (gen/elements [s/MAP-VALS [s/ALL s/LAST]])]
|
||||
(= (transform p inc m)
|
||||
(into {} (for [[k v] m] [k (inc v)]))
|
||||
)))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue