共计 6232 个字符,预计需要花费 16 分钟才能阅读完成。
序
本文次要钻研一下 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