private long checkMemory(
      final PipelineMemoryEstimator memoryEstimator, FragmentInstanceStateMachine stateMachine)
      throws MemoryNotEnoughException {

    // if it is disabled, just return
    if (!IoTDBDescriptor.getInstance().getMemoryConfig().isEnableQueryMemoryEstimation()
        && !IoTDBDescriptor.getInstance().getConfig().isQuotaEnable()) {
      return 0;
    }

    long estimatedMemorySize = memoryEstimator.getEstimatedMemoryUsageInBytes();

    QueryRelatedResourceMetricSet.getInstance().updateEstimatedMemory(estimatedMemorySize);

    if (OPERATORS_MEMORY_BLOCK.allocate(estimatedMemorySize)) {
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug(
            "[ConsumeMemory] consume: {}, current remaining memory: {}",
            estimatedMemorySize,
            OPERATORS_MEMORY_BLOCK.getFreeMemoryInBytes());
      }
    } else {
      throw new MemoryNotEnoughException(
          String.format(
              "There is not enough memory to execute current fragment instance, "
                  + "current remaining free memory is %dB, "
                  + "estimated memory usage for current fragment instance is %dB",
              OPERATORS_MEMORY_BLOCK.getFreeMemoryInBytes(), estimatedMemorySize));
    }
    stateMachine.addStateChangeListener(
        newState -> {
          if (newState.isDone()) {
            try (SetThreadName fragmentInstanceName =
                new SetThreadName(stateMachine.getFragmentInstanceId().getFullId())) {
              OPERATORS_MEMORY_BLOCK.release(estimatedMemorySize);
              if (LOGGER.isDebugEnabled()) {
                LOGGER.debug(
                    "[ReleaseMemory] release: {}, current remaining memory: {}",
                    estimatedMemorySize,
                    OPERATORS_MEMORY_BLOCK.getFreeMemoryInBytes());
              }
            }
          }
        });
    return estimatedMemorySize;
  }
Used to plan a fragment instance. One fragment instance could be split into multiple pipelines so
that a fragment instance could be run in parallel, and thus we can take full advantages of
multi-cores.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanner.java