Optimize controller handler validation - #514
Open
MRMDevStudios wants to merge 1 commit into
Open
Conversation
Replace repeated linear handler membership checks with a derived HashSet rebuilt alongside the ordered handler list. This preserves existing stale-selector invalidation behavior while making controller lookup, insertion, and extraction validation constant-time.
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.
Summary
This PR fixes a performance issue in controller handler validation that becomes severe on large Functional Storage networks.
ControllerInventoryHandlercurrently validates that a selector's backing handler is still connected using:getItemHandlers().contains(selector.handler)Because
getItemHandlers()is an ordered list, this performs a linear scan of all connected handlers every time the validation runs.This PR keeps the existing ordered handler list intact and adds a derived
HashSet<IItemHandler>for constant-time membership validation.No separate issue was opened for this bug, so the reproduction details and profiling results are included below.
Issue
On large Storage Controller networks, external inventory automation can cause extremely large server tick stalls when interacting with the controller or a Controller Access Point.
The problem occurs because controller inventory operations may be called repeatedly across many exposed slots, while each individual operation performs a linear handler membership check.
The problematic validation is used by:
getStackInSlot(...)insertItem(...)extractItem(...)Each operation currently checks:
getDrawers().getItemHandlers().contains(selector.handler)For a controller with hundreds of connected handlers, this means every slot operation can scan the entire handler list.
When another inventory system iterates through many controller slots during insertion, the effective cost becomes approximately:
number of exposed slots × number of connected handlersThis becomes particularly expensive for large networks and for insertion attempts where the matching destination is late in the slot ordering, the storage is full, or the item cannot be inserted.
Observed case
This was identified on a Minecraft 1.21.1 NeoForge server running:
1.5.88.2.11-betaThe affected Functional Storage network contained roughly 420 item handlers and exposed roughly 1,500 controller slots.
A Spark profile of ticks exceeding 120 ms showed the following hot path: