use crate::ImageSize;
use rayon::ThreadPool;
use std::num::NonZeroUsize;
use std::thread::available_parallelism;
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Default)]
pub enum MorphologyThreadingPolicy {
Single,
Fixed(NonZeroUsize),
#[default]
Adaptive,
}
impl MorphologyThreadingPolicy {
pub fn thread_count(&self, for_size: ImageSize) -> usize {
match self {
MorphologyThreadingPolicy::Single => 1,
MorphologyThreadingPolicy::Adaptive => (for_size.width * for_size.height / (256 * 256))
.clamp(1, Self::available_parallelism()),
MorphologyThreadingPolicy::Fixed(fixed) => fixed.get(),
}
}
pub fn get_pool(&self, for_size: ImageSize) -> Option<ThreadPool> {
if *self == MorphologyThreadingPolicy::Single {
return None;
}
let threads_count = self.thread_count(for_size);
rayon::ThreadPoolBuilder::new()
.num_threads(threads_count)
.build()
.ok()
}
fn available_parallelism() -> usize {
available_parallelism()
.unwrap_or_else(|_| NonZeroUsize::new(1).unwrap())
.get()
.max(1)
}
}