Dreamacro:erofs-rs 先消除 sync/async builder 重复,再推进并行压缩
Dreamacro 认为 erofs-rs 应让共享逻辑集中在一处,优先采用更 sans-I/O 的 option 1;sync/async builder 已出现 append_flat 行为漂移,建议先从 build/sync.rs 与 build/async.rs 去重,再处理 #15 的并行压缩。reader 保留借用式零拷贝与 no_std,sync API 不应被 AsyncRead 的 Send 约束拖累。
作者原文@DreamacroThanks for the survey. It matches my understanding, and reducing duplication matters a lot to me. I'd like shared logic to live in one place as much as possible.
The builder already shows the cost of keeping two copies: they have started to drift. For example, the sync
append_flathas a single-block fast path that the async version doesn't have. Every future change, including the parallel compression in #15, would also have to be made twice.On the approaches: I lean toward option 1 (more sans-I/O). It matches the reader's design, which already has
plan_inode_read/BlockPlan. It also keeps the code in plain Rust, with readable rustdoc and error messages. Option 4 on its own doesn't solve the problem. A shared behavioural test suite is a good safety net either way, but it only catches drift and doesn't remove the duplication. Option 3 worries me even for the builder. The syncBuildercurrently accepts anyRead, while ourAsyncReadrequiresSend, so routing sync through an async core would add bounds to the sync API.On your questions:
- Yes. Zero-copy access via mmap/slices and
no_stdsupport are core features of the reader, so the sync path must keep the borrowedImage::getpath.- I'd prefer plain Rust. A small in-house
macro_rules!is acceptable if it is clearly smaller and easier to read than the alternative. I'd avoidmaybe-async-style crates, though.maybe-async, for example, chooses sync or async with a crate-wide feature, but we expose both at the same time.- Starting with the builder makes sense.
build/sync.rsandbuild/async.rsare nearly line-for-line copies around the sameState, so that's the cheapest win and the clearest signal. The reader is less of a pain point because its sans-I/O core already exists.- Nothing is pending from me in
build/. The main overlap is with #15, since both touch the compression path (append_compressed). I'd suggest landing the deduplication first. That way the parallel pipeline only has to be written once instead of separately for sync and async.The evaluation criteria look good to me. A draft PR with the comparison table is a good way to start. Feel free to go ahead.