orx-concurrent-iter 3.3.0

A thread-safe and ergonomic concurrent iterator trait and efficient lock-free implementations.
Documentation
use super::con_iter::ConIterOfIter;
use crate::pullers::ChunkPuller;
use alloc::vec::Vec;
use core::iter::FusedIterator;

pub struct ChunkPullerOfIter<'i, I>
where
    I: Iterator,
    I::Item: Send,
{
    con_iter: &'i ConIterOfIter<I>,
    buffer: Vec<Option<I::Item>>,
}

impl<'i, I> ChunkPullerOfIter<'i, I>
where
    I: Iterator,
    I::Item: Send,
{
    pub(super) fn new(con_iter: &'i ConIterOfIter<I>, chunk_size: usize) -> Self {
        let mut buffer = Vec::with_capacity(chunk_size);
        for _ in 0..chunk_size {
            buffer.push(None);
        }
        Self { con_iter, buffer }
    }
}

impl<I> ChunkPuller for ChunkPullerOfIter<'_, I>
where
    I: Iterator,
    I::Item: Send,
{
    type ChunkItem = I::Item;

    type Chunk<'c>
        = ChunksIterOfIter<'c, I::Item>
    where
        Self: 'c;

    fn chunk_size(&self) -> usize {
        self.buffer.len()
    }

    fn pull(&mut self) -> Option<Self::Chunk<'_>> {
        match self.con_iter.next_chunk_to_buffer(&mut self.buffer) {
            (_, 0) => None,
            (_, slice_len) => {
                let buffer = &mut self.buffer[0..slice_len];
                let chunk = ChunksIterOfIter { buffer, current: 0 };
                Some(chunk)
            }
        }
    }

    fn pull_with_idx(&mut self) -> Option<(usize, Self::Chunk<'_>)> {
        match self.con_iter.next_chunk_to_buffer(&mut self.buffer) {
            (_, 0) => None,
            (begin_idx, slice_len) => {
                let buffer = &mut self.buffer[0..slice_len];
                let chunk_iter = ChunksIterOfIter { buffer, current: 0 };
                Some((begin_idx, chunk_iter))
            }
        }
    }
}

// iter

pub struct ChunksIterOfIter<'i, T> {
    buffer: &'i mut [Option<T>],
    current: usize,
}

impl<T> Default for ChunksIterOfIter<'_, T> {
    fn default() -> Self {
        Self {
            buffer: &mut [],
            current: 0,
        }
    }
}

impl<T> Iterator for ChunksIterOfIter<'_, T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.buffer.get_mut(self.current).and_then(|x| {
            self.current += 1;
            x.take()
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.buffer.len().saturating_sub(self.current);
        (len, Some(len))
    }
}

impl<T> ExactSizeIterator for ChunksIterOfIter<'_, T> {
    fn len(&self) -> usize {
        self.buffer.len().saturating_sub(self.current)
    }
}

impl<T> FusedIterator for ChunksIterOfIter<'_, T> {}