Skip to main content

dark_std/sync/
map_index.rs

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