Skip to content

perf: read inventory holders without copying the block - #74

Merged
XxFran10xX merged 1 commit into
mainfrom
perf/getholder-no-snapshot
Oct 31, 2026
Merged

XxFran10xX merged 1 commit into
mainfrom
perf/getholder-no-snapshot

Conversation

@XxFran10xX

@XxFran10xX XxFran10xX commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Why

Main profiles, 20 hourly spark dumps 10-30 10:00 → 10-31 05:00 (peak 37 players). Inventory#getHolder() without an argument builds a full BlockState copy when the inventory belongs to a block (chest, barrel, double chest), and every plugin's click/open listener calls it again. Over the 20 h that cost ~200 s of main-thread time, mostly as short stalls on clicks in heavy containers; one click at 04:01 took 2.0 s. In Magic: GearInventoryManager.onClick 7.3 s, ResonanceGuiManager.refreshOpenInventories 4.0 s, ArtifactCreateGuiManager.onInventoryClick 1.6 s.

Change

  • 14 calls → getHolder(false); the 4 in GearInventoryManager.onClick are now one read.
  • Tests: MockBukkit throws on getHolder(boolean), so a test-only HolderLookupServerMock answers it.

For plugin menus the holder is the plugin's own object, so the result is identical. For real block inventories the code only type-checks or reads the holder, so the live state gives the same answer. Nothing players see changes.

Testing

  • All tests pass except the Windows-only folder-fsync failures that main also has.
  • Dev (TFMCDev01, 10-31 from 11:47 UTC): this PR's jar ran together with the other 12 jars from this round (VF, SF, MusicalInstruments, Magic on the Blood Magic branch, TLibs, GunsAndGadgets, Thievery, BirdMessenger, Surgery, CompanionPets, ActivityTF, MarketBlock), through two restarts. No error from any of them in the log. Bot TestChar1:
    • A chest, a double chest and a barrel, each full of shulker boxes of written books: open, pick up and put back, shift-click both ways. Every plugin's click/open listener ran; the stacks stayed intact and nothing was logged.
    • /faction list (row click works), /referral and /activity menus opened and worked.

🤖 Generated with Claude Code

The gear, resonance and artifact menus were slow on Main because every
getHolder() call on a container inventory copies the whole block state.
The gear click handler did this up to four times per click, and the
resonance refresh did it for every online player. These now use
getHolder(false), which returns the same holder without the copy, and the
gear click handler reads it once. The code only checks the holder's type,
so behaviour does not change. No call site needed the copying form.

MockBukkit does not implement getHolder(false), so the affected tests use
a server mock whose inventories answer it like getHolder().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 37b64ddb-6844-410b-a478-c9e6b7eba66d
Commits

Reviewing files that changed from the base of the PR and between 08935d4 and f136df1.

Files selected for processing: 10
  • src/main/java/net/tfminecraft/magic/artifact/ArtifactCarePlaces.java
  • src/main/java/net/tfminecraft/magic/gear/gui/GearInventoryManager.java
  • src/main/java/net/tfminecraft/magic/listener/MagicSessionListener.java
  • src/main/java/net/tfminecraft/magic/manager/ArtifactCreateGuiManager.java
  • src/main/java/net/tfminecraft/magic/manager/ResonanceGuiManager.java
  • src/test/java/net/tfminecraft/magic/AttunementTest.java
  • src/test/java/net/tfminecraft/magic/ChargeEdgeCoverageTest.java
  • src/test/java/net/tfminecraft/magic/GearCoverageSupport.java
  • src/test/java/net/tfminecraft/magic/HolderLookupServerMock.java
  • src/test/java/net/tfminecraft/magic/ListenerTest.java

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Summary

Summary by CodeRabbit

  • Bug Fixes
    • Improved inventory handling across artifact care, gear menus, artifact creation, and resonance screens. These interfaces now consistently recognize their associated holders during clicks, drags, refreshes, and closing. Existing acceptance checks and menu actions are unchanged, and no features or interaction options have been removed.

Production inventory holder checks now use getHolder(false). The gear click handler reuses its retrieved holder. Test support wraps MockBukkit inventories for the updated lookup, and related tests use the new method.

Changes: Inventory holder lookup

Layer / File(s) Summary
Update production holder checks
src/main/java/net/tfminecraft/magic/artifact/ArtifactCarePlaces.java, src/main/java/net/tfminecraft/magic/gear/gui/GearInventoryManager.java, src/main/java/net/tfminecraft/magic/listener/MagicSessionListener.java, src/main/java/net/tfminecraft/magic/manager/ArtifactCreateGuiManager.java, src/main/java/net/tfminecraft/magic/manager/ResonanceGuiManager.java
These code paths now retrieve inventory holders with getHolder(false). Gear click handling reuses the retrieved holder for its checks and dispatch.
Adapt test inventories
src/test/java/net/tfminecraft/magic/HolderLookupServerMock.java, src/test/java/net/tfminecraft/magic/AttunementTest.java, src/test/java/net/tfminecraft/magic/ChargeEdgeCoverageTest.java, src/test/java/net/tfminecraft/magic/GearCoverageSupport.java, src/test/java/net/tfminecraft/magic/ListenerTest.java
HolderLookupServerMock wraps inventories created through seven overloads. Test setup uses this mock, and the affected tests use or stub getHolder(false).

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Refactor

Suggested reviewers: ryanbarlow97

Merge Risk: Minimal · up to f136d

The optimization preserves the holder behavior used by production and test paths; no merge-blocking risk was found.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions github-actions Bot added the size:M 30-99 effective changed lines (tests excluded in mixed PRs). label Oct 31, 2026
@XxFran10xX
XxFran10xX marked this pull request as ready for review October 31, 2026 12:42
@XxFran10xX

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@XxFran10xX
XxFran10xX merged commit d58db3d into main Oct 31, 2026
4 checks passed
@XxFran10xX
XxFran10xX deleted the perf/getholder-no-snapshot branch October 31, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 effective changed lines (tests excluded in mixed PRs).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant