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