Skip to content

perf(deletes): Implement filtering position delete files by file path - #2936

Open
brgr-s wants to merge 8 commits into
apache:mainfrom
brgr-s:brgr-s/pos-delete-by-file-path
Open

perf(deletes): Implement filtering position delete files by file path#2936
brgr-s wants to merge 8 commits into
apache:mainfrom
brgr-s:brgr-s/pos-delete-by-file-path

Conversation

@brgr-s

@brgr-s brgr-s commented Jul 31, 2026

Copy link
Copy Markdown

Which issue does this PR close?

What changes are included in this PR?

The PR introduces (uncomments) pos_deletes_by_path in PopulatedDeleteFileIndex and populates the HashMap. To determine if a position delete file belongs in the map, it uses a helper position_delete_target that investigates

  1. is referenced_data_file set? if yes, we know the delete file applies to that path
  2. is lower == upper for the reserved field RESERVED_FIELD_ID_DELETE_FILE_PATH? If yes, we know that all entries point to the same path

As a small ergonomic imrpovement it changes eq_deletes_by_partition and pod_deletes_by_partition to take a (i32, Struct) as key, where the i32 is the partition_spec_id of the delete file.

get_deletes_for_data_file can then use pos_deletes_by_path to lookup delete files that match that specific data_file.

PR also adds a debug trace that could be usefull to determine if a read on a table is slow or OOMs (see linked issue) due to a large number of created delete file references.

Are these changes tested?

I have added unit tests.

The change was also tested locally in conjuncture with PR #2620. The task was compacting a merge-on-read table with a huge number of delete files. The test scenario can be reproduced without PR #2620, see Issue #2935.

AI Disclosure

I used AI to investigate how Spark handles delete files, to review my changes and add more tests. I also used AI to write parts of the Issue and double-check the math.

@brgr-s brgr-s changed the title fix(deletes): Implement filtering position delete files by file path perf(deletes): Implement filtering position delete files by file path Aug 5, 2026
@brgr-s
brgr-s force-pushed the brgr-s/pos-delete-by-file-path branch from 03347ff to d6abcca Compare August 5, 2026 12:52
@brgr-s
brgr-s force-pushed the brgr-s/pos-delete-by-file-path branch from d6abcca to 8008ece Compare August 5, 2026 19:26

@c-thiel c-thiel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few comments. I also see think we have at least two remaining efficiency gaps vs Java for which we should open Issues or directly follow-up PRs:

1. Equality deletes are not pruned by column statistics

Java's canContainEqDeletesForFile skips an equality delete file when the data file's and delete file's bounds for the equality fields don't overlap, or when null counts prove no rows can match. PopulatedDeleteFileIndex::get_deletes_for_data_file only applies the
sequence-number check, so every equality delete in the partition is returned, then loaded and applied.

2. Buckets are linearly scanned instead of binary-searched

Java keeps each bucket sorted by data sequence number and binary-searches the first applicable delete (findStartIndex), giving O(log n + matches). Rust filters linearly per data file.

Comment thread crates/iceberg/src/delete_file_index.rs Outdated
Comment thread crates/iceberg/src/delete_file_index.rs Outdated
Comment thread crates/iceberg/src/delete_file_index.rs Outdated
Comment thread crates/iceberg/src/delete_file_index.rs Outdated
Comment thread crates/iceberg/src/delete_file_index.rs Outdated
Comment thread crates/iceberg/src/delete_file_index.rs Outdated
brgr-s and others added 2 commits August 6, 2026 11:47
not "never applied" but "skipped for data files with known sequence number"

Co-authored-by: Christian <Christian.Thiel@outlook.com>
Co-authored-by: Christian <Christian.Thiel@outlook.com>
@brgr-s

brgr-s commented Aug 6, 2026

Copy link
Copy Markdown
Author

@c-thiel thanks for the review, changes are incoming.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scan planning matches every position delete to every data file in the partition, making planning memory O(data files × delete files)

2 participants