Skip to content

[COLLECTIONS-885] PatriciaTrie submap and range view operations silently mutate trie structure resulting in ConcurrentModificationException for any iterating threads#672

Merged
garydgregory merged 3 commits intoapache:masterfrom
griffinjm:collections-885-patriciatrie-silent-mutation-bugfix
Mar 24, 2026
Merged

[COLLECTIONS-885] PatriciaTrie submap and range view operations silently mutate trie structure resulting in ConcurrentModificationException for any iterating threads#672
garydgregory merged 3 commits intoapache:masterfrom
griffinjm:collections-885-patriciatrie-silent-mutation-bugfix

Conversation

@griffinjm
Copy link
Contributor

@griffinjm griffinjm commented Mar 19, 2026

Some methods in AbstractPatriciaTrie use a pattern where they silently mutate the trie when searching for a key which is not an exact match for an existing key in the Trie. Said methods are invoked by subMap/tailMap/headMap/prefixMap under the hood. This results in CMEs for even simple shared read access.

ceilingEntry() floorEntry() higherEntry() lowerEntry() operations:
1. insert a phantom node into the trie with the search key
2. increment the modCount
3. find the neighbor of that phantom node via nextEntry()/previousEntry()
4. remove the phantom node
5. increment the modCount again
6. then decrement modCount by 2 to hide the 2 modifications (add + remove)

The referenced modCount is used as a fail-fast mechanism in the iterators.

This fix prevents the issue by instead:

1. Finding the nearest entry via getNearestEntryForKey().
2. Determining whether the search key is less than or greater than the found entry using isBitSet() at the first differing bit.
3. Walking forward (nextEntry()) or backward (previousEntry()) to locate the correct ceiling/floor neighbor.

See https://issues.apache.org/jira/browse/COLLECTIONS-885 for all details.

…iews with subMap, headMap, tailMap, and prefixMap. Fixes shared usage where even simple read access among multiple iterating threads results in ConcurrentModificationExceptions.
@griffinjm griffinjm marked this pull request as draft March 19, 2026 20:31
@griffinjm griffinjm changed the title [COLLECTIONS-885] PatriciaTrie. Prevent silent mutatations, prevents CMEs when iterating. [COLLECTIONS-885] PatriciaTrie. Prevent silent mutations, prevents CMEs when iterating. Mar 19, 2026
@griffinjm griffinjm marked this pull request as ready for review March 19, 2026 20:32
Copy link
Member

@garydgregory garydgregory left a comment

Choose a reason for hiding this comment

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

Hello Hello @griffinjm
If I only apply the test side of the patch, all the tests still pass, the new tests should fail. This means a regression could undo whatever the main changes claim to make.

@griffinjm
Copy link
Contributor Author

Hi @garydgregory
The only test which can expose this bug, and prevent regressions would be a multithreaded test which triggers the phantom insertion causing the original iterator to fail. I can add one if necessary. I'll also attach some sequence diagrams below to help visualize the issue. Thanks.

@griffinjm
Copy link
Contributor Author

patricia-trie-concurrency-safe

@griffinjm
Copy link
Contributor Author

patricia-trie-concurrency-unsafe

…oncurrentModificationExceptions thrown by concurrent iterators.
@griffinjm
Copy link
Contributor Author

@garydgregory I added a threaded test to verify behaviour, that test should fail for the existing main branch and pass for this bugfix branch.

Copy link
Member

@garydgregory garydgregory left a comment

Choose a reason for hiding this comment

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

...

Copy link
Member

@garydgregory garydgregory left a comment

Choose a reason for hiding this comment

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

Hello @griffinjm

Please see my one comment.

@garydgregory garydgregory merged commit 4d9e0bd into apache:master Mar 24, 2026
9 checks passed
@garydgregory garydgregory changed the title [COLLECTIONS-885] PatriciaTrie. Prevent silent mutations, prevents CMEs when iterating. [COLLECTIONS-885] PatriciaTrie submap and range view operations silently mutate trie structure resulting in ConcurrentModificationException for any iterating threads Mar 24, 2026
garydgregory added a commit that referenced this pull request Mar 24, 2026
mutate trie structure resulting in ConcurrentModificationException for
any iterating threads #672
@garydgregory
Copy link
Member

@griffinjm
I mered the PR. Thank you!

@griffinjm
Copy link
Contributor Author

Great! Thank you @garydgregory

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.

2 participants