1use std::{ops::Deref, sync::Arc};
5
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8#[derive(Debug, PartialOrd, PartialEq, Ord, Eq, Hash)]
9pub struct CowVec<T>
10where
11 T: Clone + PartialEq,
12{
13 inner: Arc<Vec<T>>,
14}
15
16impl<T> CowVec<T>
17where
18 T: Clone + PartialEq,
19{
20 pub fn with_capacity(capacity: usize) -> Self {
21 let aligned_capacity = (capacity + 7) & !7;
25 Self {
26 inner: Arc::new(Vec::with_capacity(aligned_capacity)),
27 }
28 }
29
30 pub fn with_aligned_capacity(capacity: usize) -> Self {
32 let simd_alignment = 32 / std::mem::size_of::<T>().max(1);
36 let aligned_capacity = ((capacity + simd_alignment - 1) / simd_alignment) * simd_alignment;
37 Self {
38 inner: Arc::new(Vec::with_capacity(aligned_capacity)),
39 }
40 }
41
42 pub fn len(&self) -> usize {
43 self.inner.len()
44 }
45
46 pub fn capacity(&self) -> usize {
47 self.inner.capacity()
48 }
49}
50
51#[macro_export]
52macro_rules! async_cow_vec {
53 () => {
54 $crate::CowVec::new(Vec::new())
55 };
56 ($($elem:expr),+ $(,)?) => {
57 $crate::CowVec::new(vec![$($elem),+])
58 };
59}
60
61impl<T> Default for CowVec<T>
62where
63 T: Clone + PartialEq,
64{
65 fn default() -> Self {
66 Self {
67 inner: Arc::new(Vec::new()),
68 }
69 }
70}
71
72impl<T: Clone + PartialEq> PartialEq<[T]> for &CowVec<T> {
73 fn eq(&self, other: &[T]) -> bool {
74 self.inner.as_slice() == other
75 }
76}
77
78impl<T: Clone + PartialEq> PartialEq<[T]> for CowVec<T> {
79 fn eq(&self, other: &[T]) -> bool {
80 self.inner.as_slice() == other
81 }
82}
83
84impl<T: Clone + PartialEq> PartialEq<CowVec<T>> for [T] {
85 fn eq(&self, other: &CowVec<T>) -> bool {
86 self == other.inner.as_slice()
87 }
88}
89
90impl<T: Clone + PartialEq> Clone for CowVec<T> {
91 fn clone(&self) -> Self {
92 CowVec {
93 inner: Arc::clone(&self.inner),
94 }
95 }
96}
97
98impl<T: Clone + PartialEq> CowVec<T> {
99 pub fn new(vec: Vec<T>) -> Self {
100 CowVec {
101 inner: Arc::new(vec),
102 }
103 }
104
105 pub fn from_rc(rc: Arc<Vec<T>>) -> Self {
106 CowVec {
107 inner: rc,
108 }
109 }
110
111 pub fn as_slice(&self) -> &[T] {
112 &self.inner
113 }
114
115 pub fn is_owned(&self) -> bool {
116 Arc::strong_count(&self.inner) == 1
117 }
118
119 pub fn is_shared(&self) -> bool {
120 Arc::strong_count(&self.inner) > 1
121 }
122
123 pub fn get(&self, idx: usize) -> Option<&T> {
124 self.inner.get(idx)
125 }
126
127 pub fn make_mut(&mut self) -> &mut Vec<T> {
128 Arc::make_mut(&mut self.inner)
129 }
130
131 pub fn set(&mut self, idx: usize, value: T) {
132 self.make_mut()[idx] = value;
133 }
134
135 pub fn push(&mut self, value: T) {
136 self.make_mut().push(value);
137 }
138
139 pub fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
140 self.make_mut().extend(iter);
141 }
142
143 pub fn extend_from_slice(&mut self, slice: &[T]) {
144 self.make_mut().extend_from_slice(slice);
145 }
146
147 pub fn reorder(&mut self, indices: &[usize]) {
148 let vec = self.make_mut();
149 let len = vec.len();
150 assert_eq!(len, indices.len());
151
152 let mut visited = vec![false; len];
153 for start in 0..len {
154 if visited[start] || indices[start] == start {
155 continue;
156 }
157 let mut current = start;
158 while !visited[current] {
159 visited[current] = true;
160 let next = indices[current];
161 if next == start {
162 break;
163 }
164 vec.swap(current, next);
165 current = next;
166 }
167 }
168 }
169
170 pub fn aligned_chunks(&self, chunk_size: usize) -> impl Iterator<Item = &[T]> {
174 self.inner.chunks(chunk_size)
175 }
176
177 pub fn aligned_chunks_mut(&mut self, chunk_size: usize) -> impl Iterator<Item = &mut [T]> {
179 self.make_mut().chunks_mut(chunk_size)
180 }
181
182 pub fn is_simd_aligned(&self) -> bool {
184 let alignment = 32; let ptr = self.inner.as_ptr() as usize;
186 ptr % alignment == 0
187 }
188
189 pub fn take(&self, n: usize) -> Self {
190 let len = n.min(self.len());
191 CowVec::new(self.inner[..len].to_vec())
192 }
193}
194
195impl<T: Clone + PartialEq> IntoIterator for CowVec<T> {
196 type Item = T;
197 type IntoIter = std::vec::IntoIter<T>;
198
199 fn into_iter(self) -> Self::IntoIter {
200 (*self.inner).clone().into_iter()
201 }
202}
203
204impl<T: Clone + PartialEq> Deref for CowVec<T> {
205 type Target = [T];
206
207 fn deref(&self) -> &Self::Target {
208 self.as_slice()
209 }
210}
211
212impl<T> Serialize for CowVec<T>
213where
214 T: Clone + PartialEq + Serialize,
215{
216 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
217 where
218 S: Serializer,
219 {
220 self.inner.serialize(serializer)
221 }
222}
223
224impl<'de, T> Deserialize<'de> for CowVec<T>
225where
226 T: Clone + PartialEq + Deserialize<'de>,
227{
228 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
229 where
230 D: Deserializer<'de>,
231 {
232 let vec = Vec::<T>::deserialize(deserializer)?;
233 Ok(CowVec {
234 inner: Arc::new(vec),
235 })
236 }
237}
238
239#[cfg(test)]
240mod tests {
241 use crate::util::CowVec;
242
243 #[test]
244 fn test_new() {
245 let cow = CowVec::new(vec![1, 2, 3]);
246 assert_eq!(cow.get(0), Some(&1));
247 assert_eq!(cow.get(1), Some(&2));
248 assert_eq!(cow.get(2), Some(&3));
249 }
250
251 #[test]
252 fn test_is_owned() {
253 let mut owned = CowVec::new(Vec::with_capacity(16));
254 owned.extend([1, 2]);
255
256 assert!(owned.is_owned());
257
258 let shared = owned.clone();
259 assert!(!owned.is_owned());
260 assert!(!shared.is_owned());
261
262 drop(shared);
263
264 assert!(owned.is_owned());
265 }
266
267 #[test]
268 fn test_is_shared() {
269 let mut owned = CowVec::new(Vec::with_capacity(16));
270 owned.extend([1, 2]);
271
272 assert!(!owned.is_shared());
273
274 let shared = owned.clone();
275 assert!(owned.is_shared());
276 assert!(shared.is_shared());
277
278 drop(shared);
279
280 assert!(!owned.is_shared());
281 }
282
283 #[test]
284 fn test_extend() {
285 let mut owned = CowVec::new(Vec::with_capacity(16));
286 owned.extend([1, 2]);
287
288 let ptr_before_owned = ptr_of(&owned);
289 owned.extend([9, 9, 24]);
290 assert_eq!(ptr_before_owned, ptr_of(&owned)); assert_eq!(owned.len(), 5);
292
293 let mut shared = owned.clone();
294
295 let ptr_before_shared = ptr_of(&shared);
296 shared.extend([9, 9, 24]);
297 assert_ne!(ptr_before_shared, ptr_of(&shared)); assert_eq!(owned.len(), 5);
299 }
300
301 #[test]
302 fn test_push() {
303 let mut owned = CowVec::new(Vec::with_capacity(16));
304 owned.extend([1, 2]);
305
306 let ptr_before_owned = ptr_of(&owned);
307 owned.push(99);
308 assert_eq!(ptr_before_owned, ptr_of(&owned)); assert_eq!(owned.len(), 3);
310
311 let mut shared = owned.clone();
312
313 let ptr_before_shared = ptr_of(&shared);
314 shared.push(99);
315 assert_ne!(ptr_before_shared, ptr_of(&shared)); assert_eq!(owned.len(), 3);
317 }
318
319 #[test]
320 fn test_set() {
321 let mut owned = CowVec::new(Vec::with_capacity(16));
322 owned.extend([1, 2]);
323
324 let ptr_before_owned = ptr_of(&owned);
325 owned.set(1, 99);
326 assert_eq!(ptr_before_owned, ptr_of(&owned)); assert_eq!(*owned, [1, 99]);
328
329 let mut shared = owned.clone();
330
331 let ptr_before_shared = ptr_of(&shared);
332 shared.set(1, 99);
333 assert_ne!(ptr_before_shared, ptr_of(&shared)); assert_eq!(*owned, [1, 99]);
335 }
336
337 #[test]
338 fn test_reorder() {
339 let mut owned = CowVec::new(Vec::with_capacity(16));
340 owned.extend([1, 2]);
341
342 let ptr_before_owned = ptr_of(&owned);
343 owned.reorder(&[1usize, 0]);
344 assert_eq!(ptr_before_owned, ptr_of(&owned)); assert_eq!(*owned, [2, 1]);
346
347 let mut shared = owned.clone();
348
349 let ptr_before_shared = ptr_of(&shared);
350 shared.reorder(&[1usize, 0]);
351 assert_ne!(ptr_before_shared, ptr_of(&shared)); assert_eq!(*shared, [1, 2]);
353 }
354
355 #[test]
356 fn test_reorder_identity() {
357 let mut cow = CowVec::new(vec![10, 20, 30]);
358 cow.reorder(&[0, 1, 2]); assert_eq!(cow.as_slice(), &[10, 20, 30]);
360 }
361
362 #[test]
363 fn test_reorder_basic() {
364 let mut cow = CowVec::new(vec![10, 20, 30]);
365 cow.reorder(&[2, 0, 1]);
366 assert_eq!(cow.as_slice(), &[30, 10, 20]);
367 }
368
369 fn ptr_of(v: &CowVec<i32>) -> *const i32 {
370 v.as_slice().as_ptr()
371 }
372}