聊聊RedisTokenVisitor
时间:2022-07-23
本文章向大家介绍聊聊RedisTokenVisitor,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
序
本文主要研究一下RedisTokenVisitor
RedisTokenVisitor
resp-server-0.16.0/src/main/java/com/github/tonivade/resp/protocol/RedisTokenVisitor.java
public interface RedisTokenVisitor<T> {
T array(ArrayRedisToken token);
T status(StatusRedisToken token);
T string(StringRedisToken token);
T integer(IntegerRedisToken token);
T error(ErrorRedisToken token);
T unknown(UnknownRedisToken token);
static <T> LambdaRedisTokenVisitor.Builder<T> builder() {
return new LambdaRedisTokenVisitor.Builder<>();
}
}
- RedisTokenVisitor接口定义了array、status、string、integer、error、unknown方法,并提供了静态builder方法用于创建LambdaRedisTokenVisitor.Builder
AbstractRedisTokenVisitor
resp-server-0.16.0/src/main/java/com/github/tonivade/resp/protocol/AbstractRedisTokenVisitor.java
public abstract class AbstractRedisTokenVisitor<T> implements RedisTokenVisitor<T> {
@Override
public T array(ArrayRedisToken token) {
return null;
}
@Override
public T status(StatusRedisToken token) {
return null;
}
@Override
public T string(StringRedisToken token) {
return null;
}
@Override
public T error(ErrorRedisToken token) {
return null;
}
@Override
public T unknown(UnknownRedisToken token) {
return null;
}
@Override
public T integer(IntegerRedisToken token) {
return null;
}
}
- AbstractRedisTokenVisitor实现了RedisTokenVisitor接口,默认返回null
LambdaRedisTokenVisitor
resp-server-0.16.0/src/main/java/com/github/tonivade/resp/protocol/LambdaRedisTokenVisitor.java
class LambdaRedisTokenVisitor<T> implements RedisTokenVisitor<T> {
private Function<ArrayRedisToken, T> onArray;
private Function<StatusRedisToken, T> onStatus;
private Function<StringRedisToken, T> onString;
private Function<ErrorRedisToken, T> onError;
private Function<IntegerRedisToken, T> onInteger;
private Function<UnknownRedisToken, T> onUnknown;
LambdaRedisTokenVisitor(
Function<ArrayRedisToken, T> onArray,
Function<StatusRedisToken, T> onStatus,
Function<StringRedisToken, T> onString,
Function<ErrorRedisToken, T> onError,
Function<IntegerRedisToken, T> onInteger,
Function<UnknownRedisToken, T> onUnknown) {
this.onArray = onArray;
this.onStatus = onStatus;
this.onString = onString;
this.onError = onError;
this.onInteger = onInteger;
this.onUnknown = onUnknown;
}
@Override
public T array(ArrayRedisToken token) {
return onArray.apply(token);
}
@Override
public T status(StatusRedisToken token) {
return onStatus.apply(token);
}
@Override
public T string(StringRedisToken token) {
return onString.apply(token);
}
@Override
public T error(ErrorRedisToken token) {
return onError.apply(token);
}
@Override
public T unknown(UnknownRedisToken token) {
return onUnknown.apply(token);
}
@Override
public T integer(IntegerRedisToken token) {
return onInteger.apply(token);
}
public static class Builder<T> {
private Function<ArrayRedisToken, T> onArray;
private Function<StatusRedisToken, T> onStatus;
private Function<StringRedisToken, T> onString;
private Function<ErrorRedisToken, T> onError;
private Function<IntegerRedisToken, T> onInteger;
private Function<UnknownRedisToken, T> onUnknown;
public Builder<T> onArray(Function<ArrayRedisToken, T> onArray) {
this.onArray = requireNonNull(onArray);
return this;
}
public Builder<T> onStatus(Function<StatusRedisToken, T> onStatus) {
this.onStatus = requireNonNull(onStatus);
return this;
}
public Builder<T> onString(Function<StringRedisToken, T> onString) {
this.onString = requireNonNull(onString);
return this;
}
public Builder<T> onError(Function<ErrorRedisToken, T> onError) {
this.onError = requireNonNull(onError);
return this;
}
public Builder<T> onInteger(Function<IntegerRedisToken, T> onInteger) {
this.onInteger = requireNonNull(onInteger);
return this;
}
public Builder<T> onUnknown(Function<UnknownRedisToken, T> onUnknown) {
this.onUnknown = requireNonNull(onUnknown);
return this;
}
public RedisTokenVisitor<T> build() {
return new LambdaRedisTokenVisitor<>(
safe(onArray), safe(onStatus), safe(onString),
safe(onError), safe(onInteger), safe(onUnknown));
}
private <X> Function<X, T> safe(Function<X, T> function) {
return nonNull(function) ? function : x -> null;
}
}
}
- LambdaRedisTokenVisitor实现了RedisTokenVisitor接口,其构造器要求输入onArray、onStatus、onString、onError、onInteger、onUnknown这几个Function
RedisSerializer
resp-server-0.16.0/src/main/java/com/github/tonivade/resp/protocol/RedisSerializer.java
public class RedisSerializer {
private static final byte ARRAY = '*';
private static final byte ERROR = '-';
private static final byte INTEGER = ':';
private static final byte SIMPLE_STRING = '+';
private static final byte BULK_STRING = '$';
private static final byte[] DELIMITER = new byte[] { 'r', 'n' };
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private ByteBufferBuilder builder = new ByteBufferBuilder();
public byte[] encodeToken(RedisToken msg) {
msg.accept(new AbstractRedisTokenVisitor<Void>() {
@Override
public Void string(StringRedisToken token) {
addBulkStr(token.getValue());
return null;
}
@Override
public Void status(StatusRedisToken token) {
addSimpleStr(token.getValue());
return null;
}
@Override
public Void integer(IntegerRedisToken token) {
addInt(token.getValue());
return null;
}
@Override
public Void error(ErrorRedisToken token) {
addError(token.getValue());
return null;
}
@Override
public Void array(ArrayRedisToken token) {
addArray(token.getValue());
return null;
}
});
return builder.build();
}
private void addBulkStr(SafeString str) {
if (str != null) {
builder.append(BULK_STRING).append(str.length()).append(DELIMITER).append(str);
} else {
builder.append(BULK_STRING).append(-1);
}
builder.append(DELIMITER);
}
private void addSimpleStr(String str) {
builder.append(SIMPLE_STRING).append(str.getBytes()).append(DELIMITER);
}
private void addInt(Integer value) {
builder.append(INTEGER).append(value).append(DELIMITER);
}
private void addError(String str) {
builder.append(ERROR).append(str.getBytes()).append(DELIMITER);
}
private void addArray(Sequence<RedisToken> array) {
if (array != null) {
builder.append(ARRAY).append(array.size()).append(DELIMITER);
for (RedisToken token : array) {
builder.append(new RedisSerializer().encodeToken(token));
}
} else {
builder.append(ARRAY).append(0).append(DELIMITER);
}
}
private static class ByteBufferBuilder {
private static final int INITIAL_CAPACITY = 1024;
private ByteBuffer buffer = ByteBuffer.allocate(INITIAL_CAPACITY);
private ByteBufferBuilder append(int i) {
append(String.valueOf(i));
return this;
}
private ByteBufferBuilder append(String str) {
append(str.getBytes(DEFAULT_CHARSET));
return this;
}
private ByteBufferBuilder append(SafeString str) {
append(str.getBytes());
return this;
}
private ByteBufferBuilder append(byte[] buf) {
ensureCapacity(buf.length);
buffer.put(buf);
return this;
}
public ByteBufferBuilder append(byte b) {
ensureCapacity(1);
buffer.put(b);
return this;
}
private void ensureCapacity(int len) {
if (buffer.remaining() < len) {
growBuffer(len);
}
}
private void growBuffer(int len) {
int capacity = buffer.capacity() + Math.max(len, INITIAL_CAPACITY);
buffer = ByteBuffer.allocate(capacity).put(build());
}
public byte[] build() {
byte[] array = new byte[buffer.position()];
buffer.rewind();
buffer.get(array);
return array;
}
}
}
- RedisSerializer的encodeToken方法创建了匿名AbstractRedisTokenVisitor;其string方法执行addBulkStr(token.getValue());其status方法执行addSimpleStr(token.getValue());其integer方法执行addInt(token.getValue());其error方法执行addError(token.getValue());其array方法执行addArray(token.getValue())
小结
RedisTokenVisitor接口定义了array、status、string、integer、error、unknown方法,并提供了静态builder方法用于创建LambdaRedisTokenVisitor.Builder;目前RedisSerializer的encodeToken方法创建了匿名AbstractRedisTokenVisitor,提供了一个实现。不过目前这个接口的设计有点坏味道,理论上应该把差异提取到泛型中。
doc
- 我的数据访问函数库的源代码(四)—— 存储过程部分,包括存储过程的参数的封装
- [WCF 4.0新特性] 路由服务[实例篇]
- [WCF 4.0新特性] 默认终结点
- 三层架构之我见 —— 不同于您见过的三层架构。
- 来源于WCF的设计模式:可扩展对象模式[下篇]
- [WCF 4.0新特性] 标准终结点与无(.SVC)文件服务激活
- 我的数据访问类(第二版)—— for .net2.0 (二)
- 我的数据访问类(第二版)—— for .net2.0 (一)
- [WCF 4.0新特性] 路由服务[原理篇]
- 通过“访问多种数据库”的代码来学习多态!(.net2.0版)
- [WCF-Discovery] 客户端如何能够“探测”到可用的服务?
- WCF的安全审核——记录谁在敲打你的门
- Step By Step 一步一步写网站[1] —— 填加数据
- 五个解决方案让MongoDB拥有RDBMS的鲁棒性事务
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 关于 servlet 的这个问题,你能答对吗?
- MYSQL数据优化常用配置参数
- Hadoop分块存储解析及还原分块存储的文件
- ValueError: too many values to unpack (expected 2)
- VMware15更新后克隆Centos7发现网卡起不来了
- 基于SSH的医院在线挂号
- Linux-远程拷贝(scp命令)
- Kettle使用JavaScript代码处理数据
- Hadoop入门---(wordcount)统计单词出现的次数
- JS去除字符串的空格
- insertionSoft(插入排序) 2.1-1 And 重写insertionSoft 2.1-2
- Swagger-Springboot-mybatis-mysql
- Python+java+websocket+SpringMVC实时监控数据库中的表
- 基于Java图形界面的IPV4与网址的地址解析器
- 如何在千里之外能访问自己的电脑?(FRP)