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}))))