private void partitionPlan(StructLike partition, Collection<MixedFileScanTask> keyedTableTasks) {
    Map<DataTreeNode, NodeFileScanTask> nodeFileScanTaskMap = new HashMap<>();
    // planfiles() cannot guarantee the uniqueness of the file,
    // so Set<path> here is used to remove duplicate files
    Set<String> pathSets = new HashSet<>();
    keyedTableTasks.forEach(
        task -> {
          if (!pathSets.contains(task.file().path().toString())) {
            pathSets.add(task.file().path().toString());
            DataTreeNode treeNode = task.file().node();
            NodeFileScanTask nodeFileScanTask =
                nodeFileScanTaskMap.getOrDefault(treeNode, new NodeFileScanTask(treeNode));
            nodeFileScanTask.addFile(task);
            nodeFileScanTaskMap.put(treeNode, nodeFileScanTask);
          }
        });

    nodeFileScanTaskMap.forEach(
        (treeNode, nodeFileScanTask) -> {
          if (!nodeFileScanTask.isDataNode()) {
            return;
          }

          nodeFileScanTaskMap.forEach(
              (treeNode1, nodeFileScanTask1) -> {
                if (!treeNode1.equals(treeNode)
                    && (treeNode1.isSonOf(treeNode) || treeNode.isSonOf(treeNode1))) {
                  List<MixedFileScanTask> deletes =
                      nodeFileScanTask1.mixedEquityDeletes().stream()
                          .filter(file -> file.file().node().equals(treeNode1))
                          .collect(Collectors.toList());

                  nodeFileScanTask.addTasks(deletes);
                }
              });
        });

    List<NodeFileScanTask> fileScanTaskList = new ArrayList<>();
    nodeFileScanTaskMap.forEach(
        (treeNode, nodeFileScanTask) -> {
          if (!nodeFileScanTask.isDataNode()) {
            return;
          }
          fileScanTaskList.add(nodeFileScanTask);
        });

    fileScanTasks.put(partition, fileScanTaskList);
  }
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