CacheManager
This commit is contained in:
@@ -5,14 +5,7 @@ package org.redkale.caching;
|
|||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import org.redkale.annotation.Nonnull;
|
|
||||||
import org.redkale.annotation.Nullable;
|
|
||||||
import org.redkale.source.CacheMemorySource;
|
|
||||||
import org.redkale.source.CacheSource;
|
|
||||||
import org.redkale.util.TypeToken;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* //TODO 待实现
|
* //TODO 待实现
|
||||||
@@ -24,28 +17,7 @@ import org.redkale.util.TypeToken;
|
|||||||
*
|
*
|
||||||
* @since 2.8.0
|
* @since 2.8.0
|
||||||
*/
|
*/
|
||||||
public class CacheManager {
|
public interface CacheManager {
|
||||||
|
|
||||||
//缓存配置项
|
|
||||||
protected final CacheConfig config;
|
|
||||||
|
|
||||||
//数据类型与CacheValue泛型的对应关系
|
|
||||||
private final ConcurrentHashMap<Type, Type> cacheValueTypes = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
//本地缓存Source
|
|
||||||
protected final CacheSource localSource = new CacheMemorySource("caching");
|
|
||||||
|
|
||||||
//远程缓存Source
|
|
||||||
protected CacheSource remoteSource;
|
|
||||||
|
|
||||||
protected CacheManager(@Nonnull CacheConfig config, @Nullable CacheSource remoteSource) {
|
|
||||||
this.config = Objects.requireNonNull(config);
|
|
||||||
this.remoteSource = remoteSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CacheManager create(@Nonnull CacheConfig config, @Nullable CacheSource remoteSource) {
|
|
||||||
return new CacheManager(config, remoteSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------- 本地缓存 --------------------------------------
|
//-------------------------------------- 本地缓存 --------------------------------------
|
||||||
/**
|
/**
|
||||||
@@ -58,9 +30,7 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 数据值
|
* @return 数据值
|
||||||
*/
|
*/
|
||||||
public <T> T localGet(final String map, final String key, final Type type) {
|
public <T> T localGet(final String map, final String key, final Type type);
|
||||||
return get(localSource, map, key, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 本地获取字符串缓存数据, 过期返回null
|
* 本地获取字符串缓存数据, 过期返回null
|
||||||
@@ -70,8 +40,8 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 数据值
|
* @return 数据值
|
||||||
*/
|
*/
|
||||||
public final String localGetString(final String map, final String key) {
|
default String localGetString(final String map, final String key) {
|
||||||
return get(localSource, map, key, String.class);
|
return localGet(map, key, String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,9 +54,7 @@ public class CacheManager {
|
|||||||
* @param value 数据值
|
* @param value 数据值
|
||||||
* @param expire 过期时长,为null表示永不过期
|
* @param expire 过期时长,为null表示永不过期
|
||||||
*/
|
*/
|
||||||
public <T> void localSet(final String map, final String key, final Type type, final T value, Duration expire) {
|
public <T> void localSet(String map, String key, Type type, T value, Duration expire);
|
||||||
set(localSource, map, key, type, value, expire);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 本地缓存字符串数据
|
* 本地缓存字符串数据
|
||||||
@@ -96,8 +64,8 @@ public class CacheManager {
|
|||||||
* @param value 数据值
|
* @param value 数据值
|
||||||
* @param expire 过期时长,为null表示永不过期
|
* @param expire 过期时长,为null表示永不过期
|
||||||
*/
|
*/
|
||||||
public void localSetString(final String map, final String key, final String value, Duration expire) {
|
default void localSetString(final String map, final String key, final String value, Duration expire) {
|
||||||
set(localSource, map, key, String.class, value, expire);
|
localSet(map, key, String.class, value, expire);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,9 +76,7 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 删除数量
|
* @return 删除数量
|
||||||
*/
|
*/
|
||||||
public long localDel(String map, String key) {
|
public long localDel(String map, String key);
|
||||||
return del(localSource, map, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------- 远程缓存 --------------------------------------
|
//-------------------------------------- 远程缓存 --------------------------------------
|
||||||
/**
|
/**
|
||||||
@@ -123,8 +89,18 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 数据值
|
* @return 数据值
|
||||||
*/
|
*/
|
||||||
public <T> T remoteGet(final String map, final String key, final Type type) {
|
public <T> T remoteGet(final String map, final String key, final Type type);
|
||||||
return get(remoteSource, map, key, type);
|
|
||||||
|
/**
|
||||||
|
* 远程获取字符串缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
default String remoteGetString(final String map, final String key) {
|
||||||
|
return remoteGet(map, key, String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -137,21 +113,7 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 数据值
|
* @return 数据值
|
||||||
*/
|
*/
|
||||||
public <T> CompletableFuture<T> remoteGetAsync(final String map, final String key, final Type type) {
|
public <T> CompletableFuture<T> remoteGetAsync(final String map, final String key, final Type type);
|
||||||
return getAsync(remoteSource, map, key, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 远程获取字符串缓存数据, 过期返回null
|
|
||||||
*
|
|
||||||
* @param map 缓存hash
|
|
||||||
* @param key 缓存键
|
|
||||||
*
|
|
||||||
* @return 数据值
|
|
||||||
*/
|
|
||||||
public final String remoteGetString(final String map, final String key) {
|
|
||||||
return get(remoteSource, map, key, String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程异步获取字符串缓存数据, 过期返回null
|
* 远程异步获取字符串缓存数据, 过期返回null
|
||||||
@@ -161,8 +123,8 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 数据值
|
* @return 数据值
|
||||||
*/
|
*/
|
||||||
public final CompletableFuture<String> remoteGetStringAsync(final String map, final String key) {
|
default CompletableFuture<String> remoteGetStringAsync(final String map, final String key) {
|
||||||
return getAsync(remoteSource, map, key, String.class);
|
return remoteGetAsync(map, key, String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,8 +137,18 @@ public class CacheManager {
|
|||||||
* @param value 数据值
|
* @param value 数据值
|
||||||
* @param expire 过期时长,为null表示永不过期
|
* @param expire 过期时长,为null表示永不过期
|
||||||
*/
|
*/
|
||||||
public <T> void remoteSet(final String map, final String key, final Type type, final T value, Duration expire) {
|
public <T> void remoteSet(final String map, final String key, final Type type, final T value, Duration expire);
|
||||||
set(remoteSource, map, key, type, value, expire);
|
|
||||||
|
/**
|
||||||
|
* 远程缓存字符串数据
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param value 数据值
|
||||||
|
* @param expire 过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
default void remoteSetString(final String map, final String key, final String value, Duration expire) {
|
||||||
|
remoteSet(map, key, String.class, value, expire);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -189,21 +161,7 @@ public class CacheManager {
|
|||||||
* @param value 数据值
|
* @param value 数据值
|
||||||
* @param expire 过期时长,为null表示永不过期
|
* @param expire 过期时长,为null表示永不过期
|
||||||
*/
|
*/
|
||||||
public <T> CompletableFuture<Void> remoteSetAsync(final String map, final String key, final Type type, final T value, Duration expire) {
|
public <T> CompletableFuture<Void> remoteSetAsync(String map, String key, Type type, T value, Duration expire);
|
||||||
return setAsync(remoteSource, map, key, type, value, expire);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 远程缓存字符串数据
|
|
||||||
*
|
|
||||||
* @param map 缓存hash
|
|
||||||
* @param key 缓存键
|
|
||||||
* @param value 数据值
|
|
||||||
* @param expire 过期时长,为null表示永不过期
|
|
||||||
*/
|
|
||||||
public void remoteSetString(final String map, final String key, final String value, Duration expire) {
|
|
||||||
set(remoteSource, map, key, String.class, value, expire);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程异步缓存字符串数据
|
* 远程异步缓存字符串数据
|
||||||
@@ -213,8 +171,8 @@ public class CacheManager {
|
|||||||
* @param value 数据值
|
* @param value 数据值
|
||||||
* @param expire 过期时长,为null表示永不过期
|
* @param expire 过期时长,为null表示永不过期
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<Void> remoteSetStringAsync(final String map, final String key, final String value, Duration expire) {
|
default CompletableFuture<Void> remoteSetStringAsync(final String map, final String key, final String value, Duration expire) {
|
||||||
return setAsync(remoteSource, map, key, String.class, value, expire);
|
return remoteSetAsync(map, key, String.class, value, expire);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -225,9 +183,7 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 删除数量
|
* @return 删除数量
|
||||||
*/
|
*/
|
||||||
public long remoteDel(String map, String key) {
|
public long remoteDel(String map, String key);
|
||||||
return del(remoteSource, map, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程异步删除缓存数据
|
* 远程异步删除缓存数据
|
||||||
@@ -237,9 +193,7 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 删除数量
|
* @return 删除数量
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<Long> remoteDelAsync(String map, String key) {
|
public CompletableFuture<Long> remoteDelAsync(String map, String key);
|
||||||
return delAsync(remoteSource, map, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------- both缓存 --------------------------------------
|
//-------------------------------------- both缓存 --------------------------------------
|
||||||
/**
|
/**
|
||||||
@@ -252,9 +206,18 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 数据值
|
* @return 数据值
|
||||||
*/
|
*/
|
||||||
public <T> T bothGet(final String map, final String key, final Type type) {
|
public <T> T bothGet(final String map, final String key, final Type type);
|
||||||
T val = get(localSource, map, key, type);
|
|
||||||
return val == null ? get(remoteSource, map, key, type) : val;
|
/**
|
||||||
|
* 远程获取字符串缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
default String bothGetString(final String map, final String key) {
|
||||||
|
return bothGet(map, key, String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,25 +230,7 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 数据值
|
* @return 数据值
|
||||||
*/
|
*/
|
||||||
public <T> CompletableFuture<T> bothGetAsync(final String map, final String key, final Type type) {
|
public <T> CompletableFuture<T> bothGetAsync(final String map, final String key, final Type type);
|
||||||
T val = get(localSource, map, key, type);
|
|
||||||
if (val != null) {
|
|
||||||
return CompletableFuture.completedFuture(val);
|
|
||||||
}
|
|
||||||
return getAsync(remoteSource, map, key, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 远程获取字符串缓存数据, 过期返回null
|
|
||||||
*
|
|
||||||
* @param map 缓存hash
|
|
||||||
* @param key 缓存键
|
|
||||||
*
|
|
||||||
* @return 数据值
|
|
||||||
*/
|
|
||||||
public final String bothGetString(final String map, final String key) {
|
|
||||||
return bothGet(map, key, String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程异步获取字符串缓存数据, 过期返回null
|
* 远程异步获取字符串缓存数据, 过期返回null
|
||||||
@@ -295,7 +240,7 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 数据值
|
* @return 数据值
|
||||||
*/
|
*/
|
||||||
public final CompletableFuture<String> bothGetStringAsync(final String map, final String key) {
|
default CompletableFuture<String> bothGetStringAsync(final String map, final String key) {
|
||||||
return bothGetAsync(map, key, String.class);
|
return bothGetAsync(map, key, String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,9 +255,19 @@ public class CacheManager {
|
|||||||
* @param localExpire 本地过期时长,为null表示永不过期
|
* @param localExpire 本地过期时长,为null表示永不过期
|
||||||
* @param remoteExpire 远程过期时长,为null表示永不过期
|
* @param remoteExpire 远程过期时长,为null表示永不过期
|
||||||
*/
|
*/
|
||||||
public <T> void bothSet(final String map, final String key, final Type type, final T value, Duration localExpire, Duration remoteExpire) {
|
public <T> void bothSet(final String map, final String key, final Type type, final T value, Duration localExpire, Duration remoteExpire);
|
||||||
set(localSource, map, key, type, value, localExpire);
|
|
||||||
set(remoteSource, map, key, type, value, remoteExpire);
|
/**
|
||||||
|
* 远程缓存字符串数据
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param value 数据值
|
||||||
|
* @param localExpire 本地过期时长,为null表示永不过期
|
||||||
|
* @param remoteExpire 远程过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
default void bothSetString(final String map, final String key, final String value, Duration localExpire, Duration remoteExpire) {
|
||||||
|
bothSet(map, key, String.class, value, localExpire, remoteExpire);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -326,23 +281,7 @@ public class CacheManager {
|
|||||||
* @param localExpire 本地过期时长,为null表示永不过期
|
* @param localExpire 本地过期时长,为null表示永不过期
|
||||||
* @param remoteExpire 远程过期时长,为null表示永不过期
|
* @param remoteExpire 远程过期时长,为null表示永不过期
|
||||||
*/
|
*/
|
||||||
public <T> CompletableFuture<Void> bothSetAsync(final String map, final String key, final Type type, final T value, Duration localExpire, Duration remoteExpire) {
|
public <T> CompletableFuture<Void> bothSetAsync(String map, String key, Type type, T value, Duration localExpire, Duration remoteExpire);
|
||||||
set(localSource, map, key, type, value, localExpire);
|
|
||||||
return setAsync(remoteSource, map, key, type, value, remoteExpire);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 远程缓存字符串数据
|
|
||||||
*
|
|
||||||
* @param map 缓存hash
|
|
||||||
* @param key 缓存键
|
|
||||||
* @param value 数据值
|
|
||||||
* @param localExpire 本地过期时长,为null表示永不过期
|
|
||||||
* @param remoteExpire 远程过期时长,为null表示永不过期
|
|
||||||
*/
|
|
||||||
public void bothSetString(final String map, final String key, final String value, Duration localExpire, Duration remoteExpire) {
|
|
||||||
bothSet(map, key, String.class, value, localExpire, remoteExpire);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程异步缓存字符串数据
|
* 远程异步缓存字符串数据
|
||||||
@@ -353,7 +292,7 @@ public class CacheManager {
|
|||||||
* @param localExpire 本地过期时长,为null表示永不过期
|
* @param localExpire 本地过期时长,为null表示永不过期
|
||||||
* @param remoteExpire 远程过期时长,为null表示永不过期
|
* @param remoteExpire 远程过期时长,为null表示永不过期
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<Void> bothSetStringAsync(final String map, final String key, final String value, Duration localExpire, Duration remoteExpire) {
|
default CompletableFuture<Void> bothSetStringAsync(String map, String key, String value, Duration localExpire, Duration remoteExpire) {
|
||||||
return bothSetAsync(map, key, String.class, value, localExpire, remoteExpire);
|
return bothSetAsync(map, key, String.class, value, localExpire, remoteExpire);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,10 +304,7 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 删除数量
|
* @return 删除数量
|
||||||
*/
|
*/
|
||||||
public long bothDel(String map, String key) {
|
public long bothDel(String map, String key);
|
||||||
del(localSource, map, key);
|
|
||||||
return del(remoteSource, map, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程异步删除缓存数据
|
* 远程异步删除缓存数据
|
||||||
@@ -378,124 +314,6 @@ public class CacheManager {
|
|||||||
*
|
*
|
||||||
* @return 删除数量
|
* @return 删除数量
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<Long> bothDelAsync(String map, String key) {
|
public CompletableFuture<Long> bothDelAsync(String map, String key);
|
||||||
del(localSource, map, key);
|
|
||||||
return delAsync(remoteSource, map, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------- 内部方法 --------------------------------------
|
|
||||||
/**
|
|
||||||
* 获取缓存数据, 过期返回null
|
|
||||||
*
|
|
||||||
* @param <T> 泛型
|
|
||||||
* @param source 缓存源
|
|
||||||
* @param map 缓存hash
|
|
||||||
* @param key 缓存键
|
|
||||||
* @param type 数据类型
|
|
||||||
*
|
|
||||||
* @return 数据值
|
|
||||||
*/
|
|
||||||
protected <T> T get(final CacheSource source, final String map, final String key, final Type type) {
|
|
||||||
CacheValue<T> val = source.hget(map, key, loadCacheType(type));
|
|
||||||
return val != null && !val.isExpired() ? val.getValue() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取缓存数据, 过期返回null
|
|
||||||
*
|
|
||||||
* @param <T> 泛型
|
|
||||||
* @param source 缓存源
|
|
||||||
* @param map 缓存hash
|
|
||||||
* @param key 缓存键
|
|
||||||
* @param type 数据类型
|
|
||||||
*
|
|
||||||
* @return 数据值
|
|
||||||
*/
|
|
||||||
protected <T> CompletableFuture<T> getAsync(final CacheSource source, final String map, final String key, final Type type) {
|
|
||||||
return source.hgetAsync(map, key, loadCacheType(type)).thenApply(v -> {
|
|
||||||
CacheValue<T> val = (CacheValue) v;
|
|
||||||
return val != null && !val.isExpired() ? (T) val.getValue() : null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存数据
|
|
||||||
*
|
|
||||||
* @param <T> 泛型
|
|
||||||
* @param source 缓存源
|
|
||||||
* @param map 缓存hash
|
|
||||||
* @param key 缓存键
|
|
||||||
* @param type 数据类型
|
|
||||||
* @param value 数据值
|
|
||||||
* @param expire 过期时长,为null表示永不过期
|
|
||||||
*/
|
|
||||||
protected <T> void set(final CacheSource source, final String map, final String key, final Type type, final T value, Duration expire) {
|
|
||||||
Type t = loadCacheType(type, value);
|
|
||||||
source.hset(map, key, t, CacheValue.create(value, expire));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存数据
|
|
||||||
*
|
|
||||||
* @param <T> 泛型
|
|
||||||
* @param source 缓存源
|
|
||||||
* @param map 缓存hash
|
|
||||||
* @param key 缓存键
|
|
||||||
* @param type 数据类型
|
|
||||||
* @param value 数据值
|
|
||||||
* @param expire 过期时长,为null表示永不过期
|
|
||||||
*/
|
|
||||||
protected <T> CompletableFuture<Void> setAsync(final CacheSource source, final String map, final String key, final Type type, final T value, Duration expire) {
|
|
||||||
Type t = loadCacheType(type, value);
|
|
||||||
return source.hsetAsync(map, key, t, CacheValue.create(value, expire));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除缓存数据
|
|
||||||
*
|
|
||||||
* @param source 缓存源
|
|
||||||
* @param map 缓存hash
|
|
||||||
* @param key 缓存键
|
|
||||||
*
|
|
||||||
* @return 删除数量
|
|
||||||
*/
|
|
||||||
protected long del(final CacheSource source, String map, String key) {
|
|
||||||
return source.hdel(map, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除缓存数据
|
|
||||||
*
|
|
||||||
* @param source 缓存源
|
|
||||||
* @param map 缓存hash
|
|
||||||
* @param key 缓存键
|
|
||||||
*
|
|
||||||
* @return 删除数量
|
|
||||||
*/
|
|
||||||
protected CompletableFuture<Long> delAsync(final CacheSource source, String map, String key) {
|
|
||||||
return source.hdelAsync(map, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建数据类型创建对应CacheValue泛型
|
|
||||||
*
|
|
||||||
* @param type 数据类型,为null则取value的类型
|
|
||||||
* @param value 数据值
|
|
||||||
*
|
|
||||||
* @return CacheValue泛型
|
|
||||||
*/
|
|
||||||
protected Type loadCacheType(Type type, final Object value) {
|
|
||||||
return loadCacheType(type == null ? value.getClass() : type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建数据类型创建对应CacheValue泛型
|
|
||||||
*
|
|
||||||
* @param type 数据类型
|
|
||||||
*
|
|
||||||
* @return CacheValue泛型
|
|
||||||
*/
|
|
||||||
protected Type loadCacheType(Type type) {
|
|
||||||
return cacheValueTypes.computeIfAbsent(type, t -> TypeToken.createParameterizedType(null, CacheValue.class, type));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
457
src/main/java/org/redkale/caching/CacheManagerService.java
Normal file
457
src/main/java/org/redkale/caching/CacheManagerService.java
Normal file
@@ -0,0 +1,457 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.redkale.caching;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import org.redkale.annotation.AutoLoad;
|
||||||
|
import org.redkale.annotation.Component;
|
||||||
|
import org.redkale.annotation.Nonnull;
|
||||||
|
import org.redkale.annotation.Nullable;
|
||||||
|
import org.redkale.annotation.ResourceType;
|
||||||
|
import org.redkale.service.Local;
|
||||||
|
import org.redkale.service.Service;
|
||||||
|
import org.redkale.source.CacheMemorySource;
|
||||||
|
import org.redkale.source.CacheSource;
|
||||||
|
import org.redkale.util.AnyValue;
|
||||||
|
import org.redkale.util.TypeToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
*/
|
||||||
|
@Local
|
||||||
|
@Component
|
||||||
|
@AutoLoad(false)
|
||||||
|
@ResourceType(CacheManager.class)
|
||||||
|
public class CacheManagerService implements CacheManager, Service {
|
||||||
|
|
||||||
|
//缓存配置项
|
||||||
|
protected final CacheConfig config;
|
||||||
|
|
||||||
|
//数据类型与CacheValue泛型的对应关系
|
||||||
|
private final ConcurrentHashMap<Type, Type> cacheValueTypes = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
//本地缓存Source
|
||||||
|
protected final CacheMemorySource localSource = new CacheMemorySource("caching");
|
||||||
|
|
||||||
|
//远程缓存Source
|
||||||
|
protected CacheSource remoteSource;
|
||||||
|
|
||||||
|
protected CacheManagerService(@Nonnull CacheConfig config, @Nullable CacheSource remoteSource) {
|
||||||
|
this.config = Objects.requireNonNull(config);
|
||||||
|
this.remoteSource = remoteSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CacheManagerService create(@Nonnull CacheConfig config, @Nullable CacheSource remoteSource) {
|
||||||
|
return new CacheManagerService(config, remoteSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(AnyValue conf) {
|
||||||
|
this.localSource.init(conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy(AnyValue conf) {
|
||||||
|
this.localSource.destroy(conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------- 本地缓存 --------------------------------------
|
||||||
|
/**
|
||||||
|
* 本地获取缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> T localGet(final String map, final String key, final Type type) {
|
||||||
|
return get(localSource, map, key, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地缓存数据
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
* @param value 数据值
|
||||||
|
* @param expire 过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> void localSet(String map, String key, Type type, T value, Duration expire) {
|
||||||
|
set(localSource, map, key, type, value, expire);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地删除缓存数据
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 删除数量
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long localDel(String map, String key) {
|
||||||
|
return del(localSource, map, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------- 远程缓存 --------------------------------------
|
||||||
|
/**
|
||||||
|
* 远程获取缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> T remoteGet(final String map, final String key, final Type type) {
|
||||||
|
return get(remoteSource, map, key, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程异步获取缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> CompletableFuture<T> remoteGetAsync(final String map, final String key, final Type type) {
|
||||||
|
return getAsync(remoteSource, map, key, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程缓存数据
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
* @param value 数据值
|
||||||
|
* @param expire 过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
public <T> void remoteSet(final String map, final String key, final Type type, final T value, Duration expire) {
|
||||||
|
set(remoteSource, map, key, type, value, expire);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程异步缓存数据
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
* @param value 数据值
|
||||||
|
* @param expire 过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
public <T> CompletableFuture<Void> remoteSetAsync(String map, String key, Type type, T value, Duration expire) {
|
||||||
|
return setAsync(remoteSource, map, key, type, value, expire);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程删除缓存数据
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 删除数量
|
||||||
|
*/
|
||||||
|
public long remoteDel(String map, String key) {
|
||||||
|
return del(remoteSource, map, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程异步删除缓存数据
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 删除数量
|
||||||
|
*/
|
||||||
|
public CompletableFuture<Long> remoteDelAsync(String map, String key) {
|
||||||
|
return delAsync(remoteSource, map, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------- both缓存 --------------------------------------
|
||||||
|
/**
|
||||||
|
* 远程获取缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
public <T> T bothGet(final String map, final String key, final Type type) {
|
||||||
|
T val = get(localSource, map, key, type);
|
||||||
|
return val == null ? get(remoteSource, map, key, type) : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程异步获取缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
public <T> CompletableFuture<T> bothGetAsync(final String map, final String key, final Type type) {
|
||||||
|
T val = get(localSource, map, key, type);
|
||||||
|
if (val != null) {
|
||||||
|
return CompletableFuture.completedFuture(val);
|
||||||
|
}
|
||||||
|
return getAsync(remoteSource, map, key, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程获取字符串缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
public final String bothGetString(final String map, final String key) {
|
||||||
|
return bothGet(map, key, String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程异步获取字符串缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
public final CompletableFuture<String> bothGetStringAsync(final String map, final String key) {
|
||||||
|
return bothGetAsync(map, key, String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程缓存数据
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
* @param value 数据值
|
||||||
|
* @param localExpire 本地过期时长,为null表示永不过期
|
||||||
|
* @param remoteExpire 远程过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
public <T> void bothSet(final String map, final String key, final Type type, final T value, Duration localExpire, Duration remoteExpire) {
|
||||||
|
set(localSource, map, key, type, value, localExpire);
|
||||||
|
set(remoteSource, map, key, type, value, remoteExpire);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程异步缓存数据
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
* @param value 数据值
|
||||||
|
* @param localExpire 本地过期时长,为null表示永不过期
|
||||||
|
* @param remoteExpire 远程过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
public <T> CompletableFuture<Void> bothSetAsync(String map, String key, Type type, T value, Duration localExpire, Duration remoteExpire) {
|
||||||
|
set(localSource, map, key, type, value, localExpire);
|
||||||
|
return setAsync(remoteSource, map, key, type, value, remoteExpire);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程缓存字符串数据
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param value 数据值
|
||||||
|
* @param localExpire 本地过期时长,为null表示永不过期
|
||||||
|
* @param remoteExpire 远程过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
public void bothSetString(final String map, final String key, final String value, Duration localExpire, Duration remoteExpire) {
|
||||||
|
bothSet(map, key, String.class, value, localExpire, remoteExpire);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程异步缓存字符串数据
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param value 数据值
|
||||||
|
* @param localExpire 本地过期时长,为null表示永不过期
|
||||||
|
* @param remoteExpire 远程过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
public CompletableFuture<Void> bothSetStringAsync(String map, String key, String value, Duration localExpire, Duration remoteExpire) {
|
||||||
|
return bothSetAsync(map, key, String.class, value, localExpire, remoteExpire);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程删除缓存数据
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 删除数量
|
||||||
|
*/
|
||||||
|
public long bothDel(String map, String key) {
|
||||||
|
del(localSource, map, key);
|
||||||
|
return del(remoteSource, map, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程异步删除缓存数据
|
||||||
|
*
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 删除数量
|
||||||
|
*/
|
||||||
|
public CompletableFuture<Long> bothDelAsync(String map, String key) {
|
||||||
|
del(localSource, map, key);
|
||||||
|
return delAsync(remoteSource, map, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------- 内部方法 --------------------------------------
|
||||||
|
/**
|
||||||
|
* 获取缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param source 缓存源
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
protected <T> T get(final CacheSource source, final String map, final String key, final Type type) {
|
||||||
|
CacheValue<T> val = source.hget(map, key, loadCacheType(type));
|
||||||
|
return val != null && !val.isExpired() ? val.getValue() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存数据, 过期返回null
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param source 缓存源
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
*
|
||||||
|
* @return 数据值
|
||||||
|
*/
|
||||||
|
protected <T> CompletableFuture<T> getAsync(final CacheSource source, final String map, final String key, final Type type) {
|
||||||
|
if (source == null) {
|
||||||
|
return CompletableFuture.failedFuture(new NullPointerException(CacheManager.class.getSimpleName() + ".source is null"));
|
||||||
|
}
|
||||||
|
return source.hgetAsync(map, key, loadCacheType(type)).thenApply(v -> {
|
||||||
|
CacheValue<T> val = (CacheValue) v;
|
||||||
|
return val != null && !val.isExpired() ? (T) val.getValue() : null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存数据
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param source 缓存源
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
* @param value 数据值
|
||||||
|
* @param expire 过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
protected <T> void set(CacheSource source, String map, String key, Type type, T value, Duration expire) {
|
||||||
|
Type t = loadCacheType(type, value);
|
||||||
|
source.hset(map, key, t, CacheValue.create(value, expire));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存数据
|
||||||
|
*
|
||||||
|
* @param <T> 泛型
|
||||||
|
* @param source 缓存源
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
* @param type 数据类型
|
||||||
|
* @param value 数据值
|
||||||
|
* @param expire 过期时长,为null表示永不过期
|
||||||
|
*/
|
||||||
|
protected <T> CompletableFuture<Void> setAsync(CacheSource source, String map, String key, Type type, T value, Duration expire) {
|
||||||
|
if (source == null) {
|
||||||
|
return CompletableFuture.failedFuture(new NullPointerException(CacheManager.class.getSimpleName() + ".source is null"));
|
||||||
|
}
|
||||||
|
Type t = loadCacheType(type, value);
|
||||||
|
return source.hsetAsync(map, key, t, CacheValue.create(value, expire));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除缓存数据
|
||||||
|
*
|
||||||
|
* @param source 缓存源
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 删除数量
|
||||||
|
*/
|
||||||
|
protected long del(final CacheSource source, String map, String key) {
|
||||||
|
return source.hdel(map, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除缓存数据
|
||||||
|
*
|
||||||
|
* @param source 缓存源
|
||||||
|
* @param map 缓存hash
|
||||||
|
* @param key 缓存键
|
||||||
|
*
|
||||||
|
* @return 删除数量
|
||||||
|
*/
|
||||||
|
protected CompletableFuture<Long> delAsync(final CacheSource source, String map, String key) {
|
||||||
|
if (source == null) {
|
||||||
|
return CompletableFuture.failedFuture(new NullPointerException(CacheManager.class.getSimpleName() + ".source is null"));
|
||||||
|
}
|
||||||
|
return source.hdelAsync(map, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建数据类型创建对应CacheValue泛型
|
||||||
|
*
|
||||||
|
* @param type 数据类型,为null则取value的类型
|
||||||
|
* @param value 数据值
|
||||||
|
*
|
||||||
|
* @return CacheValue泛型
|
||||||
|
*/
|
||||||
|
protected Type loadCacheType(Type type, final Object value) {
|
||||||
|
return loadCacheType(type == null ? value.getClass() : type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建数据类型创建对应CacheValue泛型
|
||||||
|
*
|
||||||
|
* @param type 数据类型
|
||||||
|
*
|
||||||
|
* @return CacheValue泛型
|
||||||
|
*/
|
||||||
|
protected Type loadCacheType(Type type) {
|
||||||
|
return cacheValueTypes.computeIfAbsent(type, t -> TypeToken.createParameterizedType(null, CacheValue.class, type));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -344,7 +344,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
entry = new CacheEntry(CacheEntryType.OBJECT, key);
|
entry = new CacheEntry(CacheEntryType.OBJECT, key);
|
||||||
container.put(key, entry);
|
container.put(key, entry);
|
||||||
entry.setObjectValue(convert, type, value);
|
entry.setObjectValue(convert == null ? this.convert : convert, type, value);
|
||||||
entry.expireSeconds(expireSeconds);
|
entry.expireSeconds(expireSeconds);
|
||||||
entry.lastAccessed = System.currentTimeMillis();
|
entry.lastAccessed = System.currentTimeMillis();
|
||||||
return true;
|
return true;
|
||||||
@@ -365,7 +365,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
@Override
|
@Override
|
||||||
public <T> T getSet(String key, Convert convert, Type type, T value) {
|
public <T> T getSet(String key, Convert convert, Type type, T value) {
|
||||||
CacheEntry entry = find(key, CacheEntryType.OBJECT);
|
CacheEntry entry = find(key, CacheEntryType.OBJECT);
|
||||||
T old = entry == null ? null : (T) entry.getObjectValue(convert, type);
|
T old = entry == null ? null : (T) entry.getObjectValue(convert == null ? this.convert : convert, type);
|
||||||
set0(key, 0, convert, type, value);
|
set0(key, 0, convert, type, value);
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
@@ -387,7 +387,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
} finally {
|
} finally {
|
||||||
containerLock.unlock();
|
containerLock.unlock();
|
||||||
}
|
}
|
||||||
return entry.getObjectValue(null, type);
|
return entry.getObjectValue(convert, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -411,7 +411,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
entry.lock();
|
entry.lock();
|
||||||
try {
|
try {
|
||||||
entry.setObjectValue(convert, type, value);
|
entry.setObjectValue(convert == null ? this.convert : convert, type, value);
|
||||||
entry.expireSeconds(expireSeconds);
|
entry.expireSeconds(expireSeconds);
|
||||||
entry.lastAccessed = System.currentTimeMillis();
|
entry.lastAccessed = System.currentTimeMillis();
|
||||||
} finally {
|
} finally {
|
||||||
@@ -577,7 +577,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
entry.lock();
|
entry.lock();
|
||||||
try {
|
try {
|
||||||
if (entry.cacheType != CacheEntryType.ATOMIC) {
|
if (entry.cacheType != CacheEntryType.ATOMIC) {
|
||||||
entry.objectValue = new AtomicLong(Long.parseLong(entry.getObjectValue(null, String.class)));
|
entry.objectValue = new AtomicLong(Long.parseLong(entry.getObjectValue(convert, String.class)));
|
||||||
entry.cacheType = CacheEntryType.ATOMIC;
|
entry.cacheType = CacheEntryType.ATOMIC;
|
||||||
}
|
}
|
||||||
return ((AtomicLong) entry.objectValue).addAndGet(num);
|
return ((AtomicLong) entry.objectValue).addAndGet(num);
|
||||||
@@ -610,7 +610,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
entry.lock();
|
entry.lock();
|
||||||
try {
|
try {
|
||||||
if (entry.cacheType != CacheEntryType.DOUBLE) {
|
if (entry.cacheType != CacheEntryType.DOUBLE) {
|
||||||
entry.objectValue = new AtomicLong(Long.parseLong(entry.getObjectValue(null, String.class)));
|
entry.objectValue = new AtomicLong(Long.parseLong(entry.getObjectValue(convert, String.class)));
|
||||||
entry.cacheType = CacheEntryType.DOUBLE;
|
entry.cacheType = CacheEntryType.DOUBLE;
|
||||||
}
|
}
|
||||||
Long v = ((AtomicLong) entry.objectValue).addAndGet(Double.doubleToLongBits(num));
|
Long v = ((AtomicLong) entry.objectValue).addAndGet(Double.doubleToLongBits(num));
|
||||||
@@ -698,24 +698,25 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
if (expireSeconds > 0) {
|
if (expireSeconds > 0) {
|
||||||
entry.expireSeconds(expireSeconds);
|
entry.expireSeconds(expireSeconds);
|
||||||
}
|
}
|
||||||
|
final Convert c = convert == null ? this.convert : convert;
|
||||||
// OBJECT, ATOMIC, DOUBLE, SSET, ZSET, LIST, MAP;
|
// OBJECT, ATOMIC, DOUBLE, SSET, ZSET, LIST, MAP;
|
||||||
switch (entry.cacheType) {
|
switch (entry.cacheType) {
|
||||||
case ATOMIC:
|
case ATOMIC:
|
||||||
return CacheEntry.serialToObj(convert, type, (AtomicLong) entry.objectValue);
|
return CacheEntry.serialToObj(c, type, (AtomicLong) entry.objectValue);
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
return CacheEntry.serialToObj(convert, type, Double.longBitsToDouble(((AtomicLong) entry.objectValue).longValue()));
|
return CacheEntry.serialToObj(c, type, Double.longBitsToDouble(((AtomicLong) entry.objectValue).longValue()));
|
||||||
case SSET:
|
case SSET:
|
||||||
return (T) entry.ssetValue.stream().map(v -> CacheEntry.serialToObj(convert, type, v)).collect(Collectors.toSet());
|
return (T) entry.ssetValue.stream().map(v -> CacheEntry.serialToObj(c, type, v)).collect(Collectors.toSet());
|
||||||
case ZSET:
|
case ZSET:
|
||||||
return (T) entry.zsetValue.stream().map(v -> new CacheScoredValue(v)).collect(Collectors.toSet());
|
return (T) entry.zsetValue.stream().map(v -> new CacheScoredValue(v)).collect(Collectors.toSet());
|
||||||
case LIST:
|
case LIST:
|
||||||
return (T) entry.listValue.stream().map(v -> CacheEntry.serialToObj(convert, type, v)).collect(Collectors.toList());
|
return (T) entry.listValue.stream().map(v -> CacheEntry.serialToObj(c, type, v)).collect(Collectors.toList());
|
||||||
case MAP:
|
case MAP:
|
||||||
LinkedHashMap<String, Object> map = new LinkedHashMap();
|
LinkedHashMap<String, Object> map = new LinkedHashMap();
|
||||||
entry.mapValue.forEach((k, v) -> map.put(k, CacheEntry.serialToObj(convert, type, v)));
|
entry.mapValue.forEach((k, v) -> map.put(k, CacheEntry.serialToObj(c, type, v)));
|
||||||
return (T) map;
|
return (T) map;
|
||||||
default:
|
default:
|
||||||
return entry.getObjectValue(convert, type);
|
return entry.getObjectValue(c, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,7 +804,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
Map map = entry.mapValue;
|
Map map = entry.mapValue;
|
||||||
Serializable val = (Serializable) map.computeIfAbsent(field, f -> new AtomicLong());
|
Serializable val = (Serializable) map.computeIfAbsent(field, f -> new AtomicLong());
|
||||||
if (!(val instanceof AtomicLong)) {
|
if (!(val instanceof AtomicLong)) {
|
||||||
val = CacheEntry.objToSerial(null, AtomicLong.class, val);
|
val = CacheEntry.objToSerial(convert, AtomicLong.class, val);
|
||||||
map.put(field, val);
|
map.put(field, val);
|
||||||
}
|
}
|
||||||
return ((AtomicLong) val).addAndGet(num);
|
return ((AtomicLong) val).addAndGet(num);
|
||||||
@@ -889,7 +890,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
entry.lock();
|
entry.lock();
|
||||||
try {
|
try {
|
||||||
boolean rs = entry.setMapValueIfAbsent(field, convert, type, value) == null;
|
boolean rs = entry.setMapValueIfAbsent(field, convert == null ? this.convert : convert, type, value) == null;
|
||||||
entry.lastAccessed = System.currentTimeMillis();
|
entry.lastAccessed = System.currentTimeMillis();
|
||||||
return rs;
|
return rs;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -932,7 +933,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
List<T> rs = new ArrayList<>(fields.length);
|
List<T> rs = new ArrayList<>(fields.length);
|
||||||
for (String field : fields) {
|
for (String field : fields) {
|
||||||
rs.add(entry.getMapValue(field, null, type));
|
rs.add(entry.getMapValue(field, convert, type));
|
||||||
}
|
}
|
||||||
return rs;
|
return rs;
|
||||||
}
|
}
|
||||||
@@ -949,7 +950,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
return new LinkedHashMap();
|
return new LinkedHashMap();
|
||||||
} else {
|
} else {
|
||||||
Map map = new LinkedHashMap();
|
Map map = new LinkedHashMap();
|
||||||
entry.mapValue.forEach((k, v) -> map.put(k, CacheEntry.serialToObj(null, type, v)));
|
entry.mapValue.forEach((k, v) -> map.put(k, CacheEntry.serialToObj(convert, type, v)));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -965,7 +966,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return new ArrayList();
|
return new ArrayList();
|
||||||
} else {
|
} else {
|
||||||
Stream<T> stream = entry.mapValue.values().stream().map(v -> CacheEntry.serialToObj(null, type, v));
|
Stream<T> stream = entry.mapValue.values().stream().map(v -> CacheEntry.serialToObj(convert, type, v));
|
||||||
return new ArrayList(stream.collect(Collectors.toList()));
|
return new ArrayList(stream.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -987,12 +988,12 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
if (Utility.isEmpty(pattern)) {
|
if (Utility.isEmpty(pattern)) {
|
||||||
Set<Map.Entry<String, Serializable>> set = entry.mapValue.entrySet();
|
Set<Map.Entry<String, Serializable>> set = entry.mapValue.entrySet();
|
||||||
return set.stream()
|
return set.stream()
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, en -> CacheEntry.serialToObj(null, type, en.getValue())));
|
.collect(Collectors.toMap(Map.Entry::getKey, en -> CacheEntry.serialToObj(convert, type, en.getValue())));
|
||||||
} else {
|
} else {
|
||||||
Predicate<String> regx = Pattern.compile(pattern.replace("*", ".*")).asPredicate();
|
Predicate<String> regx = Pattern.compile(pattern.replace("*", ".*")).asPredicate();
|
||||||
Set<Map.Entry<String, Serializable>> set = entry.mapValue.entrySet();
|
Set<Map.Entry<String, Serializable>> set = entry.mapValue.entrySet();
|
||||||
return set.stream().filter(en -> regx.test(en.getKey()))
|
return set.stream().filter(en -> regx.test(en.getKey()))
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, en -> CacheEntry.serialToObj(null, type, en.getValue())));
|
.collect(Collectors.toMap(Map.Entry::getKey, en -> CacheEntry.serialToObj(convert, type, en.getValue())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1028,7 +1029,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
String obj = entry.getMapValue(field, null, String.class);
|
String obj = entry.getMapValue(field, convert, String.class);
|
||||||
return obj == null ? 0L : (long) obj.length();
|
return obj == null ? 0L : (long) obj.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1056,7 +1057,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
entry.lock();
|
entry.lock();
|
||||||
try {
|
try {
|
||||||
entry.setMapValue(field, convert, type, value);
|
entry.setMapValue(field, convert == null ? this.convert : convert, type, value);
|
||||||
entry.lastAccessed = System.currentTimeMillis();
|
entry.lastAccessed = System.currentTimeMillis();
|
||||||
} finally {
|
} finally {
|
||||||
entry.unlock();
|
entry.unlock();
|
||||||
@@ -1110,7 +1111,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
List<Serializable> list = new ArrayList(entry.listValue);
|
List<Serializable> list = new ArrayList(entry.listValue);
|
||||||
int pos = index >= 0 ? index : list.size() + index;
|
int pos = index >= 0 ? index : list.size() + index;
|
||||||
return pos >= list.size() ? null : CacheEntry.serialToObj(null, componentType, list.get(pos));
|
return pos >= list.size() ? null : CacheEntry.serialToObj(convert, componentType, list.get(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1144,7 +1145,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
entry.lock();
|
entry.lock();
|
||||||
Serializable val = CacheEntry.objToSerial(null, componentType, value);
|
Serializable val = CacheEntry.objToSerial(convert, componentType, value);
|
||||||
try {
|
try {
|
||||||
List<Serializable> list = new ArrayList<>(entry.listValue);
|
List<Serializable> list = new ArrayList<>(entry.listValue);
|
||||||
int pos = list.indexOf(pivot);
|
int pos = list.indexOf(pivot);
|
||||||
@@ -1197,7 +1198,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
entry.lock();
|
entry.lock();
|
||||||
try {
|
try {
|
||||||
for (T val : values) {
|
for (T val : values) {
|
||||||
entry.listValue.addFirst(CacheEntry.objToSerial(null, componentType, val));
|
entry.listValue.addFirst(CacheEntry.objToSerial(convert, componentType, val));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
entry.unlock();
|
entry.unlock();
|
||||||
@@ -1219,7 +1220,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
try {
|
try {
|
||||||
ConcurrentLinkedDeque list = entry.listValue;
|
ConcurrentLinkedDeque list = entry.listValue;
|
||||||
for (T val : values) {
|
for (T val : values) {
|
||||||
list.addFirst(CacheEntry.objToSerial(null, componentType, val));
|
list.addFirst(CacheEntry.objToSerial(convert, componentType, val));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
entry.unlock();
|
entry.unlock();
|
||||||
@@ -1239,7 +1240,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
entry.lock();
|
entry.lock();
|
||||||
try {
|
try {
|
||||||
return CacheEntry.serialToObj(null, componentType, entry.listValue.pollFirst());
|
return CacheEntry.serialToObj(convert, componentType, entry.listValue.pollFirst());
|
||||||
} finally {
|
} finally {
|
||||||
entry.unlock();
|
entry.unlock();
|
||||||
}
|
}
|
||||||
@@ -1300,7 +1301,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
entry.lock();
|
entry.lock();
|
||||||
try {
|
try {
|
||||||
return CacheEntry.serialToObj(null, componentType, entry.listValue.pollLast());
|
return CacheEntry.serialToObj(convert, componentType, entry.listValue.pollLast());
|
||||||
} finally {
|
} finally {
|
||||||
entry.unlock();
|
entry.unlock();
|
||||||
}
|
}
|
||||||
@@ -1321,7 +1322,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
try {
|
try {
|
||||||
ConcurrentLinkedDeque<Serializable> list = entry.listValue;
|
ConcurrentLinkedDeque<Serializable> list = entry.listValue;
|
||||||
for (T val : values) {
|
for (T val : values) {
|
||||||
list.add(CacheEntry.objToSerial(null, componentType, val));
|
list.add(CacheEntry.objToSerial(convert, componentType, val));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
entry.unlock();
|
entry.unlock();
|
||||||
@@ -1352,7 +1353,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
try {
|
try {
|
||||||
ConcurrentLinkedDeque<Serializable> list = entry.listValue;
|
ConcurrentLinkedDeque<Serializable> list = entry.listValue;
|
||||||
for (T val : values) {
|
for (T val : values) {
|
||||||
list.add(CacheEntry.objToSerial(null, componentType, val));
|
list.add(CacheEntry.objToSerial(convert, componentType, val));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
entry.unlock();
|
entry.unlock();
|
||||||
@@ -1396,15 +1397,15 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
for (int i = 0; i < Math.abs(count); i++) {
|
for (int i = 0; i < Math.abs(count); i++) {
|
||||||
int index = ThreadLocalRandom.current().nextInt(vals.size());
|
int index = ThreadLocalRandom.current().nextInt(vals.size());
|
||||||
Serializable val = vals.get(index);
|
Serializable val = vals.get(index);
|
||||||
list.add(CacheEntry.serialToObj(null, componentType, val));
|
list.add(CacheEntry.serialToObj(convert, componentType, val));
|
||||||
}
|
}
|
||||||
} else { //不可以重复
|
} else { //不可以重复
|
||||||
if (count >= vals.size()) {
|
if (count >= vals.size()) {
|
||||||
return vals.stream()
|
return vals.stream()
|
||||||
.map(val -> (T) CacheEntry.serialToObj(null, componentType, val)).collect(Collectors.toList());
|
.map(val -> (T) CacheEntry.serialToObj(convert, componentType, val)).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
return vals.subList(0, count).stream()
|
return vals.subList(0, count).stream()
|
||||||
.map(val -> (T) CacheEntry.serialToObj(null, componentType, val)).collect(Collectors.toList());
|
.map(val -> (T) CacheEntry.serialToObj(convert, componentType, val)).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@@ -1423,7 +1424,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
boolean rs = false;
|
boolean rs = false;
|
||||||
entry.lock();
|
entry.lock();
|
||||||
try {
|
try {
|
||||||
Serializable val = CacheEntry.objToSerial(null, componentType, member);
|
Serializable val = CacheEntry.objToSerial(convert, componentType, member);
|
||||||
rs = entry.ssetValue.remove(val);
|
rs = entry.ssetValue.remove(val);
|
||||||
} finally {
|
} finally {
|
||||||
entry.unlock();
|
entry.unlock();
|
||||||
@@ -1444,7 +1445,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
entry2.lock();
|
entry2.lock();
|
||||||
try {
|
try {
|
||||||
entry2.addSsetValue(null, componentType, member);
|
entry2.addSsetValue(convert, componentType, member);
|
||||||
} finally {
|
} finally {
|
||||||
entry2.unlock();
|
entry2.unlock();
|
||||||
}
|
}
|
||||||
@@ -1460,7 +1461,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
@Override
|
@Override
|
||||||
public <T> Set<T> sdiff(final String key, final Type componentType, final String... key2s) {
|
public <T> Set<T> sdiff(final String key, final Type componentType, final String... key2s) {
|
||||||
return sdiff0(key, key2s).stream()
|
return sdiff0(key, key2s).stream()
|
||||||
.map(v -> (T) CacheEntry.serialToObj(null, componentType, v))
|
.map(v -> (T) CacheEntry.serialToObj(convert, componentType, v))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1519,7 +1520,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
@Override
|
@Override
|
||||||
public <T> Set<T> sinter(final String key, final Type componentType, final String... key2s) {
|
public <T> Set<T> sinter(final String key, final Type componentType, final String... key2s) {
|
||||||
return sinter0(key, key2s).stream()
|
return sinter0(key, key2s).stream()
|
||||||
.map(v -> (T) CacheEntry.serialToObj(null, componentType, v))
|
.map(v -> (T) CacheEntry.serialToObj(convert, componentType, v))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1587,7 +1588,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
@Override
|
@Override
|
||||||
public <T> Set<T> sunion(final String key, final Type componentType, final String... key2s) {
|
public <T> Set<T> sunion(final String key, final Type componentType, final String... key2s) {
|
||||||
return sunion0(key, key2s).stream()
|
return sunion0(key, key2s).stream()
|
||||||
.map(v -> (T) CacheEntry.serialToObj(null, componentType, v))
|
.map(v -> (T) CacheEntry.serialToObj(convert, componentType, v))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1650,7 +1651,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
return new LinkedHashSet<>();
|
return new LinkedHashSet<>();
|
||||||
}
|
}
|
||||||
return entry.ssetValue.stream()
|
return entry.ssetValue.stream()
|
||||||
.map(v -> (T) CacheEntry.serialToObj(null, componentType, v))
|
.map(v -> (T) CacheEntry.serialToObj(convert, componentType, v))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1666,7 +1667,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
CacheEntry entry = find(key, CacheEntryType.SSET);
|
CacheEntry entry = find(key, CacheEntryType.SSET);
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
map.put(key, entry.ssetValue.stream()
|
map.put(key, entry.ssetValue.stream()
|
||||||
.map(v -> (T) CacheEntry.serialToObj(null, componentType, v))
|
.map(v -> (T) CacheEntry.serialToObj(convert, componentType, v))
|
||||||
.collect(Collectors.toSet()));
|
.collect(Collectors.toSet()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1718,7 +1719,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
entry.lock();
|
entry.lock();
|
||||||
try {
|
try {
|
||||||
for (T val : values) {
|
for (T val : values) {
|
||||||
entry.addSsetValue(null, componentType, val);
|
entry.addSsetValue(convert, componentType, val);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
entry.unlock();
|
entry.unlock();
|
||||||
@@ -1744,7 +1745,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
@Override
|
@Override
|
||||||
public <T> boolean sismember(final String key, final Type type, final T value) {
|
public <T> boolean sismember(final String key, final Type type, final T value) {
|
||||||
CacheEntry entry = find(key, CacheEntryType.SSET);
|
CacheEntry entry = find(key, CacheEntryType.SSET);
|
||||||
return entry != null && entry.ssetValue.contains(CacheEntry.objToSerial(null, type, value));
|
return entry != null && entry.ssetValue.contains(CacheEntry.objToSerial(convert, type, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1771,7 +1772,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
if (del != null) {
|
if (del != null) {
|
||||||
cset.remove(del);
|
cset.remove(del);
|
||||||
return CacheEntry.serialToObj(null, componentType, del);
|
return CacheEntry.serialToObj(convert, componentType, del);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1803,7 +1804,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Serializable item = it.next();
|
Serializable item = it.next();
|
||||||
rms.add(item);
|
rms.add(item);
|
||||||
list.add(CacheEntry.serialToObj(null, componentType, item));
|
list.add(CacheEntry.serialToObj(convert, componentType, item));
|
||||||
if (++index >= count) {
|
if (++index >= count) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1835,7 +1836,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
Iterator<Serializable> it = cset.iterator();
|
Iterator<Serializable> it = cset.iterator();
|
||||||
Set<T> list = new LinkedHashSet<>();
|
Set<T> list = new LinkedHashSet<>();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
list.add(CacheEntry.serialToObj(null, componentType, it.next()));
|
list.add(CacheEntry.serialToObj(convert, componentType, it.next()));
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1856,7 +1857,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
long count = 0;
|
long count = 0;
|
||||||
for (T val : values) {
|
for (T val : values) {
|
||||||
count += entry.ssetValue.remove(CacheEntry.objToSerial(null, type, val)) ? 1 : 0;
|
count += entry.ssetValue.remove(CacheEntry.objToSerial(convert, type, val)) ? 1 : 0;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@@ -2248,7 +2249,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
OBJECT, ATOMIC, DOUBLE, SSET, ZSET, LIST, MAP;
|
OBJECT, ATOMIC, DOUBLE, SSET, ZSET, LIST, MAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
//值类型只能是: String、byte[]、AtomicLong
|
//Serializable的具体数据类型只能是: String、byte[]、AtomicLong
|
||||||
public static final class CacheEntry {
|
public static final class CacheEntry {
|
||||||
|
|
||||||
volatile long lastAccessed; //最后刷新时间
|
volatile long lastAccessed; //最后刷新时间
|
||||||
@@ -2303,36 +2304,34 @@ public final class CacheMemorySource extends AbstractCacheSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//value类型只能是byte[]/String/AtomicLong
|
//value类型只能是byte[]/String/AtomicLong
|
||||||
public static <T> T serialToObj(Convert convert, @Nonnull Type type, Serializable value) {
|
public static <T> T serialToObj(@Nonnull Convert convert, @Nonnull Type type, Serializable value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Convert c = convert == null ? JsonConvert.root() : convert;
|
|
||||||
if (value.getClass() == byte[].class) {
|
if (value.getClass() == byte[].class) {
|
||||||
return (T) c.convertFrom(type, (byte[]) value);
|
return (T) convert.convertFrom(type, (byte[]) value);
|
||||||
} else { //String/AtomicLong
|
} else { //String/AtomicLong
|
||||||
if (c instanceof TextConvert) {
|
if (convert instanceof TextConvert) {
|
||||||
return (T) ((TextConvert) c).convertFrom(type, value.toString());
|
return (T) ((TextConvert) convert).convertFrom(type, value.toString());
|
||||||
} else {
|
} else {
|
||||||
return (T) c.convertFrom(type, value.toString().getBytes(StandardCharsets.UTF_8));
|
return (T) convert.convertFrom(type, value.toString().getBytes(StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//返回类型只能是byte[]/String/AtomicLong
|
//返回类型只能是byte[]/String/AtomicLong
|
||||||
public static Serializable objToSerial(Convert convert, Type type, Object value) {
|
public static Serializable objToSerial(@Nonnull Convert convert, Type type, Object value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (value instanceof String || value instanceof byte[]) {
|
if (value instanceof String || value instanceof byte[]) {
|
||||||
return (Serializable) value;
|
return (Serializable) value;
|
||||||
}
|
}
|
||||||
Convert c = convert == null ? JsonConvert.root() : convert;
|
|
||||||
Type t = type == null ? value.getClass() : type;
|
Type t = type == null ? value.getClass() : type;
|
||||||
if (c instanceof TextConvert) {
|
if (convert instanceof TextConvert) {
|
||||||
return ((TextConvert) c).convertTo(t, value);
|
return ((TextConvert) convert).convertTo(t, value);
|
||||||
} else {
|
} else {
|
||||||
return c.convertToBytes(t, value);
|
return convert.convertToBytes(t, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import java.time.Duration;
|
|||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.redkale.caching.CacheConfig;
|
import org.redkale.caching.CacheConfig;
|
||||||
import org.redkale.caching.CacheManager;
|
import org.redkale.caching.CacheManagerService;
|
||||||
import org.redkale.convert.json.JsonConvert;
|
import org.redkale.convert.json.JsonConvert;
|
||||||
import org.redkale.source.CacheMemorySource;
|
import org.redkale.source.CacheMemorySource;
|
||||||
import org.redkale.util.Utility;
|
import org.redkale.util.Utility;
|
||||||
@@ -25,7 +25,10 @@ public class CachingTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
CacheManager cache = CacheManager.create(new CacheConfig(), new CacheMemorySource("remote"));
|
CacheMemorySource remoteSource = new CacheMemorySource("remote");
|
||||||
|
remoteSource.init(null);
|
||||||
|
CacheManagerService cache = CacheManagerService.create(new CacheConfig(), remoteSource);
|
||||||
|
cache.init(null);
|
||||||
Duration expire = Duration.ofMillis(490);
|
Duration expire = Duration.ofMillis(490);
|
||||||
cache.localSetString("user", "name:haha", "myha", expire);
|
cache.localSetString("user", "name:haha", "myha", expire);
|
||||||
Assertions.assertEquals(cache.localGetString("user", "name:haha"), "myha");
|
Assertions.assertEquals(cache.localGetString("user", "name:haha"), "myha");
|
||||||
@@ -41,6 +44,7 @@ public class CachingTest {
|
|||||||
Assertions.assertEquals(cache.localGet("user", bean.getName(), CachingBean.class).toString(), json);
|
Assertions.assertEquals(cache.localGet("user", bean.getName(), CachingBean.class).toString(), json);
|
||||||
bean.setRemark(bean.getRemark() + "-新备注");
|
bean.setRemark(bean.getRemark() + "-新备注");
|
||||||
Assertions.assertEquals(cache.localGet("user", bean.getName(), CachingBean.class).toString(), json);
|
Assertions.assertEquals(cache.localGet("user", bean.getName(), CachingBean.class).toString(), json);
|
||||||
|
cache.destroy(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CachingBean {
|
public static class CachingBean {
|
||||||
|
|||||||
Reference in New Issue
Block a user