private void updateLastCacheIfPossible() {
    if (!needUpdateCache) {
      return;
    }

    int channel = 0;
    List<String> updateMeasurementList = new ArrayList<>();
    List<TimeValuePair> updateTimeValuePairList = new ArrayList<>();
    boolean hasSetLastTime = false;
    for (int i = 0; i < tableAggregators.size(); i++) {
      TableAggregator tableAggregator = tableAggregators.get(i);
      ColumnSchema schema = aggColumnSchemas.get(aggregatorInputChannels.get(channel));

      switch (schema.getColumnCategory()) {
        case TIME:
          if (!hasSetLastTime) {
            hasSetLastTime = true;
            if (i == lastTimeAggregationIdx) {
              LastDescAccumulator lastAccumulator =
                  (LastDescAccumulator) tableAggregator.getAccumulator();
              if (lastAccumulator.hasInitResult()) {
                updateMeasurementList.add("");
                updateTimeValuePairList.add(
                    new TimeValuePair(
                        lastAccumulator.getMaxTime(),
                        new TsPrimitiveType.TsLong(lastAccumulator.getMaxTime())));
              }
            } else {
              LastByDescAccumulator lastByAccumulator =
                  (LastByDescAccumulator) tableAggregator.getAccumulator();
              if (lastByAccumulator.hasInitResult() && !lastByAccumulator.isXNull()) {
                updateMeasurementList.add("");
                updateTimeValuePairList.add(
                    new TimeValuePair(
                        lastByAccumulator.getLastTimeOfY(),
                        new TsPrimitiveType.TsLong(lastByAccumulator.getLastTimeOfY())));
              }
            }
          }
          break;
        case FIELD:
          LastByDescAccumulator lastByAccumulator =
              (LastByDescAccumulator) tableAggregator.getAccumulator();
          // only can update LastCache when last_by return non-null value
          if (lastByAccumulator.hasInitResult() && !lastByAccumulator.isXNull()) {
            long lastByTime = lastByAccumulator.getLastTimeOfY();

            if (!hasSetLastTime) {
              hasSetLastTime = true;
              updateMeasurementList.add("");
              updateTimeValuePairList.add(
                  new TimeValuePair(lastByTime, new TsPrimitiveType.TsLong(lastByTime)));
            }

            updateMeasurementList.add(schema.getName());
            updateTimeValuePairList.add(
                new TimeValuePair(
                    lastByTime, cloneTsPrimitiveType(lastByAccumulator.getXResult())));
          }
          break;
        default:
          break;
      }

      channel += tableAggregator.getChannelCount();
    }

    if (!updateMeasurementList.isEmpty()) {
      String[] updateMeasurementArray = updateMeasurementList.toArray(new String[0]);
      TimeValuePair[] updateTimeValuePairArray =
          updateTimeValuePairList.toArray(new TimeValuePair[0]);
      currentDeviceEntry = deviceEntries.get(currentDeviceIndex);
      TABLE_DEVICE_SCHEMA_CACHE.updateLastCacheIfExists(
          dbName,
          currentDeviceEntry.getDeviceID(),
          updateMeasurementArray,
          updateTimeValuePairArray);
    }
  }
Main process logic, calc the last aggregation results of current device.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/LastQueryAggTableScanOperator.java