本文主要研究一下claudb的hash command

HashSetCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/hash/HashSetCommand.java

@Command("hset")
@ParamLength(3)
@ParamType(DataType.HASH)
public class HashSetCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {
    DatabaseValue value = hash(entry(request.getParam(1), request.getParam(2)));

    DatabaseValue resultValue = db.merge(safeKey(request.getParam(0)), value,
        (oldValue, newValue) -> {
          Map<SafeString, SafeString> merge = new HashMap<>();
          merge.putAll(oldValue.getHash().toMap());
          merge.putAll(newValue.getHash().toMap());
          return hash(ImmutableMap.from(merge));
        });

    ImmutableMap<SafeString, SafeString> resultMap = resultValue.getHash();

    return integer(resultMap.get(request.getParam(1)) == null);
  }
}
  • HashSetCommand实现了DBCommand接口,其execute方法先获取DatabaseValue,然后执行db.merge,先添加oldValue.getHash().toMap()再添加newValue.getHash().toMap()

HashGetCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/hash/HashGetCommand.java

@ReadOnly
@Command("hget")
@ParamLength(2)
@ParamType(DataType.HASH)
public class HashGetCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {
    ImmutableMap<SafeString, SafeString> map = db.getHash(request.getParam(0));
    return map.get(request.getParam(1))
        .map(RedisToken::string)
        .getOrElse(RedisToken::nullString);
  }
}
  • HashGetCommand实现了DBCommand接口,其execute先获取map,然后在从map取出指定key的值

HashGetAllCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/hash/HashGetAllCommand.java

@ReadOnly
@Command("hgetall")
@ParamLength(1)
@ParamType(DataType.HASH)
public class HashGetAllCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {
    DatabaseValue value = db.get(safeKey(request.getParam(0)));
    if (value != null) {
      return convert(value);
    } else {
      return array();
    }
  }
}
  • HashGetAllCommand实现了DBCommand接口,其execute方法获取DatabaseValue,然后convert一下返回

HashExistsCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/hash/HashExistsCommand.java

@ReadOnly
@Command("hexists")
@ParamLength(2)
@ParamType(DataType.HASH)
public class HashExistsCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {
    ImmutableMap<SafeString, SafeString> map = db.getHash(request.getParam(0));
    return integer(map.containsKey(request.getParam(1)));
  }
}
  • HashExistsCommand实现了DBCommand接口,其execute方法先获取db.getHash(request.getParam(0)),然后再通过map.containsKey(request.getParam(1))判断是否存在

HashDeleteCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/hash/HashDeleteCommand.java

@Command("hdel")
@ParamLength(2)
@ParamType(DataType.HASH)
public class HashDeleteCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {
    ImmutableList<SafeString> keys = request.getParams().asList().tail();

    List<SafeString> removedKeys = new LinkedList<>();
    db.merge(safeKey(request.getParam(0)), DatabaseValue.EMPTY_HASH, (oldValue, newValue) -> {
      ImmutableMap<SafeString, SafeString> merge = oldValue.getHash();
      for (SafeString key : keys) {
        merge.get(key).stream().forEach(removedKeys::add);
        merge = merge.remove(key);
      }
      return hash(merge);
    });

    return integer(!removedKeys.isEmpty());
  }
}
  • HashDeleteCommand实现了DBCommand接口,其execute方法先从请求参数提取keys,然后执行db.merge,该方法先获取oldValue.getHash(),然后遍历keys挨个remove

HashKeysCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/hash/HashKeysCommand.java

@ReadOnly
@Command("hkeys")
@ParamLength(1)
@ParamType(DataType.HASH)
public class HashKeysCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {
    ImmutableMap<SafeString, SafeString> map = db.getHash(request.getParam(0));
    return convert(map.keys());
  }
}
  • HashKeysCommand实现了DBCommand接口,其execute方法执行db.getHash(request.getParam(0)),然后返回map.keys()

HashLengthCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/hash/HashLengthCommand.java

@ReadOnly
@Command("hlen")
@ParamLength(1)
@ParamType(DataType.HASH)
public class HashLengthCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {
    ImmutableMap<SafeString, SafeString> hash = db.getHash(request.getParam(0));
    return integer(hash.size());
  }
}
  • HashLengthCommand实现了DBCommand接口,其execute方法先获取db.getHash(request.getParam(0)),然后返回hash.size()

HashMultiGetCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/hash/HashMultiGetCommand.java

@ReadOnly
@Command("hmget")
@ParamLength(2)
@ParamType(DataType.HASH)
public class HashMultiGetCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {

    ImmutableMap<SafeString, SafeString> map = db.getHash(request.getParam(0));

    List<RedisToken> rtList = new ArrayList<>();

    for (int paramNumber = 1; paramNumber < request.getParams().size(); paramNumber++) {
      Option<SafeString> oss = map.get(request.getParam(paramNumber));
      rtList.add(oss.map(RedisToken::string).getOrElse(RedisToken::nullString));
    }

    return convert(rtList);
  }

}
  • HashMultiGetCommand实现了DBCommand接口,其execute方法先获取db.getHash(request.getParam(0)),然后遍历request.getParams(),挨个取出指定key的元素添加到rtList

HashMultiSetCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/hash/HashMultiSetCommand.java

@Command("hmset")
@ParamLength(3)
@ParamType(DataType.HASH)
public class HashMultiSetCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {

    for (int paramNumber = 1; paramNumber < request.getParams().size(); paramNumber += 2) {

      SafeString mapKey = request.getParam(paramNumber);
      SafeString mapVal = request.getParam(paramNumber + 1);

      DatabaseValue value = hash(entry(mapKey, mapVal));

      db.merge(safeKey(request.getParam(0)), value,
          (oldValue, newValue) -> {
            Map<SafeString, SafeString> merge = new HashMap<>();
            merge.putAll(oldValue.getHash().toMap());
            merge.putAll(newValue.getHash().toMap());
            return hash(ImmutableMap.from(merge));
          }
      );

    }

    return responseOk();
  }
}
  • HashMultiSetCommand实现了DBCommand接口,其execute方法遍历request.getParams(),挨个执行hash(entry(mapKey, mapVal)),然后在db.merge里头添加进去

HashValuesCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/hash/HashValuesCommand.java

@ReadOnly
@Command("hvals")
@ParamLength(1)
@ParamType(DataType.HASH)
public class HashValuesCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {
    ImmutableMap<SafeString, SafeString> map = db.getHash(request.getParam(0));
    return convert(map.values());
  }
}
  • HashValuesCommand实现了DBCommand接口,其execute方法先获取db.getHash(request.getParam(0)),然后返回map.values()

小结

claudb hash相关的command有HashSetCommand、HashGetCommand、HashGetAllCommand、HashExistsCommand、HashDeleteCommand、HashKeysCommand、HashLengthCommand、HashMultiGetCommand、HashMultiSetCommand、HashValuesCommand

doc


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...