diff --git a/pom.xml b/pom.xml index fb3a316..5de4da6 100644 --- a/pom.xml +++ b/pom.xml @@ -29,14 +29,13 @@ - - - - - - - - + + + org.clojure + data.priority-map + 0.0.2-SNAPSHOT + + jira diff --git a/project.clj b/project.clj index 2b83ae8..7bed538 100644 --- a/project.clj +++ b/project.clj @@ -1,6 +1,7 @@ (defproject core.cache "0.6.3-SNAPSHOT" :description "Cache library for Clojure." - :dependencies [[org.clojure/clojure "1.5.0-master-SNAPSHOT"]] + :dependencies [[org.clojure/clojure "1.5.0-master-SNAPSHOT"] + [org.clojure/data.priority-map "0.0.2-SNAPSHOT"]] :dev-dependencies [[jline "0.9.94"] [lein-marginalia "0.7.1"] [lein-multi "1.1.0"]] diff --git a/src/main/clojure/clojure/core/cache.clj b/src/main/clojure/clojure/core/cache.clj index 619e135..29710a7 100644 --- a/src/main/clojure/clojure/core/cache.clj +++ b/src/main/clojure/clojure/core/cache.clj @@ -9,6 +9,7 @@ (ns ^{:doc "A caching library for Clojure." :author "Fogus"} clojure.core.cache + (:require [clojure.data.priority-map :refer (priority-map)]) (:import (java.lang.ref ReferenceQueue SoftReference) (java.util.concurrent ConcurrentHashMap))) @@ -181,9 +182,9 @@ (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])))) + (into (priority-map) + (concat (take (- limit (count base)) (for [k (range (- limit) 0)] [k k])) + (for [[k _] base] [k start-at])))) (defcache LRUCache [cache lru tick limit] @@ -202,17 +203,12 @@ limit))) (miss [_ item result] (let [tick+ (inc tick)] - (if-let [ks (keys lru)] + (if (>= (count lru) limit) (let [k (if (contains? lru item) item - (apply min-key lru ks)) ;; maybe evict case - sz (count ks) - c (if (>= sz limit) - (-> cache (dissoc k) (assoc item result)) - (assoc cache item result)) - l (if (>= sz limit) - (-> lru (dissoc k) (assoc item tick+)) - (assoc lru item tick+))] + (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+) @@ -288,17 +284,12 @@ (hit [_ item] (LUCache. cache (update-in lu [item] inc) limit)) (miss [_ item result] - (if-let [ks (keys lu)] - (let [k (if (contains? lu item) - ::nope - (apply min-key lu ks)) ;; maybe evict case - sz (count ks) - c (if (>= sz limit) - (-> cache (dissoc k) (assoc item result)) - (assoc cache item result)) - l (if (>= sz limit) - (-> lu (dissoc k) (update-in [item] (fnil inc 0))) - (assoc lu item 0))] + (if (>= (count lu) limit) ;; need to evict? + (let [min-key (if (contains? lu item) + ::nope + (first (peek lu))) ;; maybe evict case + c (-> cache (dissoc min-key) (assoc item result)) + l (-> lu (dissoc min-key) (update-in [item] (fnil inc 0)))] (LUCache. c l limit)) (LUCache. (assoc cache item result) ;; no change case (assoc lu item 0) @@ -581,7 +572,7 @@ [base & {threshold :threshold :or {threshold 32}}] {:pre [(number? threshold) (< 0 threshold) (map? base)]} - (clojure.core.cache/seed (LRUCache. {} {} 0 threshold) base)) + (clojure.core.cache/seed (LRUCache. {} (priority-map) 0 threshold) base)) (defn ttl-cache-factory "Returns a TTL cache with the cache and expiration-table initialied to `base` -- @@ -602,7 +593,7 @@ [base & {threshold :threshold :or {threshold 32}}] {:pre [(number? threshold) (< 0 threshold) (map? base)]} - (clojure.core.cache/seed (LUCache. {} {} threshold) base)) + (clojure.core.cache/seed (LUCache. {} (priority-map) threshold) base)) (defn lirs-cache-factory "Returns an LIRS cache with the S & R LRU lists set to the indicated