#[cfg(any(not(target_family = "wasm"), test))]
pub(crate) const MAX_THREADS: usize = 64;
pub(crate) fn resolve(programmatic: i32) -> usize {
#[cfg(target_family = "wasm")]
{
let _ = programmatic;
return 1;
}
#[cfg(not(target_family = "wasm"))]
resolve_from_lazy(
programmatic,
std::env::var("ISSUNDB_NUM_THREADS").ok().as_deref(),
std::env::var("OMP_NUM_THREADS").ok().as_deref(),
|| {
std::thread::available_parallelism()
.map(|p| p.get())
.unwrap_or(1)
},
)
}
#[cfg(test)]
fn resolve_from(
programmatic: i32,
issundb_env: Option<&str>,
omp_env: Option<&str>,
machine: usize,
) -> usize {
resolve_from_lazy(programmatic, issundb_env, omp_env, || machine)
}
#[cfg(any(not(target_family = "wasm"), test))]
fn resolve_from_lazy(
programmatic: i32,
issundb_env: Option<&str>,
omp_env: Option<&str>,
machine: impl FnOnce() -> usize,
) -> usize {
if programmatic > 0 {
return (programmatic as usize).clamp(1, MAX_THREADS);
}
for value in [issundb_env, omp_env].into_iter().flatten() {
if let Some(n) = value.trim().parse::<usize>().ok().filter(|n| *n > 0) {
return n.clamp(1, MAX_THREADS);
}
}
machine().clamp(1, MAX_THREADS)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_configured_value_never_measures_the_machine() {
let panic_if_called = || panic!("the machine count must not be computed");
assert_eq!(resolve_from_lazy(4, None, None, panic_if_called), 4);
assert_eq!(
resolve_from_lazy(0, Some("6"), None, panic_if_called),
6,
"the engine's own variable short-circuits too"
);
assert_eq!(
resolve_from_lazy(0, None, Some("3"), panic_if_called),
3,
"so does the OpenMP variable"
);
assert_eq!(resolve_from_lazy(0, None, None, || 9), 9);
}
#[test]
fn programmatic_override_takes_precedence() {
assert_eq!(resolve_from(4, Some("2"), Some("1"), 16), 4);
assert_eq!(resolve_from(1, Some("8"), None, 16), 1);
assert_eq!(resolve_from(0, Some("2"), Some("1"), 16), 2);
assert_eq!(resolve_from(-3, Some("2"), None, 16), 2);
}
#[test]
fn environment_order_then_machine() {
assert_eq!(resolve_from(0, Some("3"), Some("7"), 16), 3);
assert_eq!(resolve_from(0, None, Some("7"), 16), 7);
assert_eq!(resolve_from(0, None, None, 16), 16);
assert_eq!(resolve_from(0, None, Some("1"), 16), 1);
}
#[test]
fn malformed_environment_values_fall_through() {
assert_eq!(resolve_from(0, Some("not-a-number"), Some("2"), 16), 2);
assert_eq!(resolve_from(0, Some("0"), Some("2"), 16), 2);
assert_eq!(resolve_from(0, Some(""), None, 16), 16);
assert_eq!(resolve_from(0, Some(" 5 "), None, 16), 5);
}
#[test]
fn results_are_always_clamped() {
assert_eq!(resolve_from(10_000, None, None, 16), MAX_THREADS);
assert_eq!(resolve_from(0, Some("10000"), None, 16), MAX_THREADS);
assert_eq!(resolve_from(0, None, None, 0), 1);
assert_eq!(resolve_from(0, None, None, usize::MAX), MAX_THREADS);
let live = resolve(0);
assert!((1..=MAX_THREADS).contains(&live));
}
}