001  (ns clj-activitypub.internal.thread-cache
002    "copied from [Jahfer's clj-activitypub library](https://github.com/jahfer/clj-activitypub). 
003     If and when Jahfer issues a release of that library, this directory will be deleted and a 
004     dependency on that library will be added to the project.")
005  
006  (defn- current-time
007    "Returns current time using UNIX epoch."
008    []
009    (System/currentTimeMillis))
010  
011  (defn- update-read-at [store k v]
012    (dosync
013     (commute store assoc k
014              (merge v {:read-at (current-time)}))))
015  
016  (defn make
017    "Creates a thread-local cache."
018    ([] (make false))
019    ([cache-if-nil]
020     (let [store (ref {})]
021       (letfn [(cache-kv ([k v]
022                          (dosync
023                           (commute store assoc k
024                                    {:write-at (current-time)
025                                     :read-at (current-time)
026                                     :value v})
027                           v)))
028               (get-v ([k]
029                       (when-let [data (get @store k)]
030                         (update-read-at store k data)
031                         (:value data)))
032                 ([k compute-fn]
033                  (let [storage @store]
034                    (if (contains? storage k)
035                      (get-v k)
036                      (let [v (compute-fn)]
037                        (when (or (not (nil? v)) cache-if-nil)
038                          (cache-kv k v)
039                          (get-v k)))))))
040               (lru ([]
041                     (mapv
042                      (fn [[k v]] [k (:value v)])
043                      (sort-by #(-> % val :read-at) < @store))))]
044         {:cache-kv cache-kv
045          :get-v get-v
046          :cache-if-nil cache-if-nil
047          :lru lru}))))