序
本文主要研究一下claudb的Database
Database
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/data/Database.java
public interface Database {int size();
boolean isEmpty();
boolean containsKey(DatabaseKey key);
DatabaseValue get(DatabaseKey key);
DatabaseValue put(DatabaseKey key, DatabaseValue value);
DatabaseValue remove(DatabaseKey key);
void clear();
ImmutableSet keySet();
Sequence values();
ImmutableSet> entrySet();
default SafeString getString(SafeString key) {
return getOrDefault(safeKey(key), DatabaseValue.EMPTY_STRING).getString();
}default ImmutableList getList(SafeString key) {
return getOrDefault(safeKey(key), DatabaseValue.EMPTY_LIST).getList();
}default ImmutableSet getSet(SafeString key) {
return getOrDefault(safeKey(key), DatabaseValue.EMPTY_SET).getSet();
}default NavigableSet> getSortedSet(SafeString key) {
return getOrDefault(safeKey(key), DatabaseValue.EMPTY_ZSET).getSortedSet();
}default ImmutableMap getHash(SafeString key) {
return getOrDefault(safeKey(key), DatabaseValue.EMPTY_HASH).getHash();
}default void putAll(ImmutableMap extends DatabaseKey, ? extends DatabaseValue> map) {
map.forEach(this::put);
}default DatabaseValue putIfAbsent(DatabaseKey key, DatabaseValue value) {
DatabaseValue oldValue = https://www.it610.com/article/get(key);
if (oldValue == null) {
oldValue = put(key, value);
}
return oldValue;
}default DatabaseValue merge(DatabaseKey key, DatabaseValue value,
BiFunction remappingFunction) {
DatabaseValue oldValue = https://www.it610.com/article/get(key);
DatabaseValue newValue = oldValue == null ? value : remappingFunction.apply(oldValue, value);
if(newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}default DatabaseValue getOrDefault(DatabaseKey key, DatabaseValue defaultValue) {
DatabaseValue value = get(key);
return (value != null || containsKey(key)) ? value : defaultValue;
}default boolean isType(DatabaseKey key, DataType type) {
DatabaseValue value = get(key);
return value != null ? value.getType() == type : true;
}default boolean rename(DatabaseKey from, DatabaseKey to) {
DatabaseValue value = remove(from);
if (value != null) {
put(to, value);
return true;
}
return false;
}default void overrideAll(ImmutableMap value) {
clear();
putAll(value);
}default ImmutableSet evictableKeys(Instant now) {
return entrySet()
.filter(entry -> entry.get2().isExpired(now))
.map(Tuple2::get1);
}
}
- Database接口定义了size、isEmpty、containsKey、get、put、remove、clear、keySet、values、entrySet方法;同时还提供了getString、getList、getSet、getSortedSet、getHash、putAll、putIfAbsent、merge、getOrDefault、isType、rename、overrideAll、evictableKeys这几个default方法
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/data/OnHeapDatabase.java
public class OnHeapDatabase implements Database {private final Map cache;
public OnHeapDatabase(Map cache) {
this.cache = cache;
}@Override
public int size() {
return cache.size();
}@Override
public boolean isEmpty() {
return cache.isEmpty();
}@Override
public boolean containsKey(DatabaseKey key) {
return cache.containsKey(key);
}@Override
public DatabaseValue get(DatabaseKey key) {
DatabaseValue value = https://www.it610.com/article/cache.get(key);
if (value != null) {
if (!value.isExpired(Instant.now())) {
return value;
}
cache.remove(key);
}
return null;
}@Override
public DatabaseValue put(DatabaseKey key, DatabaseValue value) {
DatabaseValue oldValue = cache.remove(key);
cache.put(key, value);
return oldValue;
}@Override
public DatabaseValue remove(DatabaseKey key) {
return cache.remove(key);
}@Override
public void clear() {
cache.clear();
}@Override
public ImmutableSet keySet() {
return ImmutableSet.from(cache.keySet());
}@Override
public Sequence values() {
return ImmutableSet.from(cache.values());
}@Override
public ImmutableSet> entrySet() {
return ImmutableSet.from(cache.entrySet()).map(Tuple::from);
}
}
- OnHeapDatabase实现了Database接口,它使用Map结构作为cache;其get方法在取出value不为null时会判断该value是否过期,如果过期则移除该key,返回null;其put方法会先执行remove获取oldValue,在put进去新值,最后返回oldValue
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/data/OffHeapDatabase.java
public class OffHeapDatabase implements Database {private OHCache cache;
public OffHeapDatabase(OHCache cache) {
this.cache = cache;
}@Override
public int size() {
return (int) cache.size();
}@Override
public boolean isEmpty() {
return cache.size() == 0;
}@Override
public boolean containsKey(DatabaseKey key) {
return cache.containsKey(key);
}@Override
public DatabaseValue get(DatabaseKey key) {
DatabaseValue value = https://www.it610.com/article/cache.get(key);
if (value != null) {
if (!value.isExpired(Instant.now())) {
return value;
}
cache.remove(key);
}
return null;
}@Override
public DatabaseValue put(DatabaseKey key, DatabaseValue value) {
cache.put(key, value);
return value;
}@Override
public DatabaseValue remove(DatabaseKey key) {
DatabaseValue value = get(key);
cache.remove(key);
return value;
}@Override
public void clear() {
cache.clear();
}@Override
public ImmutableSet keySet() {
Set keys = new HashSet<>();
try (CloseableIterator iterator = cache.keyIterator()) {
while (iterator.hasNext()) {
keys.add(iterator.next());
}
} catch(IOException e) {
throw new UncheckedIOException(e);
}
return ImmutableSet.from(keys);
}@Override
public Sequence values() {
List values = new LinkedList<>();
for (DatabaseKey key : keySet()) {
values.add(cache.get(key));
}
return ImmutableList.from(values);
}@Override
public ImmutableSet> entrySet() {
return keySet().map(key -> Tuple.of(key, get(key)));
}
}
- OffHeapDatabase实现了Database接口,它使用OHCache作为cache,其get方法在取出value不为null时会判断该value是否过期,如果过期则移除该key,返回null;其put方法直接往cache覆盖该key,返回的是新值
public interface DatabaseFactory {
Database create(String name);
void clear();
}
- DatabaseFactory接口定义了create、clear方法
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/data/OnHeapDatabaseFactory.java
public class OnHeapDatabaseFactory implements DatabaseFactory {@Override
public Database create(String name) {
return new OnHeapDatabase(new HashMap<>());
}@Override
public void clear() {
// nothing to clear
}
}
- OnHeapDatabaseFactory实现了DatabaseFactory接口,其create使用HashMap创建OnHeapDatabase
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/data/OffHeapDatabaseFactory.java
public class OffHeapDatabaseFactory implements DatabaseFactory {@Override
public Database create(String name) {
return new OffHeapDatabase(createCache());
}private OHCache createCache() {
return builder()
.eviction(Eviction.NONE)
.throwOOME(true)
.keySerializer(new FSTSerializer<>())
.valueSerializer(new FSTSerializer<>())
.build();
}private OHCacheBuilder builder() {
return OHCacheBuilder.newBuilder();
}@Override
public void clear() {
// nothing to do
}private static class FSTSerializer implements CacheSerializer {private static final FSTConfiguration FST = FSTConfiguration.createDefaultConfiguration();
static {
FST.registerClass(DatabaseValue.class);
FST.registerClass(DatabaseKey.class);
FST.registerClass(SafeString.class);
FST.registerClass(SortedSet.class);
}@Override
public void serialize(E value, ByteBuffer buf) {
byte[] array = FST.asByteArray(value);
buf.putInt(array.length);
buf.put(array);
}@SuppressWarnings("unchecked")
@Override
public E deserialize(ByteBuffer buf) {
int length = buf.getInt();
byte[] array = new byte[length];
buf.get(array);
return (E) FST.asObject(array);
}@Override
public int serializedSize(E value) {
return FST.asByteArray(value).length + Integer.BYTES;
}
}
}
- OffHeapDatabaseFactory实现了DatabaseFactory接口,其create方法创建的是OffHeapDatabase;其createCache方法使用OHCacheBuilder来构造OHCache,其eviction为NONE,其throwOOME为true;其keySerializer及valueSerializer均为FSTSerializer
doc
- Database
推荐阅读
- Redis|redis原理之布隆过滤器(Bloom Filter)
- redis安装与基本使用
- java|图解四种 IO 模型
- Redis|Redis性能解析--Redis为什么那么快()
- java|你跳一次涨多少(今天见识到跳槽天花板!!)
- java|送你一份大厂都这么解决Redis缓存问题,面试官必问!
- (免费领取红包封面)【Redis 系列】redis 学习四,set 集合,hash 哈希,zset 有序集合初步认知
- redis优化(bigkey、hotkey)
- redis高可用(主从、哨兵、集群)
- 【Redis 系列】redis 学习四,set 集合,hash 哈希,zset 有序集合初步认知