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
use ArcSwap;
use PhantomData;
use ;
use Arc;
use AtomicUsize;
/// Asynchronous API
/// Synchronous API
pub use crate*;
/// A versioned lock implementation inspired by Multi-Version Concurrency Control (MVCC).
///
/// `SnapshotLock` provides concurrent access to data with lock-free reads and exclusive writes.
/// It maintains multiple versions of the data to allow readers to access consistent
/// snapshots without blocking writers.
///
/// # Type Parameters
///
/// - `T`: The type of data being protected. Must be `Clone`. Surrounding lock is `Send` and `Sync` if `T` is `Send`
///
/// # Examples
///
/// ```
/// use snaplock::SnapshotLock;
///
/// let lock = SnapshotLock::new(String::from("Hello"));
///
/// // Multiple readers can access the data concurrently
/// let reader1 = lock.read();
/// let reader2 = lock.read();
/// assert_eq!(*reader1, "Hello");
/// assert_eq!(*reader2, "Hello");
///
/// // Writers have exclusive access
/// let mut writer = lock.write();
/// writer.push_str(", World!");
///
/// // During write readers see old values
/// let reader3 = lock.read();
/// assert_eq!(*reader3, "Hello");
/// drop(writer);
///
/// // When write is finished, new readers see the updated value
/// let reader4 = lock.read();
/// assert_eq!(*reader4, "Hello, World!");
///
/// // Old readers still see their old value
/// assert_eq!(*reader1, "Hello");
/// assert_eq!(*reader2, "Hello");
/// assert_eq!(*reader3, "Hello");
/// ```
/// A read guard that provides immutable access to a snapshot of `SnapshotLock` data.
///
/// This guard holds a shared reference to the data and ensures that the
/// snapshot remains consistent throughout its lifetime. Multiple read guards
/// can exist concurrently without blocking each other.
///
/// # Type Parameters
///
/// - `T`: The type of data being accessed.
///
/// # Examples
///
/// ```
/// # use snaplock::SnapshotLock;
/// let lock = SnapshotLock::new(100);
/// let guard = lock.read();
/// assert_eq!(*guard, 100);
/// ```
;
/// A write guard that provides exclusive mutable access to `SnapshotLock` data.
///
/// This guard holds an exclusive lock on the data and allows modifications.
/// When the guard is dropped, the version number is incremented and the
/// changes become visible to subsequent readers.
///
/// # Type Parameters
///
/// - `T`: The type of data being modified.
/// - `'a`: The lifetime of the lock guard.
///
/// # Examples
///
/// ```
/// # use snaplock::SnapshotLock;
/// let lock = SnapshotLock::new(vec![1, 2, 3]);
/// {
/// let mut guard = lock.write();
/// guard.push(4);
/// } // Changes are committed and version incremented when guard is dropped
/// let reader = lock.read();
/// assert_eq!(*reader, vec![1, 2, 3, 4]);
/// ```
;