1 | ;; my personal memoization extensions |
2 | (ns com.github.kyleburton.sandbox.memoize |
3 | (:require [com.github.kyleburton.sandbox.utils :as kutils])) |
4 |
|
5 | (defn make-once-only [f] |
6 | "Memoize a function so it is only invoked once, regardless of arguments." |
7 | (let [atm (atom nil)] |
8 | (fn [& args] |
9 | (if (not @atm) |
10 | (do |
11 | (prn "resetting the atom, args=" args) |
12 | (reset! atm {:run true :result (apply f args)}) |
13 | @atm)) |
14 | (:result @atm)))) |
15 |
|
16 | (defmacro def-once-only [name & args] |
17 | `(def ~name (make-once-only (fn ~@args)))) |
18 |
|
19 | (def *store-registry* (atom { })) |
20 |
|
21 | (defn register-store [name fn] |
22 | (reset! *store-registry* (assoc @*store-registry* name fn))) |
23 |
|
24 | (def memoize-map-store |
25 | (let [cache (atom {})] |
26 | (fn [op key & [val]] |
27 | (cond (= :get op) |
28 | (@cache key) |
29 | (= :chk op) |
30 | (contains? @cache key) |
31 | (= :put op) |
32 | (do |
33 | (reset! cache (assoc @cache key val)) |
34 | (@cache key)) |
35 | true |
36 | (throw (RuntimeException. (format "memoize-map-store: error, unknown op: %s" op))))))) |
37 |
|
38 | (register-store :default memoize-map-store) |
39 |
|
40 | ;; (memoize-map-store :get :a) |
41 | ;; (memoize-map-store :chk :a) |
42 | ;; (memoize-map-store :put :a 1) |
43 |
|
44 | ;; |
45 | ;; :store is a function that implements the store/retreive of |
46 | ;; unserialized data - persistence is a concern of the store |
47 | ;; |
48 | ;; :key is a function for generating the store key |
49 | ;; |
50 |
|
51 | ;; TODO: HERE: need to complete this |
52 | ;; (defn memoize-with-store [fn & params] |
53 | ;; (let [args (kutils/pairs->map params) |
54 | ;; keyfn (:key args kutils/freeze) |
55 | ;; store (if (keyword? (:store args)) |
56 | ;; (*store-registry* (:store args) |
57 | ;; (:default *store-registry*)))] |
58 | ;; (fn [& args] |
59 | ;; (let [k (keyfn args)] |
60 | ;; (cond (store :chk k) |
61 | ;; (store :get k) |
62 | ;; true |
63 | ;; (do |
64 | ;; (store :put k (apply fn args)) |
65 | ;; (store :get k))))) |
66 |
|
67 |
|
68 |
|
69 |
|
70 | ;; (doall |
71 | ;; (doseq [provider (seq (java.security.Security/getProviders)) |
72 | ;; service (seq (.getServices provider))] |
73 | ;; (prn (format "provider:%s service:%s" provider service)))) |
74 |
|
75 | ;; (let [provider (first (first (map #(vec (.toArray (.getServices %))) (vec (java.security.Security/getProviders)))))] |
76 | ;; (prn (format "algorithm: %s" (.getAlgorithm provider))) |
77 | ;; (prn (format "type: %s" (.getType provider))) |
78 | ;; (prn (format "provider: %s" (.getName (.getProvider provider)))) |
79 | ;; (prn (format "class-name: %s" (.getClassName provider)))) |
80 |
|
81 | ;; (defn make-memoize-dir-store [path] |
82 | ;; (fn [op key & [val]] |
83 | ;; (.mkdirs (java.io.File. path)) |
84 | ;; (let [fname (java.io.File. (str path "/" key))] |
85 | ;; (cond (= :get op) |
86 | ;; (prn "pull from disk: " fname) |
87 | ;; (= :chk op) |
88 | ;; (prn "exists? on disk: " fname) |
89 | ;; (= :put op) |
90 | ;; (prn "store to disk: " fname) |
91 | ;; true |
92 | ;; (throw (RuntimeException. (format "memoize-map-store: error, unknown op: %s" op))))))) |
93 |
|
94 | ;; (def mmds (make-memoize-dir-store "/home/mortis/tmp/mem.clj")) |
95 | ;; (mmds :put "foo" 1) |