Skip to content

perf(update): carry the extracted tree across sparse chain steps - #252

Merged
peters merged 2 commits into
mainfrom
autoresearch/update-chain-apply-opt
Aug 31, 2026
Merged

perf(update): carry the extracted tree across sparse chain steps#252
peters merged 2 commits into
mainfrom
autoresearch/update-chain-apply-opt

Conversation

@peters

@peters peters commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Purpose

Autoresearch update-surface idea 1, measured to a keep: the chain walker was re-extracting the full current archive for every sparse delta. The per-step profile (via the BENCH_STEP_TIMING knob from #251) showed the step cost was ops ~4.3 s + extract ~1.0 s + repack ~0.6 s + hash ~0.07 s — the extract is removable without touching verification.

Change

  • apply_target_deltas carries an extracted working dir across consecutive sparse deltas: the starting archive is extracted once, each step applies its ops in place, and the per-step repack + full SHA-256 check are unchanged (verification semantics intact).
  • A non-sparse hop rebuilds from archive bytes and drops the carried tree; the next sparse hop re-extracts once.
  • sparse_ops split into shared ops+repack segments with a new apply_sparse_step_in_place entry; the single-shot path reuses the same code.
  • Unit regression: a two-step carried chain produces byte-identical archives to the single-shot path at every step.

Measured (48-core/251 GB host, seed 42, same-session A/B)

chain before after Δ
100 deltas, scale 1.0 (promotion gate) 656,990 ms 488,689 ms −25.6%
20 deltas, scale 1.0 128,699 ms 100,689 ms (repeat: 101,076) −21.8%
20 deltas, scale 0.25 35,125–36,690 ms 28,170 ms ~−20%

Download bytes and the installed payload are byte-identical (the update bench asserts the install tree matches the last release; publish side untouched).

Behavior impact

Same product behavior: per-step full SHA-256 verification preserved, payload byte-identical, no format/API change. Client-side apply only — publisher cost unchanged.

Test evidence

  • RUSTFLAGS="-D warnings" cargo test --workspace — green (incl. new equivalence test)
  • clippy all-targets + blocking strict — clean; fmt clean
  • A/B rows in auto/update/results.tsv; docs/performance/update-chains.md updated with the per-step breakdown and the new open item (the ops phase itself now dominates; the remaining ~0.7 s per-step repack+hash is kept deliberately — it is what enables per-step verification)

The chain walker re-extracted the full current archive for every
sparse delta before applying the per-file ops. The 100-delta
per-step profile (BENCH_STEP_TIMING) showed the per-step cost was
ops ~4.3 s + extract ~1.0 s + repack ~0.6 s + hash ~0.07 s, so the
re-extract was removable without touching the per-step repack and
full SHA-256 verification:

- apply_target_deltas now keeps a working dir across consecutive
  sparse deltas: the starting archive is extracted once, each step
  applies its ops in place, and the step's repack + per-step full
  SHA-256 check are unchanged
- a non-sparse hop rebuilds from archive bytes and drops the carried
  tree; the next sparse hop re-extracts once
- sparse_ops split into shared ops+repack segments with a new
  apply_sparse_step_in_place entry; the single-shot path reuses the
  same code
- unit test: a two-step carried chain produces byte-identical
  archives to the single-shot path at every step

Measured (48-core/251 GB host, seed 42, same session A/B):
- 100-delta scale 1.0: apply 656,990 -> 488,689 ms (-25.6%)
- 20-delta scale 1.0: 128,699 -> 100,689 ms (-21.8%), repeat
  101,076 ms
- 20-delta scale 0.25: 35,125-36,690 -> 28,170 ms
- download bytes and the installed payload are byte-identical
  (install-tree bench assertion; unit equivalence test)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Optimizes sparse delta-chain application by reusing an extracted working tree while preserving per-step archive verification.

Changes:

  • Adds in-place sparse delta application and repacking.
  • Carries working trees across consecutive sparse updates.
  • Adds equivalence coverage and records benchmark improvements.

Reviewed changes

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

Show a summary per file
File Description
crates/surge-core/src/update/manager/apply/delta.rs Implements carried-tree chain application.
crates/surge-core/src/releases/delta/sparse_ops.rs Extracts shared in-place operations and repacking.
crates/surge-core/src/releases/delta/mod.rs Exposes internal sparse-step helpers.
crates/surge-core/src/releases/delta/tests.rs Tests byte-identical consecutive sparse steps.
docs/performance/update-chains.md Documents measured performance and remaining costs.
auto/update/program.md Records the successful optimization experiment.
auto/update/results.tsv Adds benchmark results.

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

Comment thread crates/surge-core/src/update/manager/apply/delta.rs Outdated
Comment thread crates/surge-core/src/update/manager/apply/delta.rs
Comment thread crates/surge-core/src/update/manager/apply/delta.rs
- run the sparse arm inside a Result-returning closure so every
  failure flows through the shared per-delta error handler (filename
  context + VerifyFailureBudget) instead of early-returning raw
- drop the carried working dir on non-sparse hops: a sparse ->
  archive -> sparse chain previously applied the final sparse delta
  to the stale pre-hop tree (caught by a new mixed-chain regression
  test: per-file source hash mismatch on the final hop)
- normalize (trim) patch_format/algorithm in is_sparse_file_ops_delta
  to match the dispatch normalization, so padded descriptors take
  the carry path like the dispatcher classifies them

Regression tests: mixed sparse/archive/sparse chain applies to the
correct tree; a corrupted sparse delta reports the filename through
the shared handler; classifier normalization unit test.
@peters
peters merged commit cba8ff5 into main Aug 31, 2026
15 checks passed
@peters
peters deleted the autoresearch/update-chain-apply-opt branch August 31, 2026 12:24
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