Skip to content

Commit 7cf6607

Browse files
committed
imports-and-refers-analysis: remove tracking and caching
Tracking was excessively obstrusive (it monkey-patched clojure.repl) and coupled (to nrepl middleware). Now `symbols->ns-syms` doesn't use caching at all, as it ran in less than 1ms anyway. Similarly `all-ns-imports` has been removed of any caching. This function was a little more expensive (100ms for a medium-sized project), but parallelizing it brings that cost down to 20ms which seems more than acceptable for an end user. These changes are backed by `refactor-nrepl.ns.imports-and-refers-analysis-test`.
1 parent 8a3e5db commit 7cf6607

File tree

1 file changed

+12
-46
lines changed

1 file changed

+12
-46
lines changed

src/refactor_nrepl/ns/imports_and_refers_analysis.clj

Lines changed: 12 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,23 @@
44
(ns refactor-nrepl.ns.imports-and-refers-analysis
55
"Formerly known as `refactor-nrepl.ns.slam.hound.regrow`."
66
(:require
7-
[nrepl.middleware.interruptible-eval :refer [*msg*]]
87
[refactor-nrepl.ns.class-search :as class-search]))
98

10-
(def ^:dynamic *cache* (atom {}))
11-
(def ^:dynamic *dirty-ns* (atom #{}))
12-
13-
(defn wrap-clojure-repl [f]
14-
(fn [& args]
15-
(when-let [ns (some-> *msg* :ns symbol find-ns)]
16-
(swap! *dirty-ns* conj ns))
17-
(apply f args)))
18-
19-
;; XXX remove this if possible, we shouldn't be this sort of stuff.
20-
(alter-var-root #'clojure.main/repl wrap-clojure-repl)
21-
22-
(defn cache-with-dirty-tracking
23-
"The function to be cached, f, should have two signatures. A zero-operand
24-
signature which computes the result for all namespaces, and a two-operand
25-
version which takes the previously computed result and a list of dirty
26-
namespaces, and returns an updated result."
27-
[k f]
28-
(if *cache*
29-
(if-let [cached (get @*cache* k)]
30-
(if-let [dirty (seq @*dirty-ns*)]
31-
(k (swap! *cache* assoc k (f cached dirty)))
32-
cached)
33-
(k (swap! *cache* assoc k (f))))
34-
(f)))
35-
36-
(defn clear-cache! []
37-
(when *cache*
38-
(reset! *cache* {})
39-
(reset! *dirty-ns* #{})))
40-
41-
(defn- all-ns-imports*
9+
;; Benefits from `pmap` because ns-imports is somewhat expensive.
10+
(defn- all-ns-imports
4211
([]
43-
(all-ns-imports* {} (all-ns)))
12+
(all-ns-imports {} (all-ns)))
4413
([init namespaces]
45-
(reduce (fn [imports ns]
46-
(assoc imports ns (ns-imports ns)))
47-
init namespaces)))
48-
49-
(defn- all-ns-imports []
50-
(cache-with-dirty-tracking :all-ns-imports all-ns-imports*))
51-
52-
(defn- symbols->ns-syms*
14+
(->> namespaces
15+
(pmap (fn [ns]
16+
[ns, (ns-imports ns)]))
17+
(into init))))
18+
19+
;; Doesn't need parallelization (unlike `all-ns-imports`),
20+
;; as this defn is instantaneous.
21+
(defn- symbols->ns-syms
5322
([]
54-
(symbols->ns-syms* {} (all-ns)))
23+
(symbols->ns-syms {} (all-ns)))
5524
([init namespaces]
5625
(reduce
5726
(fn [m ns] (let [ns-sym (ns-name ns)]
@@ -61,9 +30,6 @@
6130
m (keys (ns-publics ns)))))
6231
init namespaces)))
6332

64-
(defn- symbols->ns-syms []
65-
(cache-with-dirty-tracking :symbols->ns-syms symbols->ns-syms*))
66-
6733
(defn- ns-import-candidates
6834
"Search (all-ns) for imports that match missing-sym, returning a set of
6935
class symbols. This is slower than scanning through the list of static

0 commit comments

Comments
 (0)