diff --git a/pom.xml b/pom.xml
index 8c11457..c1a88e5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,6 +112,12 @@
3.3.2
+
+ com.datastax.cassandra
+ cassandra-driver-extras
+ 3.3.2
+
+
com.diffplug.durian
durian
@@ -136,12 +142,24 @@
4.3.10.RELEASE
+
+ javax.cache
+ cache-api
+ 1.1.0
+
+
com.google.guava
guava
20.0
+
+ ca.exprofesso
+ guava-jcache
+ 1.0.4
+
+
io.zipkin.java
@@ -259,7 +277,6 @@
1.7.1
runtime
-
diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java
index 79ef069..76f3509 100644
--- a/src/main/java/net/helenus/core/HelenusSession.java
+++ b/src/main/java/net/helenus/core/HelenusSession.java
@@ -15,25 +15,12 @@
*/
package net.helenus.core;
-import static net.helenus.core.Query.eq;
-
import brave.Tracer;
import com.codahale.metrics.MetricRegistry;
import com.datastax.driver.core.*;
import com.google.common.collect.Table;
-import java.io.Closeable;
-import java.io.PrintStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.*;
-import java.util.concurrent.Executor;
-import java.util.function.Function;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
import net.helenus.core.cache.CacheUtil;
import net.helenus.core.cache.Facet;
-import net.helenus.core.cache.SessionCache;
import net.helenus.core.cache.UnboundFacet;
import net.helenus.core.operation.*;
import net.helenus.core.reflect.Drafted;
@@ -50,6 +37,24 @@ import net.helenus.support.Fun.Tuple6;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.cache.Cache;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
+import javax.cache.configuration.MutableConfiguration;
+import javax.cache.spi.CachingProvider;
+import java.io.Closeable;
+import java.io.PrintStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+import java.util.concurrent.Executor;
+import java.util.function.Function;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import static net.helenus.core.Query.eq;
+
public class HelenusSession extends AbstractSessionOperations implements Closeable {
public static final Object deleted = new Object();
@@ -68,7 +73,7 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
private final SessionRepository sessionRepository;
private final Executor executor;
private final boolean dropSchemaOnClose;
- private final SessionCache sessionCache;
+ private final CacheManager cacheManager;
private final RowColumnValueProvider valueProvider;
private final StatementColumnValuePreparer valuePreparer;
private final Metadata metadata;
@@ -77,21 +82,21 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
private volatile boolean showValues;
HelenusSession(
- Session session,
- String usingKeyspace,
- CodecRegistry registry,
- boolean showCql,
- boolean showValues,
- PrintStream printStream,
- SessionRepositoryBuilder sessionRepositoryBuilder,
- Executor executor,
- boolean dropSchemaOnClose,
- ConsistencyLevel consistencyLevel,
- boolean defaultQueryIdempotency,
- Class extends UnitOfWork> unitOfWorkClass,
- SessionCache sessionCache,
- MetricRegistry metricRegistry,
- Tracer tracer) {
+ Session session,
+ String usingKeyspace,
+ CodecRegistry registry,
+ boolean showCql,
+ boolean showValues,
+ PrintStream printStream,
+ SessionRepositoryBuilder sessionRepositoryBuilder,
+ Executor executor,
+ boolean dropSchemaOnClose,
+ ConsistencyLevel consistencyLevel,
+ boolean defaultQueryIdempotency,
+ Class extends UnitOfWork> unitOfWorkClass,
+ CacheManager cacheManager,
+ MetricRegistry metricRegistry,
+ Tracer tracer) {
this.session = session;
this.registry = registry == null ? CodecRegistry.DEFAULT_INSTANCE : registry;
this.usingKeyspace =
@@ -109,11 +114,14 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
this.unitOfWorkClass = unitOfWorkClass;
this.metricRegistry = metricRegistry;
this.zipkinTracer = tracer;
+ this.cacheManager = cacheManger;
- if (sessionCache == null) {
- this.sessionCache = SessionCache.defaultCache();
- } else {
- this.sessionCache = sessionCache;
+ if (cacheManager == null) {
+ MutableConfiguration configuration = new MutableConfiguration<>();
+ configuration.setStoreByValue(false);
+ configuration.setTypes(String.class, Object.class);
+ CachingProvider cachingProvider = Caching.getCachingProvider(GuavaCacheManager.class.getName());
+ cacheManager = cachingProvider.getCacheManager();
}
this.valueProvider = new RowColumnValueProvider(this.sessionRepository);
@@ -214,10 +222,13 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
@Override
public Object checkCache(String tableName, List facets) {
Object result = null;
- for (String key : CacheUtil.flatKeys(tableName, facets)) {
- result = sessionCache.get(key);
- if (result != null) {
- return result;
+ Cache cache = cacheManager.getCache(tableName);
+ if (cache != null) {
+ for (String key : CacheUtil.flatKeys(tableName, facets)) {
+ result = cache.get(key);
+ if (result != null) {
+ return result;
+ }
}
}
return null;
@@ -226,7 +237,10 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
@Override
public void cacheEvict(List facets) {
String tableName = CacheUtil.schemaName(facets);
- CacheUtil.flatKeys(tableName, facets).forEach(key -> sessionCache.invalidate(key));
+ Cache cache = cacheManager.getCache(tableName);
+ if (cache != null) {
+ CacheUtil.flatKeys(tableName, facets).forEach(key -> cache.remove(key));
+ }
}
@Override
@@ -278,6 +292,7 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null;
if (entity.isCacheable()) {
List boundFacets = new ArrayList<>();
+ String tableName = CacheUtil.schemaName(boundFacets);
for (Facet facet : entity.getFacets()) {
if (facet instanceof UnboundFacet) {
UnboundFacet unboundFacet = (UnboundFacet) facet;
@@ -305,34 +320,43 @@ public class HelenusSession extends AbstractSessionOperations implements Closeab
}
}
List facetCombinations = CacheUtil.flattenFacets(boundFacets);
- String tableName = CacheUtil.schemaName(boundFacets);
replaceCachedFacetValues(pojo, tableName, facetCombinations);
}
}
- List> deletedFacetSets =
- uowCache
- .values()
- .stream()
- .filter(Either::isRight)
- .map(Either::getRight)
- .collect(Collectors.toList());
- for (List facets : deletedFacetSets) {
- String tableName = CacheUtil.schemaName(facets);
- List keys = CacheUtil.flatKeys(tableName, facets);
- keys.forEach(key -> sessionCache.invalidate(key));
- }
+ if (cacheManager != null) {
+ List> deletedFacetSets =
+ uowCache
+ .values()
+ .stream()
+ .filter(Either::isRight)
+ .map(Either::getRight)
+ .collect(Collectors.toList());
+ for (List facets : deletedFacetSets) {
+ String tableName = CacheUtil.schemaName(facets);
+ Cache cache = cacheManager.getCache(tableName);
+ if (cache != null) {
+ List keys = CacheUtil.flatKeys(tableName, facets);
+ keys.forEach(key -> cache.remove(key));
+ }
+ }
+ }
}
private void replaceCachedFacetValues(
Object pojo, String tableName, List facetCombinations) {
for (String[] combination : facetCombinations) {
- String cacheKey = tableName + "." + Arrays.toString(combination);
- if (pojo == null || pojo == HelenusSession.deleted) {
- sessionCache.invalidate(cacheKey);
- } else {
- sessionCache.put(cacheKey, pojo);
- }
+ String cacheKey = tableName + "." + Arrays.toString(combination);
+ if (cacheManager != null) {
+ Cache cache = cacheManager.getCache(tableName);
+ if (cache != null) {
+ if (pojo == null || pojo == HelenusSession.deleted) {
+ cache.remove(cacheKey);
+ } else {
+ cache.put(cacheKey, pojo);
+ }
+ }
+ }
}
}
diff --git a/src/main/java/net/helenus/core/SessionInitializer.java b/src/main/java/net/helenus/core/SessionInitializer.java
index 5904494..26c921b 100644
--- a/src/main/java/net/helenus/core/SessionInitializer.java
+++ b/src/main/java/net/helenus/core/SessionInitializer.java
@@ -17,26 +17,8 @@ package net.helenus.core;
import brave.Tracer;
import com.codahale.metrics.MetricRegistry;
-import com.datastax.driver.core.CodecRegistry;
-import com.datastax.driver.core.ConsistencyLevel;
-import com.datastax.driver.core.KeyspaceMetadata;
-import com.datastax.driver.core.Session;
-import com.datastax.driver.core.TableMetadata;
-import com.datastax.driver.core.UserType;
+import com.datastax.driver.core.*;
import com.google.common.util.concurrent.MoreExecutors;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.function.Consumer;
-import net.helenus.core.cache.SessionCache;
import net.helenus.core.reflect.DslExportable;
import net.helenus.mapping.HelenusEntity;
import net.helenus.mapping.HelenusEntityType;
@@ -47,6 +29,14 @@ import net.helenus.support.Either;
import net.helenus.support.HelenusException;
import net.helenus.support.PackageUtil;
+import javax.cache.CacheManager;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.*;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.function.Consumer;
+
public final class SessionInitializer extends AbstractSessionOperations {
private final Session session;
@@ -67,7 +57,7 @@ public final class SessionInitializer extends AbstractSessionOperations {
private boolean dropUnusedIndexes = false;
private KeyspaceMetadata keyspaceMetadata;
private AutoDdl autoDdl = AutoDdl.UPDATE;
- private SessionCache sessionCache = null;
+ private CacheManager cacheManager = null;
SessionInitializer(Session session, String keyspace) {
this.session = session;
@@ -157,8 +147,8 @@ public final class SessionInitializer extends AbstractSessionOperations {
return this;
}
- public SessionInitializer setSessionCache(SessionCache sessionCache) {
- this.sessionCache = sessionCache;
+ public SessionInitializer setCacheManager(CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
return this;
}
@@ -304,7 +294,7 @@ public final class SessionInitializer extends AbstractSessionOperations {
consistencyLevel,
idempotent,
unitOfWorkClass,
- sessionCache,
+ cacheManager,
metricRegistry,
zipkinTracer);
}
diff --git a/src/main/java/net/helenus/core/cache/GuavaCache.java b/src/main/java/net/helenus/core/cache/GuavaCache.java
deleted file mode 100644
index 5418c3a..0000000
--- a/src/main/java/net/helenus/core/cache/GuavaCache.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2015 The Helenus Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.helenus.core.cache;
-
-import com.google.common.cache.Cache;
-
-public class GuavaCache implements SessionCache {
-
- final Cache cache;
-
- GuavaCache(Cache cache) {
- this.cache = cache;
- }
-
- @Override
- public void invalidate(K key) {
- cache.invalidate(key);
- }
-
- @Override
- public V get(K key) {
- return cache.getIfPresent(key);
- }
-
- @Override
- public void put(K key, V value) {
- cache.put(key, value);
- }
-}
diff --git a/src/main/java/net/helenus/core/cache/SessionCache.java b/src/main/java/net/helenus/core/cache/SessionCache.java
deleted file mode 100644
index 4b6d8d0..0000000
--- a/src/main/java/net/helenus/core/cache/SessionCache.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2015 The Helenus Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.helenus.core.cache;
-
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.RemovalListener;
-import com.google.common.cache.RemovalNotification;
-import java.util.concurrent.TimeUnit;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public interface SessionCache {
-
- static final Logger LOG = LoggerFactory.getLogger(SessionCache.class);
-
- static SessionCache defaultCache() {
- GuavaCache cache;
- RemovalListener listener =
- new RemovalListener() {
- @Override
- public void onRemoval(RemovalNotification n) {
- if (n.wasEvicted()) {
- String cause = n.getCause().name();
- LOG.info(cause);
- }
- }
- };
-
- cache =
- new GuavaCache(
- CacheBuilder.newBuilder()
- .maximumSize(25_000)
- .expireAfterAccess(5, TimeUnit.MINUTES)
- .softValues()
- .removalListener(listener)
- .build());
-
- return cache;
- }
-
- void invalidate(K key);
-
- V get(K key);
-
- void put(K key, V value);
-}