use crate::error::{Result, ZiporaError};
#[derive(Debug, Clone)]
pub struct RadixSortConfig {
pub use_parallel: bool,
pub parallel_threshold: usize,
pub radix_bits: usize,
pub use_counting_sort_threshold: usize,
pub use_simd: bool,
}
impl Default for RadixSortConfig {
fn default() -> Self {
Self {
use_parallel: true,
parallel_threshold: 10_000,
radix_bits: 8,
use_counting_sort_threshold: 256,
use_simd: cfg!(feature = "simd"),
}
}
}
#[derive(Debug, Clone)]
pub struct CpuFeatures {
pub avx2: bool,
pub bmi2: bool,
pub popcnt: bool,
pub avx512f: bool,
pub avx512bw: bool,
}
impl CpuFeatures {
pub fn detect() -> Self {
#[cfg(target_arch = "x86_64")]
{
Self {
avx2: std::arch::is_x86_feature_detected!("avx2"),
bmi2: std::arch::is_x86_feature_detected!("bmi2"),
popcnt: std::arch::is_x86_feature_detected!("popcnt"),
avx512f: std::arch::is_x86_feature_detected!("avx512f"),
avx512bw: std::arch::is_x86_feature_detected!("avx512bw"),
}
}
#[cfg(not(target_arch = "x86_64"))]
{
Self {
avx2: false,
bmi2: false,
popcnt: false,
avx512f: false,
avx512bw: false,
}
}
}
pub fn has_advanced_simd(&self) -> bool {
self.avx2 && self.bmi2
}
pub fn has_avx512(&self) -> bool {
self.avx512f && self.avx512bw
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SortingStrategy {
Insertion,
TimSort,
LsdRadix,
MsdRadix,
Adaptive,
}
#[derive(Debug, Clone)]
pub struct DataCharacteristics {
pub size: usize,
pub is_nearly_sorted: bool,
pub is_string_data: bool,
pub estimated_entropy: f64,
pub max_key_bits: usize,
}
impl DataCharacteristics {
pub fn analyze_integers<T>(data: &[T]) -> Self
where
T: Copy + Into<u64> + Ord,
{
let size = data.len();
let mut inversions = 0usize;
let mut sorted_runs = 0usize;
let mut current_run_length = 1usize;
for i in 1..data.len() {
if data[i] >= data[i - 1] {
current_run_length += 1;
} else {
inversions += 1;
if current_run_length > 1 {
sorted_runs += 1;
}
current_run_length = 1;
}
}
if current_run_length > 1 {
sorted_runs += 1;
}
let inversion_threshold = if size <= 10 {
std::cmp::max(1, size / 5) } else {
size / 10 };
let is_nearly_sorted =
inversions < inversion_threshold && (sorted_runs >= 1 || inversions == 0);
let mut max_val = 0u64;
for &item in data {
max_val = max_val.max(item.into());
}
let max_key_bits = if max_val == 0 {
1
} else {
64 - max_val.leading_zeros() as usize
};
let estimated_entropy = if size > 0 { (size as f64).log2() } else { 0.0 };
Self {
size,
is_nearly_sorted,
is_string_data: false,
estimated_entropy,
max_key_bits,
}
}
pub fn analyze_strings(data: &[Vec<u8>]) -> Self {
let size = data.len();
let mut inversions = 0usize;
for i in 1..data.len() {
if data[i] < data[i - 1] {
inversions += 1;
}
}
let is_nearly_sorted = inversions < std::cmp::max(1, size / 10);
let max_length = data.iter().map(|s| s.len()).max().unwrap_or(0);
let estimated_entropy = if size > 0 { (size as f64).log2() } else { 0.0 };
Self {
size,
is_nearly_sorted,
is_string_data: true,
estimated_entropy,
max_key_bits: max_length * 8, }
}
}
#[derive(Debug, Clone)]
pub struct AdvancedRadixSortConfig {
pub use_secure_memory: bool,
pub adaptive_strategy: bool,
pub force_strategy: Option<SortingStrategy>,
pub use_parallel: bool,
pub parallel_threshold: usize,
pub num_threads: usize,
pub radix_bits: usize,
pub insertion_sort_threshold: usize,
pub counting_sort_threshold: usize,
pub use_simd: bool,
pub use_work_stealing: bool,
pub prefetch_distance: usize,
pub cache_alignment: usize,
pub memory_budget: usize,
pub enable_profiling: bool,
}
impl Default for AdvancedRadixSortConfig {
fn default() -> Self {
Self {
use_secure_memory: true,
adaptive_strategy: true,
force_strategy: None,
use_parallel: true,
parallel_threshold: 10_000,
num_threads: 0, radix_bits: 8,
insertion_sort_threshold: 100,
counting_sort_threshold: 1024,
use_simd: cfg!(feature = "simd"),
use_work_stealing: true,
prefetch_distance: 2,
cache_alignment: 64,
memory_budget: 64 * 1024 * 1024, enable_profiling: false,
}
}
}
#[derive(Debug, Clone)]
pub struct AdvancedAlgorithmStats {
pub basic_stats: crate::algorithms::AlgorithmStats,
pub strategy_used: SortingStrategy,
pub cpu_features_used: CpuFeatures,
pub estimated_cache_misses: u64,
pub peak_memory_bytes: usize,
pub threads_used: usize,
pub phase_times: PhaseTimes,
}
#[derive(Debug, Clone)]
pub struct PhaseTimes {
pub analysis_time_us: u64,
pub allocation_time_us: u64,
pub sorting_time_us: u64,
pub merging_time_us: u64,
pub cleanup_time_us: u64,
}