in java/fury-core/src/main/java/org/apache/fury/meta/ClassDefEncoder.java [126:207]
static MemoryBuffer encodeClassDef(
ClassResolver classResolver,
Class<?> type,
Map<String, List<FieldInfo>> classLayers,
boolean isObjectType) {
MemoryBuffer classDefBuf = MemoryBuffer.newHeapBuffer(128);
for (Map.Entry<String, List<FieldInfo>> entry : classLayers.entrySet()) {
String className = entry.getKey();
List<FieldInfo> fields = entry.getValue();
// | num fields + register flag | header + package name | header + class name
// | header + type id + field name | next field info | ... |
int currentClassHeader = (fields.size() << 1);
if (classResolver.isRegisteredById(type)) {
currentClassHeader |= 1;
classDefBuf.writeVarUint32Small7(currentClassHeader);
classDefBuf.writeVarUint32Small7(classResolver.getRegisteredClassId(type));
} else {
classDefBuf.writeVarUint32Small7(currentClassHeader);
Class<?> currentType = getType(type, className);
String ns, typename;
if (classResolver.isRegisteredByName(type)) {
Tuple2<String, String> nameTuple = classResolver.getRegisteredNameTuple(type);
ns = nameTuple.f0;
typename = nameTuple.f1;
} else {
Tuple2<String, String> encoded = Encoders.encodePkgAndClass(currentType);
ns = encoded.f0;
typename = encoded.f1;
}
writePkgName(classDefBuf, ns);
writeTypeName(classDefBuf, typename);
}
writeFieldsInfo(classDefBuf, fields);
}
byte[] compressed =
classResolver
.getFury()
.getConfig()
.getMetaCompressor()
.compress(classDefBuf.getHeapMemory(), 0, classDefBuf.writerIndex());
boolean isCompressed = false;
if (compressed.length < classDefBuf.writerIndex()) {
isCompressed = true;
classDefBuf = MemoryBuffer.fromByteArray(compressed);
classDefBuf.writerIndex(compressed.length);
}
long hash =
MurmurHash3.murmurhash3_x64_128(
classDefBuf.getHeapMemory(), 0, classDefBuf.writerIndex(), 47)[0];
long header;
int numClasses = classLayers.size() - 1; // num class must be greater than 0
if (numClasses > 0b1110) {
header = 0b1111;
} else {
header = numClasses;
}
header |= SCHEMA_COMPATIBLE_FLAG;
if (isObjectType) {
header |= OBJECT_TYPE_FLAG;
}
if (isCompressed) {
header |= COMPRESSION_FLAG;
}
// this id will be part of generated codec, a negative number won't be allowed in class name.
hash <<= 8;
header |= Math.abs(hash);
MemoryBuffer buffer = MemoryUtils.buffer(classDefBuf.writerIndex() + 10);
int len = classDefBuf.writerIndex() + toInt(numClasses > 0b1110);
if (len > 255) {
header |= SIZE_TWO_BYTES_FLAG;
buffer.writeInt64(header);
buffer.writeInt16((short) len);
} else {
buffer.writeInt64(header);
buffer.writeByte(len);
}
if (numClasses > 0b1110) {
buffer.writeVarUint32Small7(numClasses - 0b1110);
}
buffer.writeBytes(classDefBuf.getHeapMemory(), 0, classDefBuf.writerIndex());
return buffer;
}