smr_swap/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3//! A minimal locking, version-based concurrent swap library.
4//!
5//! This library provides a mechanism to swap values atomically while allowing concurrent readers
6//! to access the old value until they are done. It uses `swmr-cell` for version-based garbage collection.
7//!
8//! # Example
9//!
10//! ```rust
11//! use smr_swap::SmrSwap;
12//! use std::thread;
13//!
14//! let mut swap = SmrSwap::new(0);
15//!
16//! // Get a thread-local reader
17//! let local = swap.local();
18//!
19//! // Writer stores a new value
20//! swap.store(1);
21//!
22//! // Read in another thread
23//! let local2 = swap.local();
24//! let handle = thread::spawn(move || {
25//!     let guard = local2.load();
26//!     assert_eq!(*guard, 1);
27//! });
28//!
29//! handle.join().unwrap();
30//! ```
31
32use core::fmt;
33use core::ops::Deref;
34use swmr_cell::SwmrCell;
35
36// Re-export for backward compatibility
37pub use swmr_cell::{LocalReader as CellLocalReader, PinGuard, SwmrReader as CellSwmrReader};
38
39/// Main entry point for the SMR swap library.
40///
41/// A single-writer, multi-reader swap container with version-based garbage collection.
42///
43/// SMR swap 库的主入口点。
44///
45/// 单写多读的交换容器,带有基于版本的垃圾回收。
46pub struct SmrSwap<T: 'static> {
47    cell: SwmrCell<T>,
48    local: LocalReader<T>,
49}
50
51/// A handle for creating `LocalReader`s that can be shared across threads.
52///
53/// Unlike `LocalReader`, which is `!Sync` and bound to a single thread,
54/// `SmrReader` is `Sync` and `Clone`. It acts as a factory for `LocalReader`s.
55///
56/// 可以跨线程共享的用于创建 `LocalReader` 的句柄。
57///
58/// 与 `!Sync` 且绑定到单个线程的 `LocalReader` 不同,
59/// `SmrReader` 是 `Sync` 和 `Clone` 的。它充当 `LocalReader` 的工厂。
60pub struct SmrReader<T: 'static> {
61    inner: CellSwmrReader<T>,
62}
63
64impl<T: 'static> SmrReader<T> {
65    /// Create a new `LocalReader` for the current thread.
66    ///
67    /// 为当前线程创建一个新的 `LocalReader`。
68    #[inline]
69    pub fn local(&self) -> LocalReader<T> {
70        LocalReader {
71            inner: self.inner.local(),
72        }
73    }
74}
75
76impl<T: 'static> Clone for SmrReader<T> {
77    #[inline]
78    fn clone(&self) -> Self {
79        Self {
80            inner: self.inner.clone(),
81        }
82    }
83}
84
85impl<T: 'static> fmt::Debug for SmrReader<T> {
86    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87        f.debug_struct("SmrReader").finish()
88    }
89}
90
91/// Thread-local reader handle, not Sync.
92///
93/// Each thread should create its own `LocalReader` via `SmrSwap::local()` and reuse it.
94/// `LocalReader` is `!Sync` and should not be shared between threads.
95///
96/// 线程本地的读取句柄,不是 Sync。
97///
98/// 每个线程应该通过 `SmrSwap::local()` 创建自己的 `LocalReader` 并重复使用。
99/// `LocalReader` 是 `!Sync` 的,不应在线程之间共享。
100pub struct LocalReader<T: 'static> {
101    inner: CellLocalReader<T>,
102}
103
104/// RAII guard for reading values.
105///
106/// Dereference to access the value. The value is protected until the guard is dropped.
107///
108/// 用于读取值的 RAII 守卫。
109///
110/// 解引用以访问值。在守卫被 drop 之前,值是受保护的。
111pub struct ReadGuard<'a, T: 'static> {
112    inner: PinGuard<'a, T>,
113}
114
115impl<'a, T> Deref for ReadGuard<'a, T> {
116    type Target = T;
117
118    #[inline(always)]
119    fn deref(&self) -> &T {
120        &*self.inner
121    }
122}
123
124impl<'a, T> Clone for ReadGuard<'a, T> {
125    #[inline]
126    fn clone(&self) -> Self {
127        ReadGuard {
128            inner: self.inner.clone(),
129        }
130    }
131}
132
133// ============================================================================
134// SmrSwap implementation
135// ============================================================================
136
137impl<T: 'static> SmrSwap<T> {
138    /// Create a new SMR container with the given initial value.
139    ///
140    /// 使用给定的初始值创建新的 SMR 容器。
141    #[inline]
142    pub fn new(initial: T) -> Self {
143        let cell = SwmrCell::builder()
144            .auto_reclaim_threshold(Some(4))
145            .build(initial);
146        let local = LocalReader {
147            inner: cell.local(),
148        };
149        Self { cell, local }
150    }
151
152    /// Create a new thread-local reader for this container.
153    ///
154    /// Each thread should create its own `LocalReader` and reuse it.
155    /// The `LocalReader` is `Send` but not `Sync`.
156    ///
157    /// 为此容器创建一个新的线程本地读取者。
158    ///
159    /// 每个线程应该创建自己的 `LocalReader` 并重复使用。
160    /// `LocalReader` 是 `Send` 但不是 `Sync`。
161    #[inline]
162    pub fn local(&self) -> LocalReader<T> {
163        LocalReader {
164            inner: self.cell.local(),
165        }
166    }
167
168    /// Create a new `SmrReader` that can be shared across threads.
169    ///
170    /// `SmrReader` is `Sync` + `Clone` and acts as a factory for `LocalReader`s.
171    /// This is useful for distributing reader creation capability to other threads.
172    ///
173    /// 创建一个新的 `SmrReader`,可以在线程之间共享。
174    ///
175    /// `SmrReader` 是 `Sync` + `Clone` 的,充当 `LocalReader` 的工厂。
176    /// 这对于将读者创建能力分发给其他线程很有用。
177    #[inline]
178    pub fn reader(&self) -> SmrReader<T> {
179        SmrReader {
180            inner: self.cell.reader(),
181        }
182    }
183
184    /// Store a new value, making it visible to readers.
185    ///
186    /// The old value is retired and will be garbage collected when safe.
187    ///
188    /// 存储新值,使其对读者可见。
189    ///
190    /// 旧值已退休,将在安全时被垃圾回收。
191    #[inline]
192    pub fn store(&mut self, new_value: T) {
193        self.cell.store(new_value);
194    }
195
196    /// Get a reference to the current value (writer-only, no pinning required).
197    ///
198    /// This is only accessible from the writer thread since `SmrSwap` is `!Sync`.
199    ///
200    /// 获取当前值的引用(仅写者可用,无需 pin)。
201    ///
202    /// 这只能从写者线程访问,因为 `SmrSwap` 是 `!Sync` 的。
203    #[inline]
204    pub fn get(&self) -> &T {
205        self.cell.get()
206    }
207
208    /// Update the value using a closure.
209    ///
210    /// The closure receives the current value and should return the new value.
211    /// This is equivalent to `swap.store(f(swap.get()))` but more ergonomic.
212    ///
213    /// 使用闭包更新值。
214    ///
215    /// 闭包接收当前值并应返回新值。
216    /// 这相当于 `swap.store(f(swap.get()))` 但更符合人体工程学。
217    #[inline]
218    pub fn update<F>(&mut self, f: F)
219    where
220        F: FnOnce(&T) -> T,
221    {
222        self.cell.update(f);
223    }
224
225    /// Get the current global version.
226    ///
227    /// The version is incremented each time `store()` is called.
228    ///
229    /// 获取当前全局版本。
230    ///
231    /// 每次调用 `store()` 时版本会增加。
232    #[inline]
233    pub fn version(&self) -> usize {
234        self.cell.version()
235    }
236
237    /// Get the number of retired objects waiting for garbage collection.
238    ///
239    /// 获取等待垃圾回收的已退休对象数量。
240    #[inline]
241    pub fn garbage_count(&self) -> usize {
242        self.cell.garbage_count()
243    }
244
245    /// Get a reference to the previously stored value, if any.
246    ///
247    /// Returns `None` if no previous value exists (i.e., only the initial value has been stored).
248    ///
249    /// 获取上一个存储值的引用(如果存在)。
250    ///
251    /// 如果不存在上一个值(即只存储了初始值),则返回 `None`。
252    #[inline]
253    pub fn previous(&self) -> Option<&T> {
254        self.cell.previous()
255    }
256
257    /// Manually trigger garbage collection.
258    ///
259    /// This is usually not necessary as garbage is collected automatically.
260    ///
261    /// 手动触发垃圾回收。
262    ///
263    /// 通常不需要,因为垃圾会自动回收。
264    #[inline]
265    pub fn collect(&mut self) {
266        self.cell.collect();
267    }
268
269    /// Read the current value with RAII guard.
270    ///
271    /// Returns a `ReadGuard` that can be dereferenced to access the value.
272    /// The value is protected until the guard is dropped.
273    ///
274    /// 使用 RAII 守卫读取当前值。
275    ///
276    /// 返回一个可以解引用来访问值的 `ReadGuard`。
277    /// 在守卫被 drop 之前,值是受保护的。
278    #[inline]
279    pub fn load(&self) -> ReadGuard<'_, T> {
280        self.local.load()
281    }
282
283    /// Load the current value and clone it.
284    ///
285    /// This is a convenience method equivalent to `self.load().cloned()`.
286    ///
287    /// # Example
288    ///
289    /// ```rust
290    /// use smr_swap::SmrSwap;
291    ///
292    /// let swap = SmrSwap::new(String::from("hello"));
293    ///
294    /// // Instead of: (*swap.load()).clone()
295    /// // Or: swap.load().cloned()
296    /// let value: String = swap.load_cloned();
297    /// assert_eq!(value, "hello");
298    /// ```
299    ///
300    /// 加载当前值并克隆它。
301    ///
302    /// 这是一个便捷方法,等同于 `self.load().cloned()`。
303    #[inline]
304    pub fn load_cloned(&self) -> T
305    where
306        T: Clone,
307    {
308        self.load().cloned()
309    }
310
311    /// Atomically swap the current value with a new one.
312    ///
313    /// Returns the old value.
314    ///
315    /// 原子地将当前值与新值交换。
316    ///
317    /// 返回旧的值。
318    #[inline]
319    pub fn swap(&mut self, new_value: T) -> T
320    where
321        T: Clone,
322    {
323        let old_value = self.cell.get().clone();
324        self.cell.store(new_value);
325        old_value
326    }
327
328    /// Apply a closure function to the current value and return the result.
329    ///
330    /// The closure receives a reference to the current value and returns a new value.
331    /// Returns a guard to the new value.
332    ///
333    /// 对当前值应用闭包函数并返回结果。
334    ///
335    /// 闭包接收当前值的引用,返回新值。
336    /// 返回新值的守卫。
337    #[inline]
338    pub fn update_and_fetch<F>(&mut self, f: F) -> ReadGuard<'_, T>
339    where
340        F: FnOnce(&T) -> T,
341    {
342        let new_value = f(self.cell.get());
343        self.cell.store(new_value);
344        self.local.load()
345    }
346
347    /// Apply a closure function to the current value with mutable access to both.
348    ///
349    /// The closure receives the current value and should return the new value.
350    /// Returns a guard to the old value (before update).
351    ///
352    /// 对当前值应用闭包函数,具有对两者的可变访问。
353    ///
354    /// 闭包接收当前值并应返回新值。
355    /// 返回旧值(更新前)的守卫。
356    #[inline]
357    pub fn fetch_and_update<F>(&mut self, f: F) -> ReadGuard<'_, T>
358    where
359        F: FnOnce(&T) -> T,
360    {
361        let old_guard = self.local.load();
362        let new_value = f(self.cell.get());
363        self.cell.store(new_value);
364        old_guard
365    }
366}
367
368// ============================================================================
369// LocalReader implementation
370// ============================================================================
371
372impl<T: 'static> LocalReader<T> {
373    /// Read the current value with RAII guard.
374    ///
375    /// Returns a `ReadGuard` that holds the pin and the reference.
376    /// The pin is automatically released when the guard is dropped.
377    ///
378    /// 使用 RAII 守卫读取当前值。
379    ///
380    /// 返回一个持有 pin 和引用的 `ReadGuard`。
381    /// 当守卫被 drop 时,pin 会自动释放。
382    #[inline]
383    pub fn load(&self) -> ReadGuard<'_, T> {
384        ReadGuard {
385            inner: self.inner.pin(),
386        }
387    }
388
389    /// Check if this reader is currently pinned.
390    ///
391    /// 检查此读者当前是否被 pin。
392    #[inline]
393    pub fn is_pinned(&self) -> bool {
394        self.inner.is_pinned()
395    }
396
397    /// Get the current global version.
398    ///
399    /// Note: This returns the global version, not the pinned version.
400    /// To get the pinned version, use `ReadGuard::version()`.
401    ///
402    /// 获取当前全局版本。
403    ///
404    /// 注意:这返回全局版本,而不是 pin 的版本。
405    /// 要获取 pin 的版本,请使用 `ReadGuard::version()`。
406    #[inline]
407    pub fn version(&self) -> usize {
408        self.inner.version()
409    }
410
411    /// Apply a closure function to the current value and transform the result.
412    ///
413    /// This method reads the current value, applies the closure to transform it,
414    /// and returns the transformed result.
415    ///
416    /// 对当前值应用闭包函数并转换结果。
417    ///
418    /// 这个方法读取当前值,应用闭包进行转换,并返回转换后的结果。
419    #[inline]
420    pub fn map<F, U>(&self, f: F) -> U
421    where
422        F: FnOnce(&T) -> U,
423    {
424        let guard = self.inner.pin();
425        f(&*guard)
426    }
427
428    /// Apply a closure function to the current value, returning Some if the closure returns true.
429    ///
430    /// 对当前值应用闭包函数,如果闭包返回 true 则返回 Some。
431    #[inline]
432    pub fn filter<F>(&self, f: F) -> Option<ReadGuard<'_, T>>
433    where
434        F: FnOnce(&T) -> bool,
435    {
436        let guard = self.inner.pin();
437        if f(&*guard) {
438            Some(ReadGuard { inner: guard })
439        } else {
440            None
441        }
442    }
443
444    /// Load the current value and clone it.
445    ///
446    /// This is a convenience method equivalent to `self.load().cloned()`.
447    ///
448    /// # Example
449    ///
450    /// ```rust
451    /// use smr_swap::SmrSwap;
452    ///
453    /// let swap = SmrSwap::new(String::from("hello"));
454    /// let local = swap.local();
455    ///
456    /// // Instead of: (*local.load()).clone()
457    /// // Or: local.load().cloned()
458    /// let value: String = local.load_cloned();
459    /// assert_eq!(value, "hello");
460    /// ```
461    ///
462    /// 加载当前值并克隆它。
463    ///
464    /// 这是一个便捷方法,等同于 `self.load().cloned()`。
465    #[inline]
466    pub fn load_cloned(&self) -> T
467    where
468        T: Clone,
469    {
470        self.load().cloned()
471    }
472
473    /// Create a new `SmrReader` from this `LocalReader`.
474    ///
475    /// `SmrReader` is `Sync` + `Clone` and acts as a factory for `LocalReader`s.
476    /// This is equivalent to calling `swap.reader()`, but using the `LocalReader`'s reference to the shared state.
477    ///
478    /// 从此 `LocalReader` 创建一个新的 `SmrReader`。
479    /// `SmrReader` 是 `Sync` + `Clone` 的,充当 `LocalReader` 的工厂。
480    /// 这相当于调用 `swap.reader()`,但使用 `LocalReader` 对共享状态的引用。
481    #[inline]
482    pub fn share(&self) -> SmrReader<T> {
483        SmrReader {
484            inner: self.inner.share(),
485        }
486    }
487
488    /// Convert this `LocalReader` into a `SmrReader`.
489    ///
490    /// This consumes the `LocalReader` and returns a `SmrReader`
491    /// that can be sent to another thread to create new `LocalReader`s.
492    ///
493    /// 将此 `LocalReader` 转换为 `SmrReader`。
494    /// 这会消耗 `LocalReader` 并返回一个 `SmrReader`,
495    /// 该 `SmrReader` 可以发送到另一个线程以创建新 `LocalReader`。
496    #[inline]
497    pub fn into_swmr(self) -> SmrReader<T> {
498        SmrReader {
499            inner: self.inner.into_swmr(),
500        }
501    }
502}
503
504impl<T: 'static> Clone for LocalReader<T> {
505    #[inline]
506    fn clone(&self) -> Self {
507        LocalReader {
508            inner: self.inner.clone(),
509        }
510    }
511}
512
513impl<T: 'static> fmt::Debug for LocalReader<T> {
514    #[inline]
515    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
516        f.debug_struct("LocalReader")
517            .field("is_pinned", &self.is_pinned())
518            .field("version", &self.version())
519            .finish()
520    }
521}
522
523// ============================================================================
524// ReadGuard additional implementations
525// ============================================================================
526
527impl<T: 'static> ReadGuard<'_, T> {
528    /// Get the version that this guard is pinned to.
529    ///
530    /// 获取此守卫被 pin 到的版本。
531    #[inline]
532    pub fn version(&self) -> usize {
533        self.inner.version()
534    }
535
536    /// Clone the inner value and return it.
537    ///
538    /// This is useful when you need to return the value instead of the guard.
539    ///
540    /// # Example
541    ///
542    /// ```rust
543    /// use smr_swap::SmrSwap;
544    ///
545    /// let swap = SmrSwap::new(42);
546    /// let value: i32 = swap.load().cloned();
547    /// assert_eq!(value, 42);
548    /// ```
549    ///
550    /// 克隆内部值并返回。
551    ///
552    /// 当你需要返回值而不是守卫时很有用。
553    #[inline]
554    pub fn cloned(&self) -> T
555    where
556        T: Clone,
557    {
558        self.deref().clone()
559    }
560
561    /// Convert the guard into the inner value by cloning.
562    ///
563    /// This consumes the guard and returns a clone of the inner value.
564    ///
565    /// 通过克隆将守卫转换为内部值。
566    ///
567    /// 这会消耗守卫并返回内部值的克隆。
568    #[inline]
569    pub fn into_inner(self) -> T
570    where
571        T: Clone,
572    {
573        self.deref().clone()
574    }
575}
576
577impl<T: 'static> AsRef<T> for ReadGuard<'_, T> {
578    #[inline]
579    fn as_ref(&self) -> &T {
580        self.deref()
581    }
582}
583
584impl<T: fmt::Debug + 'static> fmt::Debug for ReadGuard<'_, T> {
585    #[inline]
586    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
587        f.debug_struct("ReadGuard")
588            .field("value", &self.deref())
589            .field("version", &self.version())
590            .finish()
591    }
592}
593
594// ============================================================================
595// Standard Trait Implementations
596// 标准 trait 实现
597// ============================================================================
598
599impl<T: Default + 'static> Default for SmrSwap<T> {
600    /// Create a new SmrSwap with the default value.
601    ///
602    /// 使用默认值创建一个新的 SmrSwap。
603    #[inline]
604    fn default() -> Self {
605        Self::new(T::default())
606    }
607}
608
609impl<T: 'static> From<T> for SmrSwap<T> {
610    /// Create a new SmrSwap from a value.
611    ///
612    /// 从一个值创建一个新的 SmrSwap。
613    #[inline]
614    fn from(value: T) -> Self {
615        Self::new(value)
616    }
617}
618
619impl<T: fmt::Debug + 'static> fmt::Debug for SmrSwap<T> {
620    #[inline]
621    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
622        f.debug_struct("SmrSwap")
623            .field("value", self.get())
624            .field("version", &self.version())
625            .field("garbage_count", &self.garbage_count())
626            .finish()
627    }
628}
629
630#[cfg(test)]
631mod tests;