序
本文次要钻研一下claudb的list command
LeftPushCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/list/LeftPushCommand.java
@Command("lpush")@ParamLength(2)@ParamType(DataType.LIST)public class LeftPushCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { ImmutableList<SafeString> values = request.getParams().asList().tail().reverse(); DatabaseValue result = db.merge(safeKey(request.getParam(0)), list(values), (oldValue, newValue) -> list(newValue.getList().appendAll(oldValue.getList()))); return RedisToken.integer(result.size()); }}
- LeftPushCommand实现了DBCommand接口,其execute办法提取values,而后执行db.merge,在newValue.getList()之后追加上oldValue.getList()
LeftPopCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/list/LeftPopCommand.java
@Command("lpop")@ParamLength(1)@ParamType(DataType.LIST)public class LeftPopCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { List<SafeString> removed = new LinkedList<>(); db.merge(safeKey(request.getParam(0)), DatabaseValue.EMPTY_LIST, (oldValue, newValue) -> { ImmutableList<SafeString> list = oldValue.getList(); list.head().stream().forEach(removed::add); return list(list.tail()); }); if (removed.isEmpty()) { return nullString(); } else { return string(removed.remove(0)); } }}
- LeftPopCommand实现了DBCommand接口,其execute办法执行db.merge,它先获取oldValue.getList(),而后取出head增加到removed中,而后再通过list.tail()抛弃head作为新的后果
RightPushCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/list/RightPushCommand.java
@Command("rpush")@ParamLength(2)@ParamType(DataType.LIST)public class RightPushCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { ImmutableList<SafeString> values = request.getParams().asList().tail(); DatabaseValue result = db.merge(safeKey(request.getParam(0)), list(values), (oldValue, newValue) -> list(oldValue.getList().appendAll(newValue.getList()))); return integer(result.size()); }}
- RightPushCommand实现了DBCommand接口,其execute办法提取values,而后执行db.merge,在oldValue.getList()之后追加上newValue.getList()
RightPopCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/list/RightPopCommand.java
@Command("rpop")@ParamLength(1)@ParamType(DataType.LIST)public class RightPopCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { List<SafeString> removed = new LinkedList<>(); db.merge(safeKey(request.getParam(0)), DatabaseValue.EMPTY_LIST, (oldValue, newValue) -> { ImmutableList<SafeString> list = oldValue.getList(); list.reverse().head().stream().forEach(removed::add); return list(list.reverse().tail().reverse()); }); if (removed.isEmpty()) { return nullString(); } else { return string(removed.remove(0)); } }}
- RightPopCommand实现了DBCommand接口,其execute办法执行db.merge,它先获取oldValue.getList(),而后取出list倒数的head增加到removed中,而后再通过list.reverse().tail()抛弃head再reverse作为新的后果
ListLengthCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/list/ListLengthCommand.java
@ReadOnly@Command("llen")@ParamLength(1)@ParamType(DataType.LIST)public class ListLengthCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { ImmutableList<SafeString> list = db.getList(request.getParam(0)); return integer(list.size()); }}
- ListLengthCommand实现了DBCommand接口,其execute办法先通过db.getList(request.getParam(0))获取list,而后返回integer(list.size())
ListRangeCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/list/ListRangeCommand.java
@ReadOnly@Command("lrange")@ParamLength(3)@ParamType(DataType.LIST)public class ListRangeCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { try { DatabaseValue value = db.getOrDefault(safeKey(request.getParam(0)), DatabaseValue.EMPTY_LIST); ImmutableList<SafeString> list = value.getList(); int from = Integer.parseInt(request.getParam(1).toString()); if (from < 0) { from = list.size() + from; } int to = Integer.parseInt(request.getParam(2).toString()); if (to < 0) { to = list.size() + to; } int min = Math.min(from, to); int max = Math.max(from, to); // TODO: use Array ImmutableList<SafeString> result = ImmutableList.from(list.stream().skip(min).limit((max - min) + 1)); return convert(result); } catch (NumberFormatException e) { return error("ERR value is not an integer or out of range"); } }}
- ListRangeCommand实现了DBCommand接口,其execute办法先获取list,之后修改min及max,而后取ImmutableList.from(list.stream().skip(min).limit((max - min) + 1))
ListIndexCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/list/ListIndexCommand.java
@ReadOnly@Command("lindex")@ParamLength(2)@ParamType(DataType.LIST)public class ListIndexCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { try { ImmutableList<SafeString> list = db.getList(request.getParam(0)); int index = Integer.parseInt(request.getParam(1).toString()); if (index < 0) { index = list.size() + index; } // TODO: fix asArray return string(list.asArray().get(index)); } catch (NumberFormatException e) { return error("ERR value is not an integer or out of range"); } catch (IndexOutOfBoundsException e) { return nullString(); } }}
- ListIndexCommand实现了DBCommand接口,其execute办法先获取list,而后返回string(list.asArray().get(index))
ListSetCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/list/ListSetCommand.java
@Command("lset")@ParamLength(3)@ParamType(DataType.LIST)public class ListSetCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { try { int index = Integer.parseInt(request.getParam(1).toString()); db.merge(safeKey(request.getParam(0)), DatabaseValue.EMPTY_LIST, (oldValue, newValue) -> { ImmutableList<SafeString> oldList = oldValue.getList(); // TODO: use Array List<SafeString> array = new ArrayList<>(oldList.toList()); array.set(index > -1 ? index : array.size() + index, request.getParam(2)); return list(array); }); return status("OK"); } catch (NumberFormatException e) { return error("ERR value is not an integer or out of range"); } catch (IndexOutOfBoundsException e) { return error("ERR index out of range"); } }}
- ListSetCommand实现了DBCommand接口,其execute办法先读取index参数,而后执行db.merge,它读取oldList,而后执行array.set(index > -1 ? index : array.size() + index, request.getParam(2)),最初返回list(array)
小结
claudb list相干的command有LeftPushCommand、LeftPopCommand、RightPushCommand、RightPopCommand、ListLengthCommand、ListRangeCommand、ListIndexCommand、ListSetCommand
doc
- command/list