private Expression readChunk()

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);
    }
  }