mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#652 - ENH: L2 cache - add @CacheQueryTuning annotation
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Specify cache tuning for query caching on a specific entity type.
|
||||
* <p>
|
||||
* If this is not specified then the system default settings are used.
|
||||
* </p>
|
||||
*/
|
||||
@Target({ ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CacheQueryTuning {
|
||||
|
||||
/**
|
||||
* The maximum size for the cache.
|
||||
* <p>
|
||||
* This defaults to 0 which means unlimited.
|
||||
* </p>
|
||||
*/
|
||||
int maxSize() default 0;
|
||||
|
||||
/**
|
||||
* The maximum time (in seconds) that a cache entry is allowed to stay in the
|
||||
* cache when it has not been accessed.
|
||||
* <p>
|
||||
* This defaults to 0 which means unlimited.
|
||||
* </p>
|
||||
*/
|
||||
int maxIdleSecs() default 0;
|
||||
|
||||
/**
|
||||
* The maximum time (in seconds) a cache entry is allowed to stay in the
|
||||
* cache.
|
||||
* <p>
|
||||
* This is not generally required as the cache entries are automatically
|
||||
* evicted when related data changes are committed.
|
||||
* </p>
|
||||
* <p>
|
||||
* This defaults to 0 which means unlimited.
|
||||
* </p>
|
||||
*/
|
||||
int maxSecsToLive() default 0;
|
||||
|
||||
/**
|
||||
* The frequency (in seconds) that cache trimming should occur.
|
||||
* <p>
|
||||
* This is a hint for cache implementations that use background cache trimming.
|
||||
* </p>
|
||||
*/
|
||||
int trimFrequency() default 0;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebean.cache;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheQueryTuning;
|
||||
import com.avaje.ebean.annotation.CacheTuning;
|
||||
|
||||
/**
|
||||
@@ -30,13 +31,13 @@ public class ServerCacheOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create merging default options with the deployment specified ones.
|
||||
* Create from the cacheTuning deployment annotation.
|
||||
*/
|
||||
public ServerCacheOptions(ServerCacheOptions defaults) {
|
||||
this.maxSize = defaults.getMaxSize();
|
||||
this.maxIdleSecs = defaults.getMaxIdleSecs();
|
||||
this.maxSecsToLive = defaults.getMaxIdleSecs();
|
||||
this.trimFrequency = defaults.getTrimFrequency();
|
||||
public ServerCacheOptions(CacheQueryTuning cacheTuning) {
|
||||
this.maxSize = cacheTuning.maxSize();
|
||||
this.maxIdleSecs = cacheTuning.maxIdleSecs();
|
||||
this.maxSecsToLive = cacheTuning.maxSecsToLive();
|
||||
this.trimFrequency = cacheTuning.trimFrequency();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+32
-29
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.cache;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheQueryTuning;
|
||||
import com.avaje.ebean.annotation.CacheTuning;
|
||||
import com.avaje.ebean.cache.ServerCache;
|
||||
import com.avaje.ebean.cache.ServerCacheFactory;
|
||||
@@ -24,29 +25,15 @@ public class DefaultCacheHolder {
|
||||
|
||||
private final ServerCacheOptions defaultOptions;
|
||||
|
||||
private final boolean useBeanTuning;
|
||||
|
||||
/**
|
||||
* Create with a cache factory and default cache options.
|
||||
*
|
||||
* @param cacheFactory the factory for creating the cache
|
||||
* @param defaultOptions the default options for tuning the cache
|
||||
* @param useBeanTuning if true then use the bean class specific tuning. This is
|
||||
* generally false for the query cache.
|
||||
*/
|
||||
public DefaultCacheHolder(ServerCacheFactory cacheFactory,
|
||||
ServerCacheOptions defaultOptions, boolean useBeanTuning) {
|
||||
|
||||
public DefaultCacheHolder(ServerCacheFactory cacheFactory, ServerCacheOptions defaultOptions) {
|
||||
this.cacheFactory = cacheFactory;
|
||||
this.defaultOptions = defaultOptions;
|
||||
this.useBeanTuning = useBeanTuning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default cache options.
|
||||
*/
|
||||
public ServerCacheOptions getDefaultOptions() {
|
||||
return defaultOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +48,7 @@ public class DefaultCacheHolder {
|
||||
synchronized (monitor) {
|
||||
cache = synchMap.get(cacheKey);
|
||||
if (cache == null) {
|
||||
ServerCacheOptions options = getCacheOptions(cacheKey);
|
||||
ServerCacheOptions options = getCacheOptions(cacheKey, type);
|
||||
cache = cacheFactory.createCache(type, cacheKey, options);
|
||||
synchMap.put(cacheKey, cache);
|
||||
concMap.put(cacheKey, cache);
|
||||
@@ -94,25 +81,41 @@ public class DefaultCacheHolder {
|
||||
/**
|
||||
* Return the cache options for a given bean type.
|
||||
*/
|
||||
private ServerCacheOptions getCacheOptions(String beanType) {
|
||||
ServerCacheOptions getCacheOptions(String beanType, ServerCacheType type) {
|
||||
|
||||
if (useBeanTuning) {
|
||||
// read the deployment annotation
|
||||
try {
|
||||
Class<?> cls = Class.forName(beanType);
|
||||
CacheTuning cacheTuning = cls.getAnnotation(CacheTuning.class);
|
||||
if (cacheTuning != null) {
|
||||
ServerCacheOptions o = new ServerCacheOptions(cacheTuning);
|
||||
o.applyDefaults(defaultOptions);
|
||||
return o;
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ignore
|
||||
try {
|
||||
Class<?> cls = Class.forName(beanType);
|
||||
switch (type) {
|
||||
case QUERY:
|
||||
return getQueryOptions(cls);
|
||||
default:
|
||||
return getBeanOptions(cls);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return defaultOptions.copy();
|
||||
}
|
||||
|
||||
private ServerCacheOptions getQueryOptions(Class<?> cls) {
|
||||
CacheQueryTuning tuning = cls.getAnnotation(CacheQueryTuning.class);
|
||||
if (tuning != null) {
|
||||
ServerCacheOptions o = new ServerCacheOptions(tuning);
|
||||
o.applyDefaults(defaultOptions);
|
||||
return o;
|
||||
}
|
||||
return defaultOptions.copy();
|
||||
}
|
||||
|
||||
private ServerCacheOptions getBeanOptions(Class<?> cls) {
|
||||
CacheTuning cacheTuning = cls.getAnnotation(CacheTuning.class);
|
||||
if (cacheTuning != null) {
|
||||
ServerCacheOptions o = new ServerCacheOptions(cacheTuning);
|
||||
o.applyDefaults(defaultOptions);
|
||||
return o;
|
||||
}
|
||||
return defaultOptions.copy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+17
-2
@@ -34,7 +34,6 @@ public class DefaultServerCache implements ServerCache {
|
||||
*/
|
||||
public static final CompareByLastAccess BY_LAST_ACCESS = new CompareByLastAccess();
|
||||
|
||||
|
||||
/**
|
||||
* The underlying map (ConcurrentHashMap or similar)
|
||||
*/
|
||||
@@ -89,7 +88,23 @@ public class DefaultServerCache implements ServerCache {
|
||||
this.maxSize = maxSize;
|
||||
this.maxIdleSecs = maxIdleSecs;
|
||||
this.maxSecsToLive = maxSecsToLive;
|
||||
this.trimFrequency = trimFrequency;
|
||||
this.trimFrequency = determineTrim(maxIdleSecs, maxSecsToLive, trimFrequency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine a good trimFrequency as half of maxIdleSecs (or maxSecsToLive).
|
||||
*/
|
||||
int determineTrim(int maxIdleSecs, int maxSecsToLive, int trimFrequency) {
|
||||
if (trimFrequency > 0) {
|
||||
return trimFrequency;
|
||||
}
|
||||
if (maxIdleSecs > 0) {
|
||||
return maxIdleSecs / 2 - 1;
|
||||
}
|
||||
if (maxSecsToLive > 0) {
|
||||
return maxSecsToLive / 2 - 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-4
@@ -31,10 +31,10 @@ public class DefaultServerCacheManager implements ServerCacheManager {
|
||||
*/
|
||||
public DefaultServerCacheManager(ServerCacheFactory cacheFactory, ServerCacheOptions defaultBeanOptions, ServerCacheOptions defaultQueryOptions) {
|
||||
this.cacheFactory = cacheFactory;
|
||||
this.beanCache = new DefaultCacheHolder(cacheFactory, defaultBeanOptions, true);
|
||||
this.queryCache = new DefaultCacheHolder(cacheFactory, defaultQueryOptions, false);
|
||||
this.naturalKeyCache = new DefaultCacheHolder(cacheFactory, defaultQueryOptions, false);
|
||||
this.collectionIdsCache = new DefaultCacheHolder(cacheFactory, defaultQueryOptions, false);
|
||||
this.beanCache = new DefaultCacheHolder(cacheFactory, defaultBeanOptions);
|
||||
this.queryCache = new DefaultCacheHolder(cacheFactory, defaultQueryOptions);
|
||||
this.naturalKeyCache = new DefaultCacheHolder(cacheFactory, defaultBeanOptions);
|
||||
this.collectionIdsCache = new DefaultCacheHolder(cacheFactory, defaultBeanOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user