Skip to content

The last page-named test locals say block - #2393

Merged
matrixarkai merged 1 commit into
mainfrom
refactor/the-last-page-named-test-locals-say-block
Oct 30, 2026
Merged

matrixarkai merged 1 commit into
mainfrom
refactor/the-last-page-named-test-locals-say-block

Conversation

@matrixarkai

Copy link
Copy Markdown
Owner

block is the canonical spelling for this crate's one storage tier. What is left of the
page vocabulary in Rust code is 248 identifier occurrences over 30 distinct tokens
(whole-token, comments and string literals excluded, measured at 0d8caa647 and again at
59c0f4745 — the number has not moved), and almost all of them are pinned: by
DURABLE_NAMES, by a committed compat/ corpus, by a published report key, or by a
dependency's own API.

These four are pinned by nothing. They are local let bindings and fields on structs
declared inside a test module: never serialized, never a published key, and their only
string occurrences are format-string interpolations of the binding itself.

name becomes sites
pages_before / pages_after blocks_before / blocks_after 8 files, 57 occurrences
pages_before / pages_after in evict_scale.rs live_blocks_before / live_blocks_after 8 occurrences
AddressCount::page_entries block_entries 5 occurrences
Recovery::page_read_bytes block_read_bytes 4 occurrences

74 replacements over 10 files, and nothing else in the crate still spells any of the four.

Why evict_scale.rs gets a different name

releasing_a_mixed_batch_releases_exactly_the_clean_buckets_and_leaves_the_rest_whole
already declares blocks_before — a vector indexed by routing bucket — and then declares
pages_before, a map keyed by object name, in the same scope. The mechanical rename
shadows the first with the second, and the read at the bottom of the function picks up the
wrong binding. The compiler catches that one because the two types differ, which is luck
rather than a guarantee. Both bindings here are filled from live_blocks_by_key, so they
take that helper's name instead.

It is the only one of the nine files where both spellings are live in one scope, and the
check is a set intersection of the files holding each spelling rather than a memory.

What does not move, and what each decline costs

  • In DURABLE_NAMES, so a store written by an older build still has to decode them:
    page_size, page_store, page_index_entries, page_index_count, page_segment_id,
    page_id, page_ref_key, staged_pages, slot_page_ref_count, page_address_count,
    compact_pages, page.
  • Quoted in a committed compat/ corpus: page_address, page_address_fields,
    page_index, page_index_entry, page_index_entry_count, page_index_entry_fields,
    page_index_entry_samples, page_index_rebuild_watermark, page_index_rebuild_count,
    page_reads, page_writes, pages, stale_page_tombstones,
    storage_manager_page_gc_count, reclaim_page. A corpus is a record of what the engine
    emitted, not an expectation of what it should emit, so regenerating one destroys the only
    record there is of an older build's output.
  • A dependency's API, and the names belong to that dependency:
    CacheKey::page_with_slot, page_with_slot_generation, invalidate_page_segment.
  • page_store_reads is pinned by no registry and is read by field access in three places,
    one of them an assertion in the integration corpus, across three published report
    structs — two of which carry no block-spelled twin to fall back on.
  • compact_pages and reclaim_page are also PREFIX-pinned. Six skip reasons extend them
    (compact_pages_disabled, compact_pages_no_pressure, compact_pages_not_leading,
    compact_pages_nothing_to_relocate, reclaim_page_disabled, reclaim_page_no_pressure)
    and data_node/tests/part3.rs matches a declined phase with starts_with(phase). Moving
    the phase name alone breaks that match while every name-level check stays green. There is
    a second prefix pin of the same shape in
    engine/tests/what_the_slot_index_is_made_of.rs, which sums the block-level accounting
    terms with label.starts_with("page/").

Validation

cargo check -p temporalstore-rust --all-targets
cargo test --release -p temporalstore-rust --lib data_node::tests::part3 -- --test-threads=1
cargo test --release -p temporalstore-rust --lib engine::tests::evict_scale -- --test-threads=1
cargo test --release -p temporalstore-rust --lib engine::tests::index_write_amplification::index_recovery_cost -- --test-threads=1
cargo test --release -p temporalstore-rust --lib engine::tests::address_word_footprint::what_a_block_address_costs_per_record_at_two_ranges_and_two_corpus_sizes -- --test-threads=1 --ignored --exact
cargo test --release -p temporalstore-rust --lib engine::tests::container_blocks_are_batched -- --test-threads=1
cargo test --release -p temporalstore-rust --lib engine::tests::bucket_mark_in_place_budget -- --test-threads=1
cargo test --release -p temporalstore-rust --lib engine::tests::restore_large_scale -- --test-threads=1
cargo test --release -p temporalstore-rust --lib engine::tests::round_walk_scope -- --test-threads=1
cargo test --release -p temporalstore-rust --lib engine::tests::set_listing_source -- --test-threads=1
cargo test --release -p temporalstore-rust --lib engine::tests::write_after_fold -- --test-threads=1
cargo test --release -p temporalstore-rust --lib open_read_scale -- --test-threads=1
cargo test --release -p temporalstore-rust --lib page_and_block_name_one_tier -- --test-threads=1

Every arm reports a non-zero pass count. Two of them did not, the first time:
engine::tests::index_recovery_cost matched nothing and still exited 0, because the module
is actually nested under engine::tests::index_write_amplification; and
engine::tests::address_word_footprint reported 0 passed; 1 ignored, because its only
test is #[ignore]d and the suite therefore never runs it. Both are above under the form
that actually runs them, at 4 and 1 passing.

The rename ran as a whole-token substitution validated against a known answer at the
pattern's edges — a digit, an underscore and a letter adjacent to the token are all
rejected — took its root from a parameter, refused to start on a dirty tree, and asserted
afterwards that git reports exactly the files it wrote and that none of the four names
survives in them.

🤖 Generated with Claude Code

`block` is the canonical spelling for this crate's one storage tier, and these four names
are the part of what is left that no registry pins. They are local `let` bindings and
fields on structs declared inside a test module: never serialized, never a published key,
and their only string occurrences are format-string interpolations of the binding itself.

  pages_before / pages_after  -> blocks_before / blocks_after   (8 files, 57 sites)
  pages_before / pages_after  -> live_blocks_before / _after    (evict_scale.rs, 8 sites)
  AddressCount::page_entries  -> block_entries                  (5 sites)
  Recovery::page_read_bytes   -> block_read_bytes               (4 sites)

`evict_scale.rs` takes different names because
`releasing_a_mixed_batch_releases_exactly_the_clean_buckets_and_leaves_the_rest_whole`
already declares `blocks_before` -- a vector indexed by routing bucket -- in the same
scope as `pages_before`, a map keyed by object name. The mechanical rename shadows the
first with the second and the read at the bottom of the function picks up the wrong
binding; the compiler catches it only because the two types differ. Both bindings here
are filled from `live_blocks_by_key`, so they take that helper's name.

74 replacements over 10 files. Nothing published, stored, stamped or valued moves, and
nothing else in the crate still spells any of the four.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@matrixarkai
matrixarkai merged commit df5649d into main Oct 30, 2026
7 checks passed
@matrixarkai
matrixarkai deleted the refactor/the-last-page-named-test-locals-say-block branch October 30, 2026 07:12
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.

2 participants