use super::{CoverageReport, Superblock, SuperblockId};
#[derive(Debug, Clone)]
pub struct SuperblockResult {
pub id: SuperblockId,
pub success: bool,
pub error: Option<String>,
}
#[derive(Debug)]
pub struct CoverageExecutor {
superblocks: Vec<Superblock>,
worker_count: usize,
work_stealing: bool,
}
impl CoverageExecutor {
#[must_use]
pub fn new(superblocks: Vec<Superblock>) -> Self {
Self {
superblocks,
worker_count: num_cpus(),
work_stealing: true,
}
}
#[must_use]
pub fn with_workers(mut self, count: usize) -> Self {
self.worker_count = count;
self
}
#[must_use]
pub fn with_work_stealing(mut self, enabled: bool) -> Self {
self.work_stealing = enabled;
self
}
pub fn execute<F>(&self, test_fn: F) -> CoverageReport
where
F: Fn(&Superblock) -> SuperblockResult + Send + Sync,
{
let total_blocks = self.superblocks.iter().map(|sb| sb.block_count()).sum();
let mut report = CoverageReport::new(total_blocks);
for superblock in &self.superblocks {
let result = test_fn(superblock);
if result.success {
for block in superblock.iter() {
report.record_hit(*block);
}
}
}
report
}
#[must_use]
pub fn superblock_count(&self) -> usize {
self.superblocks.len()
}
#[must_use]
pub fn total_block_count(&self) -> usize {
self.superblocks.iter().map(|sb| sb.block_count()).sum()
}
#[must_use]
pub fn worker_count(&self) -> usize {
self.worker_count
}
}
fn num_cpus() -> usize {
4
}