static FileInfo calculateFileInfo(TsFileSequenceReader reader) throws IOException {
    int totalChunkNum = 0;
    int maxChunkNum = 0;
    int maxAlignedSeriesNumInDevice = -1;
    int maxDeviceChunkNum = 0;
    long maxMemCostToReadAlignedSeriesMetadata = 0;
    long maxMemCostToReadNonAlignedSeriesMetadata = 0;
    TsFileDeviceIterator deviceIterator = reader.getAllDevicesIteratorWithIsAligned();
    long totalMetadataSize = 0;
    while (deviceIterator.hasNext()) {
      int deviceChunkNum = 0;
      int alignedSeriesNumInDevice = 0;

      Pair<IDeviceID, Boolean> deviceWithIsAlignedPair = deviceIterator.next();
      IDeviceID device = deviceWithIsAlignedPair.left;
      boolean isAlignedDevice = deviceWithIsAlignedPair.right;
      long memCostToReadMetadata = 0;

      Iterator<Map<String, List<ChunkMetadata>>> measurementChunkMetadataListMapIterator =
          reader.getMeasurementChunkMetadataListMapIterator(device);
      while (measurementChunkMetadataListMapIterator.hasNext()) {
        Map<String, List<ChunkMetadata>> measurementChunkMetadataListMap =
            measurementChunkMetadataListMapIterator.next();
        if (isAlignedDevice) {
          alignedSeriesNumInDevice += measurementChunkMetadataListMap.size();
        }

        for (Map.Entry<String, List<ChunkMetadata>> measurementChunkMetadataList :
            measurementChunkMetadataListMap.entrySet()) {
          int currentChunkMetadataListSize = measurementChunkMetadataList.getValue().size();
          long measurementNameRamSize =
              RamUsageEstimator.sizeOf(measurementChunkMetadataList.getKey());
          long chunkMetadataMemCost = 0;
          long currentSeriesRamSize = measurementNameRamSize;
          for (ChunkMetadata chunkMetadata : measurementChunkMetadataList.getValue()) {
            // chunkMetadata should not be a null value
            if (chunkMetadata != null) {
              TSDataType dataType = chunkMetadata.getDataType();
              chunkMetadataMemCost =
                  chunkMetadataMemCost != 0
                      ? chunkMetadataMemCost
                      : (ChunkMetadata.calculateRamSize(chunkMetadata.getMeasurementUid(), dataType)
                          - measurementNameRamSize);
              if (dataType == TSDataType.TEXT) {
                // add ram size for first value and last value
                currentSeriesRamSize +=
                    chunkMetadata.getStatistics().getRetainedSizeInBytes()
                        - BinaryStatistics.INSTANCE_SIZE;
              } else {
                break;
              }
            } else {
              LOGGER.warn(
                  "{} has null chunk metadata, file is {}",
                  device.toString() + "." + measurementChunkMetadataList.getKey(),
                  reader.getFileName());
            }
          }
          currentSeriesRamSize += chunkMetadataMemCost * currentChunkMetadataListSize;
          if (isAlignedDevice) {
            memCostToReadMetadata += currentSeriesRamSize;
          } else {
            maxMemCostToReadNonAlignedSeriesMetadata =
                Math.max(maxMemCostToReadNonAlignedSeriesMetadata, currentSeriesRamSize);
          }
          deviceChunkNum += currentChunkMetadataListSize;
          totalChunkNum += currentChunkMetadataListSize;
          maxChunkNum = Math.max(maxChunkNum, currentChunkMetadataListSize);
          totalMetadataSize += currentSeriesRamSize;
        }
      }
      if (isAlignedDevice) {
        maxAlignedSeriesNumInDevice =
            Math.max(maxAlignedSeriesNumInDevice, alignedSeriesNumInDevice);
      }
      maxDeviceChunkNum = Math.max(maxDeviceChunkNum, deviceChunkNum);
      maxMemCostToReadAlignedSeriesMetadata =
          Math.max(maxMemCostToReadAlignedSeriesMetadata, memCostToReadMetadata);
    }
    long averageChunkMetadataSize = totalChunkNum == 0 ? 0 : totalMetadataSize / totalChunkNum;
    return new FileInfo(
        totalChunkNum,
        maxChunkNum,
        maxAlignedSeriesNumInDevice,
        maxDeviceChunkNum,
        averageChunkMetadataSize,
        maxMemCostToReadAlignedSeriesMetadata,
        maxMemCostToReadNonAlignedSeriesMetadata);
  }
Get the details of the tsfile, the returned array contains the following elements in sequence:

<p>total chunk num in this tsfile

<p>max chunk num of one timeseries in this tsfile

<p>max aligned series num in one device. If there is no aligned series in this file, then it
turns to be -1.

<p>max chunk num of one device in this tsfile

@throws IOException if io errors occurred
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/estimator/CompactionEstimateUtils.java