pub mod batch;
pub mod raster;
pub mod tiles;
pub use batch::{BatchConfig, BatchResult, parallel_batch_process, parallel_map};
pub use raster::{
ChunkConfig, ReduceOp, parallel_focal_mean, parallel_focal_median, parallel_map_raster,
parallel_map_raster_with_config, parallel_reduce_raster, parallel_transform_raster,
};
pub use tiles::{TileConfig, TileProcessor, parallel_generate_overviews, parallel_process_tiles};
#[derive(Debug, Clone)]
pub struct ParallelConfig {
pub num_threads: Option<usize>,
pub chunk_size: Option<usize>,
pub progress: bool,
}
impl Default for ParallelConfig {
fn default() -> Self {
Self {
num_threads: None,
chunk_size: None,
progress: false,
}
}
}
impl ParallelConfig {
#[must_use]
pub const fn new() -> Self {
Self {
num_threads: None,
chunk_size: None,
progress: false,
}
}
#[must_use]
pub const fn with_threads(mut self, num_threads: usize) -> Self {
self.num_threads = Some(num_threads);
self
}
#[must_use]
pub const fn with_chunk_size(mut self, chunk_size: usize) -> Self {
self.chunk_size = Some(chunk_size);
self
}
#[must_use]
pub const fn with_progress(mut self, progress: bool) -> Self {
self.progress = progress;
self
}
}
#[must_use]
pub fn calculate_chunk_size(total_elements: usize, num_threads: Option<usize>) -> usize {
let threads = num_threads.unwrap_or_else(num_cpus);
let target_chunks = threads * 6;
const MIN_CHUNK_SIZE: usize = 64 * 1024 / core::mem::size_of::<f64>();
const MAX_CHUNK_SIZE: usize = 4 * 1024 * 1024 / core::mem::size_of::<f64>();
let chunk_size = total_elements / target_chunks;
chunk_size.clamp(MIN_CHUNK_SIZE, MAX_CHUNK_SIZE)
}
#[must_use]
fn num_cpus() -> usize {
rayon::current_num_threads()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parallel_config_default() {
let config = ParallelConfig::default();
assert!(config.num_threads.is_none());
assert!(config.chunk_size.is_none());
assert!(!config.progress);
}
#[test]
fn test_parallel_config_builder() {
let config = ParallelConfig::new()
.with_threads(4)
.with_chunk_size(1024)
.with_progress(true);
assert_eq!(config.num_threads, Some(4));
assert_eq!(config.chunk_size, Some(1024));
assert!(config.progress);
}
#[test]
fn test_calculate_chunk_size() {
let chunk_size = calculate_chunk_size(1_000_000, Some(4));
assert!(chunk_size > 0);
assert!(chunk_size < 1_000_000);
}
#[test]
fn test_num_cpus() {
let cpus = num_cpus();
assert!(cpus > 0);
}
}