1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! Shared rayon fan-out sizing helper, plus the two "sequential below a
//! threshold, rayon `par_iter` at or above it" dispatch shapes every
//! per-item fan-out in this crate uses.
//!
//! Multiple bulk-parallel paths (`commands::add`'s per-file and per-chunk
//! hashing fan-outs; `remote_dispatch`'s per-entry pack-compression,
//! delta-encoding, and signature-verification fan-outs) share this
//! crossover shape — rayon's pool-dispatch overhead loses to a plain loop
//! for a handful of items and wins clearly once there's enough work per
//! thread to amortize it. Each call site picks its own `N`
//! (entries-per-thread) from its own bench, since the per-item cost
//! differs (a BLAKE3 hash vs. a zstd compression pass vs. an Ed25519
//! verify); [`threshold`] is the one place the
//! `N * rayon::current_num_threads()` arithmetic itself lives, so call
//! sites can't drift on the formula, only on the bench-measured constant
//! each passes in.
//!
//! [`map_seq_or_par`]/[`try_map_seq_or_par`] additionally share the
//! branch-and-collect boilerplate itself, for the two shapes common to
//! more than one call site (by-reference, `Fn(&T[, bool]) -> U`/
//! `Result<U, E>`, output in input order). Not every fan-out fits: a
//! few sites need a different shape on purpose —
//! `remote_dispatch::mod::prepare_delta_batch` consumes its input by
//! value (`into_par_iter`, avoiding a clone `&[T]` would force), and
//! `remote_dispatch::packmap::verify_new_object_signatures` chunks the
//! parallel path deliberately (bounding wasted work past a hostile
//! fetch's first bad signature — see that function's own doc). Forcing
//! either into one of these two shapes would need extra generic
//! machinery to claw back what a bespoke loop gets for free; they stay
//! bespoke rather than fit a shape that doesn't actually match their
//! constraint.
use *;
/// The item count at or above which a caller should fan work out across
/// rayon's global thread pool instead of running it in a plain
/// sequential loop, for a pool of the process's actual size.
///
/// Reads rayon's already-initialized global pool size (cheap: an
/// atomic load after first use, no allocation).
pub
/// Map `f` over `items` — sequentially below `threshold`, via rayon's
/// global thread pool at or above it — preserving input order either
/// way. `f`'s second argument is `true` exactly when the parallel path
/// was taken, for the rare caller (`commands::add::hash_pending_batch`)
/// whose per-item work itself needs to know whether it's already running
/// as one of several concurrently-busy rayon workers (to avoid nesting
/// a second fan-out into an already-saturated pool) — callers that don't
/// care can ignore the argument.
pub
/// [`map_seq_or_par`], for a per-item `f` that can fail — the collected
/// `Result` short-circuits on the first `Err` either way (rayon's
/// `FromParallelIterator` impl for `Result` matches `Iterator`'s in that
/// respect, modulo already-dispatched parallel work still running to
/// completion — see `verify_new_object_signatures`'s doc for why that
/// distinction matters enough to keep it bespoke there).
pub