Skip to content

perf: reuse unchanged live character snapshots in identity lookups - #153

Merged
XxFran10xX merged 4 commits into
mainfrom
perf/identity-snapshot
Nov 6, 2026
Merged

XxFran10xX merged 4 commits into
mainfrom
perf/identity-snapshot

Conversation

@XxFran10xX

@XxFran10xX XxFran10xX commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

CharacterIdentityService.info (through TLibs Characters.info, called very often by CompanionPets and SimpleFactions) cost about 5 s an hour on Main's main thread. Every call scanned all online accounts with stream pipelines and rebuilt a fresh CharacterInfo for every character of each matching account.

  • New LiveSnapshot: a live character's last snapshot together with every value it was built from (owner, id, name, status, race id, trait ids, playtime, last played).
  • CharacterDirectory keeps these per character (weak keys) and reuses one only while every value still matches. Otherwise it rebuilds with the unchanged snapshot(), so quarantine, duplicate claims and warning text are the same as before.
  • The reuse check reads the live character on every lookup, so any edit counts at once (rename, status, race, trait list edits, playtime, id, switch, hide). No invalidation hooks are needed.
  • The account scans in CharacterIdentityService use plain loops instead of stream pipelines; the matching logic is unchanged.

Local micro-benchmark (30 players × 3 characters): about 11 µs → 3 µs per info().

Tests

  • New CharacterIdentityServiceTest cases: reuse until any value changes, compared with a fresh snapshot after each of 16 edits; same quarantine warnings when a character breaks after being cached; failing getters; id case and owner changes compared with a directory fed fresh snapshots only; a duplicate id differing only in case.
  • Windows: same failing set as main (directory fsync); CI is authoritative.

No gameplay change.

Dev test

Dev (TFMCDev01, 11-05): /players, placeholders and faction menu show the right character; a rename via /rpcharacter edit and back shows at once everywhere; hide/unhide updates /players and TAB; character switching followed at once. No new "Character directory unavailable" lines.

🤖 Generated with Claude Code

XxFran10xX and others added 4 commits November 5, 2026 11:53
CharacterIdentityService.info overlays every loaded account holding the
character before each lookup, and that rebuilt a fresh CharacterInfo for each
of the account's characters every time (colour stripping, trait sets, record
copies). On Main it cost about 5 s an hour on the main thread, mostly from
CompanionPets and SimpleFactions lookups through TLibs Characters.info.

The directory now keeps each live character's last snapshot together with
every value it was built from (owner, id, name, status, race id, trait ids,
playtime, last played) and reuses it while all of them are unchanged. The
check reads the live character on every lookup, so any edit, however it is
made, is seen at once; no invalidation hooks are needed. Directory updates,
quarantine and duplicate handling run exactly as before. The per-lookup scans
of loaded accounts use plain loops instead of stream pipelines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ner edits

Review fixes: a failing read while checking a reused snapshot now just
rebuilds it (so the rebuild reports the failure as before), failing to record
a fresh snapshot only skips reuse, and the owner scan no longer skips reading
other accounts' ids when the owner holds none. Tests now check the exact
quarantine warnings, id case and owner changes against a directory fed fresh
snapshots only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t edits

Review round 2: the values a reused snapshot is checked against are now read
before the snapshot is built, so an edit landing between the two reads can
only cost a rebuild, never a stale reuse. Tests add a same-size trait list
edit, compare quarantine warnings with a directory fed fresh snapshots only,
and show that a character whose values cannot be recorded is rebuilt each
time with the same result.

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

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • Bug Fixes
    • Character ID lookups and refreshes now handle differences in letter case consistently, including when matching characters across accounts.
    • Character data remains consistent across lookup methods when its recorded details have not changed, and updates are reflected when those details do change.
    • Invalid or changing character data is handled more safely during directory updates, helping prevent failures from disrupting other character lookups.

The directory caches live-character snapshots while their recorded values remain unchanged. Owner and character refreshes use explicit case-insensitive ID matching.

Changes: Character identity lookups

Layer / File(s) Summary
Live snapshot reuse
src/main/java/net/tfminecraft/rpcharacters/identity/CharacterDirectory.java, src/main/java/net/tfminecraft/rpcharacters/identity/LiveSnapshot.java, src/test/java/net/tfminecraft/rpcharacters/identity/CharacterIdentityServiceTest.java
A weak-keyed cache reuses character information when the owner and recorded values match. Tests cover reuse, rebuilding, invalid values, read failures, and owner changes.
Case-insensitive ID matching
src/main/java/net/tfminecraft/rpcharacters/identity/CharacterIdentityService.java, src/test/java/net/tfminecraft/rpcharacters/identity/CharacterIdentityServiceTest.java
Owner and character refreshes scan character IDs without case sensitivity. Tests cover duplicate IDs that differ only by case.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Refactor

Suggested reviewers: ryanbarlow97

Merge Risk: Minimal · up to 3bfea

No actionable issue remains from this review; the change is mergeable after normal checks.

- [ ] 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

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: 6a92646b-8434-4670-8827-88642f4702e1
Commits

Reviewing files that changed from the base of the PR and between b4e9d00 and 3bfea21.

Files selected for processing: 4

  • src/main/java/net/tfminecraft/rpcharacters/identity/CharacterDirectory.java
  • src/main/java/net/tfminecraft/rpcharacters/identity/CharacterIdentityService.java
  • src/main/java/net/tfminecraft/rpcharacters/identity/LiveSnapshot.java
  • src/test/java/net/tfminecraft/rpcharacters/identity/CharacterIdentityServiceTest.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.

@github-actions github-actions Bot added the size:L 100-499 effective changed lines (tests excluded in mixed PRs). label Nov 5, 2026
@XxFran10xX
XxFran10xX marked this pull request as ready for review November 6, 2026 14:27
@XxFran10xX

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Action performed

Full review finished.

@XxFran10xX
XxFran10xX merged commit fc1ae01 into main Nov 6, 2026
4 checks passed
@XxFran10xX
XxFran10xX deleted the perf/identity-snapshot branch November 6, 2026 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 effective changed lines (tests excluded in mixed PRs).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant