Records two measurements as repeatable benchmarks: the same hash-only read
through the buffered and the mapped source read mode, and the cache
publication path where an unchanged stored hash is compared and left alone
while a changed one is written back. The second pair is what keeps a Scan from
paying a physical attribute write per file.
Feeds the exactly-one-callback test through four batches with a recording
source, so the stop assertions cover the items the run actually produced
instead of depending on how far the index raced ahead of the cancel, and
anchors the TESTING.md filter that selects every signature cache test.
Replaces the streaming request/result API with caller-owned items and
consolidates the content options, following the Job execution performance
design.
- `Item`, `BatchSource` and `Run` replace `StreamRequest`, `StreamResult`,
`StreamSource`, `StreamSink` and `RunStream`. Every accepted item receives
exactly one terminal callback from a single goroutine and without doing
I/O; an item ACP cannot process reports `Failed`, and a completion carries
one outcome per requested target in request order with its error identity
preserved. A graceful stop stops feeding, finishes the items in flight and
reports the rest, and a hard stop abandons per-item accounting.
- One `HashPolicy` replaces `WithHash`, `WithSignatureCache` and
`ForceRehash`. A stored hash is read whenever the policy uses the cache,
reused only where the policy allows it, and refreshed only when it differs.
- A source-only `WithReadMode` selects buffered (the default) or mapped
reads, and buffered sources open with `O_NOATIME` where the platform has
it. `LinearDevice` keeps request ordering, append targets and abort-on-error
but no longer selects the read mode.
- `Overwrite` becomes a target-device option, `WithReadBuffer` sets the read
buffer, and `SelectFiles` returns the entries the command line copies,
replacing `AccurateJob`, `WildcardJob` and the walk options.
- Copy consumers share one reference-counted chunk buffer each from a common
pool, and the per-item write goroutines finish before the result channel
closes, so no finished item can be dropped.
The command line tools, the documentation and the test suite move with the
API, including semantic tests for the callback contract, the stop and drain
paths, the hash policy matrix and the read modes.
The writer no longer re-derives or revalidates live size and mtime around
the xattr write. The reader already compares the stored snapshot against
the file and treats a mismatch as stale, so an entry queued for a version
that has since changed can never read back as a hit, while rewriting it
from live metadata would bind a hash to a version it was not computed for.
The regression test seeds a decoy attribute, asserts that the queued
snapshot lands unchanged, and asserts that the reader reports a miss for a
file whose metadata moved on.
Concurrent source preparation can no longer reorder writes to a linear
target. Preparation reports one outcome per indexed request; the ordering
stage buffers later outcomes until the request's turn and only then
transfers the reader, so a source waits for its consumer after the
ordering stage has taken it. Skipped and failed requests advance the order
without a write, so one unresolvable source no longer stalls the requests
behind it. Random targets keep completion-order concurrency.