From 0b4a68eed0b2c318ff610c007aa82ba9547ecf62 Mon Sep 17 00:00:00 2001 From: Janos Meszaros Date: Sun, 12 Dec 2021 13:02:20 +0100 Subject: [PATCH 1/6] Add Cache protocol and a default core.cache-based implementation --- deps.edn | 1 + src/porsas/cache.clj | 13 +++++++++++++ test/porsas/cache_test.clj | 13 +++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 src/porsas/cache.clj create mode 100644 test/porsas/cache_test.clj diff --git a/deps.edn b/deps.edn index 053d893..3995132 100644 --- a/deps.edn +++ b/deps.edn @@ -1,5 +1,6 @@ {:paths ["src"] :deps {org.postgresql/postgresql {:mvn/version "42.3.1"} + org.clojure/core.cache {:mvn/version "1.0.225"} io.vertx/vertx-pg-client {:mvn/version "4.2.1"}} :aliases {:test {:extra-paths ["test"] :extra-deps {org.clojure/clojure {:mvn/version "1.10.3"} diff --git a/src/porsas/cache.clj b/src/porsas/cache.clj new file mode 100644 index 0000000..ed9fa3f --- /dev/null +++ b/src/porsas/cache.clj @@ -0,0 +1,13 @@ +(ns porsas.cache + (:require [clojure.core.cache.wrapped :as c])) + +(defprotocol Cache + (lookup-or-set [this k value-fn] "Lookup a value in the cache based on `k` and if not found set its value based on `value-fn` and returns it.") + (elements [this] "Returns the actual state of the cache.")) + + +(defrecord CoreCache [a] + Cache + (lookup-or-set [this k value-fn] + (c/lookup-or-miss (:a this) k value-fn)) + (elements [this] (into {} @(:a this)))) diff --git a/test/porsas/cache_test.clj b/test/porsas/cache_test.clj new file mode 100644 index 0000000..e027806 --- /dev/null +++ b/test/porsas/cache_test.clj @@ -0,0 +1,13 @@ +(ns porsas.cache-test + (:require [clojure.test :as t] + [clojure.core.cache.wrapped :as c] + [porsas.cache :as sut])) + +(t/deftest cache + (let [c (sut/->CoreCache (c/basic-cache-factory {}))] + (t/is (= {} (sut/elements c))) + + (t/is (= ::a (sut/lookup-or-set c :a (constantly ::a)))) + (t/is (= ::a (sut/lookup-or-set c :a (constantly ::b)))) + + (t/is (= {:a ::a} (sut/elements c))))) From ae1f7974c9b6e9b01a46225adbeae97c46369a3a Mon Sep 17 00:00:00 2001 From: Janos Meszaros Date: Sun, 12 Dec 2021 14:53:57 +0100 Subject: [PATCH 2/6] Wire in cache --- src/porsas/async.clj | 33 +++++++++++++------------- src/porsas/cache.clj | 5 ++++ src/porsas/core.clj | 3 --- src/porsas/jdbc.clj | 48 ++++++++++++++++++-------------------- src/porsas/next.clj | 17 ++++++-------- test/porsas/async_test.clj | 7 +++--- 6 files changed, 54 insertions(+), 59 deletions(-) diff --git a/src/porsas/async.clj b/src/porsas/async.clj index 079abad..717ee11 100644 --- a/src/porsas/async.clj +++ b/src/porsas/async.clj @@ -1,11 +1,12 @@ (ns porsas.async - (:require [porsas.core :as p]) + (:require [porsas.cache :as cache] + [porsas.core :as p]) (:import (io.vertx.pgclient PgPool PgConnectOptions) (io.vertx.sqlclient PoolOptions Tuple RowSet) io.vertx.sqlclient.impl.ArrayTuple io.vertx.pgclient.impl.RowImpl (io.vertx.core Vertx Handler AsyncResult VertxOptions) - (java.util Collection HashMap Map) + java.util.Collection (clojure.lang PersistentVector) (java.util.concurrent CompletableFuture Executor CompletionStage) (java.util.function Function))) @@ -100,21 +101,19 @@ | key | description | | --------------|-------------| | `:row` | Optional function of `tuple->value` or a [[RowCompiler]] to convert rows into values - | `:cache` | Optional [[java.util.Map]] instance to hold the compiled rowmappers" + | `:cache` | Optional [[porsas.cache/Cache]] instance to hold the compiled rowmappers" ([] (context {})) - ([{:keys [row cache] :or {cache (HashMap.)}}] - (let [cache (or cache (reify Map (get [_ _]) (put [_ _ _]) (entrySet [_]))) - ->row (fn [sql ^RowSet rs] - (let [cols (col-map rs) - row (cond - (satisfies? p/RowCompiler row) (p/compile-row row (map last cols)) - row row - :else (p/rs->map-of-cols cols))] - (.put ^Map cache sql row) - row))] + ([{:keys [row cache]}] + (let [cache (or cache (cache/create-cache)) + ->row (fn [_sql ^RowSet rs] + (let [cols (col-map rs)] + (cond + (satisfies? p/RowCompiler row) (p/compile-row row (map last cols)) + row row + :else (p/rs->map-of-cols cols))))] (reify - p/Cached - (cache [_] (into {} cache)) + cache/Cached + (cache [_] (cache/elements cache)) Context (-query-one [_ pool sqlvec] (let [sql (-get-sql sqlvec) @@ -130,7 +129,7 @@ it (.iterator rs)] (if-not (.hasNext it) (.complete cf nil) - (let [row (or (.get ^Map cache sql) (->row sql rs))] + (let [row (cache/lookup-or-set cache sql #(->row %1 rs))] (.complete cf (row (.next it)))))) (.completeExceptionally cf (.cause ^AsyncResult res))))))) cf)) @@ -146,7 +145,7 @@ (if (.succeeded ^AsyncResult res) (let [rs ^RowSet (.result ^AsyncResult res) it (.iterator rs) - row (or (.get ^Map cache sql) (->row sql rs))] + row (cache/lookup-or-set cache sql #(->row %1 rs))] (loop [res []] (if (.hasNext it) (recur (conj res (row (.next it)))) diff --git a/src/porsas/cache.clj b/src/porsas/cache.clj index ed9fa3f..e4fab6f 100644 --- a/src/porsas/cache.clj +++ b/src/porsas/cache.clj @@ -5,9 +5,14 @@ (lookup-or-set [this k value-fn] "Lookup a value in the cache based on `k` and if not found set its value based on `value-fn` and returns it.") (elements [this] "Returns the actual state of the cache.")) +(defprotocol Cached + (cache [this])) (defrecord CoreCache [a] Cache (lookup-or-set [this k value-fn] (c/lookup-or-miss (:a this) k value-fn)) (elements [this] (into {} @(:a this)))) + +(defn create-cache [] + (->CoreCache (c/basic-cache-factory {}))) diff --git a/src/porsas/core.clj b/src/porsas/core.clj index a450d33..36940fc 100644 --- a/src/porsas/core.clj +++ b/src/porsas/core.clj @@ -9,9 +9,6 @@ (defprotocol GetValue (get-value [this i])) -(defprotocol Cached - (cache [this])) - ;; ;; Implementation ;; diff --git a/src/porsas/jdbc.clj b/src/porsas/jdbc.clj index 3530536..0dac216 100644 --- a/src/porsas/jdbc.clj +++ b/src/porsas/jdbc.clj @@ -1,8 +1,9 @@ (ns porsas.jdbc - (:require [porsas.core :as p]) + (:require [porsas.cache :as cache] + [porsas.core :as p]) (:import (java.sql Connection PreparedStatement ResultSet ResultSetMetaData) (javax.sql DataSource) - (java.util Iterator Map) + java.util.Iterator (clojure.lang PersistentVector))) ;; @@ -118,42 +119,39 @@ | --------------|-------------| | `:row` | Optional function of `rs->value` or a [[RowCompiler]] to convert rows into values | `:key` | Optional function of `rs-meta i->key` to create key for map-results - | `:cache` | Optional [[java.util.Map]] instance to hold the compiled rowmappers" + | `:cache` | Optional [[porsas.cache/Cache]] instance to hold the compiled rowmappers" ([] (context {})) - ([{:keys [row key cache] :or {key (unqualified-key) - cache (java.util.HashMap.)}}] - (let [cache (or cache (reify Map (get [_ _]) (put [_ _ _]) (entrySet [_]))) - ->row (fn [sql rs] - (let [cols (col-map rs key) - row (cond - (satisfies? p/RowCompiler row) (p/compile-row row (map last cols)) - row row - :else (p/rs->map-of-cols cols))] - (.put ^Map cache sql row) - row))] + ([{:keys [row key cache] :or {key (unqualified-key)}}] + (let [c (or cache (cache/create-cache)) + ->row (fn [_sql rs] + (let [cols (col-map rs key)] + (cond + (satisfies? p/RowCompiler row) (p/compile-row row (map last cols)) + row row + :else (p/rs->map-of-cols cols))))] (reify - p/Cached - (cache [_] (into {} cache)) + cache/Cached + (cache [_] (cache/elements cache)) Context (-query-one [_ connection sqlvec] - (let [sql (-get-sql sqlvec) + (let [sql (-get-sql sqlvec) params (-get-parameter-iterator sqlvec) - ps (.prepareStatement ^Connection connection sql)] + ps (.prepareStatement ^Connection connection sql)] (try (prepare! ps params) - (let [rs (.executeQuery ps) - row (or (.get ^Map cache sql) (->row sql rs))] - (if (.next rs) (row rs))) + (let [rs (.executeQuery ps) + row (cache/lookup-or-set c sql #(->row %1 rs))] + (when (.next rs) (row rs))) (finally (.close ps))))) (-query [_ connection sqlvec] (let [sql (-get-sql sqlvec) - it (-get-parameter-iterator sqlvec) - ps (.prepareStatement ^Connection connection sql)] + it (-get-parameter-iterator sqlvec) + ps (.prepareStatement ^Connection connection sql)] (try (prepare! ps it) - (let [rs (.executeQuery ps) - row (or (.get ^Map cache sql) (->row sql rs))] + (let [rs (.executeQuery ps) + row (cache/lookup-or-set c sql #(->row %1 rs))] (loop [res []] (if (.next rs) (recur (conj res (row rs))) diff --git a/src/porsas/next.clj b/src/porsas/next.clj index 534ff74..d9ed1ba 100644 --- a/src/porsas/next.clj +++ b/src/porsas/next.clj @@ -1,24 +1,21 @@ (ns porsas.next (:require [next.jdbc.result-set :as rs] - [porsas.jdbc :as pj] - [porsas.core :as p]) - (:import (java.sql ResultSet) - (java.util HashMap))) + [porsas.cache :as cache] + [porsas.core :as p] + [porsas.jdbc :as pj]) + (:import (java.sql ResultSet))) (defn caching-row-builder "A [[next.jdbc.result-set/RowBuilder]] implementation using porsas. WIP." ([] (caching-row-builder (pj/qualified-key))) ([key] - (let [cache (HashMap.)] ;; TODO: make bounded + (let [cache (cache/create-cache)] (fn [^ResultSet rs opts] (let [sql (:next.jdbc/sql-string opts) - ->row (or (.get cache sql) - (let [->row (p/rs-> 1 nil (map last (pj/col-map rs key)))] - (.put cache sql ->row) - ->row))] + ->row (cache/lookup-or-set cache sql (fn [_] (p/rs-> 1 nil (map last (pj/col-map rs key)))))] (reify - p/Cached + cache/Cached (cache [_] (into {} cache)) rs/RowBuilder (->row [_] (->row rs)) diff --git a/test/porsas/async_test.clj b/test/porsas/async_test.clj index 6ad84c5..a823a52 100644 --- a/test/porsas/async_test.clj +++ b/test/porsas/async_test.clj @@ -6,9 +6,8 @@ [manifold.deferred :as d]) (:import io.vertx.pgclient.PgPool)) -(def pool-opts {:uri "postgresql://localhost:5432/porsas" - :user "user" - :password "password"}) +(def pool-opts {:uri "postgresql://localhost:5432/porsas" + :user "postgres"}) (t/deftest async (let [pool (pa/pool pool-opts)] @@ -17,7 +16,7 @@ (pa/then :name) (deref)))) - (t/is (= "io.reactiverse.pgclient.PgException: relation \"non_existing\" does not exist" + (t/is (= "io.vertx.pgclient.PgException: ERROR: relation \"non_existing\" does not exist (42P01)" (-> (pa/query-one pool ["SELECT * from non_existing where id=$1" 1]) (pa/then :name) (pa/catch #(-> % .getMessage)) From 64f7d14d894cd214ba360e3de7ad3ccf7d828f1d Mon Sep 17 00:00:00 2001 From: Janos Meszaros Date: Sun, 12 Dec 2021 17:18:58 +0100 Subject: [PATCH 3/6] Add cloffeine-based cache --- deps.edn | 1 + src/porsas/async.clj | 2 +- src/porsas/cache.clj | 24 +++++++++++++++++------- src/porsas/jdbc.clj | 2 +- src/porsas/next.clj | 2 +- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/deps.edn b/deps.edn index 3995132..627acac 100644 --- a/deps.edn +++ b/deps.edn @@ -1,6 +1,7 @@ {:paths ["src"] :deps {org.postgresql/postgresql {:mvn/version "42.3.1"} org.clojure/core.cache {:mvn/version "1.0.225"} + com.appsflyer/cloffeine {:mvn/version "1.0.0"} io.vertx/vertx-pg-client {:mvn/version "4.2.1"}} :aliases {:test {:extra-paths ["test"] :extra-deps {org.clojure/clojure {:mvn/version "1.10.3"} diff --git a/src/porsas/async.clj b/src/porsas/async.clj index 717ee11..f4fe83a 100644 --- a/src/porsas/async.clj +++ b/src/porsas/async.clj @@ -104,7 +104,7 @@ | `:cache` | Optional [[porsas.cache/Cache]] instance to hold the compiled rowmappers" ([] (context {})) ([{:keys [row cache]}] - (let [cache (or cache (cache/create-cache)) + (let [cache (or cache (cache/create-caffeine-cache)) ->row (fn [_sql ^RowSet rs] (let [cols (col-map rs)] (cond diff --git a/src/porsas/cache.clj b/src/porsas/cache.clj index e4fab6f..1eb3915 100644 --- a/src/porsas/cache.clj +++ b/src/porsas/cache.clj @@ -1,5 +1,6 @@ (ns porsas.cache - (:require [clojure.core.cache.wrapped :as c])) + (:require [clojure.core.cache.wrapped :as c] + [cloffeine.cache :as cache])) (defprotocol Cache (lookup-or-set [this k value-fn] "Lookup a value in the cache based on `k` and if not found set its value based on `value-fn` and returns it.") @@ -8,11 +9,20 @@ (defprotocol Cached (cache [this])) -(defrecord CoreCache [a] - Cache - (lookup-or-set [this k value-fn] - (c/lookup-or-miss (:a this) k value-fn)) - (elements [this] (into {} @(:a this)))) +(defrecord CoreCache [c] + Cache + (lookup-or-set [this k value-fn] + (c/lookup-or-miss (:c this) k value-fn)) + (elements [this] (into {} @(:c this)))) (defn create-cache [] - (->CoreCache (c/basic-cache-factory {}))) + (->CoreCache (c/lru-cache-factory {}))) + +(defrecord CaffeineCache [c] + Cache + (lookup-or-set [this k value-fn] + (cache/get (:c this) k value-fn)) + (elements [this] (into {} (cache/as-map (:c this))))) + +(defn create-caffeine-cache [] + (->CaffeineCache (cache/make-cache))) diff --git a/src/porsas/jdbc.clj b/src/porsas/jdbc.clj index 0dac216..5cd344a 100644 --- a/src/porsas/jdbc.clj +++ b/src/porsas/jdbc.clj @@ -122,7 +122,7 @@ | `:cache` | Optional [[porsas.cache/Cache]] instance to hold the compiled rowmappers" ([] (context {})) ([{:keys [row key cache] :or {key (unqualified-key)}}] - (let [c (or cache (cache/create-cache)) + (let [c (or cache (cache/create-caffeine-cache)) ->row (fn [_sql rs] (let [cols (col-map rs key)] (cond diff --git a/src/porsas/next.clj b/src/porsas/next.clj index d9ed1ba..4798a8e 100644 --- a/src/porsas/next.clj +++ b/src/porsas/next.clj @@ -10,7 +10,7 @@ ([] (caching-row-builder (pj/qualified-key))) ([key] - (let [cache (cache/create-cache)] + (let [cache (cache/create-caffeine-cache)] (fn [^ResultSet rs opts] (let [sql (:next.jdbc/sql-string opts) ->row (cache/lookup-or-set cache sql (fn [_] (p/rs-> 1 nil (map last (pj/col-map rs key)))))] From 47bff79eff8d4a382ae4edafa14252e5facff20c Mon Sep 17 00:00:00 2001 From: Janos Meszaros Date: Sat, 8 Jan 2022 14:37:35 +0100 Subject: [PATCH 4/6] Moving cache implementations into separate namespaces --- deps.edn | 4 ++-- project.clj | 2 ++ src/porsas/async.clj | 2 +- src/porsas/cache.clj | 23 ++--------------------- src/porsas/cache/caffeine.clj | 12 ++++++++++++ src/porsas/cache/core.clj | 12 ++++++++++++ src/porsas/jdbc.clj | 2 +- src/porsas/next.clj | 4 ++-- test/porsas/cache_test.clj | 21 ++++++++++++++------- 9 files changed, 48 insertions(+), 34 deletions(-) create mode 100644 src/porsas/cache/caffeine.clj create mode 100644 src/porsas/cache/core.clj diff --git a/deps.edn b/deps.edn index 627acac..abaf05c 100644 --- a/deps.edn +++ b/deps.edn @@ -1,11 +1,11 @@ {:paths ["src"] :deps {org.postgresql/postgresql {:mvn/version "42.3.1"} - org.clojure/core.cache {:mvn/version "1.0.225"} - com.appsflyer/cloffeine {:mvn/version "1.0.0"} io.vertx/vertx-pg-client {:mvn/version "4.2.1"}} :aliases {:test {:extra-paths ["test"] :extra-deps {org.clojure/clojure {:mvn/version "1.10.3"} com.clojure-goes-fast/clj-async-profiler {:mvn/version "0.5.1"} + org.clojure/core.cache {:mvn/version "1.0.225"} + com.appsflyer/cloffeine {:mvn/version "1.0.0"} funcool/promesa {:mvn/version "2.0.1"} manifold/manifold {:mvn/version "0.1.8"} com.h2database/h2 {:mvn/version "1.4.199"} diff --git a/project.clj b/project.clj index d0fc31b..1564ddb 100644 --- a/project.clj +++ b/project.clj @@ -13,6 +13,8 @@ :profiles {:dev {:global-vars {*warn-on-reflection* true} :dependencies [[org.clojure/clojure "1.10.3"] [com.clojure-goes-fast/clj-async-profiler "0.5.1"] + [org.clojure/core.cache "1.0.225"] + [com.appsflyer/cloffeine "1.0.0"] [funcool/promesa "2.0.1"] [manifold "0.1.8"] [com.h2database/h2 "1.4.199"] diff --git a/src/porsas/async.clj b/src/porsas/async.clj index f4fe83a..5b558ad 100644 --- a/src/porsas/async.clj +++ b/src/porsas/async.clj @@ -104,7 +104,7 @@ | `:cache` | Optional [[porsas.cache/Cache]] instance to hold the compiled rowmappers" ([] (context {})) ([{:keys [row cache]}] - (let [cache (or cache (cache/create-caffeine-cache)) + (let [cache (or cache ((requiring-resolve 'porsas.cache.caffeine/create-cache))) ->row (fn [_sql ^RowSet rs] (let [cols (col-map rs)] (cond diff --git a/src/porsas/cache.clj b/src/porsas/cache.clj index 1eb3915..4fa586e 100644 --- a/src/porsas/cache.clj +++ b/src/porsas/cache.clj @@ -1,28 +1,9 @@ -(ns porsas.cache - (:require [clojure.core.cache.wrapped :as c] - [cloffeine.cache :as cache])) +(ns porsas.cache) (defprotocol Cache - (lookup-or-set [this k value-fn] "Lookup a value in the cache based on `k` and if not found set its value based on `value-fn` and returns it.") + (lookup-or-set [this k value-fn] "Lookups a value in the cache based on `k` and if not found sets its value based on `value-fn` and returns it.") (elements [this] "Returns the actual state of the cache.")) (defprotocol Cached (cache [this])) -(defrecord CoreCache [c] - Cache - (lookup-or-set [this k value-fn] - (c/lookup-or-miss (:c this) k value-fn)) - (elements [this] (into {} @(:c this)))) - -(defn create-cache [] - (->CoreCache (c/lru-cache-factory {}))) - -(defrecord CaffeineCache [c] - Cache - (lookup-or-set [this k value-fn] - (cache/get (:c this) k value-fn)) - (elements [this] (into {} (cache/as-map (:c this))))) - -(defn create-caffeine-cache [] - (->CaffeineCache (cache/make-cache))) diff --git a/src/porsas/cache/caffeine.clj b/src/porsas/cache/caffeine.clj new file mode 100644 index 0000000..b3afe18 --- /dev/null +++ b/src/porsas/cache/caffeine.clj @@ -0,0 +1,12 @@ +(ns porsas.cache.caffeine + (:require [cloffeine.cache :as cache] + [porsas.cache :as pc])) + +(defrecord CaffeineCache [c] + pc/Cache + (lookup-or-set [this k value-fn] + (cache/get (:c this) k value-fn)) + (elements [this] (into {} (cache/as-map (:c this))))) + +(defn create-cache [] + (->CaffeineCache (cache/make-cache))) diff --git a/src/porsas/cache/core.clj b/src/porsas/cache/core.clj new file mode 100644 index 0000000..c6dd356 --- /dev/null +++ b/src/porsas/cache/core.clj @@ -0,0 +1,12 @@ +(ns porsas.cache.core + (:require [clojure.core.cache.wrapped :as c] + [porsas.cache :as pc])) + +(defrecord CoreCache [c] + pc/Cache + (lookup-or-set [this k value-fn] + (c/lookup-or-miss (:c this) k value-fn)) + (elements [this] (into {} @(:c this)))) + +(defn create-cache [] + (->CoreCache (c/lru-cache-factory {}))) diff --git a/src/porsas/jdbc.clj b/src/porsas/jdbc.clj index 5cd344a..9e3a551 100644 --- a/src/porsas/jdbc.clj +++ b/src/porsas/jdbc.clj @@ -122,7 +122,7 @@ | `:cache` | Optional [[porsas.cache/Cache]] instance to hold the compiled rowmappers" ([] (context {})) ([{:keys [row key cache] :or {key (unqualified-key)}}] - (let [c (or cache (cache/create-caffeine-cache)) + (let [c (or cache ((requiring-resolve 'porsas.cache.caffeine/create-cache))) ->row (fn [_sql rs] (let [cols (col-map rs key)] (cond diff --git a/src/porsas/next.clj b/src/porsas/next.clj index 4798a8e..17457b8 100644 --- a/src/porsas/next.clj +++ b/src/porsas/next.clj @@ -9,8 +9,8 @@ "A [[next.jdbc.result-set/RowBuilder]] implementation using porsas. WIP." ([] (caching-row-builder (pj/qualified-key))) - ([key] - (let [cache (cache/create-caffeine-cache)] + ([key & {:keys [cache]}] + (let [cache (or cache ((requiring-resolve 'porsas.cache.caffeine/create-cache)))] (fn [^ResultSet rs opts] (let [sql (:next.jdbc/sql-string opts) ->row (cache/lookup-or-set cache sql (fn [_] (p/rs-> 1 nil (map last (pj/col-map rs key)))))] diff --git a/test/porsas/cache_test.clj b/test/porsas/cache_test.clj index e027806..966ebfb 100644 --- a/test/porsas/cache_test.clj +++ b/test/porsas/cache_test.clj @@ -1,13 +1,20 @@ (ns porsas.cache-test (:require [clojure.test :as t] - [clojure.core.cache.wrapped :as c] - [porsas.cache :as sut])) + [clojure.template :refer [do-template]] + [porsas.cache :as sut] + [porsas.cache.core :as core] + [porsas.cache.caffeine :as caffeine])) (t/deftest cache - (let [c (sut/->CoreCache (c/basic-cache-factory {}))] - (t/is (= {} (sut/elements c))) + (do-template + [t cache] + (let [c cache] + (t/testing t + (t/is (= {} (sut/elements c))) - (t/is (= ::a (sut/lookup-or-set c :a (constantly ::a)))) - (t/is (= ::a (sut/lookup-or-set c :a (constantly ::b)))) + (t/is (= ::a (sut/lookup-or-set c :a (constantly ::a)))) + (t/is (= ::a (sut/lookup-or-set c :a (constantly ::b)))) - (t/is (= {:a ::a} (sut/elements c))))) + (t/is (= {:a ::a} (sut/elements c))))) + "core cache" (core/create-cache) + "caffeine" (caffeine/create-cache))) From a0a668c0ddf48ddcc1e5be355e6f800d9fbd8eaa Mon Sep 17 00:00:00 2001 From: Janos Meszaros Date: Sat, 8 Jan 2022 15:08:51 +0100 Subject: [PATCH 5/6] Use caffeine directly instead of clj wrapper --- deps.edn | 2 +- project.clj | 2 +- src/porsas/cache/caffeine.clj | 18 +++++++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/deps.edn b/deps.edn index abaf05c..9126921 100644 --- a/deps.edn +++ b/deps.edn @@ -5,7 +5,7 @@ :extra-deps {org.clojure/clojure {:mvn/version "1.10.3"} com.clojure-goes-fast/clj-async-profiler {:mvn/version "0.5.1"} org.clojure/core.cache {:mvn/version "1.0.225"} - com.appsflyer/cloffeine {:mvn/version "1.0.0"} + com.github.ben-manes.caffeine/caffeine {:mvn/version "3.0.5"} funcool/promesa {:mvn/version "2.0.1"} manifold/manifold {:mvn/version "0.1.8"} com.h2database/h2 {:mvn/version "1.4.199"} diff --git a/project.clj b/project.clj index 1564ddb..0e2aab4 100644 --- a/project.clj +++ b/project.clj @@ -14,7 +14,7 @@ :dependencies [[org.clojure/clojure "1.10.3"] [com.clojure-goes-fast/clj-async-profiler "0.5.1"] [org.clojure/core.cache "1.0.225"] - [com.appsflyer/cloffeine "1.0.0"] + [com.github.ben-manes.caffeine/caffeine "3.0.5"] [funcool/promesa "2.0.1"] [manifold "0.1.8"] [com.h2database/h2 "1.4.199"] diff --git a/src/porsas/cache/caffeine.clj b/src/porsas/cache/caffeine.clj index b3afe18..c299835 100644 --- a/src/porsas/cache/caffeine.clj +++ b/src/porsas/cache/caffeine.clj @@ -1,12 +1,20 @@ (ns porsas.cache.caffeine - (:require [cloffeine.cache :as cache] - [porsas.cache :as pc])) + (:require [porsas.cache :as pc]) + (:import [com.github.benmanes.caffeine.cache Caffeine Cache] + java.util.function.Function)) + +(defn ->function ^Function [f] + (reify Function + (apply [_this t] + (f t)))) (defrecord CaffeineCache [c] pc/Cache (lookup-or-set [this k value-fn] - (cache/get (:c this) k value-fn)) - (elements [this] (into {} (cache/as-map (:c this))))) + (.get ^Cache (:c this) k (->function value-fn))) + (elements [this] (into {} (.asMap ^Cache (:c this))))) (defn create-cache [] - (->CaffeineCache (cache/make-cache))) + (->CaffeineCache (-> (Caffeine/newBuilder) + (.maximumSize 10000) + (.build)))) From 20139559486e2e36ac0acb5d8ebced60a2aac97a Mon Sep 17 00:00:00 2001 From: Janos Meszaros Date: Sat, 8 Jan 2022 15:09:24 +0100 Subject: [PATCH 6/6] :next.jdbc/sql-string was renamed to :next.jdbc/sql-params https://github.com/seancorfield/next-jdbc/blame/develop/CHANGELOG.md#L272 --- src/porsas/next.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/porsas/next.clj b/src/porsas/next.clj index 17457b8..acca0bd 100644 --- a/src/porsas/next.clj +++ b/src/porsas/next.clj @@ -12,7 +12,7 @@ ([key & {:keys [cache]}] (let [cache (or cache ((requiring-resolve 'porsas.cache.caffeine/create-cache)))] (fn [^ResultSet rs opts] - (let [sql (:next.jdbc/sql-string opts) + (let [sql (:next.jdbc/sql-params opts) ->row (cache/lookup-or-set cache sql (fn [_] (p/rs-> 1 nil (map last (pj/col-map rs key)))))] (reify cache/Cached