private ListenableFuture<?> tryGetNext() {
    if (schemaReader == null) {
      schemaReader = createTimeSeriesReader();
    }
    while (true) {
      try {
        ListenableFuture<?> readerBlocked = schemaReader.isBlocked();
        if (!readerBlocked.isDone()) {
          SettableFuture<?> settableFuture = SettableFuture.create();
          readerBlocked.addListener(
              () -> {
                next = constructTsBlockAndClearMap(countMap);
                settableFuture.set(null);
              },
              directExecutor());
          return settableFuture;
        } else if (schemaReader.hasNext()) {
          ISchemaInfo schemaInfo = schemaReader.next();
          PartialPath path = schemaInfo.getPartialPath();
          if (path.getNodeLength() <= level) {
            continue;
          }
          PartialPath levelPath = new PartialPath(Arrays.copyOf(path.getNodes(), level + 1));
          countMap.compute(
              levelPath,
              (k, v) -> {
                if (v == null) {
                  return 1L;
                } else {
                  return v + 1;
                }
              });
          if (countMap.size() == DEFAULT_BATCH_SIZE) {
            next = constructTsBlockAndClearMap(countMap);
            return NOT_BLOCKED;
          }
        } else {
          if (countMap.isEmpty()) {
            next = null;
            isFinished = true;
          } else {
            next = constructTsBlockAndClearMap(countMap);
          }
          return NOT_BLOCKED;
        }
      } catch (Exception e) {
        throw new SchemaExecutionException(e);
      }
    }
  }
Try to get next TsBlock. If the next is not ready, return a future. After success, {@link
CountGroupByLevelScanOperator#next} will be set.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/CountGroupByLevelScanOperator.java