(defcache LRUCache [cache lru tick limit]
CacheProtocol
(lookup [_ item]
(get cache item))
(lookup [_ item not-found]
(get cache item not-found))
(has? [_ item]
(contains? cache item))
(hit [_ item]
(let [tick+ (inc tick)]
(LRUCache. cache
(if (contains? cache item)
(assoc lru item tick+)
lru)
tick+
limit)))
(miss [_ item result]
(let [tick+ (inc tick)]
(if (>= (count lru) limit)
(let [k (if (contains? lru item)
item
(first (peek lru))) ;; minimum-key, maybe evict case
c (-> cache (dissoc k) (assoc item result))
l (-> lru (dissoc k) (assoc item tick+))]
(LRUCache. c l tick+ limit))
(LRUCache. (assoc cache item result) ;; no change case
(assoc lru item tick+)
tick+
limit))))
(evict [this key]
(if (contains? cache key)
(LRUCache. (dissoc cache key)
(dissoc lru key)
(inc tick)
limit)
this))
(seed [_ base]
(LRUCache. base
(build-leastness-queue base limit 0)
0
limit))
Object
(toString [_]
(str cache \, \space lru \, \space tick \, \space limit)))