Skip to content

table: keep dense lookup for wide messages - #517

Merged
iainmcgin merged 3 commits into
anthropics:mainfrom
fallintoplace:perf/table-wide-dense-lookup
Oct 12, 2026
Merged

iainmcgin merged 3 commits into
anthropics:mainfrom
fallintoplace:perf/table-wide-dense-lookup

Conversation

@fallintoplace

Copy link
Copy Markdown
Contributor

What

Keep dense lookup for low field numbers in messages with 255 or more fields.

Why

Wide messages currently fall back to binary search for every field.

Implementation

Keep indices for fields below 64 in the dense lookup table.

Benchmark

Not applicable.

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@iainmcgin

Copy link
Copy Markdown
Collaborator

[claude code] Thanks for this. The change is correct: the dense array is filled only for field numbers below 64, entries are sorted by field number, so such a field is at index 62 or lower and its index-plus-one always fits a u8, whatever the number of entries. The removed assert was redundant with the const checks that remain.

It is on hold for ordering, not for content. It conflicts with the open table codec stack (#475 to #478) in Table::new and in two test files, and that stack merges first. Once it is in I will rebase this PR and push one maintainer commit, then approve it:

  • reword the two comments that still describe the 255-entry limit (buffa-test/build.rs, and the W254/W255/W256 tests, which then stop straddling a boundary);
  • u8::try_from in place of the as u8 cast in the codegen-side mirror;
  • drop the Changed fragment: the table codec is unreleased, so the stack's Added fragment covers it.

There is no action for you in the meantime.

# Conflicts:
#	buffa/src/table/mod.rs
…message tests

The generator converts a dense slot's index with u8::try_from and reports
an overflow, which takes repeated field numbers, as a CodeGenError.

A message with 255 fields or more now has a dense array, so the W254,
W255 and W256 tests set the fields either side of its end (63 and 64),
and two Table::new tests cover a dense array beside more than 255
entries. The comments that described the old rule are reworded.

The table codec is unreleased, so the changelog fragment is removed.
@iainmcgin

Copy link
Copy Markdown
Collaborator

[claude code] Thanks for this, the lookup change itself is unchanged. I pushed a merge of main and one maintainer commit on top:

  • Merge with main: the oneof support that landed since added a check next to the assert this PR removes in Table::new. The resolution keeps that check and removes only the 255-entry assert, which the two remaining dense checks already cover.
  • dense_lookup in the generator converts the index with u8::try_from and returns a CodeGenError when it does not fit, which takes a descriptor with repeated field numbers. A test builds such a descriptor.
  • The W254, W255 and W256 tests in buffa-test straddled the old 255 rule. They now also set fields 63 and 64, the two sides of the end of the dense array, and their names and the comments in build.rs say what they cover after this PR. Two Table::new tests cover a dense array beside more than 255 entries.
  • The changelog fragment is removed: the table codec has not been released, so a change to it is not a changelog entry.

@iainmcgin
iainmcgin enabled auto-merge October 12, 2026 20:07
@iainmcgin
iainmcgin added this pull request to the merge queue Oct 12, 2026
Merged via the queue into anthropics:main with commit 2d237e6 Oct 12, 2026
11 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants