Repository navigation
perf(replay): Use hash set for mask view class lookups - #6410
Merged
Merged
Conversation
maskViewClasses and unmaskViewClasses were backed by a CopyOnWriteArraySet, whose contains() is a linear scan. The view hierarchy traversal checks both sets for every superclass of every view on the main thread, so capture cost grew with the size of the configured class lists. Back both sets with a ConcurrentHashMap key set for O(1) lookups while keeping thread-safe, non-throwing iteration. Co-Authored-By: Roman Zavarnitsyn <roman.zavarnitsyn@sentry.io>
sentry-junior
Bot
requested review from
0xadam-brown and
runningcode
and removed request for
a team
October 28, 2026 20:53
📲 Install BuildsAndroid
|
christophaigner
approved these changes
Oct 28, 2026
ConcurrentHashMap-backed sets reject null keys, while the previous CopyOnWriteArraySet accepted them. Hybrid SDKs (e.g. React Native via ReadableArray.getString) can pass null despite the @NotNull annotation, which would now throw during SDK init. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📜 Description
SentryMaskingOptions.maskViewClassesandunmaskViewClasseswere backed byCopyOnWriteArraySet, and itscontains()scans the whole list. This PR backs both withCollections.newSetFromMap(new ConcurrentHashMap<>())instead:contains,add, andremoveare now O(1).ConcurrentModificationException.ConcurrentHashMap.newKeySet()because it needs API 24.Set<String>, andcheckKotlinAbipasses.Behavior change: the sets no longer keep insertion order. The only place that order showed up is the
maskedViewClassesandunmaskedViewClasseslists in the replay options event. Those lists are informational, soSessionCaptureStrategyTestnow checks their contents without checking order.💡 Motivation and Context
During each replay capture,
ViewHierarchyNode.shouldMaskwalks every view's superclass chain on the main thread (Class.isAssignableFrom(Set<String>)). At each level it callscontains()on both sets, and most views match neither. With a linearcontains(), the cost of each capture grew with views × class depth × (mask + unmask list size). This came up for a customer considering mask lists with thousands of entries. With constant-time lookups, list size no longer affects capture cost. Compose nodes (ComposeViewHierarchyNode) get the same improvement.💚 How did you test it?
I ran these locally on JDK 21:
:sentry:test:SentryMaskingOptionsTest,SentryReplayOptionsTest,RRWebOptionsEventSerializationTest:sentry-android-replay:testReleaseUnitTest:SessionCaptureStrategyTest,viewhierarchy.*(masking, container, and Compose masking tests):sentry-android-core:testReleaseUnitTest:SentryScreenshotOptionsTest,ScreenshotEventProcessorTest,ManifestMetadataReaderTest:sentry:spotlessApply,:sentry-android-replay:spotlessApply(no changes),:sentry:checkKotlinAbiI haven't benchmarked this on a device.
📝 Checklist
sendDefaultPIIis enabled.via roman.
--
View Junior Session [Sentry]