concurrent_slice/
slice.rs1use crate::{chunk::Chunk, chunks::Chunks, common::*, iter::Iter, windows::Windows};
2
3pub trait ConcurrentSlice<T> {
5 fn concurrent_split_at(self, index: usize) -> (Chunk<Self, T>, Chunk<Self, T>)
10 where
11 Self: 'static + AsMut<[T]> + Sized + Send,
12 T: 'static + Send,
13 {
14 unsafe {
15 let data = Arc::new(self);
16 let ptr = Arc::as_ptr(&data) as *mut Self;
17 let slice: &mut [T] = ptr.as_mut().unwrap().as_mut();
18 let lslice = NonNull::new_unchecked(&mut slice[0..index] as *mut [T]);
19 let rslice = NonNull::new_unchecked(&mut slice[index..] as *mut [T]);
20
21 (
22 Chunk {
23 data: data.clone(),
24 slice: lslice,
25 },
26 Chunk {
27 data,
28 slice: rslice,
29 },
30 )
31 }
32 }
33
34 fn concurrent_chunks(mut self, chunk_size: usize) -> Chunks<Self, T>
45 where
46 Self: 'static + AsMut<[T]> + Sized + Send,
47 T: 'static + Send,
48 {
49 let len = self.as_mut().len();
50 assert!(
51 len == 0 || chunk_size > 0,
52 "chunk_size must be positive for non-empty slice"
53 );
54
55 Chunks {
56 index: 0,
57 chunk_size,
58 end: len,
59 data: Arc::new(self),
60 _phantom: PhantomData,
61 }
62 }
63
64 fn concurrent_chunks_by_division(
73 mut self,
74 division: impl Into<Option<usize>>,
75 ) -> Chunks<Self, T>
76 where
77 Self: 'static + AsMut<[T]> + Sized + Send,
78 T: 'static + Send,
79 {
80 let len = self.as_mut().len();
81 let division = division.into().unwrap_or_else(num_cpus::get);
82
83 let chunk_size = if len == 0 {
84 0
85 } else {
86 assert!(
87 division > 0,
88 "division must be positive for non-empty slice, but get zero"
89 );
90 (len + division - 1) / division
91 };
92
93 Chunks {
94 index: 0,
95 chunk_size,
96 end: len,
97 data: Arc::new(self),
98 _phantom: PhantomData,
99 }
100 }
101
102 fn owning_iter(self) -> Iter<Self, T>
104 where
105 Self: 'static + Send + Deref + CloneStableAddress,
106 Self::Target: AsRef<[T]>,
107 {
108 let owner = OwningRef::new(self).map(|me| me.as_ref());
109 Iter { owner, index: 0 }
110 }
111
112 fn owning_windows(self, size: usize) -> Windows<Self, T>
116 where
117 Self: 'static + Send + Deref + CloneStableAddress,
118 Self::Target: AsRef<[T]>,
119 {
120 assert!(size > 0, "size must be positive");
121 let owner = OwningRef::new(self).map(|me| me.as_ref());
122
123 Windows {
124 owner,
125 size,
126 index: 0,
127 }
128 }
129}
130
131impl<S, T> ConcurrentSlice<T> for S {}