Skip to content

refactor(merge-tree): drop unnecessary red-black tree usage - #28128

Open
Matt Rakow (ChumpChief) wants to merge 3 commits into
microsoft:mainfrom
ChumpChief:rbtree-cleanup-trivial
Open

refactor(merge-tree): drop unnecessary red-black tree usage#28128
Matt Rakow (ChumpChief) wants to merge 3 commits into
microsoft:mainfrom
ChumpChief:rbtree-cleanup-trivial

Conversation

@ChumpChief

@ChumpChief Matt Rakow (ChumpChief) commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Description

merge-tree ships a hand-written red-black tree (src/collections/rbTree.ts, ~765 lines) which I'd like to remove. This PR is the first, smallest step: it clears out the two uses that a Map handles, and deletes some dead test code that mentions the tree. It does not touch any of the ordered-lookup consumers, and it does not delete rbTree.ts — those follow in separate PRs.

#27966 has the complete removal, including measurements for every replacement. It's being split into reviewable pieces, of which this is the first; read it there if you want the full picture before reviewing the parts.

Replace RedBlackTree with Map. Client.clientNameToIds and TestServer.upstreamMap are plain key/value lookups. Neither ever iterates in order, walks a range, or asks for a nearest neighbour — the only operations are get, put, and existence checks. A red-black tree buys nothing here beyond a comparator and an allocation per entry.

This also fixes a latent bug in getOrAddShortClientId, which tested membership with if (!this.clientNameToIds.get(id)). That is only correct because RedBlackTree.get returns an RBNode wrapper, which is always truthy — the moment the container changed to one returning the stored value, a legitimately falsy value would have been treated as absent. The Map version uses .has().

Remove dead test code. beastTest.spec.ts exports simpleTest, integerTest1 and fileTest1, none of which are called by anything: no it() or describe() wraps them, and there are no references anywhere else in the repo. Removing them also retires LinearDictionary, a hand-written array-backed SortedDictionary that existed solely as the oracle fileTest1 compared the tree against, plus two property printers and a took timing helper. These were the only mentions of RedBlackTree in the test suite, but since none of them run, no test loses coverage.

Delete the orphaned comparators. With those gone, compareNumbers and compareStrings in mergeTreeNodes.ts have no callers left — they had been feeding the RedBlackTree instantiations and LinearDictionary. Both were removed from the public API in #17952 after a deprecation period, are not re-exported from any barrel, and appear in no api-report. The identically named helpers in dds/tree and id-compressor are separate local definitions and are unaffected.

No public API is affected — every type involved is @internal and none appear in an api-report.

Tracked by AB#80505.

Reviewer Guidance

The review process is outlined in the pull request guidelines.

The three commits are best read in order — each removal is what strands the next.

This is deliberately the boring slice of a larger cleanup, split out so the interesting parts can be reviewed on their own. Still to come, as separate PRs carved out of #27966, in rough order:

  • Replace the red-black tree in the three endpoint indexes (endpointIndex, endpointInRangeIndex, startpointInRangeIndex) with a shared SortedSet subclass. Includes a bug fix: intervals sharing an end position currently overwrite one another.
  • Replace the augmented interval tree behind OverlappingIntervalsIndex with a sorted array plus a segment tree of maximum end positions.
  • Delete rbTree.ts and its exports.

…kups

Client.clientNameToIds and TestServer.upstreamMap used RedBlackTree purely
as a key/value dictionary - neither called any ordered operation (floor,
ceil, min, max, walk, mapRange). A plain Map provides the same behavior
with O(1) lookup instead of O(log n) pointer chasing.

Note that getOrAddShortClientId previously tested the returned node for
truthiness, which was only correct because a node object is always truthy.
The Map equivalent uses has() so that short client id 0 is handled
correctly.

This is a step toward removing the hand-rolled red-black tree
implementation entirely. All types involved are internal-only, so there is
no API surface change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`simpleTest`, `integerTest1` and `fileTest1` are exported from beastTest.spec.ts but nothing
calls them: the suite only runs `firstTest`, `randolicious`, `mergeTreeCheckedTest`,
`clientServer` and `findReplacePerf`, none of which touch a RedBlackTree. Removing them also
retires `LinearDictionary`, a hand-written array-backed SortedDictionary which existed solely as
the oracle `fileTest1` compared the tree against, along with the two property printers and
`took`.

No test which runs today loses any coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ChumpChief
Matt Rakow (ChumpChief) requested a review from a team as a code owner August 31, 2026 16:41
Copilot AI lite review requested due to automatic review settings August 31, 2026 16:41
@github-actions github-actions Bot added area: tools area: dds Issues related to distributed data structures area: repo Repo related work area: website base: main PRs targeted against main branch labels Aug 31, 2026
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Hi! Thank you for opening this PR. Want me to review it?

Based on the diff (264 lines, 4 files), I've queued these reviewers:

  • Correctness — logic errors, race conditions, lifecycle issues
  • Security — vulnerabilities, secret exposure, injection
  • API Compatibility — breaking changes, release tags, type design
  • Performance — algorithmic regressions, memory leaks
  • Testing — coverage gaps, hollow tests

How this works

  • Adjust the reviewer set by ticking/unticking boxes above. Reviewer toggles alone don't trigger anything.

  • Tick Start review below to dispatch the review fleet.

  • After review finishes, tick Start review again to request another run — it auto-resets after each dispatch.

  • This comment updates as new commits land; your reviewer selections are preserved.

  • Start review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

`compareNumbers` and `compareStrings` in mergeTreeNodes.ts have no remaining callers. They
were removed from the public API in microsoft#17952 after a deprecation period, are not re-exported
from any barrel and appear in no api-report, and the last references were the RedBlackTree
instantiations and LinearDictionary comparator removed earlier in this PR.

The identically named helpers in `dds/tree` and `id-compressor` are separate local
definitions and are unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fleet Review — In progress

Running reviewers: correctness, security, api-compatibility, performance

View run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: dds Issues related to distributed data structures area: repo Repo related work area: tools area: website base: main PRs targeted against main branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants