public void insertTablet(
      InsertTabletNode insertTabletNode,
      List<int[]> rangeList,
      TSStatus[] results,
      boolean noFailure,
      long[] infoForMetrics)
      throws WriteProcessException {

    ensureMemTable(infoForMetrics);

    long[] memIncrements =
        scheduleMemoryBlock(insertTabletNode, rangeList, results, noFailure, infoForMetrics);

    long startTime = System.nanoTime();
    WALFlushListener walFlushListener;
    try {
      walFlushListener = walNode.log(workMemTable.getMemTableId(), insertTabletNode, rangeList);
      if (walFlushListener.waitForResult() == WALFlushListener.Status.FAILURE) {
        throw walFlushListener.getCause();
      }
    } catch (Exception e) {
      for (int[] rangePair : rangeList) {
        int start = rangePair[0];
        int end = rangePair[1];
        for (int i = start; i < end; i++) {
          if (e instanceof IoTDBRuntimeException) {
            results[i] =
                RpcUtils.getStatus(((IoTDBRuntimeException) e).getErrorCode(), e.getMessage());
          } else {
            results[i] = RpcUtils.getStatus(TSStatusCode.INTERNAL_SERVER_ERROR, e.getMessage());
          }
        }
      }
      rollbackMemoryInfo(memIncrements);
      throw new WriteProcessException(e);
    } finally {
      // recordScheduleWalCost
      infoForMetrics[2] += System.nanoTime() - startTime;
    }

    startTime = System.nanoTime();

    PipeDataNodeAgent.runtime().assignSimpleProgressIndexIfNeeded(insertTabletNode);
    if (!insertTabletNode.isGeneratedByPipe()) {
      workMemTable.markAsNotGeneratedByPipe();
    }
    PipeInsertionDataNodeListener.getInstance()
        .listenToInsertNode(
            dataRegionInfo.getDataRegion().getDataRegionId(),
            dataRegionInfo.getDataRegion().getDatabaseName(),
            walFlushListener.getWalEntryHandler(),
            insertTabletNode,
            tsFileResource);

    int pointInserted = 0;
    for (int[] rangePair : rangeList) {
      int start = rangePair[0];
      int end = rangePair[1];
      try {
        if (insertTabletNode.isAligned()) {
          pointInserted +=
              workMemTable.insertAlignedTablet(
                  insertTabletNode, start, end, noFailure ? null : results);
        } else {
          pointInserted += workMemTable.insertTablet(insertTabletNode, start, end);
        }
      } catch (WriteProcessException e) {
        for (int i = start; i < end; i++) {
          results[i] = RpcUtils.getStatus(TSStatusCode.INTERNAL_SERVER_ERROR, e.getMessage());
        }
        throw new WriteProcessException(e);
      }
      for (int i = start; i < end; i++) {
        results[i] = RpcUtils.SUCCESS_STATUS;
      }

      final List<Pair<IDeviceID, Integer>> deviceEndOffsetPairs =
          insertTabletNode.splitByDevice(start, end);
      tsFileResource.updateStartTime(
          deviceEndOffsetPairs.get(0).left, insertTabletNode.getTimes()[start]);
      if (!sequence) {
        // For sequence tsfile, we update the endTime only when the file is prepared to be closed.
        // For unsequence tsfile, we have to update the endTime for each insertion.
        tsFileResource.updateEndTime(
            deviceEndOffsetPairs.get(0).left,
            insertTabletNode.getTimes()[deviceEndOffsetPairs.get(0).right - 1]);
      }
      for (int i = 1; i < deviceEndOffsetPairs.size(); i++) {
        // the end offset of i - 1 is the start offset of i
        tsFileResource.updateStartTime(
            deviceEndOffsetPairs.get(i).left,
            insertTabletNode.getTimes()[deviceEndOffsetPairs.get(i - 1).right]);
        if (!sequence) {
          tsFileResource.updateEndTime(
              deviceEndOffsetPairs.get(i).left,
              insertTabletNode.getTimes()[deviceEndOffsetPairs.get(i).right - 1]);
        }
      }
    }
    tsFileResource.updateProgressIndex(insertTabletNode.getProgressIndex());

    // recordScheduleMemTableCost
    infoForMetrics[3] += System.nanoTime() - startTime;
    // update memtable point inserted count
    infoForMetrics[4] += pointInserted;
  }
Insert batch data of insertTabletPlan into the workingMemtable. 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 rangeList start and end index list of rows to be inserted in insertTabletPlan
@param results result array
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/TsFileProcessor.java