001 (ns clj-activitypub.internal.thread-cache)
002
003 (defn- current-time
004 "Returns current time using UNIX epoch."
005 []
006 (System/currentTimeMillis))
007
008 (defn- update-read-at [store k v]
009 (dosync
010 (commute store assoc k
011 (merge v {:read-at (current-time)}))))
012
013 (defn make
014 "Creates a thread-local cache."
015 ([] (make false))
016 ([cache-if-nil]
017 (let [store (ref {})]
018 (letfn [(cache-kv ([k v]
019 (dosync
020 (commute store assoc k
021 {:write-at (current-time)
022 :read-at (current-time)
023 :value v})
024 v)))
025 (get-v ([k]
026 (when-let [data (get @store k)]
027 (update-read-at store k data)
028 (:value data)))
029 ([k compute-fn]
030 (let [storage @store]
031 (if (contains? storage k)
032 (get-v k)
033 (let [v (compute-fn)]
034 (when (or (not (nil? v)) cache-if-nil)
035 (cache-kv k v)
036 (get-v k)))))))
037 (lru ([]
038 (mapv
039 (fn [[k v]] [k (:value v)])
040 (sort-by #(-> % val :read-at) < @store))))]
041 {:cache-kv cache-kv
042 :get-v get-v
043 :cache-if-nil cache-if-nil
044 :lru lru}))))