@Override
  public CloseableIterable<Record> readDeletedData() {
    if (input.rePosDeletedDataFiles() == null) {
      return CloseableIterable.empty();
    }

    Schema schema =
        new Schema(
            MetadataColumns.FILE_PATH,
            MetadataColumns.ROW_POSITION,
            org.apache.amoro.table.MetadataColumns.TREE_NODE_FIELD);
    Schema requireSchema =
        fileProjection(tableSchema, schema, deleteFilter.hasPosition(), deleteFilter.deleteIds());

    CloseableIterable<Record> concat =
        CloseableIterable.concat(
            CloseableIterable.transform(
                CloseableIterable.withNoopClose(
                    Arrays.stream(input.rePosDeletedDataFiles()).collect(Collectors.toList())),
                s -> openFile(s, spec, requireSchema)));

    StructForDelete<Record> structForDelete =
        new StructForDelete<>(requireSchema, deleteFilter.deleteIds());
    CloseableIterable<StructForDelete<Record>> structForDeleteCloseableIterable =
        CloseableIterable.transform(concat, structForDelete::wrap);

    CloseableIterable<Record> iterable =
        CloseableIterable.transform(
            deleteFilter.filterNegate(structForDeleteCloseableIterable), StructForDelete::recover);
    return iterable;
  }
Read data by {@link CombinedIcebergScanTask} for optimizer of native iceberg. During the
execution of readData and readDeleteData, delete data is read only once, thereby improving
performance.
amoro-format-iceberg/src/main/java/org/apache/amoro/io/reader/GenericCombinedIcebergDataReader.java