swmr-cell 0.3.1

A thread-safe single-writer multi-reader cell with wait-free reads and version-based garbage collection
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
//! # SWMR Version-Based Single Object
//!
//! This crate provides a single-writer, multi-reader (SWMR) cell that supports
//! concurrent wait-free reads and lock-free writes using version-based garbage collection.
//!
//! ## Core Concepts
//!
//! - **Single Object**: The `swmr_cell` library manages a single versioned object per `SwmrCell`.
//! - **Version**: The version counter represents the state of the object. Each write increments the version.
//! - **Pinning**: Readers pin the current version when they start reading, preventing the writer from reclaiming that version (and any older versions still visible to other readers) until they are done.
//!
//! ## Typical Usage
//!
//! ```rust
//! use swmr_cell::SwmrCell;
//!
//! // 1. Create a new SWMR cell with an initial value
//! let mut cell = SwmrCell::new(42i32);
//!
//! // 2. Create a local reader for this thread (or pass to another thread)
//! let local = cell.local_reader();
//!
//! // 3. Pin and read the value by dereferencing the guard
//! let guard = local.pin();
//! assert_eq!(*guard, 42);
//! drop(guard);
//!
//! // 4. Writer updates the value
//! cell.store(100i32);
//!
//! // 5. Read the new value
//! let guard = local.pin();
//! assert_eq!(*guard, 100);
//! drop(guard);
//!
//! // 6. Manually collect garbage (optional, happens automatically too)
//! cell.collect();
//! ```
#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(not(feature = "std"))]
extern crate alloc;

#[cfg(all(not(feature = "std"), test))]
extern crate std;

mod shim;

#[cfg(test)]
mod tests;
use crate::shim::{
    Arc, AtomicPtr, AtomicUsize, Box, Cell, Mutex, Ordering, Vec, VecDeque, heavy_barrier,
    light_barrier,
};
use core::{fmt, marker::PhantomData, ops::Deref};

/// Default threshold for automatic garbage reclamation (count of retired nodes).
/// 自动垃圾回收的默认阈值(已退休节点的数量)。
pub(crate) const AUTO_RECLAIM_THRESHOLD: usize = 16;

/// Represents a reader that is not currently pinned to any version.
/// 表示当前未被钉住到任何版本的读者。
pub(crate) const INACTIVE_VERSION: usize = usize::MAX;

/// A single-writer, multi-reader cell with version-based garbage collection.
///
/// `SwmrCell` provides safe concurrent access where one writer can update the value
/// and multiple readers can read it concurrently. Readers access the value by
/// creating a `LocalReader` and pinning it.
///
/// 单写多读单元,带有基于版本的垃圾回收。
///
/// `SwmrCell` 提供安全的并发访问,其中一个写入者可以更新值,
/// 多个读者可以并发读取它。读者通过创建 `LocalReader` 并 pin 来访问值。
pub struct SwmrCell<T: 'static, const RP: bool = false> {
    shared: Arc<SharedState<T, RP>>,
    garbage: GarbageSet<T>,
    auto_reclaim_threshold: Option<usize>,
}

impl<T: 'static> SwmrCell<T, false> {
    /// Create a new SWMR cell with default settings and the given initial value.
    ///
    /// 使用默认设置和给定的初始值创建一个新的 SWMR 单元。
    #[inline]
    pub fn new(data: T) -> Self {
        Self::builder().build(data)
    }

    /// Returns a builder for configuring the SWMR cell.
    ///
    /// 返回用于配置 SWMR 单元的构建器。
    #[inline]
    pub fn builder() -> SwmrCellBuilder<T, false> {
        SwmrCellBuilder::default()
    }
}

impl<T: 'static, const RP: bool> SwmrCell<T, RP> {
    /// Create a new `LocalReader` for reading.
    ///
    /// Each thread should create its own `LocalReader` and reuse it.
    /// `LocalReader` is `!Sync` and should not be shared between threads.
    ///
    /// 创建一个新的 `LocalReader` 用于读取。
    /// 每个线程应该创建自己的 `LocalReader` 并重复使用。
    /// `LocalReader` 是 `!Sync` 的,不应在线程之间共享。
    #[inline]
    pub fn local_reader(&self) -> LocalReader<T, RP> {
        LocalReader::new(self.shared.clone())
    }

    /// Create a new `SwmrReaderFactory` that can be shared across threads.
    ///
    /// `SwmrReaderFactory` is `Sync` + `Clone` and acts as a factory for `LocalReader`s.
    /// This is useful for distributing reader creation capability to other threads.
    ///
    /// 创建一个新的 `SwmrReaderFactory`,可以在线程之间共享。
    /// `SwmrReaderFactory` 是 `Sync` + `Clone` 的,充当 `LocalReader` 的工厂。
    /// 这对于将读者创建能力分发给其他线程很有用。
    #[inline]
    pub fn reader_factory(&self) -> SwmrReaderFactory<T, RP> {
        SwmrReaderFactory {
            shared: self.shared.clone(),
        }
    }

    /// Store a new value, making it visible to readers.
    /// The old value is retired and will be garbage collected.
    ///
    /// This operation increments the global version.
    ///
    /// 存储新值,使其对读者可见。
    /// 旧值已退休,将被垃圾回收。
    /// 此操作会增加全局版本。
    pub fn store(&mut self, data: T) {
        let new_ptr = Box::into_raw(Box::new(data));
        let old_ptr = self.shared.ptr.swap(new_ptr, Ordering::Release);

        // Increment global version.
        // The old value belongs to the previous version (the one before this increment).
        // 增加全局版本。
        // 旧值属于前一个版本(此次增加之前的那个)。
        let old_version = self.shared.global_version.fetch_add(1, Ordering::AcqRel);

        if !old_ptr.is_null() {
            // Safe because we just swapped it out and we own the writer
            unsafe {
                self.garbage.add(Box::from_raw(old_ptr), old_version);
            }
        }

        // Auto-reclaim
        if let Some(threshold) = self.auto_reclaim_threshold
            && self.garbage.len() > threshold
        {
            self.collect();
        }
    }

    /// Get a reference to the previously stored value, if any.
    ///
    /// Returns `None` if no previous value exists (i.e., only the initial value has been stored).
    ///
    /// **Note**: The previous value is guaranteed not to be garbage collected because
    /// `collect()` uses `safety_limit = current_version - 2`, which always preserves
    /// the most recently retired value (version = current_version - 1).
    ///
    /// This is useful for comparing the current value with the previous one,
    /// or for implementing undo/rollback logic.
    ///
    /// 获取上一个存储值的引用(如果存在)。
    ///
    /// 如果不存在上一个值(即只存储了初始值),则返回 `None`。
    ///
    /// **注意**:上一个值保证不会被垃圾回收,因为 `collect()` 使用 `safety_limit = current_version - 2`,
    /// 这始终保留最近退休的值(版本 = current_version - 1)。
    ///
    /// 这对于将当前值与上一个值进行比较,或实现撤销/回滚逻辑很有用。
    ///
    /// # Example
    ///
    /// ```rust
    /// use swmr_cell::SwmrCell;
    ///
    /// let mut cell = SwmrCell::new(1);
    /// assert!(cell.previous().is_none()); // No previous value yet
    ///
    /// cell.store(2);
    /// assert_eq!(cell.previous(), Some(&1)); // Previous value is 1
    ///
    /// cell.store(3);
    /// assert_eq!(cell.previous(), Some(&2)); // Previous value is 2
    /// ```
    #[inline]
    pub fn previous(&self) -> Option<&T> {
        self.garbage.back()
    }

    /// Get a reference to the current value (writer-only, no pinning required).
    ///
    /// This is only accessible from the writer thread since `SwmrCell` is `!Sync`.
    ///
    /// 获取当前值的引用(仅写者可用,无需 pin)。
    /// 这只能从写者线程访问,因为 `SwmrCell` 是 `!Sync` 的。
    #[inline]
    pub fn get(&self) -> &T {
        // Safety: We own the writer, and the current pointer is always valid.
        // 安全性:我们拥有写者,当前指针始终有效。
        unsafe { &*self.shared.ptr.load(Ordering::Acquire) }
    }

    /// Update the value using a closure.
    ///
    /// The closure receives the current value and should return the new value.
    /// This is equivalent to `cell.store(f(cell.get().clone()))` but more ergonomic.
    ///
    /// 使用闭包更新值。
    /// 闭包接收当前值并应返回新值。
    /// 这相当于 `cell.store(f(cell.get().clone()))` 但更符合人体工程学。
    #[inline]
    pub fn update<F>(&mut self, f: F)
    where
        F: FnOnce(&T) -> T,
    {
        let new_value = f(self.get());
        self.store(new_value);
    }

    /// Get the current global version.
    ///
    /// The version is incremented each time `store()` or `replace()` is called.
    ///
    /// 获取当前全局版本。
    /// 每次调用 `store()` 或 `replace()` 时版本会增加。
    #[inline]
    pub fn version(&self) -> usize {
        self.shared.global_version.load(Ordering::Acquire)
    }

    /// Get the number of retired objects waiting for garbage collection.
    ///
    /// 获取等待垃圾回收的已退休对象数量。
    #[inline]
    pub fn garbage_count(&self) -> usize {
        self.garbage.len()
    }

    /// Manually trigger garbage collection.
    /// 手动触发垃圾回收。
    pub fn collect(&mut self) {
        // In this design, we don't necessarily advance the version just for collection.
        // But we need to find min_active_version.

        let current_version = self.shared.global_version.load(Ordering::Acquire);

        // Safety limit ensures we never reclaim the most recent retired value (previous).
        // The most recent retired value has version = current_version - 1.
        // With safety_limit = current_version - 2, we only reclaim versions < current_version - 2,
        // so the previous value (version = current_version - 1) is always preserved.
        // 安全限制确保我们永远不会回收最近退休的值(previous)。
        // 最近退休的值的版本 = current_version - 1。
        // 使用 safety_limit = current_version - 2,我们只回收版本 < current_version - 2 的,
        // 因此上一个值(版本 = current_version - 1)始终被保留。
        let safety_limit = current_version.saturating_sub(2);

        let mut min_active = current_version;

        // Force memory visibility of any preceding stores and serialize reader streams.
        // This ensures we see any active readers that have completed their light_barrier.
        heavy_barrier::<RP>();

        let mut shared_readers = self.shared.readers.lock();

        for arc_slot in shared_readers.iter() {
            let version = arc_slot.active_version.load(Ordering::Acquire);
            if version != INACTIVE_VERSION {
                min_active = min_active.min(version);
            }
        }

        // Clean up dead reader slots (strong_count == 1 means only SharedState holds it)
        // 清理死读者槽(strong_count == 1 表示只有 SharedState 持有它)
        shared_readers.retain(|arc_slot| Arc::strong_count(arc_slot) > 1);

        drop(shared_readers);

        let reclaim_threshold = min_active.min(safety_limit);

        self.shared
            .min_active_version
            .store(reclaim_threshold, Ordering::Release);

        self.garbage.collect(reclaim_threshold, current_version);
    }
}

/// A handle for creating `LocalReader`s that can be shared across threads.
///
/// Unlike `LocalReader`, which is `!Sync` and bound to a single thread,
/// `SwmrReaderFactory` is `Sync` and `Clone`. It holds a reference to the shared state
/// but does not register a reader slot until `local_reader()` is called.
///
/// 可以跨线程共享的用于创建 `LocalReader` 的句柄。
///
/// 与 `!Sync` 且绑定到单个线程的 `LocalReader` 不同,
/// `SwmrReaderFactory` 是 `Sync` 和 `Clone` 的。它持有对共享状态的引用,
/// 但直到调用 `local_reader()` 时才注册读者槽。
pub struct SwmrReaderFactory<T: 'static, const RP: bool = false> {
    shared: Arc<SharedState<T, RP>>,
}

impl<T: 'static, const RP: bool> SwmrReaderFactory<T, RP> {
    /// Create a new `LocalReader` for the current thread.
    ///
    /// 为当前线程创建一个新的 `LocalReader`。
    #[inline]
    pub fn local_reader(&self) -> LocalReader<T, RP> {
        LocalReader::new(self.shared.clone())
    }
}

impl<T: 'static, const RP: bool> Clone for SwmrReaderFactory<T, RP> {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            shared: self.shared.clone(),
        }
    }
}

impl<T: 'static, const RP: bool> fmt::Debug for SwmrReaderFactory<T, RP> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("SwmrReaderFactory")
            .field("read_preferred", &RP)
            .finish()
    }
}

/// A builder for configuring and creating a SWMR cell.
///
/// 用于配置和创建 SWMR 单元的构建器。
pub struct SwmrCellBuilder<T, const RP: bool = false> {
    auto_reclaim_threshold: Option<usize>,
    marker: PhantomData<T>,
}

impl<T: 'static, const RP: bool> SwmrCellBuilder<T, RP> {
    /// Sets the threshold for automatic garbage reclamation.
    ///
    /// When the number of retired objects exceeds this threshold,
    /// garbage collection is triggered automatically during `store`.
    ///
    /// Set to `None` to disable automatic reclamation.
    /// Default is `Some(64)`.
    ///
    /// 设置自动垃圾回收的阈值。
    /// 当已退休对象的数量超过此阈值时,将在 `store` 期间自动触发垃圾回收。
    /// 设置为 `None` 以禁用自动回收。
    /// 默认为 `Some(64)`。
    #[inline]
    pub fn auto_reclaim_threshold(mut self, threshold: Option<usize>) -> Self {
        self.auto_reclaim_threshold = threshold;
        self
    }

    /// Creates a new SWMR cell with the configured settings and initial value.
    ///
    /// 使用配置的设置和初始值创建一个新的 SWMR 单元。
    pub fn build(self, data: T) -> SwmrCell<T, RP> {
        let shared = Arc::new(SharedState {
            global_version: AtomicUsize::new(0),
            min_active_version: AtomicUsize::new(0),
            ptr: AtomicPtr::new(Box::into_raw(Box::new(data))),
            readers: Mutex::new(Vec::new()),
        });

        SwmrCell {
            shared,
            garbage: GarbageSet::new(),
            auto_reclaim_threshold: self.auto_reclaim_threshold,
        }
    }
}

impl<T: 'static, const RP: bool> Default for SwmrCellBuilder<T, RP> {
    fn default() -> Self {
        SwmrCellBuilder {
            auto_reclaim_threshold: Some(AUTO_RECLAIM_THRESHOLD),
            marker: PhantomData,
        }
    }
}

impl<T: 'static> SwmrCellBuilder<T, false> {
    /// Enable read-preferred mode.
    ///
    /// 启用读优先模式。
    #[inline]
    pub fn read_preferred(self) -> SwmrCellBuilder<T, true> {
        SwmrCellBuilder {
            auto_reclaim_threshold: self.auto_reclaim_threshold,
            marker: PhantomData,
        }
    }
}

/// Manages retired objects and their reclamation.
///
/// This struct encapsulates the logic for:
/// - Storing retired objects in version-ordered queue.
/// - Reclaiming objects when they are safe to delete.
///
/// 管理已退休对象及其回收。
///
/// 此结构体封装了以下逻辑:
/// - 将已退休对象存储在按版本排序的队列中。
/// - 当对象可以安全删除时进行回收。
struct GarbageSet<T> {
    /// Queue of garbage items, ordered by version.
    /// Each element is (version, node).
    queue: VecDeque<(usize, Box<T>)>,
}

impl<T> GarbageSet<T> {
    /// Create a new empty garbage set.
    /// 创建一个新的空垃圾集合。
    fn new() -> Self {
        Self {
            queue: VecDeque::new(),
        }
    }

    /// Get the total number of retired objects.
    /// 获取已退休对象的总数。
    #[inline]
    fn len(&self) -> usize {
        self.queue.len()
    }

    /// Get a reference to the most recently retired object (the previous value).
    /// 获取最近退休对象(上一个值)的引用。
    #[inline]
    fn back(&self) -> Option<&T> {
        self.queue.back().map(|(_, boxed)| boxed.as_ref())
    }

    /// Add a retired node to the set for the current version.
    ///
    /// 将已退休节点添加到当前版本的集合中。
    #[inline]
    fn add(&mut self, node: Box<T>, current_version: usize) {
        self.queue.push_back((current_version, node));
    }

    /// Reclaim garbage that is safe to delete.
    ///
    /// Garbage from versions older than `min_active_version` is dropped.
    ///
    /// 回收可以安全删除的垃圾。
    ///
    /// 来自比 `min_active_version` 更旧的版本的垃圾将被 drop。
    #[inline]
    fn collect(&mut self, min_active_version: usize, _current_version: usize) {
        // We reclaim everything that is strictly older than min_active_version.
        // If min_active_version == current_version, then everything (all < current_version) is reclaimed.
        while let Some((version, _)) = self.queue.front() {
            if *version >= min_active_version {
                break;
            }
            self.queue.pop_front(); // Box<T> is dropped here
        }
    }
}

/// A slot allocated for a reader thread to record its active version.
///
/// Cache-aligned to prevent false sharing between readers.
///
/// 为读者线程分配的槽,用于记录其活跃版本。
/// 缓存对齐以防止读者之间的伪共享。
#[derive(Debug)]
#[repr(align(64))]
pub(crate) struct ReaderSlot {
    /// The version currently being accessed by the reader, or INACTIVE_VERSION.
    /// 读者当前访问的版本,或 INACTIVE_VERSION。
    pub(crate) active_version: AtomicUsize,
}

/// Global shared state for the version GC domain.
///
/// Contains the global version, the minimum active version, the data pointer, and the list of reader slots.
///
/// version GC 域的全局共享状态。
/// 包含全局版本、最小活跃版本、数据指针和读者槽列表。
#[repr(align(64))]
pub(crate) struct SharedState<T: 'static, const RP: bool = false> {
    /// The global monotonic version counter.
    /// 全局单调版本计数器。
    pub(crate) global_version: AtomicUsize,
    /// The minimum version among all active readers (cached for performance).
    /// 所有活跃读者中的最小版本(为性能而缓存)。
    pub(crate) min_active_version: AtomicUsize,
    /// The current data pointer.
    /// 当前数据指针。
    pub(crate) ptr: AtomicPtr<T>,
    /// List of all registered reader slots. Protected by a Mutex.
    /// 所有注册读者槽的列表。由 Mutex 保护。
    pub(crate) readers: Mutex<Vec<Arc<ReaderSlot>>>,
}

impl<T: 'static, const RP: bool> Drop for SharedState<T, RP> {
    fn drop(&mut self) {
        // Drop the current value held by ptr to avoid leaking it.
        // Drop ptr 持有的当前值,以避免泄漏。
        let ptr = self.ptr.load(Ordering::Acquire);
        if !ptr.is_null() {
            unsafe {
                drop(Box::from_raw(ptr));
            }
        }
    }
}

/// A reader thread's local version state.
///
/// Each reader thread should create exactly one `LocalReader` via `SwmrCell::local_reader()`.
/// It is `!Sync` (due to `Cell`) and must be stored per-thread.
///
/// The `LocalReader` is used to:
/// - Pin the thread to the current version via `pin()`.
/// - Obtain a `PinGuard` that protects access to values and can be dereferenced.
///
/// **Thread Safety**: `LocalReader` is not `Sync` and must be used by only one thread.
///
/// 读者线程的本地版本状态。
/// 每个读者线程应该通过 `SwmrCell::local_reader()` 创建恰好一个 `LocalReader`。
/// 它是 `!Sync` 的(因为 `Cell`),必须在每个线程中存储。
/// `LocalReader` 用于:
/// - 通过 `pin()` 将线程钉住到当前版本。
/// - 获取保护对值访问的 `PinGuard`,可以解引用来读取值。
///   **线程安全性**:`LocalReader` 不是 `Sync` 的,必须仅由一个线程使用。
pub struct LocalReader<T: 'static, const RP: bool = false> {
    slot: Arc<ReaderSlot>,
    shared: Arc<SharedState<T, RP>>,
    pin_count: Cell<usize>,
}

impl<T: 'static, const RP: bool> LocalReader<T, RP> {
    fn new(shared: Arc<SharedState<T, RP>>) -> Self {
        let slot = Arc::new(ReaderSlot {
            active_version: AtomicUsize::new(INACTIVE_VERSION),
        });

        // Register the reader immediately in the shared readers list
        shared.readers.lock().push(Arc::clone(&slot));

        LocalReader {
            slot,
            shared,
            pin_count: Cell::new(0),
        }
    }

    /// Pin this thread to the current version.
    ///
    /// Returns a `PinGuard` that keeps the thread pinned for its lifetime.
    /// The guard can be dereferenced to access the current value.
    ///
    /// **Reentrancy**: This method is reentrant. Multiple calls can be nested, and the thread
    /// remains pinned until all returned guards are dropped. You can also clone a guard to create
    /// additional references: `let guard2 = guard1.clone();`
    ///
    /// **Example**:
    /// ```ignore
    /// let local = cell.local_reader();
    /// let guard1 = local.pin();
    /// let value = *guard1;  // Dereference to read
    /// let guard2 = local.pin();  // Reentrant call
    /// let guard3 = guard1.clone();     // Clone for nested scope
    /// // Thread remains pinned until all three guards are dropped
    /// ```
    ///
    /// While pinned, the thread is considered "active" at a particular version,
    /// and the garbage collector will not reclaim data from that version.
    ///
    /// 将此线程钉住到当前版本。
    ///
    /// 返回一个 `PinGuard`,在其生命周期内保持线程被钉住。
    /// 可以解引用该守卫来访问当前值。
    ///
    /// **可重入性**:此方法是可重入的。多个调用可以嵌套,线程在所有返回的守卫被 drop 之前保持被钉住。
    /// 你也可以克隆一个守卫来创建额外的引用:`let guard2 = guard1.clone();`
    ///
    /// **示例**:
    /// ```ignore
    /// let local = cell.local_reader();
    /// let guard1 = local.pin();
    /// let value = *guard1;  // 解引用来读取
    /// let guard2 = local.pin();  // 可重入调用
    /// let guard3 = guard1.clone();     // 克隆用于嵌套作用域
    /// // 线程保持被钉住直到所有三个守卫被 drop
    /// ```
    ///
    /// 当被钉住时,线程被认为在特定版本"活跃",垃圾回收器不会回收该版本的数据。
    /// Check if this reader is currently pinned.
    ///
    /// 检查此读者当前是否被 pin。
    #[inline]
    pub fn is_pinned(&self) -> bool {
        self.pin_count.get() > 0
    }

    /// Get the current global version.
    ///
    /// Note: This returns the global version, not the pinned version.
    /// To get the pinned version, use `PinGuard::version()`.
    ///
    /// 获取当前全局版本。
    /// 注意:这返回全局版本,而不是 pin 的版本。
    /// 要获取 pin 的版本,请使用 `PinGuard::version()`。
    #[inline]
    pub fn version(&self) -> usize {
        self.shared.global_version.load(Ordering::Acquire)
    }

    #[inline]
    pub fn pin(&self) -> PinGuard<'_, T, RP> {
        let pin_count = self.pin_count.get();

        // Reentrant pin: the version is already protected by the outer pin.
        // Just increment count and reuse the existing pinned pointer.
        // 可重入 pin:版本已经被外层 pin 保护。
        // 只需增加计数并复用现有的 pinned 指针。
        if pin_count > 0 {
            self.pin_count.set(pin_count + 1);

            // Load the pointer that corresponds to our already-pinned version.
            // Since we're reentrant, we should see the same or newer pointer.
            // 加载与我们已 pin 版本对应的指针。
            // 由于是可重入的,我们应该看到相同或更新的指针。
            let ptr = self.shared.ptr.load(Ordering::Acquire);
            let version = self.slot.active_version.load(Ordering::Acquire);

            return PinGuard {
                local: self,
                ptr,
                version,
            };
        }

        // First pin: need to acquire a version and validate it.
        // 首次 pin:需要获取版本并验证。
        loop {
            let current_version = self.shared.global_version.load(Ordering::Acquire);

            self.slot
                .active_version
                .store(current_version, Ordering::Release);

            // Light barrier coupled with Writer's Heavy barrier prevents Store-Load reordering.
            light_barrier::<RP>();

            // Check if our version is still valid (not yet reclaimed).
            // 检查我们的版本是否仍然有效(尚未被回收)。
            let min_active = self.shared.min_active_version.load(Ordering::Acquire);

            if current_version >= min_active {
                break;
            }

            // Version was reclaimed between our read and store.
            // Retry with a fresh version.
            // 版本在我们读取和存储之间被回收了。
            // 用新版本重试。
            core::hint::spin_loop();
        }

        self.pin_count.set(1);

        // Capture the pointer and version at pin time for snapshot semantics.
        // 在 pin 时捕获指针和版本以实现快照语义。
        let ptr = self.shared.ptr.load(Ordering::Acquire);
        let version = self.slot.active_version.load(Ordering::Acquire);

        PinGuard {
            local: self,
            ptr,
            version,
        }
    }

    /// Create a new `SwmrReaderFactory` from this `LocalReader`.
    ///
    /// `SwmrReaderFactory` is `Sync` + `Clone` and acts as a factory for `LocalReader`s.
    /// This is equivalent to calling `swmr_cell.reader_factory()`, but using the `LocalReader`'s reference to the shared state.
    ///
    /// 从此 `LocalReader` 创建一个新的 `SwmrReaderFactory`。
    /// `SwmrReaderFactory` 是 `Sync` + `Clone` 的,充当 `LocalReader` 的工厂。
    /// 这相当于调用 `swmr_cell.reader_factory()`,但使用 `LocalReader` 对共享状态的引用。
    #[inline]
    pub fn reader_factory(&self) -> SwmrReaderFactory<T, RP> {
        SwmrReaderFactory {
            shared: self.shared.clone(),
        }
    }

    /// Convert this `LocalReader` into a `SwmrReaderFactory`.
    ///
    /// This consumes the `LocalReader` and returns a `SwmrReaderFactory`
    /// that can be sent to another thread to create new `LocalReader`s.
    ///
    /// 将此 `LocalReader` 转换为 `SwmrReaderFactory`。
    /// 这会消耗 `LocalReader` 并返回一个 `SwmrReaderFactory`,
    /// 该 `SwmrReaderFactory` 可以发送到另一个线程以创建新 `LocalReader`。
    #[inline]
    pub fn into_swmr(self) -> SwmrReaderFactory<T, RP> {
        SwmrReaderFactory {
            shared: self.shared.clone(),
        }
    }
}

impl<T: 'static, const RP: bool> Clone for LocalReader<T, RP> {
    #[inline]
    fn clone(&self) -> Self {
        Self::new(self.shared.clone())
    }
}

/// A guard that keeps the current thread pinned to a version.
///
/// `PinGuard` is obtained by calling `LocalReader::pin()`.
/// It implements `Deref<Target = T>` to allow reading the current value.
/// It is `!Send` and `!Sync` because it references a `!Sync` `LocalReader`.
/// Its lifetime is bound to the `LocalReader` it came from.
///
/// While a `PinGuard` is held, the thread is considered "active" at a particular version,
/// and the garbage collector will not reclaim data from that version.
///
/// `PinGuard` supports internal cloning via reference counting (increments the pin count),
/// allowing nested pinning. The thread remains pinned until all cloned guards are dropped.
///
/// **Safety**: The `PinGuard` is the mechanism that ensures safe concurrent access to
/// shared values. Readers must always hold a valid `PinGuard` when accessing
/// shared data.
///
/// 一个保持当前线程被钉住到一个版本的守卫。
/// `PinGuard` 通过调用 `LocalReader::pin()` 获得。
/// 它实现了 `Deref<Target = T>`,允许读取当前值。
/// 它是 `!Send` 和 `!Sync` 的,因为它引用了一个 `!Sync` 的 `LocalReader`。
/// 它的生命周期被绑定到它来自的 `LocalReader`。
/// 当 `PinGuard` 被持有时,线程被认为在特定版本"活跃",
/// 垃圾回收器不会回收该版本的数据。
/// `PinGuard` 支持通过引用计数的内部克隆(增加 pin 计数),允许嵌套 pinning。
/// 线程保持被钉住直到所有克隆的守卫被 drop。
/// **安全性**:`PinGuard` 是确保对值安全并发访问的机制。
/// 读者在访问共享数据时必须始终持有有效的 `PinGuard`。
#[must_use]
pub struct PinGuard<'a, T: 'static, const RP: bool = false> {
    local: &'a LocalReader<T, RP>,
    /// The pointer captured at pin time for snapshot semantics.
    /// 在 pin 时捕获的指针,用于快照语义。
    ptr: *const T,
    /// The version at pin time.
    /// pin 时的版本。
    version: usize,
}

impl<T: 'static, const RP: bool> PinGuard<'_, T, RP> {
    /// Get the version that this guard is pinned to.
    ///
    /// 获取此守卫被 pin 到的版本。
    #[inline]
    pub fn version(&self) -> usize {
        self.version
    }
}

impl<'a, T, const RP: bool> Deref for PinGuard<'a, T, RP> {
    type Target = T;

    /// Dereference to access the pinned value.
    ///
    /// Returns a reference to the value that was current when this guard was created.
    /// This provides snapshot semantics - the value won't change during the guard's lifetime.
    ///
    /// 解引用以访问被 pin 的值。
    ///
    /// 返回对创建此守卫时当前值的引用。
    /// 这提供了快照语义 - 在守卫的生命周期内值不会改变。
    #[inline]
    fn deref(&self) -> &T {
        // Safety: pin() guarantees pinned_version >= min_active,
        // and the pointer was captured at pin time.
        // The value is valid as long as guard is held.
        // 安全性:pin() 保证 pinned_version >= min_active,
        // 并且指针在 pin 时被捕获。
        // 只要 guard 被持有,值就是有效的。
        unsafe { &*self.ptr }
    }
}

impl<'a, T, const RP: bool> Clone for PinGuard<'a, T, RP> {
    /// Clone this guard to create a nested pin.
    ///
    /// Cloning increments the pin count, and the thread remains pinned until all cloned guards
    /// are dropped. This allows multiple scopes to hold pins simultaneously.
    ///
    /// 克隆此守卫以创建嵌套 pin。
    ///
    /// 克隆会增加 pin 计数,线程保持被钉住直到所有克隆的守卫被 drop。
    /// 这允许多个作用域同时持有 pin。
    #[inline]
    fn clone(&self) -> Self {
        let pin_count = self.local.pin_count.get();

        assert!(
            pin_count > 0,
            "BUG: Cloning a PinGuard in an unpinned state (pin_count = 0). \
             This indicates incorrect API usage or a library bug."
        );

        self.local.pin_count.set(pin_count + 1);

        PinGuard {
            local: self.local,
            ptr: self.ptr,
            version: self.version,
        }
    }
}

impl<'a, T, const RP: bool> Drop for PinGuard<'a, T, RP> {
    #[inline]
    fn drop(&mut self) {
        let pin_count = self.local.pin_count.get();

        assert!(
            pin_count > 0,
            "BUG: Dropping a PinGuard in an unpinned state (pin_count = 0). \
             This indicates incorrect API usage or a library bug."
        );

        if pin_count == 1 {
            self.local
                .slot
                .active_version
                .store(INACTIVE_VERSION, Ordering::Release);
        }

        self.local.pin_count.set(pin_count - 1);
    }
}

impl<T: 'static, const RP: bool> AsRef<T> for PinGuard<'_, T, RP> {
    #[inline]
    fn as_ref(&self) -> &T {
        self.deref()
    }
}

// ============================================================================
// Standard Trait Implementations
// 标准 trait 实现
// ============================================================================

impl<T: Default + 'static, const RP: bool> Default for SwmrCell<T, RP> {
    /// Create a new SWMR cell with the default value.
    ///
    /// 使用默认值创建一个新的 SWMR 单元。
    #[inline]
    fn default() -> Self {
        SwmrCell::from(T::default())
    }
}

impl<T: 'static, const RP: bool> From<T> for SwmrCell<T, RP> {
    /// Create a new SWMR cell from a value.
    ///
    /// 从一个值创建一个新的 SWMR 单元。
    #[inline]
    fn from(value: T) -> Self {
        SwmrCellBuilder::default().build(value)
    }
}

impl<T: fmt::Debug + 'static, const RP: bool> fmt::Debug for SwmrCell<T, RP> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("SwmrCell")
            .field("value", self.get())
            .field("version", &self.version())
            .field("garbage_count", &self.garbage_count())
            .field("reclaim_threshold", &self.auto_reclaim_threshold)
            .field("is_read-preferred", &RP)
            .finish()
    }
}

impl<T: 'static, const RP: bool> fmt::Debug for LocalReader<T, RP> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("LocalReader")
            .field("is_pinned", &self.is_pinned())
            .field("version", &self.version())
            .field("is_read-preferred", &RP)
            .finish()
    }
}

impl<T: fmt::Debug + 'static, const RP: bool> fmt::Debug for PinGuard<'_, T, RP> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("PinGuard")
            .field("value", &self.deref())
            .field("version", &self.version)
            .field("is_read-preferred", &RP)
            .finish()
    }
}