perf: round 24 — download_zip per-item authz+metadata N+1 → batch (validated authorization pass)
The ROUND23-deferred download_zip N+1, given its own validated pass. The individually-selected files were authorized + fetched one at a time via get_file_with_perms (require + get = 2 serial round-trips/file) before any streaming — a 200-file selection was 400 serial round-trips. AFTER routes the whole multi-select through the new FileRetrievalService::get_files_by_ids_with_perms: one check_files_read_batch (the PgAclEngine resolves every file's drive in ONE query and primes the resource->drive cache) + one get_files_by_ids. 2N round-trips -> 2. Authorization is unchanged and still enforced BEFORE any ZIP entry is written: - add_file_entry_streamed writes the entry header (the filename) before it opens the authorized stream, so the pre-filter is load-bearing — a denied file must never reach it or its name leaks into the archive. AFTER a denied/missing id is absent from the authorized map and is skipped in the same input order, exactly as the old loop skipped a denied get_file_with_perms; it never reaches the entry write. The authz moved from a per-file require to one batch check EARLIER in the same function, not into or after the stream. - The stream open keeps its own per-file Read check (now a primed-cache hit) + Recents recording; check_files_read_batch is documented + gated as identical to looping require. Because the change is authorization-sensitive, the gate is the security property itself. bench_round24_zip_authz drives the real PgAclEngine over a seeded, interleaved mix of owned (granted drive) + denied (other drive) + missing ids and asserts: the batch inclusion set AND input order are identical to the per-file require loop; the included set is exactly the caller's owned files; no denied or missing id is ever included (the authz-regression tripwire); and the batch fetch returns exactly the owned files. Latency (cold, 600-item 1/3-owned selection): 559 -> 267 ms (2.10x; the realistic all-owned selection is O(1) -> a larger win). See benches/ROUND24.md. The folder selections are left as-is (root counts are small and there is no check_folders_read_batch primitive to batch through). Verified: cargo clippy --features bench --all-targets -D warnings clean, cargo fmt --all --check clean, cargo test --lib --features bench = 529 passed / 0 failed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DKyQ4AnYtgp1JtjzweyMeo
This commit is contained in:
+15
@@ -354,6 +354,21 @@ name = "bench_micro_allocs"
|
||||
path = "examples/bench_micro_allocs.rs"
|
||||
required-features = ["bench"]
|
||||
|
||||
# Round-24 battery ────────────────────────────────────────────────────────────
|
||||
|
||||
# Round-24 download_zip authz+metadata N+1 → batch, VALIDATED. The per-file
|
||||
# get_file_with_perms (require + get, 2 round-trips/file) becomes one
|
||||
# check_files_read_batch + one get_files_by_ids. Because the change is
|
||||
# authorization-sensitive, the gate is the security property: the batch check
|
||||
# must make the identical per-file inclusion decision (same set AND input order)
|
||||
# as the shipped-before require loop, over owned + denied + missing ids, and
|
||||
# never include a denied/missing file. Drives the real PgAclEngine. Needs the
|
||||
# dev Postgres up (reads DATABASE_URL from .env).
|
||||
[[example]]
|
||||
name = "bench_round24_zip_authz"
|
||||
path = "examples/bench_round24_zip_authz.rs"
|
||||
required-features = ["bench"]
|
||||
|
||||
# Round-23 battery ────────────────────────────────────────────────────────────
|
||||
|
||||
# Round-23 CPU/alloc micro-pack (no Postgres) — deterministic alloc gates for
|
||||
|
||||
Reference in New Issue
Block a user