public StructLikeMap<Collection<MixedFileScanTask>> groupFilesByPartition(
      PartitionSpec partitionSpec,
      CloseableIterable<MixedFileScanTask> changeTasks,
      CloseableIterable<MixedFileScanTask> baseTasks) {
    StructLikeMap<Collection<MixedFileScanTask>> filesGroupedByPartition =
        StructLikeMap.create(partitionSpec.partitionType());
    try {
      changeTasks.forEach(
          task ->
              filesGroupedByPartition
                  .computeIfAbsent(task.file().partition(), k -> Lists.newArrayList())
                  .add(task));
      baseTasks.forEach(
          task ->
              filesGroupedByPartition
                  .computeIfAbsent(task.file().partition(), k -> Lists.newArrayList())
                  .add(task));
      return filesGroupedByPartition;
    } finally {
      try {
        changeTasks.close();
        baseTasks.close();
      } catch (IOException e) {
        LOG.warn("Failed to close table scan of {} ", table.id(), e);
      }
    }
  }
Construct tree node task according to partition 1. Put all files into the node they originally
belonged to 2. Find all data nodes, traverse, and find the delete that intersects them
amoro-format-iceberg/src/main/java/org/apache/amoro/scan/BasicKeyedTableScan.java