移除continuousid功能
This commit is contained in:
@@ -51,22 +51,11 @@ public @interface Cacheable {
|
|||||||
*/
|
*/
|
||||||
int interval() default 0;
|
int interval() default 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* (Optional) DataSource是否直接返回对象的真实引用, 而不是copy一份
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
boolean direct() default false;
|
boolean direct() default false;
|
||||||
|
|
||||||
/**
|
|
||||||
* (Optional) 主键字段是否同时满足: 1、类型为int;2、主键值可为数组下标;3、记录总数有限;<br>
|
|
||||||
* 用于EntityCache的全量数据是否用Array存储,主键值作为数组下标
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
boolean sequent() default true;
|
boolean sequent() default false;
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
boolean continuousid() default false;
|
boolean continuousid() default false;
|
||||||
|
|||||||
@@ -1906,10 +1906,6 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CacheEntryType findEntryType(Type type) {
|
|
||||||
return CacheEntryType.OBJECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum CacheEntryType {
|
public static enum CacheEntryType {
|
||||||
OBJECT, ATOMIC, DOUBLE, SSET, ZSET, LIST, MAP;
|
OBJECT, ATOMIC, DOUBLE, SSET, ZSET, LIST, MAP;
|
||||||
}
|
}
|
||||||
@@ -1958,20 +1954,6 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
return JsonFactory.root().getConvert().convertTo(this);
|
return JsonFactory.root().getConvert().convertTo(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ConvertColumn(ignore = true)
|
|
||||||
// public boolean isListCacheType() {
|
|
||||||
// return cacheType == CacheEntryType.LIST;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @ConvertColumn(ignore = true)
|
|
||||||
// public boolean isSetCacheType() {
|
|
||||||
// return cacheType == CacheEntryType.SSET || cacheType == CacheEntryType.ZSET;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @ConvertColumn(ignore = true)
|
|
||||||
// public boolean isMapCacheType() {
|
|
||||||
// return cacheType == CacheEntryType.MAP;
|
|
||||||
// }
|
|
||||||
@ConvertColumn(ignore = true)
|
@ConvertColumn(ignore = true)
|
||||||
public boolean isExpired() {
|
public boolean isExpired() {
|
||||||
return expireMills > 0 && (lastAccessed + expireMills) < System.currentTimeMillis();
|
return expireMills > 0 && (lastAccessed + expireMills) < System.currentTimeMillis();
|
||||||
|
|||||||
@@ -38,9 +38,6 @@ public final class EntityCache<T> {
|
|||||||
// CopyOnWriteArrayList 插入慢、查询快; 10w数据插入需要3.2秒; ConcurrentLinkedQueue 插入快、查询慢;10w数据查询需要 0.062秒, 查询慢40%;
|
// CopyOnWriteArrayList 插入慢、查询快; 10w数据插入需要3.2秒; ConcurrentLinkedQueue 插入快、查询慢;10w数据查询需要 0.062秒, 查询慢40%;
|
||||||
private Collection<T> list = new ConcurrentLinkedQueue();
|
private Collection<T> list = new ConcurrentLinkedQueue();
|
||||||
|
|
||||||
//sequent=true此字段值才有效
|
|
||||||
private T[] array;
|
|
||||||
|
|
||||||
//Flipper.sort转换成Comparator的缓存
|
//Flipper.sort转换成Comparator的缓存
|
||||||
private final Map<String, Comparator<T>> sortComparators = new ConcurrentHashMap<>();
|
private final Map<String, Comparator<T>> sortComparators = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -78,38 +75,23 @@ public final class EntityCache<T> {
|
|||||||
//@Cacheable的定时更新秒数,为0表示不定时更新
|
//@Cacheable的定时更新秒数,为0表示不定时更新
|
||||||
final int interval;
|
final int interval;
|
||||||
|
|
||||||
//@Cacheable的主键字段是否同时满足: 1、类型为int;2、主键值可为数组下标;3、记录总数有限;
|
|
||||||
final boolean sequent;
|
|
||||||
|
|
||||||
//@Cacheable的定时器
|
//@Cacheable的定时器
|
||||||
private ScheduledThreadPoolExecutor scheduler;
|
private ScheduledThreadPoolExecutor scheduler;
|
||||||
|
|
||||||
private CompletableFuture<List<T>> loadFuture;
|
private CompletableFuture<List<T>> loadFuture;
|
||||||
|
|
||||||
public EntityCache(final EntityInfo<T> info, final Cacheable c) {
|
public EntityCache(final EntityInfo<T> info, final Cacheable c) {
|
||||||
this(info, c != null ? c.interval() : 0, c != null && c.direct(), c != null && c.sequent());
|
this(info, c != null ? c.interval() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityCache(final EntityInfo<T> info, final int cacheInterval, final boolean cacheDirect, final boolean cacheContinuousid) {
|
EntityCache(final EntityInfo<T> info, final int cacheInterval) {
|
||||||
this.info = info;
|
this.info = info;
|
||||||
this.interval = cacheInterval < 0 ? 0 : cacheInterval;
|
this.interval = cacheInterval < 0 ? 0 : cacheInterval;
|
||||||
this.sequent = cacheContinuousid && info.getPrimary().type() == int.class;
|
|
||||||
this.type = info.getType();
|
this.type = info.getType();
|
||||||
this.arrayer = info.getArrayer();
|
this.arrayer = info.getArrayer();
|
||||||
this.creator = info.getCreator();
|
this.creator = info.getCreator();
|
||||||
this.primary = info.primary;
|
this.primary = info.primary;
|
||||||
org.redkale.persistence.VirtualEntity ve = info.getType().getAnnotation(org.redkale.persistence.VirtualEntity.class);
|
this.needCopy = true;
|
||||||
boolean direct = cacheDirect;
|
|
||||||
if (!direct) {
|
|
||||||
direct = ve != null && ve.direct();
|
|
||||||
}
|
|
||||||
{ //兼容废弃类
|
|
||||||
org.redkale.source.VirtualEntity ve2 = info.getType().getAnnotation(org.redkale.source.VirtualEntity.class);
|
|
||||||
if (!direct && ve2 != null) {
|
|
||||||
direct = ve2.direct();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.needCopy = !direct;
|
|
||||||
this.newCopier = Copier.create(type, type, (e, c) -> {
|
this.newCopier = Copier.create(type, type, (e, c) -> {
|
||||||
try {
|
try {
|
||||||
return e.getAnnotation(Transient.class) == null && e.getAnnotation(javax.persistence.Transient.class) == null;
|
return e.getAnnotation(Transient.class) == null && e.getAnnotation(javax.persistence.Transient.class) == null;
|
||||||
@@ -147,26 +129,24 @@ public final class EntityCache<T> {
|
|||||||
if (loading.getAndSet(true)) {
|
if (loading.getAndSet(true)) {
|
||||||
return this.loadFuture;
|
return this.loadFuture;
|
||||||
}
|
}
|
||||||
if (info.fullloader == null) {
|
if (info.fullLoader == null) {
|
||||||
this.list = new ConcurrentLinkedQueue();
|
this.list = new ConcurrentLinkedQueue();
|
||||||
this.array = null;
|
|
||||||
this.map = new ConcurrentHashMap();
|
this.map = new ConcurrentHashMap();
|
||||||
this.fullloaded = true;
|
this.fullloaded = true;
|
||||||
loading.set(false);
|
loading.set(false);
|
||||||
return this.loadFuture;
|
return this.loadFuture;
|
||||||
}
|
}
|
||||||
this.fullloaded = false;
|
this.fullloaded = false;
|
||||||
CompletableFuture<List> allFuture = info.fullloader.apply(info.source, info);
|
CompletableFuture<List> allFuture = info.fullLoader.apply(info.source, info);
|
||||||
this.loadFuture = (CompletableFuture) allFuture;
|
this.loadFuture = (CompletableFuture) allFuture;
|
||||||
if (allFuture == null) {
|
if (allFuture == null) {
|
||||||
this.list = new ConcurrentLinkedQueue();
|
this.list = new ConcurrentLinkedQueue();
|
||||||
this.array = null;
|
|
||||||
this.map = new ConcurrentHashMap();
|
this.map = new ConcurrentHashMap();
|
||||||
this.fullloaded = true;
|
this.fullloaded = true;
|
||||||
loading.set(false);
|
loading.set(false);
|
||||||
return this.loadFuture;
|
return this.loadFuture;
|
||||||
}
|
}
|
||||||
if (this.interval > 0 && this.scheduler == null && info.fullloader != null) {
|
if (this.interval > 0 && this.scheduler == null && info.fullLoader != null) {
|
||||||
this.scheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> {
|
this.scheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> {
|
||||||
final Thread t = new Thread(r, "Redkale-EntityCache-" + type.getSimpleName() + "-Thread");
|
final Thread t = new Thread(r, "Redkale-EntityCache-" + type.getSimpleName() + "-Thread");
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
@@ -175,14 +155,13 @@ public final class EntityCache<T> {
|
|||||||
this.scheduler.scheduleAtFixedRate(() -> {
|
this.scheduler.scheduleAtFixedRate(() -> {
|
||||||
try {
|
try {
|
||||||
ConcurrentHashMap newmap2 = new ConcurrentHashMap();
|
ConcurrentHashMap newmap2 = new ConcurrentHashMap();
|
||||||
List<T> all2 = info.fullloader.apply(info.source, info).join();
|
List<T> all2 = info.fullLoader.apply(info.source, info).join();
|
||||||
if (all2 != null) {
|
if (all2 != null) {
|
||||||
all2.stream().filter(x -> x != null).forEach(x -> {
|
all2.stream().filter(x -> x != null).forEach(x -> {
|
||||||
newmap2.put(this.primary.get(x), x);
|
newmap2.put(this.primary.get(x), x);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.list = all2 == null ? new ConcurrentLinkedQueue() : new ConcurrentLinkedQueue(all2);
|
this.list = all2 == null ? new ConcurrentLinkedQueue() : new ConcurrentLinkedQueue(all2);
|
||||||
this.array = transferArray(all2);
|
|
||||||
this.map = newmap2;
|
this.map = newmap2;
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
logger.log(Level.SEVERE, type + " schedule(interval=" + interval + "s) Cacheable error", t);
|
logger.log(Level.SEVERE, type + " schedule(interval=" + interval + "s) Cacheable error", t);
|
||||||
@@ -202,7 +181,6 @@ public final class EntityCache<T> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.list = new ConcurrentLinkedQueue(all);
|
this.list = new ConcurrentLinkedQueue(all);
|
||||||
this.array = transferArray(all);
|
|
||||||
this.map = newmap;
|
this.map = newmap;
|
||||||
this.fullloaded = true;
|
this.fullloaded = true;
|
||||||
loading.set(false);
|
loading.set(false);
|
||||||
@@ -210,24 +188,6 @@ public final class EntityCache<T> {
|
|||||||
return this.loadFuture;
|
return this.loadFuture;
|
||||||
}
|
}
|
||||||
|
|
||||||
private T[] transferArray(List<T> all) {
|
|
||||||
if (sequent && all != null && !all.isEmpty()) {
|
|
||||||
try {
|
|
||||||
int maxid = all.stream().mapToInt(v -> v == null ? 0 : (Integer) primary.get(v)).max().orElse(0);
|
|
||||||
T[] result = arrayer.apply(maxid + 1);
|
|
||||||
for (T v : all) {
|
|
||||||
int index = v == null ? 0 : (Integer) primary.get(v);
|
|
||||||
result[index] = v;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (Exception e) { //主键值可能是负数,导致数组下标异常
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<T> getType() {
|
public Class<T> getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@@ -235,7 +195,6 @@ public final class EntityCache<T> {
|
|||||||
public int clear() {
|
public int clear() {
|
||||||
this.fullloaded = false;
|
this.fullloaded = false;
|
||||||
this.list = new ConcurrentLinkedQueue();
|
this.list = new ConcurrentLinkedQueue();
|
||||||
this.array = null;
|
|
||||||
this.map = new ConcurrentHashMap();
|
this.map = new ConcurrentHashMap();
|
||||||
if (this.scheduler != null) {
|
if (this.scheduler != null) {
|
||||||
this.scheduler.shutdownNow();
|
this.scheduler.shutdownNow();
|
||||||
@@ -284,22 +243,6 @@ public final class EntityCache<T> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sequent && array != null) {
|
|
||||||
T[] array0 = array;
|
|
||||||
T[] result = arrayer.apply(pks.length);
|
|
||||||
if (needCopy) {
|
|
||||||
for (int i = 0; i < result.length; i++) {
|
|
||||||
T rs = array0[(Integer) pks[i]];
|
|
||||||
result[i] = rs == null ? null : newCopier.apply(this.creator.create(), rs);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < result.length; i++) {
|
|
||||||
T rs = array0[(Integer) pks[i]];
|
|
||||||
result[i] = rs == null ? null : rs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
T[] result = arrayer.apply(pks.length);
|
T[] result = arrayer.apply(pks.length);
|
||||||
for (int i = 0; i < result.length; i++) {
|
for (int i = 0; i < result.length; i++) {
|
||||||
T rs = map.get(pks[i]);
|
T rs = map.get(pks[i]);
|
||||||
@@ -803,9 +746,6 @@ public final class EntityCache<T> {
|
|||||||
T old = this.map.putIfAbsent(this.primary.get(rs), rs);
|
T old = this.map.putIfAbsent(this.primary.get(rs), rs);
|
||||||
if (old == null) {
|
if (old == null) {
|
||||||
this.list.add(rs);
|
this.list.add(rs);
|
||||||
if (sequent) {
|
|
||||||
this.array = transferArray(new ArrayList<>(this.list));
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.WARNING, this.type + " cache repeat insert data: " + entity);
|
logger.log(Level.WARNING, this.type + " cache repeat insert data: " + entity);
|
||||||
@@ -822,9 +762,6 @@ public final class EntityCache<T> {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
this.list.remove(rs);
|
this.list.remove(rs);
|
||||||
if (sequent) {
|
|
||||||
this.array[(Integer) primary.get(rs)] = null;
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,9 +788,6 @@ public final class EntityCache<T> {
|
|||||||
ids[++i] = this.primary.get(t);
|
ids[++i] = this.primary.get(t);
|
||||||
this.map.remove(ids[i]);
|
this.map.remove(ids[i]);
|
||||||
this.list.remove(t);
|
this.list.remove(t);
|
||||||
if (sequent) {
|
|
||||||
this.array[(Integer) primary.get(t)] = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ public final class EntityInfo<T> {
|
|||||||
final DataSource source;
|
final DataSource source;
|
||||||
|
|
||||||
//全量数据的加载器
|
//全量数据的加载器
|
||||||
final BiFunction<DataSource, EntityInfo, CompletableFuture<List>> fullloader;
|
final BiFunction<DataSource, EntityInfo, CompletableFuture<List>> fullLoader;
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -344,9 +344,9 @@ public final class EntityInfo<T> {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, type + " init @VirtualEntity.loader error", e);
|
logger.log(Level.SEVERE, type + " init @VirtualEntity.loader error", e);
|
||||||
}
|
}
|
||||||
this.fullloader = loader;
|
this.fullLoader = loader;
|
||||||
} else {
|
} else {
|
||||||
this.fullloader = fullloader;
|
this.fullLoader = fullloader;
|
||||||
if (tableName0 != null && !tableName0.isEmpty() && tableName0.indexOf('.') >= 0) {
|
if (tableName0 != null && !tableName0.isEmpty() && tableName0.indexOf('.') >= 0) {
|
||||||
throw new SourceException(type + " have illegal table.name on @Table");
|
throw new SourceException(type + " have illegal table.name on @Table");
|
||||||
}
|
}
|
||||||
@@ -687,10 +687,7 @@ public final class EntityInfo<T> {
|
|||||||
Cacheable c1 = type.getAnnotation(Cacheable.class);
|
Cacheable c1 = type.getAnnotation(Cacheable.class);
|
||||||
javax.persistence.Cacheable c2 = type.getAnnotation(javax.persistence.Cacheable.class);
|
javax.persistence.Cacheable c2 = type.getAnnotation(javax.persistence.Cacheable.class);
|
||||||
if (this.table == null || (!cacheForbidden && c1 != null && c1.value()) || (!cacheForbidden && c2 != null && c2.value())) {
|
if (this.table == null || (!cacheForbidden && c1 != null && c1.value()) || (!cacheForbidden && c2 != null && c2.value())) {
|
||||||
this.cache = new EntityCache<>(this,
|
this.cache = new EntityCache<>(this, c1 == null ? (c2 == null ? 0 : c2.interval()) : c1.interval());
|
||||||
c1 == null ? (c2 == null ? 0 : c2.interval()) : c1.interval(),
|
|
||||||
c1 == null ? (c2 == null ? false : c2.direct()) : c1.direct(),
|
|
||||||
c1 == null ? false : c1.sequent());
|
|
||||||
} else {
|
} else {
|
||||||
this.cache = null;
|
this.cache = null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user