concurrent_slice/
chunks.rs

1use crate::{chunk::Chunk, common::*, guard::Guard};
2
3/// An iterator that yields [chunks](Chunk).
4#[derive(Debug)]
5pub struct Chunks<S, T>
6where
7    S: 'static + Send,
8    T: 'static + Send,
9{
10    pub(super) index: usize,
11    pub(super) chunk_size: usize,
12    pub(super) end: usize,
13    pub(super) data: Arc<S>,
14    pub(super) _phantom: PhantomData<T>,
15}
16
17impl<S, T> Chunks<S, T>
18where
19    S: 'static + Send,
20    T: 'static + Send,
21{
22    /// Obtains the guard that is used to recover the owning data.
23    pub fn guard(&self) -> Guard<S> {
24        Guard {
25            data: self.data.clone(),
26        }
27    }
28
29    /// Gets the reference count on the owning data.
30    pub fn ref_count(&self) -> usize {
31        Arc::strong_count(&self.data)
32    }
33}
34
35impl<S, T> Iterator for Chunks<S, T>
36where
37    S: 'static + AsMut<[T]> + Send,
38    T: 'static + Send,
39{
40    type Item = Chunk<S, T>;
41
42    fn next(&mut self) -> Option<Self::Item> {
43        if self.index >= self.end {
44            return None;
45        }
46
47        let start = self.index;
48        let end = cmp::min(start + self.chunk_size, self.end);
49        self.index = end;
50
51        let data = self.data.clone();
52
53        let slice = unsafe {
54            let ptr = Arc::as_ptr(&data) as *mut S;
55            let slice: &mut [T] = ptr.as_mut().unwrap().as_mut();
56            NonNull::new_unchecked(&mut slice[start..end] as *mut [T])
57        };
58
59        Some(Chunk { data, slice })
60    }
61}