Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.redkale.source.CacheMemorySource Maven / Gradle / Ivy
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.source;
import java.io.*;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.*;
import java.util.logging.*;
import javax.annotation.Resource;
import org.redkale.convert.json.*;
import org.redkale.net.sncp.*;
import org.redkale.service.*;
import org.redkale.util.*;
/**
* CacheSource的默认实现--内存缓存
*
* @param value类型
*
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@Local
@AutoLoad(false)
@SuppressWarnings("unchecked")
@ResourceType(CacheSource.class)
public class CacheMemorySource extends AbstractService implements CacheSource, Service, AutoCloseable, Resourcable {
private static final Type STRING_ENTRY_TYPE = new TypeToken>() {
}.getType();
private static final Type LONG_ENTRY_TYPE = new TypeToken>() {
}.getType();
private static final Type ATOMIC_ENTRY_TYPE = new TypeToken>() {
}.getType();
@Resource(name = "APP_HOME")
private File home;
@Resource
private JsonConvert defaultConvert;
@Resource(name = "$_convert")
private JsonConvert convert;
private boolean needStore;
private Type objValueType;
private ScheduledThreadPoolExecutor scheduler;
private Consumer expireHandler;
private final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
protected final ConcurrentHashMap> container = new ConcurrentHashMap<>();
protected final BiConsumer futureCompleteConsumer = (r, t) -> {
if (t != null) logger.log(Level.SEVERE, "CompletableFuture complete error", (Throwable) t);
};
@RpcRemote
protected CacheSource remoteSource;
public CacheMemorySource() {
}
@Override
public final void initValueType(Type valueType) {
this.objValueType = valueType;
this.initTransient(this.objValueType == null);
}
@Override
public final void initTransient(boolean flag) {
this.needStore = !flag;
}
@Override
public final String getType() {
return "memory";
}
@Override
@SuppressWarnings("unchecked")
public void init(AnyValue conf) {
if (this.convert == null) this.convert = this.defaultConvert;
if (this.convert == null) this.convert = JsonConvert.root();
final CacheMemorySource self = this;
AnyValue prop = conf == null ? null : conf.getAnyValue("properties");
if (prop != null) {
String storeValueStr = prop.getValue("value-type");
if (storeValueStr != null) {
try {
this.initValueType(Thread.currentThread().getContextClassLoader().loadClass(storeValueStr));
} catch (Throwable e) {
logger.log(Level.SEVERE, self.getClass().getSimpleName() + " load key & value store class (" + storeValueStr + ") error", e);
}
}
this.initTransient(prop.getBoolValue("store-ignore", false));
}
String expireHandlerClass = prop == null ? null : prop.getValue("expirehandler");
if (expireHandlerClass != null) {
try {
this.expireHandler = (Consumer) Thread.currentThread().getContextClassLoader().loadClass(expireHandlerClass).getDeclaredConstructor().newInstance();
} catch (Throwable e) {
logger.log(Level.SEVERE, self.getClass().getSimpleName() + " new expirehandler class (" + expireHandlerClass + ") instance error", e);
}
}
if (scheduler == null) {
this.scheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> {
final Thread t = new Thread(r, self.getClass().getSimpleName() + "-Expirer-Thread");
t.setDaemon(true);
return t;
});
final List keys = new ArrayList<>();
scheduler.scheduleWithFixedDelay(() -> {
try {
keys.clear();
int now = (int) (System.currentTimeMillis() / 1000);
container.forEach((k, x) -> {
if (x.expireSeconds > 0 && (now > (x.lastAccessed + x.expireSeconds))) {
keys.add(x.key);
}
});
for (String key : keys) {
CacheEntry entry = container.remove(key);
if (expireHandler != null && entry != null) expireHandler.accept(entry);
}
} catch (Throwable t) {
logger.log(Level.SEVERE, "CacheMemorySource schedule(interval=" + 10 + "s) error", t);
}
}, 10, 10, TimeUnit.SECONDS);
if (logger.isLoggable(Level.FINEST)) logger.finest(self.getClass().getSimpleName() + ":" + self.resourceName() + " start schedule expire executor");
}
if (Sncp.isRemote(self)) return;
boolean datasync = false; //是否从远程同步过数据
//----------同步数据……-----------
// TODO
if (this.needStore) {
try {
File store = home == null ? new File("cache/" + resourceName()) : new File(home, "cache/" + resourceName());
if (!store.isFile() || !store.canRead()) return;
LineNumberReader reader = new LineNumberReader(new FileReader(store));
if (this.objValueType == null) this.objValueType = Object.class;
final Type storeObjType = TypeToken.createParameterizedType(null, CacheEntry.class, objValueType);
String line;
while ((line = reader.readLine()) != null) {
if (line.isEmpty()) continue;
Type convertType = storeObjType;
if (line.startsWith("{\"cacheType\":\"" + CacheEntryType.LONG)) {
convertType = LONG_ENTRY_TYPE;
} else if (line.startsWith("{\"cacheType\":\"" + CacheEntryType.STRING)) {
convertType = STRING_ENTRY_TYPE;
} else if (line.startsWith("{\"cacheType\":\"" + CacheEntryType.ATOMIC)) {
convertType = ATOMIC_ENTRY_TYPE;
}
CacheEntry entry = convert.convertFrom(convertType, line);
if (entry.isExpired()) continue;
if (datasync && container.containsKey(entry.key)) continue; //已经同步了
container.put(entry.key, entry);
}
reader.close();
store.delete();
} catch (Exception e) {
logger.log(Level.SEVERE, CacheSource.class.getSimpleName() + "(" + resourceName() + ") load store file error ", e);
}
}
if (remoteSource != null && !Sncp.isRemote(this)) {
SncpClient client = Sncp.getSncpClient((Service) remoteSource);
if (client != null && client.getRemoteGroupTransport() != null
&& client.getRemoteGroupTransport().getRemoteAddresses().length > 0) {
super.runAsync(() -> {
try {
CompletableFuture>> listFuture = remoteSource.queryListAsync();
listFuture.whenComplete((list, exp) -> {
if (exp != null) {
if (logger.isLoggable(Level.FINEST)) logger.log(Level.FINEST, CacheSource.class.getSimpleName() + "(" + resourceName() + ") queryListAsync error", exp);
} else {
for (CacheEntry entry : list) {
container.put(entry.key, entry);
}
}
});
} catch (Exception e) {
if (logger.isLoggable(Level.FINEST)) logger.log(Level.FINEST, CacheSource.class.getSimpleName() + "(" + resourceName() + ") queryListAsync error, maybe remote node connot connect ", e);
}
});
}
}
}
public static void main(String[] args) throws Exception {
AnyValue.DefaultAnyValue conf = new AnyValue.DefaultAnyValue();
conf.addValue("node", new AnyValue.DefaultAnyValue().addValue("addr", "127.0.0.1").addValue("port", "6379"));
CacheMemorySource source = new CacheMemorySource();
source.defaultConvert = JsonFactory.root().getConvert();
source.initValueType(String.class); //value用String类型
source.initTransient(false);
source.init(conf);
System.out.println("------------------------------------");
source.remove("key1");
source.remove("key2");
source.remove("300");
source.set("key1", "value1");
source.setString("keystr1", "strvalue1");
source.setLong("keylong1", 333L);
source.set("300", "4000");
source.getAndRefresh("key1", 3500);
System.out.println("[有值] 300 GET : " + source.get("300"));
System.out.println("[有值] key1 GET : " + source.get("key1"));
System.out.println("[无值] key2 GET : " + source.get("key2"));
System.out.println("[有值] keylong1 GET : " + source.getLong("keylong1", 0L));
System.out.println("[有值] key1 EXISTS : " + source.exists("key1"));
System.out.println("[无值] key2 EXISTS : " + source.exists("key2"));
source.remove("keys3");
source.appendListItem("keys3", "vals1");
source.appendListItem("keys3", "vals2");
System.out.println("-------- keys3 追加了两个值 --------");
System.out.println("[两值] keys3 VALUES : " + source.getCollection("keys3"));
System.out.println("[有值] keys3 EXISTS : " + source.exists("keys3"));
source.removeListItem("keys3", "vals1");
System.out.println("[一值] keys3 VALUES : " + source.getCollection("keys3"));
source.getCollectionAndRefresh("keys3", 3000);
source.remove("sets3");
source.appendSetItem("sets3", "setvals1");
source.appendSetItem("sets3", "setvals2");
source.appendSetItem("sets3", "setvals1");
System.out.println("[两值] sets3 VALUES : " + source.getCollection("sets3"));
System.out.println("[有值] sets3 EXISTS : " + source.exists("sets3"));
source.removeSetItem("sets3", "setvals1");
System.out.println("[一值] sets3 VALUES : " + source.getCollection("sets3"));
System.out.println("sets3 大小 : " + source.getCollectionSize("sets3"));
System.out.println("all keys: " + source.queryKeys());
System.out.println("newnum 值 : " + source.incr("newnum"));
System.out.println("newnum 值 : " + source.decr("newnum"));
System.out.println("------------------------------------");
source.destroy(null);
source.init(null);
System.out.println("all keys: " + source.queryKeys());
System.out.println("[有值] keylong1 GET : " + source.getLong("keylong1", 0L));
}
@Override
public void close() throws Exception { //给Application 关闭时调用
destroy(null);
}
@Override
public String resourceName() {
Resource res = this.getClass().getAnnotation(Resource.class);
return res == null ? "cachememory" : res.name();
}
@Override
public void destroy(AnyValue conf) {
if (scheduler != null) scheduler.shutdownNow();
if (!this.needStore || Sncp.isRemote(this) || container.isEmpty()) return;
try {
File store = new File(home, "cache/" + resourceName());
store.getParentFile().mkdirs();
PrintStream stream = new PrintStream(store, "UTF-8");
final Type storeObjType = TypeToken.createParameterizedType(null, CacheEntry.class, objValueType);
final Type storeSetType = TypeToken.createParameterizedType(null, CacheEntry.class, objValueType);
final Type storeListType = TypeToken.createParameterizedType(null, CacheEntry.class, objValueType);
Collection> entrys = container.values();
for (CacheEntry entry : entrys) {
Type convertType = storeObjType;
if (entry.cacheType == CacheEntryType.LONG) {
convertType = LONG_ENTRY_TYPE;
} else if (entry.cacheType == CacheEntryType.STRING) {
convertType = STRING_ENTRY_TYPE;
} else if (entry.cacheType == CacheEntryType.ATOMIC) {
convertType = ATOMIC_ENTRY_TYPE;
} else if (entry.cacheType == CacheEntryType.OBJECT) {
convertType = storeObjType;
} else if (entry.cacheType == CacheEntryType.LONG_LIST) {
convertType = LONG_ENTRY_TYPE;
} else if (entry.cacheType == CacheEntryType.LONG_SET) {
convertType = LONG_ENTRY_TYPE;
} else if (entry.cacheType == CacheEntryType.STRING_LIST) {
convertType = STRING_ENTRY_TYPE;
} else if (entry.cacheType == CacheEntryType.STRING_SET) {
convertType = STRING_ENTRY_TYPE;
} else if (entry.cacheType == CacheEntryType.OBJECT_LIST) {
convertType = storeListType;
} else if (entry.cacheType == CacheEntryType.OBJECT_SET) {
convertType = storeSetType;
}
try {
stream.println(convert.convertTo(convertType, entry));
} catch (Exception ee) {
System.err.println(storeSetType + "-----" + entry);
throw ee;
}
}
container.clear();
stream.close();
} catch (Exception e) {
logger.log(Level.SEVERE, CacheSource.class.getSimpleName() + "(" + resourceName() + ") store to file error ", e);
}
}
@Override
public boolean exists(String key) {
if (key == null) return false;
CacheEntry entry = container.get(key);
if (entry == null) return false;
return !entry.isExpired();
}
@Override
public CompletableFuture existsAsync(final String key) {
return CompletableFuture.supplyAsync(() -> exists(key), getExecutor());
}
@Override
@SuppressWarnings("unchecked")
public V get(String key) {
if (key == null) return null;
CacheEntry entry = container.get(key);
if (entry == null || entry.isExpired()) return null;
if (entry.isListCacheType()) return (V) (entry.listValue == null ? null : new ArrayList(entry.listValue));
if (entry.isSetCacheType()) return (V) (entry.csetValue == null ? null : new HashSet(entry.csetValue));
return (V) entry.objectValue;
}
@Override
public T get(final String key, final Type type) {
return (T) get(key);
}
@Override
public String getString(String key) {
if (key == null) return null;
CacheEntry entry = container.get(key);
if (entry == null || entry.isExpired()) return null;
return (String) entry.objectValue;
}
@Override
public long getLong(String key, long defValue) {
if (key == null) return defValue;
CacheEntry entry = container.get(key);
if (entry == null || entry.isExpired()) return defValue;
return entry.objectValue == null ? defValue : (entry.objectValue instanceof AtomicLong ? ((AtomicLong) entry.objectValue).get() : (Long) entry.objectValue);
}
@Override
public CompletableFuture getAsync(final String key) {
return CompletableFuture.supplyAsync(() -> get(key), getExecutor());
}
@Override
public CompletableFuture getAsync(final String key, final Type type) {
return CompletableFuture.supplyAsync(() -> (T) get(key), getExecutor());
}
@Override
public CompletableFuture getStringAsync(final String key) {
return CompletableFuture.supplyAsync(() -> getString(key), getExecutor());
}
@Override
public CompletableFuture getLongAsync(final String key, long defValue) {
return CompletableFuture.supplyAsync(() -> getLong(key, defValue), getExecutor());
}
@Override
@RpcMultiRun
@SuppressWarnings("unchecked")
public V getAndRefresh(String key, final int expireSeconds) {
if (key == null) return null;
CacheEntry entry = container.get(key);
if (entry == null || entry.isExpired()) return null;
entry.lastAccessed = (int) (System.currentTimeMillis() / 1000);
entry.expireSeconds = expireSeconds;
if (entry.isListCacheType()) return (V) (entry.listValue == null ? null : new ArrayList(entry.listValue));
if (entry.isSetCacheType()) return (V) (entry.csetValue == null ? null : new HashSet(entry.csetValue));
return (V) entry.objectValue;
}
@Override
public T getAndRefresh(final String key, final int expireSeconds, final Type type) {
return (T) getAndRefresh(key, expireSeconds);
}
@Override
@RpcMultiRun
@SuppressWarnings("unchecked")
public String getStringAndRefresh(String key, final int expireSeconds) {
if (key == null) return null;
CacheEntry entry = container.get(key);
if (entry == null || entry.isExpired()) return null;
entry.lastAccessed = (int) (System.currentTimeMillis() / 1000);
entry.expireSeconds = expireSeconds;
return (String) entry.objectValue;
}
@Override
@RpcMultiRun
public long getLongAndRefresh(String key, final int expireSeconds, long defValue) {
if (key == null) return defValue;
CacheEntry entry = container.get(key);
if (entry == null || entry.isExpired()) return defValue;
entry.lastAccessed = (int) (System.currentTimeMillis() / 1000);
entry.expireSeconds = expireSeconds;
return entry.objectValue == null ? defValue : (entry.objectValue instanceof AtomicLong ? ((AtomicLong) entry.objectValue).get() : (Long) entry.objectValue);
}
@Override
@RpcMultiRun
public CompletableFuture getAndRefreshAsync(final String key, final int expireSeconds) {
return CompletableFuture.supplyAsync(() -> getAndRefresh(key, expireSeconds), getExecutor());
}
@Override
public CompletableFuture getAndRefreshAsync(final String key, final int expireSeconds, final Type type) {
return CompletableFuture.supplyAsync(() -> getAndRefresh(key, expireSeconds, type), getExecutor());
}
@Override
@RpcMultiRun
public CompletableFuture getStringAndRefreshAsync(final String key, final int expireSeconds) {
return CompletableFuture.supplyAsync(() -> getStringAndRefresh(key, expireSeconds), getExecutor());
}
@Override
@RpcMultiRun
public CompletableFuture getLongAndRefreshAsync(final String key, final int expireSeconds, long defValue) {
return CompletableFuture.supplyAsync(() -> getLongAndRefresh(key, expireSeconds, defValue), getExecutor());
}
@Override
@RpcMultiRun
public void refresh(String key, final int expireSeconds) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null) return;
entry.lastAccessed = (int) (System.currentTimeMillis() / 1000);
entry.expireSeconds = expireSeconds;
}
@Override
@RpcMultiRun
public CompletableFuture refreshAsync(final String key, final int expireSeconds) {
return CompletableFuture.runAsync(() -> refresh(key, expireSeconds), getExecutor()).whenComplete(futureCompleteConsumer);
}
protected void set(CacheEntryType cacheType, String key, Object value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null) {
entry = new CacheEntry(cacheType, key, value, null, null);
container.putIfAbsent(key, entry);
} else {
entry.expireSeconds = 0;
entry.objectValue = value;
entry.lastAccessed = (int) (System.currentTimeMillis() / 1000);
}
}
@Override
@RpcMultiRun
public void set(String key, V value) {
set(CacheEntryType.OBJECT, key, value);
}
@Override
public void set(String key, Type type, T value) {
set(CacheEntryType.OBJECT, key, value);
}
@Override
@RpcMultiRun
public void setString(String key, String value) {
set(CacheEntryType.STRING, key, value);
}
@Override
@RpcMultiRun
public void setLong(String key, long value) {
set(CacheEntryType.LONG, key, value);
}
@Override
@RpcMultiRun
public CompletableFuture setAsync(String key, V value) {
return CompletableFuture.runAsync(() -> set(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
public CompletableFuture setAsync(String key, Type type, T value) {
return CompletableFuture.runAsync(() -> set(key, type, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture setStringAsync(String key, String value) {
return CompletableFuture.runAsync(() -> setString(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture setLongAsync(String key, long value) {
return CompletableFuture.runAsync(() -> setLong(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
protected void set(CacheEntryType cacheType, int expireSeconds, String key, Object value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null) {
entry = new CacheEntry(cacheType, expireSeconds, key, value, null, null);
container.putIfAbsent(key, entry);
} else {
if (expireSeconds > 0) entry.expireSeconds = expireSeconds;
entry.lastAccessed = (int) (System.currentTimeMillis() / 1000);
entry.objectValue = value;
}
}
@Override
@RpcMultiRun
public void set(int expireSeconds, String key, V value) {
set(CacheEntryType.OBJECT, expireSeconds, key, value);
}
@Override
public void set(final int expireSeconds, String key, Type type, T value) {
set(CacheEntryType.OBJECT, expireSeconds, key, value);
}
@Override
@RpcMultiRun
public void setString(int expireSeconds, String key, String value) {
set(CacheEntryType.STRING, expireSeconds, key, value);
}
@Override
@RpcMultiRun
public void setLong(int expireSeconds, String key, long value) {
set(CacheEntryType.LONG, expireSeconds, key, value);
}
@Override
@RpcMultiRun
public CompletableFuture setAsync(int expireSeconds, String key, V value) {
return CompletableFuture.runAsync(() -> set(expireSeconds, key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
public CompletableFuture setAsync(int expireSeconds, String key, Type type, T value) {
return CompletableFuture.runAsync(() -> set(expireSeconds, key, type, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture setStringAsync(int expireSeconds, String key, String value) {
return CompletableFuture.runAsync(() -> setString(expireSeconds, key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture setLongAsync(int expireSeconds, String key, long value) {
return CompletableFuture.runAsync(() -> setLong(expireSeconds, key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public void setExpireSeconds(String key, int expireSeconds) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null) return;
entry.expireSeconds = expireSeconds;
}
@Override
@RpcMultiRun
public CompletableFuture setExpireSecondsAsync(final String key, final int expireSeconds) {
return CompletableFuture.runAsync(() -> setExpireSeconds(key, expireSeconds), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public void remove(String key) {
if (key == null) return;
container.remove(key);
}
@Override
@RpcMultiRun
public long incr(final String key) {
return incr(key, 1);
}
@Override
@RpcMultiRun
public CompletableFuture incrAsync(final String key) {
return CompletableFuture.supplyAsync(() -> incr(key), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public long incr(final String key, long num) {
CacheEntry entry = container.get(key);
if (entry == null) {
synchronized (container) {
entry = container.get(key);
if (entry == null) {
entry = new CacheEntry(CacheEntryType.ATOMIC, key, new AtomicLong(), null, null);
container.put(key, entry);
}
}
}
return ((AtomicLong) entry.objectValue).addAndGet(num);
}
@Override
@RpcMultiRun
public CompletableFuture incrAsync(final String key, long num) {
return CompletableFuture.supplyAsync(() -> incr(key, num), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public long decr(final String key) {
return incr(key, -1);
}
@Override
@RpcMultiRun
public CompletableFuture decrAsync(final String key) {
return CompletableFuture.supplyAsync(() -> decr(key), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public long decr(final String key, long num) {
return incr(key, -num);
}
@Override
@RpcMultiRun
public CompletableFuture decrAsync(final String key, long num) {
return CompletableFuture.supplyAsync(() -> decr(key, num), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture removeAsync(final String key) {
return CompletableFuture.runAsync(() -> remove(key), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
public Collection getCollection(final String key) {
return (Collection) get(key);
}
@Override
public Collection getCollection(final String key, final Type componentType) {
return (Collection) get(key);
}
@Override
public Map> getCollectionMap(final boolean set, final Type componentType, final String... keys) {
Map> map = new HashMap<>();
for (String key : keys) {
Collection s = (Collection) get(key);
if (s != null) map.put(key, s);
}
return map;
}
@Override
public Collection getStringCollection(final String key) {
return (Collection) get(key);
}
@Override
public Map> getStringCollectionMap(final boolean set, final String... keys) {
Map> map = new HashMap<>();
for (String key : keys) {
Collection s = (Collection) get(key);
if (s != null) map.put(key, s);
}
return map;
}
@Override
public Collection getLongCollection(final String key) {
return (Collection) get(key);
}
@Override
public Map> getLongCollectionMap(final boolean set, final String... keys) {
Map> map = new HashMap<>();
for (String key : keys) {
Collection s = (Collection) get(key);
if (s != null) map.put(key, s);
}
return map;
}
@Override
public CompletableFuture> getCollectionAsync(final String key) {
return CompletableFuture.supplyAsync(() -> getCollection(key), getExecutor());
}
@Override
public CompletableFuture> getCollectionAsync(final String key, final Type componentType) {
return CompletableFuture.supplyAsync(() -> getCollection(key, componentType), getExecutor());
}
@Override
public CompletableFuture>> getCollectionMapAsync(final boolean set, final Type componentType, final String... keys) {
return CompletableFuture.supplyAsync(() -> getCollectionMap(set, componentType, keys), getExecutor());
}
@Override
public CompletableFuture> getStringCollectionAsync(final String key) {
return CompletableFuture.supplyAsync(() -> getStringCollection(key), getExecutor());
}
@Override
public CompletableFuture>> getStringCollectionMapAsync(final boolean set, final String... keys) {
return CompletableFuture.supplyAsync(() -> getStringCollectionMap(set, keys), getExecutor());
}
@Override
public CompletableFuture> getLongCollectionAsync(final String key) {
return CompletableFuture.supplyAsync(() -> getLongCollection(key), getExecutor());
}
@Override
public CompletableFuture>> getLongCollectionMapAsync(final boolean set, final String... keys) {
return CompletableFuture.supplyAsync(() -> getLongCollectionMap(set, keys), getExecutor());
}
@Override
public int getCollectionSize(final String key) {
Collection collection = (Collection) get(key);
return collection == null ? 0 : collection.size();
}
@Override
public CompletableFuture getCollectionSizeAsync(final String key) {
return CompletableFuture.supplyAsync(() -> getCollectionSize(key), getExecutor());
}
@Override
@RpcMultiRun
public Collection getCollectionAndRefresh(final String key, final int expireSeconds) {
return (Collection) getAndRefresh(key, expireSeconds);
}
@Override
public Collection getCollectionAndRefresh(final String key, final int expireSeconds, final Type componentType) {
return (Collection) getAndRefresh(key, expireSeconds, componentType);
}
@Override
@RpcMultiRun
public Collection getStringCollectionAndRefresh(final String key, final int expireSeconds) {
return (Collection) getAndRefresh(key, expireSeconds);
}
@Override
public boolean existsSetItem(final String key, final V value) {
Collection list = getCollection(key);
return list != null && list.contains(value);
}
@Override
public boolean existsSetItem(final String key, final Type type, final T value) {
Collection list = getCollection(key);
return list != null && list.contains(value);
}
@Override
public CompletableFuture existsSetItemAsync(final String key, final V value) {
return CompletableFuture.supplyAsync(() -> existsSetItem(key, value), getExecutor());
}
@Override
public CompletableFuture existsSetItemAsync(final String key, final Type type, final T value) {
return CompletableFuture.supplyAsync(() -> existsSetItem(key, type, value), getExecutor());
}
@Override
public boolean existsStringSetItem(final String key, final String value) {
Collection list = getStringCollection(key);
return list != null && list.contains(value);
}
@Override
public CompletableFuture existsStringSetItemAsync(final String key, final String value) {
return CompletableFuture.supplyAsync(() -> existsStringSetItem(key, value), getExecutor());
}
@Override
public boolean existsLongSetItem(final String key, final long value) {
Collection list = getLongCollection(key);
return list != null && list.contains(value);
}
@Override
public CompletableFuture existsLongSetItemAsync(final String key, final long value) {
return CompletableFuture.supplyAsync(() -> existsLongSetItem(key, value), getExecutor());
}
@Override
@RpcMultiRun
public Collection getLongCollectionAndRefresh(final String key, final int expireSeconds) {
return (Collection) getAndRefresh(key, expireSeconds);
}
@Override
@RpcMultiRun
public CompletableFuture> getCollectionAndRefreshAsync(final String key, final int expireSeconds) {
return CompletableFuture.supplyAsync(() -> getCollectionAndRefresh(key, expireSeconds), getExecutor());
}
@Override
public CompletableFuture> getCollectionAndRefreshAsync(final String key, final int expireSeconds, final Type componentType) {
return CompletableFuture.supplyAsync(() -> getCollectionAndRefresh(key, expireSeconds, componentType), getExecutor());
}
@Override
@RpcMultiRun
public CompletableFuture> getStringCollectionAndRefreshAsync(final String key, final int expireSeconds) {
return CompletableFuture.supplyAsync(() -> getStringCollectionAndRefresh(key, expireSeconds), getExecutor());
}
@Override
@RpcMultiRun
public CompletableFuture> getLongCollectionAndRefreshAsync(final String key, final int expireSeconds) {
return CompletableFuture.supplyAsync(() -> getLongCollectionAndRefresh(key, expireSeconds), getExecutor());
}
protected void appendListItem(CacheEntryType cacheType, String key, Object value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null || !entry.isListCacheType() || entry.listValue == null) {
ConcurrentLinkedQueue list = new ConcurrentLinkedQueue();
entry = new CacheEntry(cacheType, key, null, null, list);
CacheEntry old = container.putIfAbsent(key, entry);
if (old != null) list = old.listValue;
if (list != null) list.add(value);
} else {
entry.listValue.add(value);
}
}
@Override
@RpcMultiRun
public void appendListItem(String key, V value) {
appendListItem(CacheEntryType.OBJECT_LIST, key, value);
}
@Override
public void appendListItem(String key, Type componentType, T value) {
appendListItem(CacheEntryType.OBJECT_LIST, key, value);
}
@Override
@RpcMultiRun
public void appendStringListItem(String key, String value) {
appendListItem(CacheEntryType.STRING_LIST, key, value);
}
@Override
@RpcMultiRun
public void appendLongListItem(String key, long value) {
appendListItem(CacheEntryType.LONG_LIST, key, value);
}
@Override
@RpcMultiRun
public CompletableFuture appendListItemAsync(final String key, final V value) {
return CompletableFuture.runAsync(() -> appendListItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
public CompletableFuture appendListItemAsync(final String key, final Type componentType, final T value) {
return CompletableFuture.runAsync(() -> appendListItem(key, componentType, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture appendStringListItemAsync(final String key, final String value) {
return CompletableFuture.runAsync(() -> appendStringListItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture appendLongListItemAsync(final String key, final long value) {
return CompletableFuture.runAsync(() -> appendLongListItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public void removeListItem(String key, V value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null || entry.listValue == null) return;
entry.listValue.remove(value);
}
@Override
public void removeListItem(String key, final Type componentType, T value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null || entry.listValue == null) return;
entry.listValue.remove(value);
}
@Override
@RpcMultiRun
public void removeStringListItem(String key, String value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null || entry.listValue == null) return;
entry.listValue.remove(value);
}
@Override
@RpcMultiRun
public void removeLongListItem(String key, long value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null || entry.listValue == null) return;
entry.listValue.remove(value);
}
@Override
@RpcMultiRun
public CompletableFuture removeListItemAsync(final String key, final V value) {
return CompletableFuture.runAsync(() -> removeListItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
public CompletableFuture removeListItemAsync(final String key, final Type componentType, T value) {
return CompletableFuture.runAsync(() -> removeListItem(key, componentType, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture removeStringListItemAsync(final String key, final String value) {
return CompletableFuture.runAsync(() -> removeStringListItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture removeLongListItemAsync(final String key, final long value) {
return CompletableFuture.runAsync(() -> removeLongListItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
protected void appendSetItem(CacheEntryType cacheType, String key, Object value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null || !entry.isSetCacheType() || entry.csetValue == null) {
CopyOnWriteArraySet set = new CopyOnWriteArraySet();
entry = new CacheEntry(cacheType, key, null, set, null);
CacheEntry old = container.putIfAbsent(key, entry);
if (old != null) set = old.csetValue;
if (set != null) set.add(value);
} else {
entry.csetValue.add(value);
}
}
@Override
@RpcMultiRun
public void appendSetItem(String key, V value) {
appendSetItem(CacheEntryType.OBJECT_SET, key, value);
}
@Override
public void appendSetItem(String key, final Type componentType, T value) {
appendSetItem(CacheEntryType.OBJECT_SET, key, value);
}
@Override
@RpcMultiRun
public void appendStringSetItem(String key, String value) {
appendSetItem(CacheEntryType.OBJECT_SET, key, value);
}
@Override
@RpcMultiRun
public void appendLongSetItem(String key, long value) {
appendSetItem(CacheEntryType.OBJECT_SET, key, value);
}
@Override
@RpcMultiRun
public CompletableFuture appendSetItemAsync(final String key, final V value) {
return CompletableFuture.runAsync(() -> appendSetItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
public CompletableFuture appendSetItemAsync(final String key, final Type componentType, T value) {
return CompletableFuture.runAsync(() -> appendSetItem(key, componentType, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture appendStringSetItemAsync(final String key, final String value) {
return CompletableFuture.runAsync(() -> appendStringSetItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture appendLongSetItemAsync(final String key, final long value) {
return CompletableFuture.runAsync(() -> appendLongSetItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public void removeSetItem(String key, V value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null || entry.csetValue == null) return;
entry.csetValue.remove(value);
}
@Override
public void removeSetItem(String key, Type type, T value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null || entry.csetValue == null) return;
entry.csetValue.remove(value);
}
@Override
@RpcMultiRun
public void removeStringSetItem(String key, String value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null || entry.csetValue == null) return;
entry.csetValue.remove(value);
}
@Override
@RpcMultiRun
public void removeLongSetItem(String key, long value) {
if (key == null) return;
CacheEntry entry = container.get(key);
if (entry == null || entry.csetValue == null) return;
entry.csetValue.remove(value);
}
@Override
@RpcMultiRun
public CompletableFuture removeSetItemAsync(final String key, final V value) {
return CompletableFuture.runAsync(() -> removeSetItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
public CompletableFuture removeSetItemAsync(final String key, final Type componentType, final T value) {
return CompletableFuture.runAsync(() -> removeSetItem(key, componentType, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture removeStringSetItemAsync(final String key, final String value) {
return CompletableFuture.runAsync(() -> removeStringSetItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
@RpcMultiRun
public CompletableFuture removeLongSetItemAsync(final String key, final long value) {
return CompletableFuture.runAsync(() -> removeLongSetItem(key, value), getExecutor()).whenComplete(futureCompleteConsumer);
}
@Override
public List queryKeys() {
return new ArrayList<>(container.keySet());
}
@Override
public List queryKeysStartsWith(String startsWith) {
if (startsWith == null) return queryKeys();
List rs = new ArrayList<>();
container.keySet().stream().filter(x -> x.startsWith(startsWith)).forEach(x -> rs.add(x));
return rs;
}
@Override
public List queryKeysEndsWith(String endsWith) {
if (endsWith == null) return queryKeys();
List rs = new ArrayList<>();
container.keySet().stream().filter(x -> x.endsWith(endsWith)).forEach(x -> rs.add(x));
return rs;
}
@Override
public int getKeySize() {
return container.size();
}
@Override
public CompletableFuture>> queryListAsync() {
return CompletableFuture.completedFuture(new ArrayList<>(container.values()));
}
@Override
public List> queryList() {
return new ArrayList<>(container.values());
}
@Override
public CompletableFuture> queryKeysAsync() {
return CompletableFuture.completedFuture(new ArrayList<>(container.keySet()));
}
@Override
public CompletableFuture> queryKeysStartsWithAsync(String startsWith) {
return CompletableFuture.completedFuture(queryKeysStartsWith(startsWith));
}
@Override
public CompletableFuture> queryKeysEndsWithAsync(String endsWith) {
return CompletableFuture.completedFuture(queryKeysEndsWith(endsWith));
}
@Override
public CompletableFuture getKeySizeAsync() {
return CompletableFuture.completedFuture(container.size());
}
}