public static TemplatedInfo deserialize(ByteBuffer byteBuffer) {

    int measurementSize = ReadWriteIOUtils.readInt(byteBuffer);
    List<String> measurementList = new ArrayList<>();
    int cnt = measurementSize;
    while (cnt-- > 0) {
      measurementList.add(ReadWriteIOUtils.readString(byteBuffer));
    }

    cnt = measurementSize;
    List<IMeasurementSchema> measurementSchemaList = new ArrayList<>();
    while (cnt-- > 0) {
      // MeasurementSchema is ok?
      measurementSchemaList.add(MeasurementSchema.deserializeFrom(byteBuffer));
    }

    cnt = measurementSize;
    List<TSDataType> dataTypeList = new ArrayList<>();
    while (cnt-- > 0) {
      dataTypeList.add(ReadWriteIOUtils.readDataType(byteBuffer));
    }

    Ordering scanOrder = Ordering.values()[ReadWriteIOUtils.readInt(byteBuffer)];

    boolean queryAllSensors = ReadWriteIOUtils.readBool(byteBuffer);

    int listSize = ReadWriteIOUtils.readInt(byteBuffer);
    List<String> selectMeasurements = new ArrayList<>(listSize);
    while (listSize-- > 0) {
      selectMeasurements.add(ReadWriteIOUtils.readString(byteBuffer));
    }

    listSize = ReadWriteIOUtils.readInt(byteBuffer);
    List<Integer> deviceToMeasurementIndexes = new ArrayList<>(listSize);
    while (listSize-- > 0) {
      deviceToMeasurementIndexes.add(ReadWriteIOUtils.readInt(byteBuffer));
    }

    long offsetValue = ReadWriteIOUtils.readLong(byteBuffer);

    long limitValue = ReadWriteIOUtils.readLong(byteBuffer);

    Expression predicate = null;
    boolean keepNull = false;
    Map<String, List<InputLocation>> filterLayoutMap = null;
    byte hasFilter = ReadWriteIOUtils.readByte(byteBuffer);
    if (hasFilter == 1) {
      predicate = Expression.deserialize(byteBuffer);
      keepNull = ReadWriteIOUtils.readBool(byteBuffer);
      filterLayoutMap = makeLayout(measurementList);
    }

    Map<String, IMeasurementSchema> measurementSchemaMap =
        new HashMap<>(measurementSchemaList.size());
    measurementSchemaList.forEach(
        measurementSchema ->
            measurementSchemaMap.put(measurementSchema.getMeasurementName(), measurementSchema));

    Expression pushDownPredicate = null;
    byte hasPushDownFilter = ReadWriteIOUtils.readByte(byteBuffer);
    if (hasPushDownFilter == 1) {
      pushDownPredicate = Expression.deserialize(byteBuffer);
    }

    boolean aggregationQuery = ReadWriteIOUtils.readBool(byteBuffer);
    GroupByTimeParameter groupByTimeParameter = null;
    boolean outputEndTime = false;
    List<AggregationDescriptor> ascendingDescriptorList = null;
    List<AggregationDescriptor> descendingDescriptorList = null;

    if (aggregationQuery) {
      byte hasGroupByTime = ReadWriteIOUtils.readByte(byteBuffer);
      if (hasGroupByTime == 1) {
        groupByTimeParameter = GroupByTimeParameter.deserialize(byteBuffer);
      }

      outputEndTime = ReadWriteIOUtils.readBool(byteBuffer);

      int size = ReadWriteIOUtils.readInt(byteBuffer);
      ascendingDescriptorList = new ArrayList<>(size);
      while (size-- > 0) {
        ascendingDescriptorList.add(AggregationDescriptor.deserialize(byteBuffer));
      }

      size = ReadWriteIOUtils.readInt(byteBuffer);
      descendingDescriptorList = new ArrayList<>(size);
      while (size-- > 0) {
        descendingDescriptorList.add(AggregationDescriptor.deserialize(byteBuffer));
      }
    }

    TemplatedInfo templatedInfo =
        new TemplatedInfo(
            measurementList,
            measurementSchemaList,
            dataTypeList,
            scanOrder,
            queryAllSensors,
            selectMeasurements,
            deviceToMeasurementIndexes,
            offsetValue,
            limitValue,
            predicate,
            keepNull,
            measurementSchemaMap,
            filterLayoutMap,
            pushDownPredicate,
            aggregationQuery,
            groupByTimeParameter,
            outputEndTime);
    templatedInfo.setAscendingDescriptorList(ascendingDescriptorList);
    templatedInfo.setDescendingDescriptorList(descendingDescriptorList);
    return templatedInfo;
  }
If in align by device query ,all queried devices are set in one template, we can store the common
variables in TemplatedInfo to avoid repeated creation.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedInfo.java