(ns metabase.util.memoize.impl.bounded
(:require
#?(:clj [clojure.core.cache :as cache]
:cljs [cljs.cache :as cache])
[metabase.util.log :as log])) | |
(cache/defcache BoundedCache [cache threshold]
cache/CacheProtocol
(lookup [_ item] (get cache item))
(lookup [_ item not-found] (get cache item not-found))
(has? [_ item] (contains? cache item))
(hit [this _item] this)
(miss [_ item result]
(if (< (count cache) threshold)
(BoundedCache. (assoc cache item result) threshold)
;; It's too big! Throw away the original cache and start over!
(do
(log/warnf "BoundedCache threshold (%d) exceeded - runaway cache? threshold too small?" threshold)
(BoundedCache. {item result} threshold))))
(evict [_ item] (BoundedCache. (dissoc cache item) threshold))
(seed [_ base]
(assert (< (count base) threshold) "cache seed is larger than the threshold")
(BoundedCache. base threshold))) | |
Create a bounded [[clojure.core.cache]]-compatible cache. This is a basic map with no bookkeeping on Intended to be used with [[metabase.util.memoize/bounded]], rather than called directly. | (defn bounded-cache-factory
[base threshold]
{:pre [(map? base)]}
(BoundedCache. base threshold)) |