(defcache SoftCache [^java.util.Map cache ^java.util.Map rcache rq]
CacheProtocol
(lookup [_ item]
(when-let [^SoftReference r (get cache (or item ::nil))]
(if (= ::nil (.get r))
nil
(.get r))))
(lookup [_ item not-found]
(if-let [^SoftReference r (get cache (or item ::nil))]
(if-let [v (.get r)]
(if (= ::nil v)
nil
v)
not-found)
not-found))
(has? [_ item]
(let [item (or item ::nil)
^SoftReference cell (get cache item)]
(boolean
(when cell
(not (nil? (.get cell)))))))
(hit [this item]
(clear-soft-cache! cache rcache rq)
this)
(miss [this item result]
(let [item (or item ::nil)
r (make-reference result rq)]
(.put cache item r)
(.put rcache r item)
(clear-soft-cache! cache rcache rq)
this))
(evict [this key]
(let [key (or key ::nil)
r (get cache key)]
(when r
(.remove cache key)
(.remove rcache r))
(clear-soft-cache! cache rcache rq)
this))
(seed [_ base]
(let [soft-cache? (instance? SoftCache base)
cache (ConcurrentHashMap.)
rcache (ConcurrentHashMap.)
rq (ReferenceQueue.)]
(if (seq base)
(doseq [[k ^SoftReference v] base]
(let [k (or k ::nil)
r (if soft-cache?
(make-reference (.get v) rq)
(make-reference v rq))]
(.put cache k r)
(.put rcache r k))))
(SoftCache. cache rcache rq)))
Object
(toString [_] (str cache)))