private void constructResourceFromTsFile() {
    Collection<ModEntry> modificationsForResource = tsFileResource.getAllModEntries();
    Map<IDeviceID, List<ChunkMetadata>> deviceChunkMetaDataMap = writer.getDeviceChunkMetadataMap();
    for (Map.Entry<IDeviceID, List<ChunkMetadata>> entry : deviceChunkMetaDataMap.entrySet()) {
      IDeviceID deviceId = entry.getKey();
      List<ChunkMetadata> chunkMetadataList = entry.getValue();

      // measurement -> ChunkMetadataList
      Map<String, List<ChunkMetadata>> measurementToChunkMetadatas = new HashMap<>();
      for (ChunkMetadata chunkMetadata : chunkMetadataList) {
        List<ChunkMetadata> list =
            measurementToChunkMetadatas.computeIfAbsent(
                chunkMetadata.getMeasurementUid(), n -> new ArrayList<>());
        list.add(chunkMetadata);
      }
      for (ChunkMetadata chunkMetaData : chunkMetadataList) {
        // calculate startTime and endTime according to chunkMetaData and modifications
        long startTime = chunkMetaData.getStartTime();
        long endTime = chunkMetaData.getEndTime();
        // exist deletion for current measurement
        for (ModEntry modification : modificationsForResource) {
          if (!(modification.affects(deviceId, startTime, endTime)
              && modification.affects(chunkMetaData.getMeasurementUid()))) {
            continue;
          }
          // deletion is valid for current chunk
          long modsStartTime = modification.getStartTime();
          long modsEndTime = modification.getEndTime();
          if (startTime >= modsStartTime && endTime <= modsEndTime) {
            startTime = Long.MAX_VALUE;
            endTime = Long.MIN_VALUE;
          } else if (startTime >= modsStartTime && startTime <= modsEndTime) {
            startTime = modsEndTime + 1;
          } else if (endTime >= modsStartTime && endTime <= modsEndTime) {
            endTime = modsStartTime - 1;
          }
        }

        tsFileResource.updateStartTime(deviceId, startTime);
        tsFileResource.updateEndTime(deviceId, endTime);
      }
    }
    tsFileResource.updatePlanIndexes(writer.getMinPlanIndex());
    tsFileResource.updatePlanIndexes(writer.getMaxPlanIndex());
  }
Make preparation for recovery, including load .resource file (reconstruct when necessary) and
truncate the file to remaining corrected data.

@throws DataRegionException when failing to recover.
@throws IOException when failing to recover.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/recover/file/UnsealedTsFileRecoverPerformer.java