Skip to main content

dark_std/sync/
vec.rs

1use parking_lot::Mutex;
2use serde::{Deserializer, Serialize, Serializer};
3use std::cell::UnsafeCell;
4use std::fmt::{Debug, Display, Formatter};
5use std::marker::PhantomData;
6use std::slice::{Iter as SliceIter, IterMut as SliceIterMut};
7use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
8use std::sync::Arc;
9use std::vec::IntoIter;
10
11use super::{ReadGuard, ReadMapGuard, WriteGuard, WriteLock};
12
13/// Read guard returned by [`SyncVec::get`].
14pub type VecGet<'a, V> = ReadGuard<'a, V>;
15
16/// Write guard returned by [`SyncVec::get_mut`].
17pub type VecRefMut<'a, V> = WriteGuard<'a, V>;
18
19/// Read iterator returned by [`SyncVec::iter`].
20pub struct VecIter<'a, V> {
21    count: &'a AtomicUsize,
22    inner: SliceIter<'a, V>,
23    _not_send: PhantomData<*const ()>,
24}
25
26impl<'a, V> Drop for VecIter<'a, V> {
27    fn drop(&mut self) {
28        self.count.fetch_sub(1, Ordering::Release);
29    }
30}
31
32impl<'a, V> Iterator for VecIter<'a, V> {
33    type Item = &'a V;
34
35    fn next(&mut self) -> Option<Self::Item> {
36        self.inner.next()
37    }
38}
39
40/// Write iterator returned by [`SyncVec::iter_mut`].
41pub struct VecIterMut<'a, V> {
42    _w: WriteLock<'a>,
43    inner: SliceIterMut<'a, V>,
44}
45
46impl<'a, V> Iterator for VecIterMut<'a, V> {
47    type Item = &'a mut V;
48
49    fn next(&mut self) -> Option<Self::Item> {
50        self.inner.next()
51    }
52}
53
54/// An asynchronous vector that can be safely shared between threads.
55///
56/// Reads are lock-free: `get`/`iter`/`dirty_ref`/`len`/`contains` only
57/// register a reader slot with an atomic counter and then read the vector
58/// without any lock (readers never block each other and never touch a lock
59/// word). Writes take a mutex, raise a `writing` flag and wait until all
60/// in-flight readers are gone before mutating the vector in place (amortised
61/// O(1) push, no whole-container copy).
62///
63/// # Deadlock note
64/// A read guard makes writers wait until it is dropped. Do not call a write
65/// method while a read/write guard is alive in the same scope: drop the guard
66/// first (e.g. `drop(g)` before `push`/`remove`/`get_mut`), otherwise the
67/// writer waits for its own guard and deadlocks.
68pub struct SyncVec<V> {
69    dirty: UnsafeCell<Vec<V>>,
70    write: Mutex<()>,
71    id: usize,
72    writing: AtomicBool,
73    registry: Mutex<Vec<std::boxed::Box<AtomicUsize>>>,
74}
75
76// SAFETY: all writers hold `write` and wait for `readers` to drain before
77// touching `dirty`; readers either see a consistent snapshot or retry while a
78// writer is active, so concurrent access to `dirty` is race-free.
79unsafe impl<V: Send> Send for SyncVec<V> {}
80unsafe impl<V: Sync> Sync for SyncVec<V> {}
81
82impl<V> SyncVec<V> {
83    #[inline]
84    fn begin_read(&self) -> &AtomicUsize {
85        // The counter lives in thread-local storage: concurrent readers only
86        // touch their own cache line and never contend with each other. SeqCst
87        // closes the store-buffering window with the writer's all-zero scan.
88        let count = super::reader_count_for(self.id, &self.registry);
89        loop {
90            count.fetch_add(1, Ordering::SeqCst);
91            if !self.writing.load(Ordering::SeqCst) {
92                return count;
93            }
94            count.fetch_sub(1, Ordering::SeqCst);
95            std::thread::yield_now();
96        }
97    }
98
99    #[inline]
100    fn begin_write(&self) -> WriteLock<'_> {
101        let lock = self.write.lock();
102        self.writing.store(true, Ordering::SeqCst);
103        loop {
104            let registry = self.registry.lock();
105            let all_zero = registry.iter().all(|c| c.load(Ordering::SeqCst) == 0);
106            if all_zero {
107                break;
108            }
109            drop(registry);
110            std::thread::yield_now();
111        }
112        WriteLock::new(lock, &self.writing)
113    }
114
115    pub fn new_arc() -> Arc<Self> {
116        Arc::new(Self::new())
117    }
118
119    pub fn new() -> Self {
120        Self {
121            dirty: UnsafeCell::new(Vec::new()),
122            write: Mutex::new(()),
123            id: super::CONTAINER_ID.fetch_add(1, Ordering::Relaxed),
124            writing: AtomicBool::new(false),
125            registry: Mutex::new(Vec::new()),
126        }
127    }
128
129    pub fn with_capacity(capacity: usize) -> Self {
130        Self {
131            dirty: UnsafeCell::new(Vec::with_capacity(capacity)),
132            write: Mutex::new(()),
133            id: super::CONTAINER_ID.fetch_add(1, Ordering::Relaxed),
134            writing: AtomicBool::new(false),
135            registry: Mutex::new(Vec::new()),
136        }
137    }
138
139    pub fn with_vec(vec: Vec<V>) -> Self {
140        Self {
141            dirty: UnsafeCell::new(vec),
142            write: Mutex::new(()),
143            id: super::CONTAINER_ID.fetch_add(1, Ordering::Relaxed),
144            writing: AtomicBool::new(false),
145            registry: Mutex::new(Vec::new()),
146        }
147    }
148
149    pub fn insert(&self, index: usize, v: V) -> Option<V> {
150        let _w = self.begin_write();
151        unsafe { &mut *self.dirty.get() }.insert(index, v);
152        None
153    }
154
155    pub fn set(&self, index: usize, v: V) -> Option<V> {
156        let _w = self.begin_write();
157        let m = unsafe { &mut *self.dirty.get() };
158        m[index] = v;
159        None
160    }
161
162    pub fn push(&self, v: V) -> Option<V> {
163        let _w = self.begin_write();
164        unsafe { &mut *self.dirty.get() }.push(v);
165        None
166    }
167
168    pub fn pushes(&self, arr: Vec<V>) -> Option<V> {
169        let _w = self.begin_write();
170        unsafe { &mut *self.dirty.get() }.extend(arr);
171        None
172    }
173
174    pub fn push_mut(&mut self, v: V) -> Option<V> {
175        unsafe { &mut *self.dirty.get() }.push(v);
176        None
177    }
178
179    pub fn pop(&self) -> Option<V> {
180        let _w = self.begin_write();
181        unsafe { &mut *self.dirty.get() }.pop()
182    }
183
184    pub fn pop_mut(&mut self) -> Option<V> {
185        unsafe { &mut *self.dirty.get() }.pop()
186    }
187
188    pub fn remove(&self, index: usize) -> Option<V> {
189        let _w = self.begin_write();
190        let m = unsafe { &mut *self.dirty.get() };
191        if m.len() > index {
192            Some(m.remove(index))
193        } else {
194            None
195        }
196    }
197
198    pub fn remove_mut(&mut self, index: usize) -> Option<V> {
199        let m = unsafe { &mut *self.dirty.get() };
200        if m.len() > index {
201            Some(m.remove(index))
202        } else {
203            None
204        }
205    }
206
207    pub fn len(&self) -> usize {
208        let count = self.begin_read();
209        let n = unsafe { &*self.dirty.get() }.len();
210        count.fetch_sub(1, Ordering::Release);
211        n
212    }
213
214    pub fn is_empty(&self) -> bool {
215        let count = self.begin_read();
216        let b = unsafe { &*self.dirty.get() }.is_empty();
217        count.fetch_sub(1, Ordering::Release);
218        b
219    }
220
221    pub fn clear(&self) {
222        let _w = self.begin_write();
223        unsafe { &mut *self.dirty.get() }.clear();
224    }
225
226    pub fn shrink_to_fit(&self) {
227        let _w = self.begin_write();
228        unsafe { &mut *self.dirty.get() }.shrink_to_fit();
229    }
230
231    pub fn from(vec: Vec<V>) -> Self {
232        Self::with_vec(vec)
233    }
234
235    /// Returns a read-guarded reference to the value at `index`.
236    ///
237    /// The read is lock-free: it only registers a reader slot, so concurrent
238    /// reads never block each other and never take a lock. Writers wait for
239    /// the returned guard to be dropped before mutating the vector.
240    #[inline]
241    pub fn get(&self, index: usize) -> Option<VecGet<'_, V>> {
242        let count = self.begin_read();
243        let m = unsafe { &*self.dirty.get() };
244        match m.get(index) {
245            Some(v) => Some(ReadGuard::new(count, v)),
246            None => {
247                count.fetch_sub(1, Ordering::Release);
248                None
249            }
250        }
251    }
252
253    /// Returns a write-guarded mutable reference to the value at `index`.
254    ///
255    /// The guard holds the writer lock (writers are mutually exclusive and
256    /// wait for in-flight readers) until it is dropped, so the mutable
257    /// reference can never race with concurrent readers or writers. Drop it
258    /// before calling another method from the same scope.
259    #[inline]
260    pub fn get_mut(&self, index: usize) -> Option<VecRefMut<'_, V>> {
261        let w = self.begin_write();
262        let m = unsafe { &mut *self.dirty.get() };
263        match m.get_mut(index) {
264            Some(v) => Some(WriteGuard::new(w, v)),
265            None => None,
266        }
267    }
268
269    #[inline]
270    pub fn contains(&self, x: &V) -> bool
271    where
272        V: PartialEq,
273    {
274        let count = self.begin_read();
275        let b = unsafe { &*self.dirty.get() }.contains(x);
276        count.fetch_sub(1, Ordering::Release);
277        b
278    }
279
280    pub fn iter(&self) -> VecIter<'_, V> {
281        let count = self.begin_read();
282        let m = unsafe { &*self.dirty.get() };
283        VecIter {
284            count,
285            inner: m.iter(),
286            _not_send: PhantomData,
287        }
288    }
289
290    pub fn iter_mut(&self) -> VecIterMut<'_, V> {
291        let w = self.begin_write();
292        let m = unsafe { &mut *self.dirty.get() };
293        VecIterMut {
294            _w: w,
295            inner: m.iter_mut(),
296        }
297    }
298
299    pub fn into_iter(self) -> IntoIter<V> {
300        self.into_inner().into_iter()
301    }
302
303    pub fn dirty_ref(&self) -> ReadMapGuard<'_, Vec<V>> {
304        let count = self.begin_read();
305        let m = unsafe { &*self.dirty.get() };
306        ReadMapGuard::new(count, m)
307    }
308
309    pub fn into_inner(self) -> Vec<V> {
310        self.dirty.into_inner()
311    }
312}
313
314impl<V> IntoIterator for SyncVec<V> {
315    type Item = V;
316    type IntoIter = IntoIter<V>;
317
318    fn into_iter(self) -> Self::IntoIter {
319        self.into_iter()
320    }
321}
322
323impl<V> Serialize for SyncVec<V>
324where
325    V: Serialize,
326{
327    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
328    where
329        S: Serializer,
330    {
331        self.dirty_ref().serialize(serializer)
332    }
333}
334
335impl<'de, V> serde::Deserialize<'de> for SyncVec<V>
336where
337    V: serde::Deserialize<'de>,
338{
339    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
340    where
341        D: Deserializer<'de>,
342    {
343        let m = Vec::deserialize(deserializer)?;
344        Ok(Self::from(m))
345    }
346}
347
348impl<V> Debug for SyncVec<V>
349where
350    V: Debug,
351{
352    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
353        Debug::fmt(&*self.dirty_ref(), f)
354    }
355}
356
357impl<V> Display for SyncVec<V>
358where
359    V: Debug,
360{
361    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
362        Debug::fmt(&*self.dirty_ref(), f)
363    }
364}
365
366impl<V: PartialEq> PartialEq for SyncVec<V> {
367    fn eq(&self, other: &Self) -> bool {
368        (*self.dirty_ref()).eq(&*other.dirty_ref())
369    }
370}
371
372impl<V: Clone> Clone for SyncVec<V> {
373    fn clone(&self) -> Self {
374        SyncVec::from(self.dirty_ref().to_vec())
375    }
376}
377
378impl<V> Default for SyncVec<V> {
379    fn default() -> Self {
380        SyncVec::new()
381    }
382}
383
384#[macro_export]
385macro_rules! sync_vec {
386    () => (
387        $crate::sync::SyncVec::new()
388    );
389    ($elem:expr; $n:expr) => (
390        $crate::sync::SyncVec::with_vec(vec![$elem;$n])
391    );
392    ($($x:expr),+ $(,)?) => (
393        $crate::sync::SyncVec::with_vec(vec![$($x),+,])
394    );
395}