private List<InsertRowNode> insertToTsFileProcessors(
      InsertRowsNode insertRowsNode,
      boolean[] areSequence,
      long[] timePartitionIds,
      long[] infoForMetrics) {
    Map<TsFileProcessor, InsertRowsNode> tsFileProcessorMap = new HashMap<>();
    for (int i = 0; i < areSequence.length; i++) {
      InsertRowNode insertRowNode = insertRowsNode.getInsertRowNodeList().get(i);
      if (insertRowNode.allMeasurementFailed()) {
        continue;
      }
      TsFileProcessor tsFileProcessor =
          getOrCreateTsFileProcessor(timePartitionIds[i], areSequence[i]);
      if (tsFileProcessor == null) {
        continue;
      }
      int finalI = i;
      tsFileProcessorMap.compute(
          tsFileProcessor,
          (k, v) -> {
            if (v == null) {
              v = insertRowsNode.emptyClone();
              v.setSearchIndex(insertRowNode.getSearchIndex());
              v.setAligned(insertRowNode.isAligned());
              if (insertRowNode.isGeneratedByPipe()) {
                v.markAsGeneratedByPipe();
              }
              if (insertRowNode.isGeneratedByRemoteConsensusLeader()) {
                v.markAsGeneratedByRemoteConsensusLeader();
              }
            }
            if (v.isAligned() != insertRowNode.isAligned()) {
              v.setMixingAlignment(true);
            }
            v.addOneInsertRowNode(insertRowNode, finalI);
            v.updateProgressIndex(insertRowNode.getProgressIndex());
            return v;
          });
    }

    List<InsertRowNode> executedInsertRowNodeList = new ArrayList<>();
    for (Map.Entry<TsFileProcessor, InsertRowsNode> entry : tsFileProcessorMap.entrySet()) {
      TsFileProcessor tsFileProcessor = entry.getKey();
      InsertRowsNode subInsertRowsNode = entry.getValue();
      try {
        tsFileProcessor.insertRows(subInsertRowsNode, infoForMetrics);
      } catch (WriteProcessException e) {
        insertRowsNode
            .getResults()
            .put(
                subInsertRowsNode.getInsertRowNodeIndexList().get(0),
                RpcUtils.getStatus(e.getErrorCode(), e.getMessage()));
      }
      executedInsertRowNodeList.addAll(subInsertRowsNode.getInsertRowNodeList());
      // register TableSchema (and maybe more) for table insertion
      registerToTsFile(subInsertRowsNode, tsFileProcessor);
      // check memtable size and may asyncTryToFlush the work memtable
      if (entry.getKey().shouldFlush()) {
        fileFlushPolicy.apply(this, tsFileProcessor, tsFileProcessor.isSequence());
      }
    }
    return executedInsertRowNodeList;
  }
insert batch to tsfile processor thread-safety that the caller need to guarantee The rows to be
inserted are in the range [start, end) Null value in each column values will be replaced by the
subsequent non-null value, e.g., {1, null, 3, null, 5} will be {1, 3, 5, null, 5}

@param insertTabletNode insert a tablet of a device
@param sequence whether is sequence
@param rangeList start and end index list of rows to be inserted in insertTabletPlan
@param results result array
@param timePartitionId time partition id
@return false if any failure occurs when inserting the tablet, true otherwise
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java