File tree Expand file tree Collapse file tree 1 file changed +31
-0
lines changed
Expand file tree Collapse file tree 1 file changed +31
-0
lines changed Original file line number Diff line number Diff line change 1717 (let [body (wrap-fn #(doall (map f slice)))]
1818 (future-call body)))
1919 (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