Created
March 30, 2013 05:57
-
-
Save killme2008/5275571 to your computer and use it in GitHub Desktop.
A LRU cache for core.cache that supports evict handler.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (ns cache.lru | |
| (:use [clojure.core.cache :only [CacheProtocol defcache]])) | |
| (defn- build-leastness-queue | |
| [base limit start-at] | |
| (merge | |
| (into {} (take (- limit (count base)) (for [k (range (- limit) 0)] [k k]))) | |
| (into {} (for [[k _] base] [k start-at])))) | |
| (defcache LRUCache [cache lru tick limit evict-handler] | |
| 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 | |
| (assoc lru item tick+) | |
| tick+ | |
| limit | |
| evict-handler))) | |
| (miss [_ item result] | |
| (let [tick+ (inc tick)] | |
| (if-let [ks (keys lru)] | |
| (let [k (if (contains? lru item) | |
| item | |
| (apply min-key lru ks)) ;; maybe evict case | |
| sz (count ks) | |
| c (if (>= sz limit) | |
| (do | |
| (evict-handler k (get cache k)) | |
| (-> cache (dissoc k) (assoc item result))) | |
| (assoc cache item result)) | |
| l (if (>= sz limit) | |
| (-> lru (dissoc k) (assoc item tick+)) | |
| (assoc lru item tick+))] | |
| (LRUCache. c l tick+ limit evict-handler)) | |
| (LRUCache. (assoc cache item result) ;; no change case | |
| (assoc lru item tick+) | |
| tick+ | |
| limit | |
| evict-handler)))) | |
| (evict [this key] | |
| (let [v (get cache key ::miss)] | |
| (if (= v ::miss) | |
| this | |
| (LRUCache. (do | |
| (evict-handler key (get cache key)) | |
| (dissoc cache key)) | |
| (dissoc lru key) | |
| (inc tick) | |
| limit | |
| evict-handler)))) | |
| (seed [_ base] | |
| (LRUCache. base | |
| (build-leastness-queue base limit 0) | |
| 0 | |
| limit | |
| evict-handler)) | |
| Object | |
| (toString [_] | |
| (str cache \, \space lru \, \space tick \, \space limit))) | |
| (defn- default-evict-handler [k v]) | |
| (defn lru-cache-factory | |
| [base & {threshold :threshold | |
| evict-handler :evict-handler | |
| :or {threshold 32 | |
| evict-handler default-evict-handler}}] | |
| {:pre [(number? threshold) (< 0 threshold) | |
| (map? base)]} | |
| (clojure.core.cache/seed (LRUCache. {} {} 0 threshold evict-handler) base)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment