Repository navigation
quest: delete mkv-fragments, the MKV importer no longer replays input - #7515
Conversation
Quest-Claim: 935e227d3b6442f8
#6908 replaced the clone-and-replay drain with an incremental decoder, and #7234 streams blocks through its own EBML reader. A deterministic sweep (block size x chunk size, instructions and allocation) shows the O(B^2/c) slope at the audit commit and none since. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. WalkthroughThe performance survey README now records that accumulated-input replay was removed, cites the related pull requests and measured result, and names the nightly benchmark series. The Required list no longer includes the fragmented MKV import quest. The MKV fragmentation proposal was deleted. Merge Risk:
|
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: f8218f3
No actionable bugs found in this documentation-only change. Deleting the obsolete replay quest, removing its index entry, and retaining the outcome in the survey is simpler than adding another parser optimization or duplicate benchmark. The current EBML reader consumes input incrementally, and the existing mkv-chunks/mkv-payloads benchmarks are selected by the nightly container benchmark run. No runtime, API, or wire changes are introduced.
Verification: inspected the changed quest files, relevant importer/framing code, benchmark cases and nightly selection. I did not run tests or reproduce the PR's performance measurements; those results remain author-reported.
(Written by OpenAI)
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Quest deleted —
quest/m2/performance-survey/mkv-fragments.mdremoved; the maintainer chose deletion on 2026-11-01 (recorded under Decisions), so this matches the quest-completion convention. - Survey index updated — the
## Requiredbullet for the quest is removed and the existing-ownership bullet now records that the MKV importer's replay of accumulated input was removed by #6908 and #7234, with the measured no-win in this PR and nightlymkv-chunks/mkv-payloadscovering the slope.
I verified the claims rather than taking them on faith:
- No dangling references.
git grep mkv-fragmentsat the head resolves only to the edited README; the deletion removes its last reference. - The cited PRs are merged and relevant: #6908 (merged 2026-10-27,
25cd95ea64) replaced the replay with ebml-iterable's incrementalTagDecoder; #7234 (merged 2026-11-01,bdd045f361) replaced that with the importer's own EBML reader. - The behavior matches the prose:
Import::drainnow takes&[u8](rs/moq-mux/src/container/mkv/import.rs:344) and drives a streaming reader, with no retained-BytesMut/WebmIteratorreplay. - The nightly-coverage claim holds:
mkv-chunksandmkv-payloadsare Criterion groups inrs/moq-mux/benches/containers.rs, and nightlyrust-benchdiscovers every bench target throughcargo metadata(bench/run.sh:242), so they are scheduled.
Quest files only, no behavior risk, and the report carrying the measurement lives in the PR body as expected for a report-shaped quest.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
…survey/mkv-fragments Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Claims and deletes quest/m2/performance-survey/mkv-fragments.md. The maintainer chose deletion on 2026-11-01 (see Decisions).
Summary
The quest targeted
Import::draincloning the retainedBytesMutand replaying a freshWebmIteratorover it on everydecode(audit commit1d43c096e044,import.rslines 227-252). A B-byte block arriving in c-byte chunks copied O(B²/c) bytes. That code no longer exists:25cd95ea64) replaced the replay with ebml-iterable's incrementalTagDecoder. It still buffered each whole block, but did not replay it.bdd045f361) replaced that with the importer's own EBML reader (rs/moq-mux/src/container/mkv/ebml.rs). Each byte is consumed once. A block's payload streams into its frame as it arrives, and only a split element header (12 bytes at most) or a field being read is retained.I measured all three revisions. The slope is present at the audit commit and absent on both later ones. On main, copy volume and peak memory are the same at every chunk size, and instructions scale with the number of
decodecalls, not with block size. Following the survey's "accept a measured no-win" contract, this PR deletes the quest. It also rewrites the epic's stale "MKV fragmentation below concerns parser replay" sentence to record the outcome for the epic's reconciliation step.API and wire impact: none, since the PR only changes quest files.
Measurements
Method. I built one harness (
mkv_measure, below) unchanged against three source snapshots in release mode: audit =1d43c096e044, pre =b652b3e11d(parent of #7234, the #6908 decoder), and head =304ee3316a(main). Each run generates a WebM of about 4 MiB in memory: a single block forsimple-4096, otherwise 128 blocks per Cluster. It then feeds the WebM throughImport::decodein c-byte chunks and callsfinish().perf_event_openon the performance-core PMU (cpu_core, type 4). The process is pinned withtaskset -c 0-7. Counting covers only the decode/finish window, so input generation and importer setup are excluded. The cold count covers the header-through-Tracks prefix (71–107 B). The steady count covers the Clusters plusfinish().realloccounts its new size) and peak live bytes. The retained output frames are included and are the same in every variant. Instruction counts undercount bulk copies, sincerep movsbretires as a few instructions, so the allocation column is the copy measure.simple-N= VP9 keyframe SimpleBlocks of N KiB;group-1024= 1 MiB Blocks in BlockGroups;laced-64= Opus SimpleBlocks EBML-laced with 8 × 8 KiB frames;live-64= 64 KiB blocks in unknown-size Clusters inside an unknown-size Segment.cargo build --release --locked, load average ~26 (instruction counts do not depend on load). "—" marks an audit cell skipped because its predicted replay copy, total·B/(2c), exceeded 8 GiB.Bytes allocated per input byte (copy volume):
simple-1simple-1simple-1simple-64simple-64simple-64simple-1024simple-1024simple-1024simple-4096simple-4096simple-4096group-1024group-1024group-1024laced-64laced-64laced-64live-64live-64live-64Steady instructions per input byte:
simple-1simple-1simple-1simple-64simple-64simple-64simple-1024simple-1024simple-1024simple-4096simple-4096simple-4096group-1024group-1024group-1024laced-64laced-64laced-64live-64live-64live-64Reading the tables:
decodecall: 1109/B at c=1, 17.4/B at c=64, and 0.94/B at c=1500, identical for 64 KiB, 1 MiB and 4 MiB blocks. That cost is linear in calls and does not depend on block size.Peak live MiB and cold catalog startup instructions
simple-1simple-1simple-1simple-64simple-64simple-64simple-1024simple-1024simple-1024simple-4096simple-4096simple-4096group-1024group-1024group-1024laced-64laced-64laced-64live-64live-64live-64simple-1simple-1simple-1simple-64simple-64simple-64simple-1024simple-1024simple-1024simple-4096simple-4096simple-4096group-1024group-1024group-1024laced-64laced-64laced-64live-64live-64live-64First-frame latency. I did not measure this separately. The audit and pre revisions publish a block only once the whole block has arrived. Head publishes each payload byte as it arrives:
a_block_streams_into_its_frame_before_it_completes(rs/moq-mux/src/container/mkv/import.rs:1601) reads the first 1 KiB of a 1 MiB block before the block completes, with at most 12 bytes retained.Split equivalence on head (
mkv_verify, below), 21,789 comparisons, all equal. For each input, the reads published per track (group, timestamp, duration, keyframe flag, payload length and hash, gaps, ends, read errors) and thedecode/finisherrors at each chunk size match unsplit input:opus.webm(1813 B) truncated at every length, and with every byte XORed by 0x01, 0x80 and 0xff, at chunk sizes 1, 7 and 64. The outcomes covered 5031 clean imports, 1866Truncatedat finish, 265MatroskaParse, and 42 other distinct error outcomes (Opus head, lacing, timestamp rewind, negative timestamps, missing fields).Nightly coverage already exists. The nightly Criterion run and CodSpeed's simulated instruction counts both run
rs/moq-mux/benches/containers.rs. Itsmkv-chunks(1/7/64/whole onopus.webm) andmkv-payloads(1 KiB/64 KiB/1 MiB payloads × 1500/64 KiB/whole chunks) series would show a reintroduced replay: at payload 1 MiB, chunk 1500, the audit revision costs ~36× head's instructions and ~2200× its allocation. I added no new bench.Harness:
mkv_measure.rs(copied into each tree'srs/moq-mux/examples/)Harness:
mkv_verify.rs(head only, next tomkv_measure.rs)Driver:
sweep.pyRun as
quest gate python3 -I sweep.py sweep.tsv audit pre head --rounds 2, followed by apre-only pass over the small-chunk cells the first pass had skipped.Raw samples (
revision round case chunk bytes cold_bytes cold_instr steady_instr alloc_bytes allocs peak_live)Decisions
decodecall. It was not chosen: that cost is the "byte-at-a-time is ~1.9× slower" trade moq-dev/moq#7234 accepted, and it stays under 1 instruction per byte at a 1500-byte read.Choices made without asking
mkv-payloadsnightly series, and the survey only asks for retained evidence.Follow-ups (suggested, not planned)
finish()returnsMkv(Truncated), the importer leaves its tracks neither finished nor aborted until it is dropped. A subscriber'sread()then waits. In the verification this happened for 1462 truncation lengths and 29 byte flips ofopus.webm, with the same outcome at every chunk size. A refuseddecodedoes end the tracks infinish()(rs/moq-mux/src/container/mkv/import.rs:838-852). Callers that drop the importer after an error are unaffected. Consider aborting the tracks with the truncation error infinish().Checks
8c2f04c972into13aa7ca699. GitHub reported a conflict in the survey README's## Requiredlink list, which quest's merge driver resolved locally. The PR's added and removed lines are unchanged from the reviewed head; only surrounding context moved.quest check --base origin/mainon13aa7ca699: 553 documents ok.rs/moq-mux/src/container/mkv/uses its ownebml.rsreader (noWebmIteratorin the importer).mkv-chunksandmkv-payloadsare inrs/moq-mux/benches/containers.rs, which the shared Rust bench nightly runs. Main's only link to the quest is the README entry this PR removes.quest/m3/mkv-input-coalesce.mdtracks the per-decodecost from byte-at-a-time input, which matches the alternative Decision 1 left out of this quest. It does not conflict with deleting this one.quest gate nix develop -c just ci origin/mainon2334f47387: passed (markdown, gh, quest, shell, large_files, toml, nix, justfile).Review
Head
13aa7ca699: no new local review. The only change sincef8218f3520is a merge from main that leaves the PR's own added and removed lines identical. The PR touches only quest files and carries no behavior risk, so the skip under the simple-review rule (moq-dev/quest#364) still applies.Online reviews on
f8218f3520: the OpenAI automated review (review) and pullfrog (review) found no issues. CodeRabbit was rate-limited and did not review. There are no unresolved threads.🤖 Generated with Claude Code
(Written by Claude Opus 5.5)