本文次要钻研一下claudb的keys command

KeysCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/key/KeysCommand.java

@ReadOnly@Command("keys")@ParamLength(1)public class KeysCommand implements DBCommand {  @Override  public RedisToken execute(Database db, Request request) {    GlobPattern pattern = createPattern(request.getParam(0));    ImmutableSet<SafeString> keys = db.entrySet()        .filter(matchPattern(pattern))        .filter(filterExpired(Instant.now()).negate())        .map(Tuple2::get1)        .map(DatabaseKey::getValue);    return convert(keys);  }  private GlobPattern createPattern(SafeString param) {    return new GlobPattern(param.toString());  }  private Matcher1<Tuple2<DatabaseKey, DatabaseValue>> filterExpired(Instant now) {    return entry -> entry.get2().isExpired(now);  }  private Matcher1<Tuple2<DatabaseKey, DatabaseValue>> matchPattern(GlobPattern pattern) {    return entry -> pattern.match(entry.get1().toString());  }}
  • KeysCommand实现了DBCommand接口,其execute办法先通过createPattern创立GlobPattern,之后遍历db.entrySet(),过滤出matchPattern的,再过滤出非expired的,最初返回

DeleteCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/key/DeleteCommand.java

@Command("del")@ParamLength(1)public class DeleteCommand implements DBCommand {  @Override  public RedisToken execute(Database db, Request request) {    int removed = 0;    for (SafeString key : request.getParams()) {      DatabaseValue value = db.remove(safeKey(key));      if (value != null) {        removed += 1;      }    }    return integer(removed);  }}
  • DeleteCommand实现了DBCommand接口,其execute办法遍历request.getParams()执行db.remove(safeKey(key)),最初返回integer(removed)

ExistsCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/key/ExistsCommand.java

@ReadOnly@Command("exists")@ParamLength(1)public class ExistsCommand implements DBCommand {  @Override  public RedisToken execute(Database db, Request request) {    DatabaseValue value = db.get(safeKey(request.getParam(0)));    return integer(value != null ? !value.isExpired(Instant.now()) : false);  }}
  • ExistsCommand实现了DBCommand接口,其execute办法先通过db.get(safeKey(request.getParam(0)))获取DatabaseValue,之后判断是否null,非null的话再判断是否expired,非expired的返回true

TypeCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/key/TypeCommand.java

@ReadOnly@Command("type")@ParamLength(1)public class TypeCommand implements DBCommand {  @Override  public RedisToken execute(Database db, Request request) {    DatabaseValue value = db.get(safeKey(request.getParam(0)));    if (value != null) {      return status(value.getType().text());    } else {      return status(DataType.NONE.text());    }  }}
  • TypeCommand实现了DBCommand接口,其execute办法先通过db.get(safeKey(request.getParam(0)))获取DatabaseValue,若不为null则返回status(value.getType().text()),否则返回status(DataType.NONE.text())

RenameCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/key/RenameCommand.java

@Command("rename")@ParamLength(2)public class RenameCommand implements DBCommand {  @Override  public RedisToken execute(Database db, Request request) {    if (db.rename(safeKey(request.getParam(0)), safeKey(request.getParam(1)))) {      return responseOk();    } else {      return error("ERR no such key");    }  }}
  • RenameCommand实现了DBCommand接口,其execute办法执行db.rename

ExpireCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/key/ExpireCommand.java

@Command("expire")@ParamLength(2)public class ExpireCommand implements DBCommand {  @Override  public RedisToken execute(Database db, Request request) {    try {      DatabaseValue value = db.get(safeKey(request.getParam(0)));      if (value != null) {        db.put(safeKey(request.getParam(0)), value.expiredAt(parsetTtl(request.getParam(1))));      }      return integer(value != null);    } catch (NumberFormatException e) {      return error("ERR value is not an integer or out of range");    }  }  private int parsetTtl(SafeString param) {    return Integer.parseInt(param.toString());  }}
  • ExpireCommand实现了DBCommand接口,其execute办法先通过db.get(safeKey(request.getParam(0)))获取DatabaseValue,若不为null则执行value.expiredAt(parsetTtl(request.getParam(1))),而后put进去

PersistCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/key/PersistCommand.java

@Command("persist")@ParamLength(1)public class PersistCommand implements DBCommand {  @Override  public RedisToken execute(Database db, Request request) {    DatabaseValue value = db.get(safeKey(request.getParam(0)));    if (value != null) {      db.put(safeKey(request.getParam(0)), value.noExpire());    }    return integer(value != null);  }}
  • PersistCommand办法实现了DBCommand接口,其execute办法先通过db.get(safeKey(request.getParam(0)))获取DatabaseValue,若不为null则执行db.put(safeKey(request.getParam(0)), value.noExpire())

TimeToLiveCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/key/TimeToLiveCommand.java

public abstract class TimeToLiveCommand implements DBCommand {  @Override  public RedisToken execute(Database db, Request request) {    DatabaseValue value = db.get(safeKey(request.getParam(0)));    if (value != null) {      return keyExists(value);    } else {      return notExists();    }  }  protected abstract int timeToLive(DatabaseValue value, Instant now);  private RedisToken keyExists(DatabaseValue value) {    if (value.getExpiredAt() != null) {      return hasExpiredAt(value);    } else {      return integer(-1);    }  }  private RedisToken hasExpiredAt(DatabaseValue value) {    Instant now = Instant.now();    if (!value.isExpired(now)) {      return integer(timeToLive(value, now));    } else {      return notExists();    }  }  private RedisToken notExists() {    return integer(-2);  }}
  • TimeToLiveCommand申明实现DBCommand接口,其execute接口先通过db.get(safeKey(request.getParam(0)))获取DatabaseValue,若为null则返回notExists,若不为null则执行keyExists;keyExists办法在value.getExpiredAt()不为null时执行hasExpiredAt办法;hasExpiredAt办法在value.isExpired(now)为false时返回integer(timeToLive(value, now));timeToLive办法为形象办法,须要子类实现

TimeToLiveMillisCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/key/TimeToLiveMillisCommand.java

@Command("pttl")@ParamLength(1)public class TimeToLiveMillisCommand extends TimeToLiveCommand {  @Override  protected int timeToLive(DatabaseValue value, Instant now) {    return (int) value.timeToLiveMillis(now);  }}
  • TimeToLiveMillisCommand实现了TimeToLiveCommand接口,其timeToLive办法返回value.timeToLiveMillis(now)

TimeToLiveSecondsCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/key/TimeToLiveSecondsCommand.java

@Command("ttl")@ParamLength(1)public class TimeToLiveSecondsCommand extends TimeToLiveCommand {  @Override  protected int timeToLive(DatabaseValue value, Instant now) {    return value.timeToLiveSeconds(now);  }}
  • TimeToLiveSecondsCommand实现了TimeToLiveCommand接口,其timeToLive办法返回value.timeToLiveSeconds(now)

小结

claudb keys相干的command有KeysCommand、DeleteCommand、ExistsCommand、TypeCommand、RenameCommand、ExpireCommand、PersistCommand、TimeToLiveMillisCommand、TimeToLiveSecondsCommand

doc

  • KeysCommand