io.ebeaninternal.server.cache.DefaultCacheHolder Maven / Gradle / Ivy
package io.ebeaninternal.server.cache;
import io.ebean.annotation.CacheBeanTuning;
import io.ebean.annotation.CacheQueryTuning;
import io.ebean.cache.QueryCacheEntryValidate;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheConfig;
import io.ebean.cache.ServerCacheFactory;
import io.ebean.cache.ServerCacheOptions;
import io.ebean.cache.ServerCacheType;
import io.ebean.config.CurrentTenantProvider;
import io.ebean.util.AnnotationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
/**
* Manages the construction of caches.
*/
class DefaultCacheHolder {
private static final Logger log = LoggerFactory.getLogger("io.ebean.cache.ALL");
private final ConcurrentHashMap allCaches = new ConcurrentHashMap<>();
private final ConcurrentHashMap> collectIdCaches = new ConcurrentHashMap<>();
private final ServerCacheFactory cacheFactory;
private final ServerCacheOptions beanDefault;
private final ServerCacheOptions queryDefault;
private final CurrentTenantProvider tenantProvider;
private final QueryCacheEntryValidate queryCacheEntryValidate;
DefaultCacheHolder(CacheManagerOptions builder) {
this.cacheFactory = builder.getCacheFactory();
this.beanDefault = builder.getBeanDefault();
this.queryDefault = builder.getQueryDefault();
this.tenantProvider = builder.getCurrentTenantProvider();
this.queryCacheEntryValidate = builder.getQueryCacheEntryValidate();
}
ServerCache getCache(Class> beanType, String cacheKey, ServerCacheType type) {
return getCacheInternal(beanType, cacheKey, type);
}
private String key(String cacheKey, ServerCacheType type) {
return cacheKey + type.code();
}
/**
* Return the cache for a given bean type.
*/
private ServerCache getCacheInternal(Class> beanType, String cacheKey, ServerCacheType type) {
String fullKey = key(cacheKey, type);
return allCaches.computeIfAbsent(fullKey, s -> createCache(beanType, type, fullKey));
}
private ServerCache createCache(Class> beanType, ServerCacheType type, String key) {
ServerCacheOptions options = getCacheOptions(beanType, type);
if (type == ServerCacheType.COLLECTION_IDS) {
synchronized (this) {
collectIdCaches.computeIfAbsent(beanType.getName(), s -> new ConcurrentSkipListSet<>()).add(key);
}
}
return cacheFactory.createCache(new ServerCacheConfig(type, key, options, tenantProvider, queryCacheEntryValidate));
}
void clearAll() {
log.debug("clearAll");
for (ServerCache serverCache : allCaches.values()) {
serverCache.clear();
}
}
public void clear(String name) {
log.debug("clear {}", name);
clearIfExists(key(name, ServerCacheType.QUERY));
clearIfExists(key(name, ServerCacheType.BEAN));
clearIfExists(key(name, ServerCacheType.NATURAL_KEY));
Set keys = collectIdCaches.get(name);
if (keys != null) {
for (String collectionIdKey : keys) {
clearIfExists(collectionIdKey);
}
}
}
private void clearIfExists(String fullKey) {
ServerCache cache = allCaches.get(fullKey);
if (cache != null) {
log.trace("clear cache {}", fullKey);
cache.clear();
}
}
/**
* Return the cache options for a given bean type.
*/
ServerCacheOptions getCacheOptions(Class> beanType, ServerCacheType type) {
switch (type) {
case QUERY:
return getQueryOptions(beanType);
default:
return getBeanOptions(beanType);
}
}
private ServerCacheOptions getQueryOptions(Class> cls) {
CacheQueryTuning tuning = AnnotationUtil.findAnnotation(cls, CacheQueryTuning.class);
if (tuning != null) {
return new ServerCacheOptions(tuning).applyDefaults(queryDefault);
}
return queryDefault.copy();
}
private ServerCacheOptions getBeanOptions(Class> cls) {
CacheBeanTuning tuning = cls.getAnnotation(CacheBeanTuning.class);
if (tuning != null) {
return new ServerCacheOptions(tuning).applyDefaults(beanDefault);
}
return beanDefault.copy();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy