in java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java [1833:1961]
private Expression readChunk(
Expression buffer,
Expression map,
Expression size,
TypeRef<?> keyType,
TypeRef<?> valueType,
Expression chunkHeader) {
boolean keyMonomorphic = isMonomorphic(keyType);
boolean valueMonomorphic = isMonomorphic(valueType);
Class<?> keyTypeRawType = keyType.getRawType();
Class<?> valueTypeRawType = valueType.getRawType();
boolean trackingKeyRef = needWriteRef(keyType);
boolean trackingValueRef = needWriteRef(valueType);
boolean inline = keyMonomorphic && valueMonomorphic && (!trackingKeyRef || !trackingValueRef);
ListExpression expressions = new ListExpression(buffer);
Expression trackKeyRef = neq(bitand(chunkHeader, ofInt(TRACKING_KEY_REF)), ofInt(0));
Expression trackValueRef = neq(bitand(chunkHeader, ofInt(TRACKING_VALUE_REF)), ofInt(0));
Expression keyIsDeclaredType = neq(bitand(chunkHeader, ofInt(KEY_DECL_TYPE)), ofInt(0));
Expression valueIsDeclaredType = neq(bitand(chunkHeader, ofInt(VALUE_DECL_TYPE)), ofInt(0));
Expression chunkSize = new Invoke(buffer, "readUnsignedByte", "chunkSize", PRIMITIVE_INT_TYPE);
expressions.add(chunkSize);
Expression keySerializer, valueSerializer;
if (!keyMonomorphic && !valueMonomorphic) {
keySerializer = readOrGetSerializerForDeclaredType(buffer, keyTypeRawType, keyIsDeclaredType);
valueSerializer =
readOrGetSerializerForDeclaredType(buffer, valueTypeRawType, valueIsDeclaredType);
} else if (!keyMonomorphic) {
keySerializer = readOrGetSerializerForDeclaredType(buffer, keyTypeRawType, keyIsDeclaredType);
valueSerializer = getOrCreateSerializer(valueTypeRawType);
} else if (!valueMonomorphic) {
keySerializer = getOrCreateSerializer(keyTypeRawType);
valueSerializer =
readOrGetSerializerForDeclaredType(buffer, valueTypeRawType, valueIsDeclaredType);
} else {
keySerializer = getOrCreateSerializer(keyTypeRawType);
valueSerializer = getOrCreateSerializer(valueTypeRawType);
}
Expression keySerializerExpr = uninline(keySerializer);
Expression valueSerializerExpr = uninline(valueSerializer);
expressions.add(keySerializerExpr, valueSerializerExpr);
ForLoop readKeyValues =
new ForLoop(
ofInt(0),
chunkSize,
ofInt(1),
i -> {
boolean genKeyMethod =
useCollectionSerialization(keyType) || useMapSerialization(keyType);
boolean genValueMethod =
useCollectionSerialization(valueType) || useMapSerialization(valueType);
walkPath.add("key:" + keyType);
Expression keyAction, valueAction;
InvokeHint keyHint = new InvokeHint(genKeyMethod);
InvokeHint valueHint = new InvokeHint(genValueMethod);
if (genKeyMethod) {
keyHint.add(keySerializerExpr);
}
if (genValueMethod) {
valueHint.add(valueSerializer);
}
if (trackingKeyRef) {
keyAction =
new If(
trackKeyRef,
readRef(
buffer,
expr -> expr,
() ->
deserializeForNotNull(buffer, keyType, keySerializerExpr, keyHint)),
deserializeForNotNull(buffer, keyType, keySerializerExpr, keyHint),
false);
} else {
keyAction = deserializeForNotNull(buffer, keyType, keySerializerExpr, keyHint);
}
walkPath.removeLast();
walkPath.add("value:" + valueType);
if (trackingValueRef) {
valueAction =
new If(
trackValueRef,
readRef(
buffer,
expr -> expr,
() ->
deserializeForNotNull(
buffer, valueType, valueSerializerExpr, valueHint)),
deserializeForNotNull(buffer, valueType, valueSerializerExpr, valueHint),
false);
} else {
valueAction =
deserializeForNotNull(buffer, valueType, valueSerializerExpr, valueHint);
}
walkPath.removeLast();
return list(
new Invoke(map, "put", keyAction, valueAction),
new Assign(size, subtract(size, ofInt(1))));
});
expressions.add(readKeyValues);
if (inline) {
expressions.add(
new If(
gt(size, ofInt(0)),
new Assign(
chunkHeader, inlineInvoke(buffer, "readUnsignedByte", PRIMITIVE_INT_TYPE))));
return expressions;
} else {
Expression returnSizeAndHeader =
new If(
gt(size, ofInt(0)),
new Return(
(bitor(
shift("<<", size, 8),
inlineInvoke(buffer, "readUnsignedByte", PRIMITIVE_INT_TYPE)))),
new Return(ofInt(0)));
expressions.add(returnSizeAndHeader);
// method too big, spilt it into a new method.
// Generate similar signature as `AbstractMapSerializer.writeJavaChunk`(
// MemoryBuffer buffer,
// long size,
// int chunkHeader,
// Serializer keySerializer,
// Serializer valueSerializer
// )
Set<Expression> params = ofHashSet(buffer, size, chunkHeader, map);
return invokeGenerated(ctx, params, expressions, "readChunk", false);
}
}