org.redkale.source.CacheSource 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.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Function;
import org.redkale.convert.ConvertColumn;
import org.redkale.convert.json.JsonFactory;
import org.redkale.util.ConstructorParameters;
/**
* Redkale中缓存数据源的核心类。 主要供业务开发者使用, 技术开发者提供CacheSource的实现。
* CacheSource提供三种数据类型操作: String、Long和泛型指定的数据类型。
* String统一用setString、getString等系列方法。
* Long统一用setLong、getLong、incr等系列方法。
* 其他则供自定义数据类型使用。
*
* @param value的类型
*
* 详情见: https://redkale.org
*
* @author zhangjx
*/
public interface CacheSource {
public String getType();
public void initValueType(Type valueType);
public void initTransient(boolean flag);
default boolean isOpen() {
return true;
}
public boolean exists(final String key);
public V get(final String key);
public T get(final String key, final Type type);
default V getIfAbsent(final String key, Function mappingFunction) {
V rs = get(key);
if (rs == null) {
rs = mappingFunction.apply(key);
if (rs != null) set(key, rs);
}
return rs;
}
public V getAndRefresh(final String key, final int expireSeconds);
public T getAndRefresh(final String key, final int expireSeconds, final Type type);
default V getAndRefreshIfAbsent(final String key, final int expireSeconds, Function mappingFunction) {
V rs = getAndRefresh(key, expireSeconds);
if (rs == null) {
rs = mappingFunction.apply(key);
if (rs != null) set(expireSeconds, key, rs);
}
return rs;
}
public void refresh(final String key, final int expireSeconds);
public void set(final String key, final V value);
public void set(final String key, final Type type, final T value);
public void set(final int expireSeconds, final String key, final V value);
public void set(final int expireSeconds, final String key, final Type type, final T value);
public void setExpireSeconds(final String key, final int expireSeconds);
public void remove(final String key);
public long incr(final String key);
public long incr(final String key, long num);
public long decr(final String key);
public long decr(final String key, long num);
public Collection getCollection(final String key);
public Collection getCollection(final String key, final Type componentType);
public int getCollectionSize(final String key);
public Collection getCollectionAndRefresh(final String key, final int expireSeconds);
public Collection getCollectionAndRefresh(final String key, final int expireSeconds, final Type componentType);
public void appendListItem(final String key, final V value);
public void removeListItem(final String key, final V value);
public boolean existsSetItem(final String key, final V value);
public void appendSetItem(final String key, final V value);
public void removeSetItem(final String key, final V value);
public void appendListItem(final String key, final Type componentType, final T value);
public void removeListItem(final String key, final Type componentType, final T value);
public boolean existsSetItem(final String key, final Type componentType, final T value);
public void appendSetItem(final String key, final Type componentType, final T value);
public void removeSetItem(final String key, final Type componentType, final T value);
public List queryKeys();
public List queryKeysStartsWith(String startsWith);
public List queryKeysEndsWith(String endsWith);
public int getKeySize();
public List> queryList();
public String getString(final String key);
public String getStringAndRefresh(final String key, final int expireSeconds);
public void setString(final String key, final String value);
public void setString(final int expireSeconds, final String key, final String value);
public Collection getStringCollection(final String key);
public Collection getStringCollectionAndRefresh(final String key, final int expireSeconds);
public void appendStringListItem(final String key, final String value);
public void removeStringListItem(final String key, final String value);
public boolean existsStringSetItem(final String key, final String value);
public void appendStringSetItem(final String key, final String value);
public void removeStringSetItem(final String key, final String value);
public long getLong(final String key, long defValue);
public long getLongAndRefresh(final String key, final int expireSeconds, long defValue);
public void setLong(final String key, final long value);
public void setLong(final int expireSeconds, final String key, final long value);
public Collection getLongCollection(final String key);
public Collection getLongCollectionAndRefresh(final String key, final int expireSeconds);
public void appendLongListItem(final String key, final long value);
public void removeLongListItem(final String key, final long value);
public boolean existsLongSetItem(final String key, final long value);
public void appendLongSetItem(final String key, final long value);
public void removeLongSetItem(final String key, final long value);
//---------------------- CompletableFuture 异步版 ---------------------------------
public CompletableFuture existsAsync(final String key);
public CompletableFuture getAsync(final String key, final Type type);
public CompletableFuture getAsync(final String key);
default CompletableFuture getIfAbsentAsync(final String key, Function mappingFunction) {
return getAsync(key).thenCompose((V rs) -> {
if (rs == null) {
rs = mappingFunction.apply(key);
if (rs != null) {
final V v = rs;
return setAsync(key, rs).thenApply((k) -> v);
}
}
return CompletableFuture.completedFuture(rs);
});
}
public CompletableFuture getAndRefreshAsync(final String key, final int expireSeconds);
public CompletableFuture getAndRefreshAsync(final String key, final int expireSeconds, final Type type);
default CompletableFuture getAndRefreshIfAbsentAsync(final String key, final int expireSeconds, Function mappingFunction) {
return getAndRefreshAsync(key, expireSeconds).thenCompose((V rs) -> {
if (rs == null) {
rs = mappingFunction.apply(key);
if (rs != null) {
final V v = rs;
return setAsync(expireSeconds, key, rs).thenApply((k) -> v);
}
}
return CompletableFuture.completedFuture(rs);
});
}
public CompletableFuture refreshAsync(final String key, final int expireSeconds);
public CompletableFuture setAsync(final String key, final V value);
public CompletableFuture setAsync(final String key, final Type type, final T value);
public CompletableFuture setAsync(final int expireSeconds, final String key, final V value);
public CompletableFuture setAsync(final int expireSeconds, final String key, final Type type, final T value);
public CompletableFuture setExpireSecondsAsync(final String key, final int expireSeconds);
public CompletableFuture removeAsync(final String key);
public CompletableFuture incrAsync(final String key);
public CompletableFuture incrAsync(final String key, long num);
public CompletableFuture decrAsync(final String key);
public CompletableFuture decrAsync(final String key, long num);
public CompletableFuture> getCollectionAsync(final String key);
public CompletableFuture> getCollectionAsync(final String key, final Type componentType);
public CompletableFuture getCollectionSizeAsync(final String key);
public CompletableFuture> getCollectionAndRefreshAsync(final String key, final int expireSeconds);
public CompletableFuture> getCollectionAndRefreshAsync(final String key, final int expireSeconds, final Type componentType);
public CompletableFuture appendListItemAsync(final String key, final V value);
public CompletableFuture removeListItemAsync(final String key, final V value);
public CompletableFuture existsSetItemAsync(final String key, final V value);
public CompletableFuture appendSetItemAsync(final String key, final V value);
public CompletableFuture removeSetItemAsync(final String key, final V value);
public CompletableFuture appendListItemAsync(final String key, final Type componentType, final T value);
public CompletableFuture removeListItemAsync(final String key, final Type componentType, final T value);
public CompletableFuture existsSetItemAsync(final String key, final Type componentType, final T value);
public CompletableFuture appendSetItemAsync(final String key, final Type componentType, final T value);
public CompletableFuture removeSetItemAsync(final String key, final Type componentType, final T value);
public CompletableFuture> queryKeysAsync();
public CompletableFuture> queryKeysStartsWithAsync(String startsWith);
public CompletableFuture> queryKeysEndsWithAsync(String endsWith);
public CompletableFuture getKeySizeAsync();
public CompletableFuture>> queryListAsync();
public CompletableFuture getStringAsync(final String key);
public CompletableFuture getStringAndRefreshAsync(final String key, final int expireSeconds);
public CompletableFuture setStringAsync(final String key, final String value);
public CompletableFuture setStringAsync(final int expireSeconds, final String key, final String value);
public CompletableFuture> getStringCollectionAsync(final String key);
public CompletableFuture> getStringCollectionAndRefreshAsync(final String key, final int expireSeconds);
public CompletableFuture appendStringListItemAsync(final String key, final String value);
public CompletableFuture removeStringListItemAsync(final String key, final String value);
public CompletableFuture existsStringSetItemAsync(final String key, final String value);
public CompletableFuture appendStringSetItemAsync(final String key, final String value);
public CompletableFuture removeStringSetItemAsync(final String key, final String value);
public CompletableFuture getLongAsync(final String key, long defValue);
public CompletableFuture getLongAndRefreshAsync(final String key, final int expireSeconds, long defValue);
public CompletableFuture setLongAsync(final String key, long value);
public CompletableFuture setLongAsync(final int expireSeconds, final String key, final long value);
public CompletableFuture> getLongCollectionAsync(final String key);
public CompletableFuture> getLongCollectionAndRefreshAsync(final String key, final int expireSeconds);
public CompletableFuture appendLongListItemAsync(final String key, final long value);
public CompletableFuture removeLongListItemAsync(final String key, final long value);
public CompletableFuture existsLongSetItemAsync(final String key, final long value);
public CompletableFuture appendLongSetItemAsync(final String key, final long value);
public CompletableFuture removeLongSetItemAsync(final String key, final long value);
default CompletableFuture isOpenAsync() {
return CompletableFuture.completedFuture(isOpen());
}
public static enum CacheEntryType {
LONG, STRING, OBJECT, ATOMIC,
LONG_SET, STRING_SET, OBJECT_SET,
LONG_LIST, STRING_LIST, OBJECT_LIST;
}
public static final class CacheEntry {
final CacheEntryType cacheType;
final String key;
//<=0表示永久保存
int expireSeconds;
volatile int lastAccessed; //最后刷新时间
T objectValue;
CopyOnWriteArraySet csetValue;
ConcurrentLinkedQueue listValue;
public CacheEntry(CacheEntryType cacheType, String key, T objectValue, CopyOnWriteArraySet csetValue, ConcurrentLinkedQueue listValue) {
this(cacheType, 0, key, objectValue, csetValue, listValue);
}
public CacheEntry(CacheEntryType cacheType, int expireSeconds, String key, T objectValue, CopyOnWriteArraySet csetValue, ConcurrentLinkedQueue listValue) {
this(cacheType, expireSeconds, (int) (System.currentTimeMillis() / 1000), key, objectValue, csetValue, listValue);
}
@ConstructorParameters({"cacheType", "expireSeconds", "lastAccessed", "key", "objectValue", "csetValue", "listValue"})
public CacheEntry(CacheEntryType cacheType, int expireSeconds, int lastAccessed, String key, T objectValue, CopyOnWriteArraySet csetValue, ConcurrentLinkedQueue listValue) {
this.cacheType = cacheType;
this.expireSeconds = expireSeconds;
this.lastAccessed = lastAccessed;
this.key = key;
this.objectValue = objectValue;
this.csetValue = csetValue;
this.listValue = listValue;
}
@Override
public String toString() {
return JsonFactory.root().getConvert().convertTo(this);
}
@ConvertColumn(ignore = true)
public boolean isListCacheType() {
return cacheType == CacheEntryType.LONG_LIST || cacheType == CacheEntryType.STRING_LIST || cacheType == CacheEntryType.OBJECT_LIST;
}
@ConvertColumn(ignore = true)
public boolean isSetCacheType() {
return cacheType == CacheEntryType.LONG_SET || cacheType == CacheEntryType.STRING_SET || cacheType == CacheEntryType.OBJECT_SET;
}
@ConvertColumn(ignore = true)
public boolean isExpired() {
return (expireSeconds > 0 && lastAccessed + expireSeconds < (System.currentTimeMillis() / 1000));
}
public CacheEntryType getCacheType() {
return cacheType;
}
public int getExpireSeconds() {
return expireSeconds;
}
public int getLastAccessed() {
return lastAccessed;
}
public String getKey() {
return key;
}
public T getObjectValue() {
return objectValue;
}
public CopyOnWriteArraySet getCsetValue() {
return csetValue;
}
public ConcurrentLinkedQueue getListValue() {
return listValue;
}
}
}