Browse files

Incorporating Rich/Stu's feedback, no longer mutating the cache with …

…core fns.

The InfinispanCache should now respond to the core functions in the
same way a java.util.HashMap would.

The confusion over Fogus requiring a clojure map-like thing came from
me trying to replicate his unit tests, including those for
assoc/dissoc, but that's really more a test of the defcache macro, not
CacheProtocol. So it's not an appropriate test for a mutable cache
that can still act as a memoization backing store.

Also added a delete-all function to Mutable that behaves like
Map#clear but returns the instance instead of void.
  • Loading branch information...
jcrossley3 committed Mar 19, 2012
1 parent d699c15 commit fabe041d995c5b02dbeaafa87bc161b5b79bd883
@@ -50,20 +50,24 @@
(put-if-replace [cache key old new] [cache key old new options]
"Put it in only if key is there and current matches old")
(delete [cache key] [cache key value]
"Delete the entry; value must match current if passed"))
"Delete the entry; value must match current if passed")
(delete-all [cache]
"Clear all entries from the cache and return it"))
(deftype InfinispanCache [cache]
(lookup [this key]
(.valAt this key))
(has? [this key]
(.containsKey this key))
(.containsKey cache (encode key)))
(hit [this key] this)
(miss [this key value]
(assoc this key value))
(put this key value)
(evict [this key]
(.without this key))
(delete this key)
(seed [this base]
(put-all this base)
@@ -86,56 +90,34 @@
(expire (.replace cache (encode k) (encode old) (encode v) opts)))
(delete [_ key] (and key (decode (.remove cache (encode key)))))
(delete [_ key value] (.remove cache (encode key) (encode value)))
(delete-all [this] (.clear cache) this)
(seq [_]
(and (seq cache)
(for [[k v] (seq cache)]
(clojure.lang.MapEntry. (decode k) (decode v)))))
(containsKey [_ key]
(.containsKey cache (encode key)))
(get [_ key]
(decode (.get cache (encode key))))
(valAt [this key]
(decode (.get cache (encode key))))
(.get this key))
(valAt [this key not-found]
(if (.containsKey this key)
(.valAt this key)
(.get this key)
(assoc [this k v]
(.cons this [k v]))
(without [this k]
(and k (.remove cache (encode k)))
(containsKey [this k]
(.containsKey cache (encode k)))
(entryAt [this k]
(when (.containsKey this k)
(clojure.lang.MapEntry. k (.valAt this k))))
(count [_]
(clojure.core/count cache))
(cons [this elem]
(if (map? elem)
(.put-all this elem)
(.put this (first elem) (second elem)))
(empty [this]
(.clear cache)
(equiv [_ other]
(.equals cache other))
(iterator [this] (.iterator cache))
(toString [_] (str cache)))
(toString [this] (str (into {} (seq this)))))
;; Workaround the non-serializable Delay objects cached by
;; core.memoize and force every key to be a vector so that decoded
@@ -41,15 +41,15 @@
2 (.lookup c :b)
;; 42 (.lookup c :c 42)
nil (.lookup c :c))))
(testing "assoc and dissoc"
(let [c (cache "assoc")]
(are [expect actual] (= expect actual)
1 (:a (assoc c :a 1))
1 (:a (assoc c :b 2))
2 (:b (dissoc c :a))
nil (:a (dissoc c :a))
nil (:b (-> c (dissoc :a) (dissoc :b)))
0 (count (-> c (dissoc :a) (dissoc :b))))))
;; (testing "assoc and dissoc"
;; (let [c (cache "assoc")]
;; (are [expect actual] (= expect actual)
;; 1 (:a (assoc c :a 1))
;; 1 (:a (assoc c :b 2))
;; 2 (:b (dissoc c :a))
;; nil (:a (dissoc c :a))
;; nil (:b (-> c (dissoc :a) (dissoc :b)))
;; 0 (count (-> c (dissoc :a) (dissoc :b))))))
(testing "gets and cascading gets"
(let [c (cache "gets" {:a 1, :b 2, :c {:d 3, :e 4}, :f nil, :g false, nil {:h 5}})]
(are [actual expect] (= expect actual)
@@ -159,14 +159,9 @@
(is (= 2 (delete c :b)))
(is (empty? c))))
(deftest test-empty
(deftest test-delete-all
(let [c (cache "clear" {:a 1 :b 2})]
(is (= 2 (count c)))
(is (= 0 (count (empty c))))
(is (= 0 (count (delete-all c))))
(is (= 0 (count c)))))
(deftest test-conj
(is (= 1 (:a (conj (cache "conj") [:a 1])))))
(deftest test-conj
(is (= 1 (:a (merge (cache "merge") {:a 1})))))

0 comments on commit fabe041

Please sign in to comment.