Skip to content

refactor: read a directory's listing in chunks - #1528

Merged
thekevinbot merged 8 commits into
mainfrom
bot/1461-chunked-read-1016
Oct 20, 2026
Merged

thekevinbot merged 8 commits into
mainfrom
bot/1461-chunked-read-1016

Conversation

@thekevinbot

@thekevinbot thekevinbot commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Refs #1461

Step one of the wide-directory redesign: read a directory's listing in chunks. This is a structural change with no observable effect. Later steps sort and judge each chunk while the next one is being read, then merge the chunks.

  • listing::read_chunks(dir, emit) hands a directory's entries to emit as Chunks, at most CHUNK_ENTRIES (8192) at a time, as it reads them. It applies on every platform (Linux RawDir, other Unix Dir, Windows read_dir).
  • Each chunk has its own name buffer. A Listed entry records its chunk and u32 offsets into it, so it is self-contained across chunks and shrinks from 32 to 24 bytes.
  • Listing::read collects the chunks and sorts them together, so nothing outside listing.rs changes.
  • The branch carries the test: fix main's lib-test compile (scan_glob_rows visit argument) #1527 fix commit (identical change, merges cleanly) so its CI could compile the lib tests while main was red.

Output is byte-identical: same md5 for ./docs and ./ on a 1.6M-item tree.

Timings

These are paired medians on ZFS with other agents running, load 10-34.

case before (main) after
./docs (1.57M entries) vs rg 0.74-0.85 0.79-0.87
./* vs rg 0.70 0.80
after/before direct, ./docs 0.989
after/before direct, ./* 1.009
after/before direct, 20k dirs ./**/*.md 0.967

Neutral within noise. Where a wide directory's time goes (instrumented, ./docs): getdents takes about 350ms, pushing entries about 25ms, sorting about 55ms, and judging about 200ms. Sort and judge are what the later steps hide behind the read.

E2E Verification

  • Ran e2e suites locally for every affected SDK
  • Python SDK e2e: pass (targeted)
  • TypeScript SDK e2e: pass
  • Rust core e2e (if applicable): pass
  • packages/python/e2e-attestations/<branch>.json receipt written if packages/python changed (just e2e-attest-python)
  • packages/ts/e2e-attestations/<branch>.json receipt written if packages/ts changed (just e2e-attest-ts)
  • Command(s) run: uv run maturin develop --release, cargo build --release -p dirsql --features cli, testing-conventions e2e attest 'uv run python -m pytest tests/e2e/glob_speed_one_level_test.py tests/e2e/glob_speed_recursive_test.py tests/e2e/glob_speed_depth_bound_test.py tests/e2e/glob_speed_gitignore_test.py tests/e2e/glob_speed_dotfiles_test.py tests/e2e/glob_speed_matchers_test.py tests/e2e/glob_speed_node_modules_test.py tests/e2e/glob_speed_symlink_test.py tests/e2e/stat_speed_test.py tests/e2e/query_contract_test.py -q', just e2e-attest-ts, cargo test --workspace --features cli
  • Result summary: python 26 passed. A first run had one failure in glob_speed_symlink ./docs/, a 12ms native case, at load 15; it passed on rerun and in the full rerun. ts passed; cargo workspace all passed.

Changelog / Migrations

  • skip-changelog trailer: internal restructuring, no observable change.

Merge with main (2026-10-19)

skip-changelog: internal restructuring, no observable change
Each chunk keeps its own name buffer, and an entry records its chunk
in u32 offsets, so a listed entry shrinks from 32 to 24 bytes.

skip-changelog: internal restructuring, no observable change
@thekevinbot
thekevinbot merged commit 62eb406 into main Oct 20, 2026
89 checks passed
@thekevinbot
thekevinbot deleted the bot/1461-chunked-read-1016 branch October 20, 2026 11:11
@thekevinbot thekevinbot mentioned this pull request Nov 3, 2026
4 of 7 tasks
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