Skip to content

feat: parallelize per-doc check loop with Io.Group#24

Merged
laulauland merged 2 commits intomainfrom
lau/zig-0.16-parallel
Apr 17, 2026
Merged

feat: parallelize per-doc check loop with Io.Group#24
laulauland merged 2 commits intomainfrom
lau/zig-0.16-parallel

Conversation

@laulauland
Copy link
Copy Markdown
Member

Stacked on #23. Merge #23 first, then rebase and merge this.

Summary

  • Parallelizes the per-doc check loop in drift check using std.Io.Group.
  • Each doc's binding checks (read file → parse with tree-sitter → hash → optional git log for blame) runs on a separate task. Docs are independent, so no shared state beyond pre-allocated result slots.
  • Local benchmark: ~0.40s → ~0.14s (~3×) on the drift repo itself.

Design

  • Task-local CommandContext. Each task builds its own std.heap.ArenaAllocator (child of run_arena) so ctx.scratch() / ctx.resetScratch() in checkBinding, checkDocLinks, classifyRelativeLink keep working unchanged. The main CommandContext keeps scratch_arena; other commands are untouched.
  • Task-local FileCache. std.StringHashMap isn't thread-safe. Each task gets its own cache. Docs rarely share files across each other; the lost hit rate is negligible.
  • Pre-allocated result slots. results: []?DocCheckResult allocated from run_arena, one per doc. Tasks write their own slot; the main thread merges in doc-order so output stays deterministic (docs are already sorted by discoverDocGroups).
  • Error propagation. Io.Group.async tasks can't return errors to the caller. A checkOneDoc wrapper catches errors from the inner function and stores them as error_message: ?[]const u8 on the result. The main thread prints the message and returns error.LintCheckFailed during merge — same external contract as before.

Scope

Only src/commands/lint.zig changes (+173/−70). vcs.zig, lockfile.zig, markdown.zig, and other commands are untouched.

Testing

  • zig build passes.
  • zig build test passes: 63 tests, 0 failures.
  • drift check against the real repo produces the same stale-anchor output as before (same paths, same reasons, same anchors, same sort order).
  • drift check --format json still emits valid JSON (only checked_at_ms differs run-to-run).

Deferred

Other options from the Io migration plan (speculative blame via io.async, Io.Batch for link checks, startup overlap of git ls-files || git remote get-url, persistent-GitCatFile refactor) are separate follow-ups.

@laulauland laulauland force-pushed the lau/zig-0.16-parallel branch 2 times, most recently from 7c43686 to 6a592d2 Compare April 17, 2026 10:10
@laulauland laulauland force-pushed the lau/zig-0.16-parallel branch 2 times, most recently from b33cabc to 1180a84 Compare April 17, 2026 10:16
@laulauland laulauland marked this pull request as ready for review April 17, 2026 10:16
Base automatically changed from lau/zig-0.16 to main April 17, 2026 10:19
@laulauland laulauland force-pushed the lau/zig-0.16-parallel branch from 1180a84 to 76292c2 Compare April 17, 2026 10:21
@laulauland laulauland merged commit 636b371 into main Apr 17, 2026
5 checks passed
@laulauland laulauland deleted the lau/zig-0.16-parallel branch April 17, 2026 10: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.

1 participant