Skip to content

Group nodes by hash in deduplicate() - #3294

Open
tooflesswulf wants to merge 2 commits into
masterfrom
toofless/upopt-dedupe-hash
Open

Group nodes by hash in deduplicate()#3294
tooflesswulf wants to merge 2 commits into
masterfrom
toofless/upopt-dedupe-hash

Conversation

@tooflesswulf

@tooflesswulf tooflesswulf commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Describe your changes

During performance profiling on upopt I noticed the deduplicate() calls were taking really long. This change should speed that up since I used to sort the whole node list; now we're checking a hashmap keyed on a string identity to deduplicate nodes. Nothing relied the sorted node list down the line, so returning an unsorted list is okay & faster.

Issue or discord link

Testing/validation

Updated many tests

Checklist before requesting a review (leave this PR as draft if any part of this list is not done.)

  • I have commented my code in hard-to understand areas.
  • I have made corresponding changes to README or wiki.
  • For front-end changes, I have updated the corresponding English translations.
  • I have run yarn run mini-ci locally to validate format and lint.
  • If I have added a new library or app, I have updated the deployment scripts to ignore changes as needed

Summary by CodeRabbit

  • Bug Fixes

    • Improved duplicate-result handling so equivalent entries are merged consistently.
    • Excluded entries with zero or negative probability from results.
    • Preserved probability totals and stable result ordering during deduplication.
  • Tests

    • Added broader coverage for node identity, probability conservation, repeated deduplication, and cache consistency.
    • Improved comparisons to validate distributions regardless of result ordering.

tooflesswulf and others added 2 commits August 23, 2026 13:12
deduplicate() sorted the whole node list with cmpNodes and merged adjacent
equal runs. Replace that with a Map keyed on a string identity so merging is
linear, and so the output keeps the producer's order instead of imposing
cmpNodes order on every caller.

nodeKey()/baseKey() are the new identity; cmpNodes is now exported and used
only as the independent oracle the tests check nodeKey against, rather than
on any hot path. A new test block builds real trees of all three node types
and asserts the two agree in both directions -- no wrong merges (one output
node per cmpNodes-equivalence class) and no missed merges (no two output
nodes cmpNodes-equal) -- plus idempotence and per-field distinguishability.

The elixir memoization tests compared node sequences, which only held under
the old sorted output. They now compare distributions via
expectSameDistribution: same distinct nodes, same total probability on each.
That is the actual contract, and it drops the stale ordering comment in
elixirDefinitionMemoSimplified that the old behavior justified.

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

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3b3ae263-dd23-4012-a7cb-e416a857619a

📥 Commits

Reviewing files that changed from the base of the PR and between 984d82c and 16b5ee6.

📒 Files selected for processing (3)
  • libs/gi/upopt/src/deduplicate.ts
  • libs/gi/upopt/src/upOpt.test.ts
  • libs/gi/upopt/src/upOptMemoize.ts
💤 Files with no reviewable changes (1)
  • libs/gi/upopt/src/upOptMemoize.ts

Included review availability: Your plan provides up to 4 included reviews per hour; 1 remains after this review.


Walkthrough

deduplicate now uses canonical node keys with a Map, preserves first-seen order, and removes non-positive probabilities. Tests export and use cmpNodes as an identity oracle, verify probability behavior, and compare cache distributions independently of order.

Changes

Node deduplication

Layer / File(s) Summary
Identity-based node grouping
libs/gi/upopt/src/deduplicate.ts
deduplicate groups nodes by canonical keys, combines probabilities, skips non-positive entries, and returns values in insertion order. cmpNodes is now exported.
Deduplication behavior coverage
libs/gi/upopt/src/upOpt.test.ts
Tests cover field-level identity differences, probability filtering, equivalence classes, probability conservation, and idempotence. Distribution comparisons no longer depend on node order.
Order-independent cache checks
libs/gi/upopt/src/upOpt.test.ts, libs/gi/upopt/src/upOptMemoize.ts
Memoization tests compare weighted distributions by canonical key. An obsolete ordering comment is removed.

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

Merge Risk: ⚪ Minimal · up to 16b5e

The change remains merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Poem

Midnight rolls, the hash map wakes,
It gathers twins for probability’s sake.
Zero rolls vanish from sight,
Cache distributions align just right.
Somnia yawns, then pulls once more—
Tests guard the gacha floor.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change from sorting-based deduplication to hash-based grouping.
Description check ✅ Passed The description explains the performance change, testing updates, and behavior change, but leaves the issue link and checklist items incomplete.
Docstring Coverage ✅ Passed Docstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch toofless/upopt-dedupe-hash

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

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

[frontend] [Sun Aug 23 17:44:27 UTC 2026] - Deployed c78384a to https://genshin-optimizer-prs.github.io/pr/3294/frontend (Takes 3-5 minutes after this completes to be available)
[frontend] [Sun Aug 23 17:45:18 UTC 2026] - Deployed 78a643f to https://genshin-optimizer-prs.github.io/pr/3294/frontend (Takes 3-5 minutes after this completes to be available)

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.

1 participant