File tree 1 file changed +31
-0
lines changed
1 file changed +31
-0
lines changed Original file line number Diff line number Diff line change 17
17
(let [body (wrap-fn #(doall (map f slice)))]
18
18
(future-call body)))
19
19
(slice *pcollect-thread-num* coll))))))
20
+
21
+
22
+ (defn- assoc-noclobber
23
+ " An assoc wrapper which ensures that existing keys will not be
24
+ clobbered by subsequent assoc invocations.
25
+
26
+ Used as a helper for locking-memoize to ensure that (delay) refs
27
+ cannot be lost by swap! retry behavior."
28
+
29
+ [m k v]
30
+ (if (contains? m k) m
31
+ (assoc m k v)))
32
+
33
+ (defn pmemoize
34
+ " Memoizes the function f, using the same approach as
35
+ clojure.core/memoize. The practical difference is that this function
36
+ provides the gurantee that in spite of parallel invocations of the
37
+ memoized function each input to f will only ever be memoized
38
+ once. This resolves an implementation detail in clojure.core/memoize
39
+ which allows f to be applied to args without locking the cache to
40
+ prevent other threads duplicating the work."
41
+
42
+ [f]
43
+ (let [mem (atom {})]
44
+ (fn [ & args ]
45
+ (if-let [e (find @mem args)]
46
+ (deref (val e))
47
+ (-> (swap! mem assoc-noclobber
48
+ args (delay (apply f args)))
49
+ (get args)
50
+ (deref ))))))
You can’t perform that action at this time.
0 commit comments