前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊claudb的Database

聊聊claudb的Database

原创
作者头像
code4it
修改2020-08-24 10:17:04
6290
修改2020-08-24 10:17:04
举报

本文主要研究一下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<DatabaseKey> keySet();
​
  Sequence<DatabaseValue> values();
​
  ImmutableSet<Tuple2<DatabaseKey, DatabaseValue>> entrySet();
​
  default SafeString getString(SafeString key) {
    return getOrDefault(safeKey(key), DatabaseValue.EMPTY_STRING).getString();
  }
​
  default ImmutableList<SafeString> getList(SafeString key) {
    return getOrDefault(safeKey(key), DatabaseValue.EMPTY_LIST).getList();
  }
​
  default ImmutableSet<SafeString> getSet(SafeString key) {
    return getOrDefault(safeKey(key), DatabaseValue.EMPTY_SET).getSet();
  }
​
  default NavigableSet<Entry<Double, SafeString>> getSortedSet(SafeString key) {
    return getOrDefault(safeKey(key), DatabaseValue.EMPTY_ZSET).getSortedSet();
  }
​
  default ImmutableMap<SafeString, SafeString> 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 = get(key);
    if (oldValue == null) {
        oldValue = put(key, value);
    }
    return oldValue;
  }
​
  default DatabaseValue merge(DatabaseKey key, DatabaseValue value,
      BiFunction<DatabaseValue, DatabaseValue, DatabaseValue> remappingFunction) {
    DatabaseValue oldValue = 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<DatabaseKey, DatabaseValue> value) {
    clear();
    putAll(value);
  }
​
  default ImmutableSet<DatabaseKey> 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方法

OnHeapDatabase

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/data/OnHeapDatabase.java

public class OnHeapDatabase implements Database {
​
  private final Map<DatabaseKey, DatabaseValue> cache;
​
  public OnHeapDatabase(Map<DatabaseKey, DatabaseValue> 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 = 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<DatabaseKey> keySet() {
    return ImmutableSet.from(cache.keySet());
  }
​
  @Override
  public Sequence<DatabaseValue> values() {
    return ImmutableSet.from(cache.values());
  }
​
  @Override
  public ImmutableSet<Tuple2<DatabaseKey, DatabaseValue>> entrySet() {
    return ImmutableSet.from(cache.entrySet()).map(Tuple::from);
  }
}
  • OnHeapDatabase实现了Database接口,它使用Map结构作为cache;其get方法在取出value不为null时会判断该value是否过期,如果过期则移除该key,返回null;其put方法会先执行remove获取oldValue,在put进去新值,最后返回oldValue

OffHeapDatabase

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/data/OffHeapDatabase.java

public class OffHeapDatabase implements Database {
​
  private OHCache<DatabaseKey, DatabaseValue> cache;
​
  public OffHeapDatabase(OHCache<DatabaseKey, DatabaseValue> 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 = 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<DatabaseKey> keySet() {
    Set<DatabaseKey> keys = new HashSet<>();
    try (CloseableIterator<DatabaseKey> iterator = cache.keyIterator()) {
      while (iterator.hasNext()) {
        keys.add(iterator.next());
      }
    } catch(IOException e) {
      throw new UncheckedIOException(e);
    }
    return ImmutableSet.from(keys);
  }
​
  @Override
  public Sequence<DatabaseValue> values() {
    List<DatabaseValue> values = new LinkedList<>();
    for (DatabaseKey key : keySet()) {
      values.add(cache.get(key));
    }
    return ImmutableList.from(values);
  }
​
  @Override
  public ImmutableSet<Tuple2<DatabaseKey, DatabaseValue>> entrySet() {
    return keySet().map(key -> Tuple.of(key, get(key)));
  }
}
  • OffHeapDatabase实现了Database接口,它使用OHCache作为cache,其get方法在取出value不为null时会判断该value是否过期,如果过期则移除该key,返回null;其put方法直接往cache覆盖该key,返回的是新值

DatabaseFactory

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/data/DatabaseFactory.java

public interface DatabaseFactory {
  Database create(String name);
  void clear();
}
  • DatabaseFactory接口定义了create、clear方法

OnHeapDatabaseFactory

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

OffHeapDatabaseFactory

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<DatabaseKey, DatabaseValue> createCache() {
    return builder()
        .eviction(Eviction.NONE)
        .throwOOME(true)
        .keySerializer(new FSTSerializer<>())
        .valueSerializer(new FSTSerializer<>())
        .build();
  }
​
  private OHCacheBuilder<DatabaseKey, DatabaseValue> builder() {
    return OHCacheBuilder.newBuilder();
  }
​
  @Override
  public void clear() {
    // nothing to do
  }
​
  private static class FSTSerializer<E> implements CacheSerializer<E> {
​
    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

小结

claudb提供了OnHeapDatabase、OffHeapDatabase两种实现,前者使用HashMap,后者使用OHCache

doc

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Database
    • OnHeapDatabase
      • OffHeapDatabase
      • DatabaseFactory
        • OnHeapDatabaseFactory
          • OffHeapDatabaseFactory
          • 小结
          • doc
          相关产品与服务
          云数据库 Redis
          腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档