lfrlock 0.3.0

A Lock-Free Read Lock where reads never block and writes are serialized using Mutex
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
#![cfg_attr(not(feature = "std"), no_std)]

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

use core::fmt;
use core::mem::ManuallyDrop;
use core::ops::{Deref, DerefMut};
use smr_swap::{LocalReader, ReadGuard, ReaderFactory as SmrReader, SmrSwap};

#[cfg(feature = "std")]
use std::sync::Arc;

#[cfg(not(feature = "std"))]
use alloc::sync::Arc;

/// LfrLock (Lock-Free Read Lock) - Reads never block, writes are serialized using Mutex
///
/// Similar to `std::sync::Mutex`, a unified type supports both read and write operations.
/// Core features: Read operations are lock-free and never block; write operations involve copying old data, modifying, and then atomically replacing.
///
/// LfrLock (Lock-Free Read Lock) - 读取永不阻塞,写入使用 Mutex 串行化
///
/// 类似于 `std::sync::Mutex`,统一的类型同时支持读写操作。
/// 核心特性:读取操作无锁且永不阻塞;写入操作涉及复制旧数据、修改、然后原子替换。
pub struct LfrLock<T: 'static, const RP: bool = false> {
    swap: Arc<Mutex<SmrSwap<T, RP>>>,
    local: LocalReader<T, RP>,
}

impl<T: 'static> LfrLock<T, false> {
    /// Create a new LfrLock
    ///
    /// 创建新的 LfrLock
    #[inline]
    pub fn new(initial: T) -> Self {
        let swap = SmrSwap::new(initial);
        let local = swap.local_reader();

        LfrLock {
            swap: Arc::new(Mutex::new(swap)),
            local,
        }
    }
}

impl<T: 'static> LfrLock<T, true> {
    /// Create a new LfrLock with Read-Preferred optimization.
    ///
    /// 使用读优先优化创建新的 LfrLock。
    #[inline]
    pub fn new_read_preferred(initial: T) -> Self {
        let swap = SmrSwap::new_read_preferred(initial);
        let local = swap.local_reader();

        LfrLock {
            swap: Arc::new(Mutex::new(swap)),
            local,
        }
    }
}

impl<T: 'static, const RP: bool> LfrLock<T, RP> {
    /// Store a new value, making it visible to readers.
    ///
    /// The old value is retired and will be garbage collected when safe.
    ///
    /// 存储新值,使其对读者可见。
    ///
    /// 旧值已退休,将在安全时被垃圾回收。
    #[inline]
    pub fn store(&self, new_value: T) {
        let mut swap = self.swap.lock();
        swap.store(new_value);
    }

    /// Atomically swap the current value with a new one.
    ///
    /// Returns the old value.
    ///
    /// 原子地将当前值与新值交换。
    ///
    /// 返回旧的值。
    #[inline]
    pub fn swap(&self, new_value: T) -> T
    where
        T: Clone,
    {
        self.swap.lock().swap(new_value)
    }

    /// Update the value using a closure.
    ///
    /// The closure receives the current value and should return the new value.
    ///
    /// 使用闭包更新值。
    ///
    /// 闭包接收当前值并应返回新值。
    #[inline]
    pub fn update<F>(&self, f: F)
    where
        F: FnOnce(&T) -> T,
    {
        self.swap.lock().update(f);
    }

    /// Apply a closure function to the current value and return a guard to the new value.
    ///
    /// The closure receives a reference to the current value and returns a new value.
    ///
    /// 对当前值应用闭包函数并返回新值的守卫。
    ///
    /// 闭包接收当前值的引用,返回新值。
    #[inline]
    pub fn update_and_fetch<F>(&self, f: F) -> ReadGuard<'_, T, RP>
    where
        F: FnOnce(&T) -> T,
    {
        self.swap.lock().update(f);
        self.local.load()
    }

    /// Apply a closure function to the current value and return a guard to the old value.
    ///
    /// The closure receives the current value and should return the new value.
    /// Returns a guard to the old value (before update).
    ///
    /// 对当前值应用闭包函数并返回旧值的守卫。
    ///
    /// 闭包接收当前值并应返回新值。
    /// 返回旧值(更新前)的守卫。
    #[inline]
    pub fn fetch_and_update<F>(&self, f: F) -> ReadGuard<'_, T, RP>
    where
        F: FnOnce(&T) -> T,
    {
        let old_guard = self.local.load();
        self.swap.lock().update(f);
        old_guard
    }

    /// Apply a closure function to the current value and transform the result.
    ///
    /// This method reads the current value, applies the closure to transform it,
    /// and returns the transformed result.
    ///
    /// 对当前值应用闭包函数并转换结果。
    ///
    /// 这个方法读取当前值,应用闭包进行转换,并返回转换后的结果。
    #[inline]
    pub fn map<F, U>(&self, f: F) -> U
    where
        F: FnOnce(&T) -> U,
    {
        let guard = self.local.load();
        f(&*guard)
    }

    /// Apply a closure function to the current value, returning Some if the closure returns true.
    ///
    /// 对当前值应用闭包函数,如果闭包返回 true 则返回 Some。
    #[inline]
    pub fn filter<F>(&self, f: F) -> Option<ReadGuard<'_, T, RP>>
    where
        F: FnOnce(&T) -> bool,
    {
        let guard = self.local.load();
        if f(&*guard) { Some(guard) } else { None }
    }

    /// Get the current value by cloning.
    ///
    /// 通过克隆获取当前值。
    #[inline]
    pub fn get(&self) -> T
    where
        T: Clone,
    {
        (*self.local.load()).clone()
    }

    /// Write operation (Guard style) - Requires T to implement Clone
    ///
    /// Returns WriteGuard, allowing direct data modification, automatically committed on drop.
    /// Acquires Mutex lock to ensure serialized writes.
    ///
    /// 写入操作(Guard 方式)- 需要 T 实现 Clone
    ///
    /// 返回 WriteGuard,允许直接修改数据,在 drop 时自动提交。
    /// 获取 Mutex 锁,确保串行化写入。
    #[inline]
    pub fn write(&self) -> WriteGuard<'_, T, RP>
    where
        T: Clone,
    {
        WriteGuard::new(self)
    }

    /// Try to acquire write lock
    ///
    /// 尝试获取写入锁
    #[inline]
    pub fn try_write(&self) -> Option<WriteGuard<'_, T, RP>>
    where
        T: Clone,
    {
        let swap_guard = self.swap.try_lock().ok()?;

        let guard = self.local.load();
        let data = (*guard).clone();

        Some(WriteGuard {
            swap_guard,
            data: ManuallyDrop::new(data),
        })
    }

    /// Read data - never blocks
    ///
    /// 读取数据 - 永不阻塞
    #[inline]
    pub fn read(&self) -> ReadGuard<'_, T, RP> {
        self.local.load()
    }

    /// Create a factory for creating new `LfrLock` instances.
    ///
    /// The returned factory is `Sync` + `Clone` and can be shared across threads.
    ///
    /// 创建用于创建新 `LfrLock` 实例的工厂。
    ///
    /// 返回的工厂是 `Sync` + `Clone` 的,可以在线程之间共享。
    #[inline]
    pub fn factory(&self) -> LfrLockFactory<T, RP> {
        LfrLockFactory {
            swap: self.swap.clone(),
            reader: self.local.reader_factory(),
        }
    }
}

impl<T: Default + 'static> Default for LfrLock<T, false> {
    /// Create a new LfrLock with the default value.
    ///
    /// 使用默认值创建一个新的 LfrLock。
    #[inline]
    fn default() -> Self {
        Self::new(T::default())
    }
}

impl<T: 'static> From<T> for LfrLock<T, false> {
    /// Create a new LfrLock from a value.
    ///
    /// 从一个值创建一个新的 LfrLock。
    #[inline]
    fn from(value: T) -> Self {
        Self::new(value)
    }
}

impl<T: fmt::Debug + 'static, const RP: bool> fmt::Debug for LfrLock<T, RP> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let data = self.read();
        f.debug_struct("LfrLock").field("data", &*data).finish()
    }
}

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

/// Write Guard - Provides direct mutable access, automatically commits changes on Drop
/// Holds Mutex lock to ensure exclusive write access
///
/// 写入保护器 - 提供直接的可变访问,在 Drop 时自动提交更改
/// 持有 Mutex 锁,确保独占写入访问
pub struct WriteGuard<'a, T: 'static, const RP: bool = false> {
    swap_guard: MutexGuard<'a, SmrSwap<T, RP>>,
    data: ManuallyDrop<T>,
}

impl<'a, T: 'static + Clone, const RP: bool> WriteGuard<'a, T, RP> {
    #[inline]
    fn new(lock: &'a LfrLock<T, RP>) -> Self {
        // 获取 Mutex 锁
        let swap_guard = lock.swap.lock();

        let guard = lock.local.load();
        let data = (*guard).clone();

        WriteGuard {
            swap_guard,
            data: ManuallyDrop::new(data),
        }
    }
}

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

    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.data
    }
}

impl<'a, T: 'static, const RP: bool> DerefMut for WriteGuard<'a, T, RP> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.data
    }
}

impl<'a, T: 'static, const RP: bool> Drop for WriteGuard<'a, T, RP> {
    #[inline]
    fn drop(&mut self) {
        // Take data from ManuallyDrop
        // 从 ManuallyDrop 中取出数据
        let new_data = unsafe { ManuallyDrop::take(&mut self.data) };

        // Execute state swap
        // 执行状态切换
        self.swap_guard.store(new_data);
    }
}

/// Factory for creating `LfrLock` instances.
///
/// This factory is `Sync` + `Clone` and can be shared across threads.
/// It allows creating new `LfrLock` instances for the current thread.
///
/// 用于创建 `LfrLock` 实例的工厂。
///
/// 该工厂是 `Sync` + `Clone` 的,可以在线程之间共享。
/// 它允许为当前线程创建新的 `LfrLock` 实例。
pub struct LfrLockFactory<T: 'static, const RP: bool = false> {
    swap: Arc<Mutex<SmrSwap<T, RP>>>,
    reader: SmrReader<T, RP>,
}

impl<T: 'static> LfrLockFactory<T, false> {
    /// Create a new factory with the initial value.
    ///
    /// 使用初始值创建一个新工厂。
    #[inline]
    pub fn new(initial: T) -> Self {
        let swap = SmrSwap::new(initial);
        let reader = swap.reader_factory();
        Self {
            swap: Arc::new(Mutex::new(swap)),
            reader,
        }
    }
}

impl<T: 'static, const RP: bool> LfrLockFactory<T, RP> {
    /// Create a new lock instance for the current thread.
    ///
    /// 为当前线程创建一个新的锁实例。
    #[inline]
    pub fn create(&self) -> LfrLock<T, RP> {
        LfrLock {
            swap: self.swap.clone(),
            local: self.reader.local_reader(),
        }
    }
}

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

#[cfg(feature = "parking_lot")]
mod lock_impl {
    use core::ops::{Deref, DerefMut};

    /// `parking_lot::Mutex` wrapper to match API.
    pub struct Mutex<T: ?Sized>(parking_lot::Mutex<T>);

    impl<T> Mutex<T> {
        /// Like `parking_lot::Mutex::new`.
        #[inline]
        pub fn new(t: T) -> Mutex<T> {
            Mutex(parking_lot::Mutex::new(t))
        }
    }

    impl<T: ?Sized> Mutex<T> {
        /// Like `parking_lot::Mutex::lock`.
        #[inline]
        pub fn lock(&self) -> MutexGuard<'_, T> {
            MutexGuard(self.0.lock())
        }

        /// Like `parking_lot::Mutex::try_lock`.
        #[inline]
        pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
            match self.0.try_lock() {
                Some(guard) => Ok(MutexGuard(guard)),
                None => Err(TryLockError(())),
            }
        }
    }

    /// Like `parking_lot::MutexGuard`.
    #[must_use]
    pub struct MutexGuard<'a, T: ?Sized + 'a>(parking_lot::MutexGuard<'a, T>);

    impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
        type Target = T;

        #[inline]
        fn deref(&self) -> &T {
            &*self.0
        }
    }

    impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
        #[inline]
        fn deref_mut(&mut self) -> &mut T {
            &mut *self.0
        }
    }

    /// Result type for [Mutex::try_lock].
    pub type TryLockResult<T> = Result<T, TryLockError>;

    /// Error returned by [Mutex::try_lock].
    #[derive(Debug)]
    pub struct TryLockError(());
}

#[cfg(all(feature = "std", not(feature = "parking_lot")))]
mod lock_impl {
    use std::ops::{Deref, DerefMut};

    /// Like `std::sync::Mutex` except that it does not poison itself.
    pub struct Mutex<T: ?Sized>(std::sync::Mutex<T>);

    impl<T> Mutex<T> {
        /// Like `std::sync::Mutex::new`.
        #[inline]
        pub fn new(t: T) -> Mutex<T> {
            Mutex(std::sync::Mutex::new(t))
        }
    }

    impl<T: ?Sized> Mutex<T> {
        /// Like `std::sync::Mutex::lock`.
        #[inline]
        pub fn lock<'a>(&'a self) -> MutexGuard<'a, T> {
            MutexGuard(self.0.lock().unwrap_or_else(|e| e.into_inner()))
        }

        /// Like `std::sync::Mutex::try_lock`.
        #[inline]
        pub fn try_lock<'a>(&'a self) -> TryLockResult<MutexGuard<'a, T>> {
            match self.0.try_lock() {
                Ok(t) => Ok(MutexGuard(t)),
                Err(std::sync::TryLockError::Poisoned(e)) => Ok(MutexGuard(e.into_inner())),
                Err(std::sync::TryLockError::WouldBlock) => Err(TryLockError(())),
            }
        }
    }

    /// Like `std::sync::MutexGuard`.
    #[must_use]
    pub struct MutexGuard<'a, T: ?Sized + 'a>(std::sync::MutexGuard<'a, T>);

    impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
        type Target = T;

        #[inline]
        fn deref(&self) -> &T {
            self.0.deref()
        }
    }

    impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
        #[inline]
        fn deref_mut(&mut self) -> &mut T {
            self.0.deref_mut()
        }
    }

    /// Like `std::sync::TryLockResult`.
    pub type TryLockResult<T> = Result<T, TryLockError>;

    /// Like `std::sync::TryLockError`.
    #[derive(Debug)]
    pub struct TryLockError(());
}

#[cfg(all(not(feature = "std"), not(feature = "parking_lot")))]
mod lock_impl {
    use core::ops::{Deref, DerefMut};

    /// `spin::Mutex` wrapper to match `std::sync::Mutex` API.
    pub struct Mutex<T: ?Sized>(spin::Mutex<T>);

    impl<T> Mutex<T> {
        #[inline]
        pub fn new(t: T) -> Mutex<T> {
            Mutex(spin::Mutex::new(t))
        }
    }

    impl<T: ?Sized> Mutex<T> {
        #[inline]
        pub fn lock(&self) -> MutexGuard<'_, T> {
            MutexGuard(self.0.lock())
        }

        #[inline]
        pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
            match self.0.try_lock() {
                Some(guard) => Ok(MutexGuard(guard)),
                None => Err(TryLockError(())),
            }
        }
    }

    #[must_use]
    pub struct MutexGuard<'a, T: ?Sized + 'a>(spin::MutexGuard<'a, T>);

    impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
        type Target = T;

        #[inline]
        fn deref(&self) -> &T {
            &*self.0
        }
    }

    impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
        #[inline]
        fn deref_mut(&mut self) -> &mut T {
            &mut *self.0
        }
    }

    pub type TryLockResult<T> = Result<T, TryLockError>;

    #[derive(Debug)]
    pub struct TryLockError(());
}

use lock_impl::*;