use local def for cljs inline cache. faster and enables bootstrap compatibility

This commit is contained in:
Nathan Marz 2016-05-28 20:01:10 -04:00
parent bb5fcbe7b3
commit e5db7252c3
2 changed files with 36 additions and 27 deletions

View file

@ -41,6 +41,8 @@
(defn do-macroexpand-all [form]
(riddley/macroexpand-all form))
;;this is not a secure way to generate uuids  the `path` implementation
;;for cljs uses an alternative strategy
#+cljs
(defn gen-uuid-str []
(apply str (repeatedly 50 #(rand-int 9)))
@ -723,12 +725,8 @@
params-maker ; can be null
])
(defonce PATH-CACHE
#+clj (java.util.concurrent.ConcurrentHashMap.)
;;TODO: according to @dnolen, can forgo this for instead doing
;;inline defs at runtime
#+cljs (atom {})
)
#+clj
(defonce PATH-CACHE (java.util.concurrent.ConcurrentHashMap.))
(def MUST-CACHE-PATHS (mutable-cell false))
@ -744,14 +742,6 @@
(defn get-path-cache [^String k]
(.get ^java.util.concurrent.ConcurrentHashMap PATH-CACHE k))
#+cljs
(defn add-path-cache! [k v]
(swap! PATH-CACHE (fn [m] (assoc m k v))))
#+cljs
(defn get-path-cache [k]
(get @PATH-CACHE k))
(defn- extract-original-code [p]
(cond
(instance? LocalSym p) (:sym p)

View file

@ -414,7 +414,12 @@
)))
;; still possible to mess this up with alter-var-root
(defmacro path [& path] ; "inline cache"
(defmacro path
"Same as calling comp-paths, except it caches the composition of the static part
of the path for later re-use (when possible). For almost all idiomatic uses
of Specter provides huge speedup. This macro is automatically used by the
select/transform/setval/replace-in/etc. macros."
[& path]
(let [;;this is a hack, but the composition of &env is considered stable for cljs
platform (if (contains? &env :locals) :cljs :clj)
local-syms (if (= platform :cljs)
@ -439,7 +444,18 @@
;; - with invokedynamic here, could go directly to the code
;; to invoke and/or parameterize the precompiled path without
;; a bunch of checks beforehand
cache-id (i/gen-uuid-str)
cache-id (i/gen-uuid-str) ;; used for clj
cache-sym (gensym "pathcache") ;; used for cljs
info-sym (gensym "info")
get-cache-code (if (= platform :clj)
`(i/get-path-cache ~cache-id)
cache-sym
)
add-cache-code (if (= platform :clj)
`(i/add-path-cache! ~cache-id ~info-sym)
`(def ~cache-sym ~info-sym))
precompiled-sym (gensym "precompiled")
params-maker-sym (gensym "params-maker")
@ -453,11 +469,14 @@
~(mapv (fn [p] `(fn [] ~p)) possible-params)
))
]
`(let [info# (i/get-path-cache ~cache-id)
`(let [;;TODO: for cljs, use the dynamic def strategy + exists for a direct
;; inline cache
info# ~get-cache-code
^com.rpl.specter.impl.CachedPathInfo info#
(if (nil? info#)
(let [info# (i/magic-precompilation
(let [~info-sym (i/magic-precompilation
~prepared-path
~(str *ns*)
(quote ~used-locals)
@ -465,8 +484,8 @@
;;as is used-locals in cljs...
(quote ~possible-params)
)]
(i/add-path-cache! ~cache-id info#)
info#
~add-cache-code
~info-sym
)
info#
)