orx-concurrent-iter 3.3.0

A thread-safe and ergonomic concurrent iterator trait and efficient lock-free implementations.
Documentation
use crate::implementations::jagged_arrays::{
    Slices, as_raw_slice::AsRawSlice, index::JaggedIndex, indexer::JaggedIndexer,
};
use orx_pseudo_default::PseudoDefault;

#[derive(Clone)]
pub struct MatrixIndexer {
    n: usize,
}

impl MatrixIndexer {
    pub fn new(n: usize) -> Self {
        Self { n }
    }
}

impl PseudoDefault for MatrixIndexer {
    fn pseudo_default() -> Self {
        Self::new(1)
    }
}

impl JaggedIndexer for MatrixIndexer {
    unsafe fn jagged_index_unchecked<'a, T: 'a>(
        &self,
        _: &impl Slices<'a, T>,
        flat_index: usize,
    ) -> JaggedIndex {
        let f = flat_index / self.n;
        let i = flat_index % self.n;
        JaggedIndex::new(f, i)
    }

    unsafe fn jagged_index_unchecked_from_slice<'a, T: 'a>(
        &self,
        _: &[impl AsRawSlice<T>],
        flat_index: usize,
    ) -> JaggedIndex {
        let f = flat_index / self.n;
        let i = flat_index % self.n;
        JaggedIndex::new(f, i)
    }
}

#[derive(Clone)]
pub struct GeneralJaggedIndexer;

impl PseudoDefault for GeneralJaggedIndexer {
    fn pseudo_default() -> Self {
        Self
    }
}

impl JaggedIndexer for GeneralJaggedIndexer {
    unsafe fn jagged_index_unchecked<'a, T: 'a>(
        &self,
        arrays: &impl Slices<'a, T>,
        flat_index: usize,
    ) -> JaggedIndex {
        let mut idx = flat_index;
        let [mut f, mut i] = [0, 0];
        let mut current_f = 0;
        while idx > 0 {
            let current_len = unsafe { arrays.slice_at_unchecked(current_f) }.len();
            match current_len > idx {
                true => {
                    i = idx;
                    idx = 0;
                }
                false => {
                    f += 1;
                    idx -= current_len;
                }
            }
            current_f += 1;
        }
        JaggedIndex::new(f, i)
    }

    unsafe fn jagged_index_unchecked_from_slice<'a, T: 'a>(
        &self,
        arrays: &[impl AsRawSlice<T>],
        flat_index: usize,
    ) -> JaggedIndex {
        let mut idx = flat_index;
        let [mut f, mut i] = [0, 0];
        let mut current_f = 0;
        while idx > 0 {
            let current_len = arrays[current_f].length();
            match current_len > idx {
                true => {
                    i = idx;
                    idx = 0;
                }
                false => {
                    f += 1;
                    idx -= current_len;
                }
            }
            current_f += 1;
        }
        JaggedIndex::new(f, i)
    }
}