orx-concurrent-vec 3.10.0

A thread-safe, efficient and lock-free vector allowing concurrent grow, read and update operations.
Documentation
use crate::elem::ConcurrentElement;
use core::{
    cmp::Ordering,
    sync::atomic::{self, AtomicUsize},
};
use orx_concurrent_option::ConcurrentOption;
use orx_pinned_concurrent_col::{ConcurrentState, PinnedConcurrentCol, WritePermit};
use orx_pinned_vec::{ConcurrentPinnedVec, PinnedVec};

#[derive(Debug)]
pub struct ConcurrentVecState {
    pub(super) len_reserved: AtomicUsize,
    pub(super) len_written: AtomicUsize,
}

impl<T> ConcurrentState<ConcurrentElement<T>> for ConcurrentVecState {
    fn fill_memory_with(&self) -> Option<fn() -> ConcurrentElement<T>> {
        Some(|| ConcurrentElement(ConcurrentOption::none()))
    }

    fn new_for_pinned_vec<P: PinnedVec<ConcurrentElement<T>>>(pinned_vec: &P) -> Self {
        Self {
            len_reserved: pinned_vec.len().into(),
            len_written: pinned_vec.len().into(),
        }
    }

    fn new_for_con_pinned_vec<P: ConcurrentPinnedVec<ConcurrentElement<T>>>(
        _: &P,
        len: usize,
    ) -> Self {
        Self {
            len_reserved: len.into(),
            len_written: len.into(),
        }
    }

    fn write_permit<P>(
        &self,
        col: &PinnedConcurrentCol<ConcurrentElement<T>, P, Self>,
        idx: usize,
    ) -> WritePermit
    where
        P: ConcurrentPinnedVec<ConcurrentElement<T>>,
    {
        let capacity = col.capacity();

        match idx.cmp(&capacity) {
            Ordering::Less => WritePermit::JustWrite,
            Ordering::Equal => WritePermit::GrowThenWrite,
            Ordering::Greater => WritePermit::Spin,
        }
    }

    fn write_permit_n_items<P>(
        &self,
        col: &PinnedConcurrentCol<ConcurrentElement<T>, P, Self>,
        begin_idx: usize,
        num_items: usize,
    ) -> WritePermit
    where
        P: ConcurrentPinnedVec<ConcurrentElement<T>>,
    {
        let capacity = col.capacity();
        let last_idx = begin_idx + num_items - 1;

        match (begin_idx.cmp(&capacity), last_idx.cmp(&capacity)) {
            (_, core::cmp::Ordering::Less) => WritePermit::JustWrite,
            (core::cmp::Ordering::Greater, _) => WritePermit::Spin,
            _ => WritePermit::GrowThenWrite,
        }
    }

    fn release_growth_handle(&self) {}

    #[inline(always)]
    fn update_after_write(&self, _: usize, _: usize) {}

    fn try_get_no_gap_len(&self) -> Option<usize> {
        Some(self.len())
    }
}

impl ConcurrentVecState {
    #[inline(always)]
    pub(crate) fn len(&self) -> usize {
        self.len_reserved.load(atomic::Ordering::Relaxed)
    }
}