From a0f0050adaa9eb7d8a1cdc175326b20c1b32c5e6 Mon Sep 17 00:00:00 2001 From: sneak Date: Fri, 24 Jul 2026 07:52:54 +0700 Subject: [PATCH] Announce each operand on stderr before its passes With per-operand walk/hash/update cycles, a multi-operand invocation (e.g. scan /srv/*) showed pass totals that looked like the whole run's: an operator watching operand 3 of 14 hash 300k files concluded the other 20M files were being skipped. Print the operand path and its position before each cycle. --- README.md | 9 +++++++++ TODO.md | 5 +++++ scan.go | 8 +++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 618cf8a..a07d207 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,15 @@ operand before starting the next: 3. **update** — apply the operand's insertions, updates, and deletions to the database in a single transaction. +Because every operand runs its own three passes with its own totals, +`scan` announces each operand on stderr before starting it, so a +multi-operand invocation (e.g. a shell glob) is not mistaken for a +nearly-finished run: + +``` +scan: /srv/media (operand 3 of 14) +``` + Rules for the walk: - Only regular files. Skip directories, symlinks (do not follow, diff --git a/TODO.md b/TODO.md index edd38fc..e7f75bc 100644 --- a/TODO.md +++ b/TODO.md @@ -19,6 +19,11 @@ # Completed Steps +- announce each operand on stderr before its passes (2026-07-24, + branch `scan-operand-progress`): with per-operand walk/hash/update + cycles, a multi-operand run (e.g. `scan /srv/*`) showed pass totals + that looked like the whole run's — an operator watching operand 3 of + 14 hash 300k files concluded 20M files were being skipped - parallel walk (2026-07-24, branch `parallel-walk`): the walk pass was a single goroutine and took hours at ~20M files on a busy pool (observed: 22M files in 4h on a ZFS server); it is now a diff --git a/scan.go b/scan.go index 5ac6958..5f9cffa 100644 --- a/scan.go +++ b/scan.go @@ -108,7 +108,13 @@ func syncScan(db *sql.DB, roots []string, workers int, ) (scanStats, error) { var st scanStats - for _, root := range roots { + for i, root := range roots { + // Each operand runs its own walk/hash/update sequence, so + // announce it: without this, the per-operand pass totals look + // like the whole run's. + fmt.Fprintf(os.Stderr, "scan: %s (operand %d of %d)\n", + root, i+1, len(roots)) + err := syncRoot(db, root, workers, oneFS, &st) if err != nil { return st, err