pub mod parallel;
pub mod scheduler;
pub use parallel::{Job, ParallelExecutor, WorkerPool, create_executor};
pub use scheduler::{ExecutionMetrics, Task, TaskResult, TaskScheduler};
use std::time::Duration;
#[derive(Debug, Clone)]
pub struct ExecutionConfig {
pub max_workers: usize,
pub sequential: bool,
pub chunk_size: usize,
pub timeout: Option<Duration>,
}
impl Default for ExecutionConfig {
fn default() -> Self {
Self {
max_workers: num_cpus(),
sequential: false,
chunk_size: 100,
timeout: None,
}
}
}
impl ExecutionConfig {
pub fn sequential() -> Self {
Self {
max_workers: 1,
sequential: true,
chunk_size: 1,
timeout: None,
}
}
pub fn with_workers(workers: usize) -> Self {
Self {
max_workers: workers.max(1),
sequential: workers == 1,
..Default::default()
}
}
}
pub fn num_cpus() -> usize {
std::thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(1)
}
pub struct ExecutionStats {
pub files_processed: usize,
pub total_time: Duration,
pub parse_time: Duration,
pub transform_time: Duration,
}
impl ExecutionStats {
pub fn throughput(&self) -> f64 {
let secs = self.total_time.as_secs_f64();
if secs > 0.0 {
self.files_processed as f64 / secs
} else {
0.0
}
}
pub fn summary(&self) -> String {
format!(
"Processed {} files in {:.2}s ({:.2} files/s)",
self.files_processed,
self.total_time.as_secs_f64(),
self.throughput()
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_execution_config_default() {
let config = ExecutionConfig::default();
assert!(config.max_workers >= 1);
assert!(!config.sequential);
}
#[test]
fn test_execution_config_sequential() {
let config = ExecutionConfig::sequential();
assert!(config.sequential);
assert_eq!(config.max_workers, 1);
}
#[test]
fn test_execution_config_with_workers() {
let config = ExecutionConfig::with_workers(4);
assert_eq!(config.max_workers, 4);
}
#[test]
fn test_execution_stats() {
let stats = ExecutionStats {
files_processed: 100,
total_time: Duration::from_secs(10),
parse_time: Duration::from_secs(3),
transform_time: Duration::from_secs(5),
};
assert_eq!(stats.throughput(), 10.0);
}
#[test]
fn test_num_cpus() {
let cpus = num_cpus();
assert!(cpus >= 1);
}
}