本文次要钻研一下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