public void deleteByDevice(final MeasurementPath pattern, final DeleteDataNode node)
      throws IOException {
    if (SettleService.getINSTANCE().getFilesToBeSettledCount().get() != 0) {
      throw new IOException(
          "Delete failed. " + "Please do not delete until the old files settled.");
    }
    final long startTime = node.getDeleteStartTime();
    final long endTime = node.getDeleteEndTime();
    final long searchIndex = node.getSearchIndex();
    // TODO: how to avoid partial deletion?
    // FIXME: notice that if we may remove a SGProcessor out of memory, we need to close all opened
    // mod files in mergingModification, sequenceFileList, and unsequenceFileList
    writeLock("delete");

    boolean hasReleasedLock = false;

    try {
      if (deleted) {
        return;
      }
      TreeDeviceSchemaCacheManager.getInstance().invalidateLastCache(pattern);
      // write log to impacted working TsFileProcessors
      List<WALFlushListener> walListeners =
          logDeletionInWAL(startTime, endTime, searchIndex, pattern);

      for (WALFlushListener walFlushListener : walListeners) {
        if (walFlushListener.waitForResult() == WALFlushListener.Status.FAILURE) {
          logger.error("Fail to log delete to wal.", walFlushListener.getCause());
          throw walFlushListener.getCause();
        }
      }

      ModEntry deletion = new TreeDeletionEntry(pattern, startTime, endTime);

      List<TsFileResource> sealedTsFileResource = new ArrayList<>();
      List<TsFileResource> unsealedTsFileResource = new ArrayList<>();
      getTwoKindsOfTsFiles(sealedTsFileResource, unsealedTsFileResource, startTime, endTime);
      // deviceMatchInfo is used for filter the matched deviceId in TsFileResource
      // deviceMatchInfo contains the DeviceId means this device matched the pattern
      deleteDataInUnsealedFiles(unsealedTsFileResource, deletion, sealedTsFileResource);
      // capture deleteDataNode and wait it to be persisted to DAL.
      DeletionResource deletionResource =
          PipeInsertionDataNodeListener.getInstance().listenToDeleteData(dataRegionId, node);
      // just get result. We have already waited for result in `listenToDeleteData`
      if (deletionResource != null && deletionResource.waitForResult() == Status.FAILURE) {
        throw deletionResource.getCause();
      }
      writeUnlock();
      hasReleasedLock = true;

      deleteDataInSealedFiles(sealedTsFileResource, deletion);
    } catch (Exception e) {
      throw new IOException(e);
    } finally {
      if (!hasReleasedLock) {
        writeUnlock();
      }
    }
  }
Separate tsfiles in TsFileManager to sealedList and unsealedList.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java