mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1222 - Extend L2 ServerCache API with putAll(), getAll() and removeAll() methods
This commit is contained in:
+18
-4
@@ -17,9 +17,9 @@ import java.util.Set;
|
||||
*/
|
||||
public interface ServerCache {
|
||||
|
||||
default Map<Object,Object> getAll(Set<Object> keys){
|
||||
default Map<Object, Object> getAll(Set<Object> keys) {
|
||||
|
||||
Map<Object,Object> map = new LinkedHashMap<>();
|
||||
Map<Object, Object> map = new LinkedHashMap<>();
|
||||
for (Object key : keys) {
|
||||
Object value = get(key);
|
||||
if (value != null) {
|
||||
@@ -34,15 +34,29 @@ public interface ServerCache {
|
||||
*/
|
||||
Object get(Object id);
|
||||
|
||||
/**
|
||||
* Put all the values in the cache.
|
||||
*/
|
||||
default void putAll(Map<Object, Object> keyValues) {
|
||||
keyValues.forEach(this::put);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the value in the cache with a given id.
|
||||
*/
|
||||
Object put(Object id, Object value);
|
||||
void put(Object id, Object value);
|
||||
|
||||
/**
|
||||
* Remove the entries from the cache given the id values.
|
||||
*/
|
||||
default void removeAll(Set<Object> keys) {
|
||||
keys.forEach(this::remove);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a entry from the cache given its id.
|
||||
*/
|
||||
Object remove(Object id);
|
||||
void remove(Object id);
|
||||
|
||||
/**
|
||||
* Clear all entries from the cache.
|
||||
|
||||
@@ -157,9 +157,9 @@ public class LoadBeanRequest extends LoadRequest {
|
||||
for (Object aList : list) {
|
||||
EntityBean loadedBean = (EntityBean) aList;
|
||||
loadedIds.add(desc.getId(loadedBean));
|
||||
if (isLoadCache()) {
|
||||
desc.cacheBeanPut(loadedBean);
|
||||
}
|
||||
}
|
||||
if (isLoadCache()) {
|
||||
desc.cacheBeanPutAll(list);
|
||||
}
|
||||
|
||||
if (lazyLoadProperty != null) {
|
||||
|
||||
@@ -122,8 +122,7 @@ public class CacheChangeSet {
|
||||
*/
|
||||
private ManyChange many(BeanDescriptor<?> desc, String manyProperty) {
|
||||
ManyKey key = new ManyKey(desc, manyProperty);
|
||||
ManyChange manyChange = manyChangeMap.computeIfAbsent(key, ManyChange::new);
|
||||
return manyChange;
|
||||
return manyChangeMap.computeIfAbsent(key, ManyChange::new);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,15 +6,14 @@ import io.ebean.cache.ServerCacheOptions;
|
||||
import io.ebean.cache.ServerCacheStatistics;
|
||||
import io.ebean.cache.TenantAwareKey;
|
||||
import io.ebean.config.CurrentTenantProvider;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -217,20 +216,23 @@ public class DefaultServerCache implements ServerCache {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<Object, Object> keyValues) {
|
||||
keyValues.forEach(this::put);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a value into the cache.
|
||||
*/
|
||||
@Override
|
||||
public Object put(Object id, Object value) {
|
||||
public void put(Object id, Object value) {
|
||||
|
||||
Object key = key(id);
|
||||
CacheEntry entry = map.put(key, new CacheEntry(key, value));
|
||||
if (entry == null) {
|
||||
insertCount.increment();
|
||||
return null;
|
||||
} else {
|
||||
updateCount.increment();
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,14 +240,11 @@ public class DefaultServerCache implements ServerCache {
|
||||
* Remove an entry from the cache.
|
||||
*/
|
||||
@Override
|
||||
public Object remove(Object id) {
|
||||
public void remove(Object id) {
|
||||
|
||||
CacheEntry entry = map.remove(key(id));
|
||||
if (entry == null) {
|
||||
return null;
|
||||
} else {
|
||||
if (entry != null) {
|
||||
removeCount.increment();
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,10 +358,8 @@ public class DefaultServerCache implements ServerCache {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public int compare(CacheEntry entry1, CacheEntry entry2) {
|
||||
long x = entry1.getLastAccessTime();
|
||||
long y = entry2.getLastAccessTime();
|
||||
return (x < y) ? -1 : ((x == y) ? 0 : 1);
|
||||
public int compare(CacheEntry e1, CacheEntry e2) {
|
||||
return Long.compare(e1.getLastAccessTime(), e2.getLastAccessTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ import io.ebean.plugin.BeanDocType;
|
||||
import io.ebean.plugin.BeanType;
|
||||
import io.ebean.plugin.ExpressionPath;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.util.SplitName;
|
||||
import io.ebeaninternal.api.BeanCacheResult;
|
||||
import io.ebeaninternal.api.CQueryPlanKey;
|
||||
import io.ebeaninternal.api.ConcurrencyMode;
|
||||
import io.ebeaninternal.api.LoadContext;
|
||||
@@ -62,8 +64,6 @@ import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
import io.ebeaninternal.server.persist.DmlUtil;
|
||||
import io.ebeaninternal.server.query.CQueryPlan;
|
||||
import io.ebeaninternal.server.query.CQueryPlanStats.Snapshot;
|
||||
import io.ebean.util.SplitName;
|
||||
import io.ebeaninternal.api.BeanCacheResult;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
import io.ebeaninternal.server.rawsql.SpiRawSql;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
@@ -1348,6 +1348,17 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
cacheHelp.beanCachePut(bean);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void cacheBeanPutAll(Collection<?> beans) {
|
||||
if (!beans.isEmpty()) {
|
||||
cacheHelp.beanPutAll((Collection<EntityBean>)beans);
|
||||
}
|
||||
}
|
||||
|
||||
void cacheBeanPutAllDirect(Collection<EntityBean> beans) {
|
||||
cacheHelp.beanCachePutAllDirect(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a bean into the cache as the correct type.
|
||||
*/
|
||||
|
||||
@@ -418,6 +418,22 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
return CachedBeanDataFromBean.extract(targetDesc, bean);
|
||||
}
|
||||
|
||||
void beanPutAll(Collection<EntityBean> beans) {
|
||||
if (desc.inheritInfo != null) {
|
||||
Class<?> aClass = theClassOf(beans);
|
||||
desc.descOf(aClass).cacheBeanPutAllDirect(beans);
|
||||
} else {
|
||||
beanCachePutAllDirect(beans);
|
||||
}
|
||||
}
|
||||
|
||||
private Class<?> theClassOf(Collection<EntityBean> beans) {
|
||||
if (beans instanceof List) {
|
||||
return ((List)beans).get(0).getClass();
|
||||
}
|
||||
return beans.iterator().next().getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a bean into the bean cache.
|
||||
*/
|
||||
@@ -430,9 +446,41 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
}
|
||||
}
|
||||
|
||||
void beanCachePutAllDirect(Collection<EntityBean> beans) {
|
||||
|
||||
Map<Object,Object> natKeys = null;
|
||||
if (naturalKey != null) {
|
||||
natKeys = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
Map<Object,Object> map = new LinkedHashMap<>();
|
||||
for (EntityBean bean : beans) {
|
||||
CachedBeanData beanData = beanExtractData(desc, bean);
|
||||
Object id = desc.getId(bean);
|
||||
map.put(id, beanData);
|
||||
if (naturalKey != null) {
|
||||
Object naturalKey = calculateNaturalKey(beanData);
|
||||
if (naturalKey != null) {
|
||||
natKeys.put(naturalKey, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (beanLog.isDebugEnabled()) {
|
||||
beanLog.debug(" PUT ALL {}({})", cacheName, map.keySet());
|
||||
}
|
||||
getBeanCache().putAll(map);
|
||||
|
||||
if (natKeys != null && !natKeys.isEmpty()) {
|
||||
if (natLog.isDebugEnabled()) {
|
||||
natLog.debug(" PUT ALL {}({}, {})", cacheName, naturalKey, natKeys.keySet());
|
||||
}
|
||||
naturalKeyCache.putAll(natKeys);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the bean into the bean cache.
|
||||
*/
|
||||
* Put the bean into the bean cache.
|
||||
*/
|
||||
void beanCachePutDirect(EntityBean bean) {
|
||||
|
||||
CachedBeanData beanData = beanExtractData(desc, bean);
|
||||
@@ -494,6 +542,9 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (beanLog.isTraceEnabled()) {
|
||||
beanLog.trace(" GET {}({}) - hit", cacheName, id);
|
||||
}
|
||||
return convertToBean(id, readOnly, context, data);
|
||||
}
|
||||
|
||||
@@ -558,9 +609,6 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
ebi.setPersistenceContext(context);
|
||||
desc.contextPut(context, id, bean);
|
||||
|
||||
if (beanLog.isTraceEnabled()) {
|
||||
beanLog.trace(" GET {}({}) - hit", cacheName, id);
|
||||
}
|
||||
if (desc.isReadAuditing()) {
|
||||
desc.readAuditBean("l2", "", bean);
|
||||
}
|
||||
|
||||
@@ -155,9 +155,7 @@ public class DefaultOrmQueryEngine implements OrmQueryEngine {
|
||||
// load the individual beans into the bean cache
|
||||
BeanDescriptor<T> descriptor = request.getBeanDescriptor();
|
||||
Collection<T> c = result.getActualDetails();
|
||||
for (T bean : c) {
|
||||
descriptor.cacheBeanPut((EntityBean) bean);
|
||||
}
|
||||
descriptor.cacheBeanPutAll(c);
|
||||
}
|
||||
|
||||
request.mergeCacheHits(result);
|
||||
|
||||
Reference in New Issue
Block a user