public List<Integer> getRegionsToFlush(long windowsEndTime) {
    long windowsStartTime = windowsEndTime - MONITOR_INETRVAL_MILLISECONDS;
    List<Pair<Integer, Long>> regionAndFreeTimeList = new ArrayList<>();
    for (Map.Entry<Integer, RecordList> entry : regionToTraverserTime.entrySet()) {
      int regionId = entry.getKey();

      long traverserEndTime = windowsStartTime;
      long traverserFreeTime = 0;
      RecordList recordList = entry.getValue();
      Iterator<RecordNode> iterator = recordList.iterator();
      while (iterator.hasNext()) {
        RecordNode recordNode = iterator.next();
        if (recordNode.startTime > windowsEndTime) {
          break;
        }
        if (recordNode.startTime > traverserEndTime) {
          traverserFreeTime += (recordNode.startTime - traverserEndTime);
          traverserEndTime = recordNode.endTime;
        } else if (recordNode.endTime > traverserEndTime) {
          traverserEndTime = recordNode.endTime;
        }
        if (recordNode.endTime < windowsStartTime) {
          iterator.remove();
        } else if (recordNode.endTime >= windowsEndTime) {
          break;
        }
      }
      if (traverserEndTime < windowsEndTime) {
        traverserFreeTime += (windowsEndTime - traverserEndTime);
      }
      if (traverserFreeTime > FREE_FLUSH_PROPORTION * MONITOR_INETRVAL_MILLISECONDS) {
        regionAndFreeTimeList.add(new Pair<>(regionId, traverserFreeTime));
      }
    }
    regionAndFreeTimeList.sort(Comparator.comparing((Pair<Integer, Long> o) -> o.right).reversed());
    return regionAndFreeTimeList.stream().map(Pair::getLeft).collect(Collectors.toList());
  }
If there is a ReleaseTask or FlushTask, block the current thread to wait up to
MAX_WAITING_TIME_WHEN_RELEASING. The thread will be woken up if the ReleaseTask or FlushTask
ends or the wait time exceeds MAX_WAITING_TIME_WHEN_RELEASING.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/memory/ReleaseFlushMonitor.java