2021SC@SDUSC
一、代码分析内容
本次博客我们继续介绍core-serializer包中的impl包。上个博客我介绍了其中的一部分,例如AbstractSerializerDefCollection类、AbstractSerializerDefMap类、ForwardingSerializerDef类、SerializerDefWithFixedSize类、SerializerDefWithNullable类、SerializerDefWithVarLength类、SerializerExpressions类。
这些类不是定义数据结构序列化的类,而是比较层次比较高的类,层次要比具体的数据结构要高一些。而这次博客就介绍定义数据结构序列化的类。
二、impl包结构
本次先介绍SerializerDefArray类、SerializerDefBoolean类、SerializerDefByte类、SerializerDefByteBuffer类、SerializerDefChar类和SerializerDefPrimitive类这六个类。
三、代码解读
1.SerializerDefPrimitive类
我们从类名中就可以看出这是序列化定义原语的类。原语在前面几次博客中也有提到过,它在序列化器中起着比较重要的作用。下面我们来看一下它的代码。
SerializerDefPrimitive类继承了AbstractSerializerDef类和SerializerDef抽象类。它定义了primitiveType、wrappedType、wrapped,分别是原语类型,包装类型,是否已经包装。下面是它的构造方法:
protected SerializerDefPrimitive(Class<?> primitiveType, boolean wrapped) {
if (!primitiveType.isPrimitive())
throw new IllegalArgumentException("Not a primitive type");
this.primitiveType = primitiveType;
this.wrappedType = wrap(primitiveType);
this.wrapped = wrapped;
}
在构造方法中有一个判断,判断是否是原语,如果不是就抛出异常。
下面是三个重写的方法,是重写的SerializerDef类中的,它是根据是否包装来返回包装类型或者原语类型。上下两个就是序列化定于原语的编码和解码方法。
@Override
public Class<?> getEncodeType() {
return wrapped ? wrappedType : primitiveType;
}
@Override
public final Expression encoder(StaticEncoders staticEncoders, Expression buf, Variable pos, Expression value, int version, CompatibilityLevel compatibilityLevel) {
return doSerialize(buf, pos, castToPrimitive() ? cast(value, primitiveType) : value, compatibilityLevel);
}
@Override
public final Expression decoder(StaticDecoders staticDecoders, Expression in, int version, CompatibilityLevel compatibilityLevel) {
Expression expression = doDeserialize(in, compatibilityLevel);
return wrapped ? cast(expression, wrappedType) : expression;
}
2.SerializerDefArray类
SerializerDefArray类是序列化定义数组的类,它继承AbstractSerializerDef类、SerializerDefWithNullable类和 SerializerDefWithFixedSize类。
因为是有关Array的,所以此类要定义fixedSize属性,而且数组可能会为空,所以也要定义nullable这个是否可为空的属性。下面是定义的属性和构造方法:
private final SerializerDef valueSerializer;
private final int fixedSize;
private final Class<?> type;
private final boolean nullable;
public SerializerDefArray(SerializerDef serializer, Class<?> type) {
this.valueSerializer = serializer;
this.fixedSize = -1;
this.type = type;
this.nullable = false;
}
private SerializerDefArray(@NotNull SerializerDef serializer, int fixedSize, Class<?> type, boolean nullable) {
this.valueSerializer = serializer;
this.fixedSize = fixedSize;
this.type = type;
this.nullable = nullable;
}
下面是两个重写的方法,分别是SerializerDefWithFixedSize类中的方法和SerializerDefWithNullable类中的方法。
@Override
public SerializerDefArray ensureFixedSize(int fixedSize) {
return new SerializerDefArray(valueSerializer, fixedSize, type, nullable);
}
@Override
public SerializerDef ensureNullable(CompatibilityLevel compatibilityLevel) {
if (compatibilityLevel.getLevel() < LEVEL_3.getLevel()) {
return new SerializerDefNullable(this);
}
return new SerializerDefArray(valueSerializer, fixedSize, type, true);
}
3.SerializerDefBoolean类
SerializerDefBoolean类是序列化定义Boolean的类。继承了SerializerDefPrimitive类和SerializerDefWithNullable类。
它定义的属性和构造方法如下:
public static final byte NULLABLE_NULL = 0b00;
public static final byte NULLABLE_FALSE = 0b10;
public static final byte NULLABLE_TRUE = 0b11;
private final boolean nullable;
public SerializerDefBoolean() {
this(true);
}
public SerializerDefBoolean(boolean wrapped) {
this(wrapped, false);
}
public SerializerDefBoolean(boolean wrapped, boolean nullable) {
super(boolean.class, wrapped);
if (nullable && !wrapped) throw new IllegalArgumentException("Primitive cannot be nullable");
this.nullable = nullable;
}
这是一个经过序列化包装的Boolean,它也重写了几个继承自SerializerDefPrimitive类的方法。原语在这里还是很重要的,有很多类都继承了此方法。
@Override
public SerializerDef ensureWrapped() {
return new SerializerDefBoolean(true, nullable);
}
@Override
protected boolean castToPrimitive() {
return !nullable;
}
4.SerializerDefByte类
SerializerDefByte类也继承了SerializerDefPrimitive类。因为是序列化定义的字节,所以比较内容比较简单,没有再定义新的属性,而是重写了SerializerDefPrimitive类中的几个方法。
public SerializerDefByte() {
this(true);
}
public SerializerDefByte(boolean wrapped) {
super(byte.class, wrapped);
}
@Override
public SerializerDef ensureWrapped() {
return new SerializerDefByte(true);
}
@Override
protected Expression doSerialize(Expression byteArray, Variable off, Expression value, CompatibilityLevel compatibilityLevel) {
return writeByte(byteArray, off, value);
}
@Override
protected Expression doDeserialize(Expression in, CompatibilityLevel compatibilityLevel) {
return readByte(in);
}
分别是确定包装、序列化和反序列化方法。序列化是使用writeByte方法实现,反序列化是使用readByte方法实现。
5.SerializerDefChar类
SerializerDefChar类和SerializerDefByte类类似,因为都是基本的数据类型,所以实现起来都是类似的。最大的区别就是这些方法都是换乘Char对象的了。序列化和反序列化方法使用的是writeChar方法和readChar方法。
public SerializerDefChar() {
this(true);
}
public SerializerDefChar(boolean wrapped) {
super(char.class, wrapped);
}
@Override
public SerializerDef ensureWrapped() {
return new SerializerDefChar(true);
}
@Override
protected Expression doSerialize(Expression byteArray, Variable off, Expression value, CompatibilityLevel compatibilityLevel) {
return writeChar(byteArray, off, value, !compatibilityLevel.isLittleEndian());
}
@Override
protected Expression doDeserialize(Expression in, CompatibilityLevel compatibilityLevel) {
return readChar(in, !compatibilityLevel.isLittleEndian());
}
6.SerializerDefByteBuffer类
SerializerDefByteBuffer类继承了AbstractSerializerDef类和 SerializerDefWithNullable类,它是序列化定义字节缓冲的类,定义的属性和构造方法如下:
private final boolean wrapped;
private final boolean nullable;
public SerializerDefByteBuffer() {
this(false);
}
public SerializerDefByteBuffer(boolean wrapped) {
this.wrapped = wrapped;
this.nullable = false;
}
这个类中最重要的是编码和解码方法,因为它是一个字节缓冲,所以它既要有Byte的属性还要对buffer进行定义和修改。编码需要对缓冲区间进行操作,编码的过程共要使用writeVarInt和writeBytes方法在缓冲的某一位置进行编写,解码过程就是编码过程反过来。下面是encoder方法:
public Expression encoder(StaticEncoders staticEncoders, Expression buf, Variable pos, Expression value, int version, CompatibilityLevel compatibilityLevel) {
return let(
cast(value, ByteBuffer.class),
buffer -> {
if (!nullable) {
return let(call(buffer, "remaining"), remaining ->
sequence(
writeVarInt(buf, pos, remaining),
writeBytes(buf, pos, call(buffer, "array"), call(buffer, "position"), remaining)));
} else {
return ifThenElse(isNull(buffer),
writeByte(buf, pos, value((byte) 0)),
let(call(buffer, "remaining"), remaining ->
sequence(
writeVarInt(buf, pos, inc(remaining)),
writeBytes(buf, pos, call(buffer, "array"), call(buffer, "position"), remaining))));
}
});
}
四、总结
本次博客分析的是impl包中另外的6个类。除了定义原语之外的5个类都是对一定的数据结构进行序列化定义,根据原本数据结构的复杂程度,序列化定义的复杂程度也有所不同,但它们的基本结构是类似的,且都有encoder和decoder方法。