use crate::core::solver::Strategy::{Auto, Frag, List, Tree};
use crate::segm::segment::Segment;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Strategy {
List,
Tree,
Frag,
Auto,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Precision {
pub start: usize,
pub progression: usize,
}
impl Precision {
pub const ABSOLUTE: Precision = Self {
start: 0,
progression: 0,
};
pub const HIGH: Precision = Self {
start: 0,
progression: 1,
};
pub const MEDIUM_HIGH: Precision = Self {
start: 1,
progression: 1,
};
pub const MEDIUM: Precision = Self {
start: 0,
progression: 2,
};
pub const MEDIUM_LOW: Precision = Self {
start: 2,
progression: 2,
};
pub const LOW: Precision = Self {
start: 2,
progression: 3,
};
}
#[derive(Clone, Copy)]
pub struct MultithreadOptions {
pub par_sort_min_size: usize,
}
impl MultithreadOptions {
const DEFAULT_PAR_SORT_MIN_SIZE: usize = 32768;
}
impl Default for MultithreadOptions {
fn default() -> Self {
Self {
par_sort_min_size: 32768,
}
}
}
#[derive(Clone, Copy)]
pub struct Solver {
pub strategy: Strategy,
pub precision: Precision,
pub multithreading: Option<MultithreadOptions>,
}
impl Default for Solver {
fn default() -> Self {
Solver::AUTO
}
}
impl Solver {
pub const LIST: Self = Self {
strategy: List,
precision: Precision::HIGH,
multithreading: Some(MultithreadOptions {
par_sort_min_size: MultithreadOptions::DEFAULT_PAR_SORT_MIN_SIZE,
}),
};
pub const TREE: Self = Self {
strategy: Tree,
precision: Precision::HIGH,
multithreading: Some(MultithreadOptions {
par_sort_min_size: MultithreadOptions::DEFAULT_PAR_SORT_MIN_SIZE,
}),
};
pub const FRAG: Self = Self {
strategy: Frag,
precision: Precision::HIGH,
multithreading: Some(MultithreadOptions {
par_sort_min_size: MultithreadOptions::DEFAULT_PAR_SORT_MIN_SIZE,
}),
};
pub const AUTO: Self = Self {
strategy: Auto,
precision: Precision::HIGH,
multithreading: Some(MultithreadOptions {
par_sort_min_size: MultithreadOptions::DEFAULT_PAR_SORT_MIN_SIZE,
}),
};
const MAX_SPLIT_LIST_COUNT: usize = 4_000;
const MIN_FRAGMENT_COUNT: usize = 16_000;
const MAX_FILL_LIST_COUNT: usize = 8_000;
pub fn with_precision(precision: Precision) -> Self {
Self {
strategy: Auto,
precision,
multithreading: Some(MultithreadOptions {
par_sort_min_size: MultithreadOptions::DEFAULT_PAR_SORT_MIN_SIZE,
}),
}
}
pub fn with_strategy_and_precision(strategy: Strategy, precision: Precision) -> Self {
Self {
strategy,
precision,
multithreading: Some(MultithreadOptions {
par_sort_min_size: MultithreadOptions::DEFAULT_PAR_SORT_MIN_SIZE,
}),
}
}
pub(crate) fn is_list_split<C: Send>(&self, segments: &[Segment<C>]) -> bool {
match self.strategy {
List => true,
Tree | Frag => false,
Auto => segments.len() < Self::MAX_SPLIT_LIST_COUNT,
}
}
pub(crate) fn is_fragmentation_required<C: Send>(&self, segments: &[Segment<C>]) -> bool {
segments.len() > Self::MIN_FRAGMENT_COUNT || self.strategy == Frag
}
pub(crate) fn is_list_fill<C: Send>(&self, segments: &[Segment<C>]) -> bool {
match self.strategy {
List => true,
Tree | Frag => false,
Auto => segments.len() < Self::MAX_FILL_LIST_COUNT,
}
}
#[inline(always)]
pub(crate) fn is_parallel_sort_allowed(&self) -> bool {
self.multithreading.is_some()
}
}