cranpose_core/snapshot_v2/
transparent.rs1use super::*;
2
3pub struct TransparentObserverMutableSnapshot {
13 state: SnapshotState,
14 parent: Option<Weak<TransparentObserverMutableSnapshot>>,
15 nested_count: Cell<usize>,
16 applied: Cell<bool>,
17 reusable: Cell<bool>,
18}
19
20impl TransparentObserverMutableSnapshot {
21 pub fn new(
22 id: SnapshotId,
23 invalid: SnapshotIdSet,
24 read_observer: Option<ReadObserver>,
25 write_observer: Option<WriteObserver>,
26 parent: Option<Weak<TransparentObserverMutableSnapshot>>,
27 ) -> Arc<Self> {
28 Self::new_reusing(None, id, invalid, read_observer, write_observer, parent)
29 }
30
31 pub(crate) fn new_reusing(
32 recycled: Option<Arc<Self>>,
33 id: SnapshotId,
34 invalid: SnapshotIdSet,
35 read_observer: Option<ReadObserver>,
36 write_observer: Option<WriteObserver>,
37 parent: Option<Weak<Self>>,
38 ) -> Arc<Self> {
39 let fresh = Self {
40 state: SnapshotState::new_with_pinning(
41 id,
42 invalid,
43 read_observer,
44 write_observer,
45 false,
46 false,
47 ),
48 parent,
49 nested_count: Cell::new(0),
50 applied: Cell::new(false),
51 reusable: Cell::new(true),
52 };
53 if let Some(mut recycled) = recycled
54 && let Some(target) = Arc::get_mut(&mut recycled)
55 {
56 *target = fresh;
57 recycled
58 } else {
59 Arc::new(fresh)
60 }
61 }
62
63 pub fn can_reuse(&self) -> bool {
65 self.reusable.get()
66 }
67
68 pub(crate) fn observers(&self) -> (Option<ReadObserver>, Option<WriteObserver>) {
69 (
70 self.state.read_observer.borrow().clone(),
71 self.state.write_observer.borrow().clone(),
72 )
73 }
74
75 pub fn set_read_observer(&self, observer: Option<ReadObserver>) {
77 assert!(
78 self.can_reuse(),
79 "Cannot change observers on non-reusable snapshot"
80 );
81 *self.state.read_observer.borrow_mut() = observer;
82 }
83
84 pub fn set_write_observer(&self, observer: Option<WriteObserver>) {
86 assert!(
87 self.can_reuse(),
88 "Cannot change observers on non-reusable snapshot"
89 );
90 *self.state.write_observer.borrow_mut() = observer;
91 }
92
93 pub fn snapshot_id(&self) -> SnapshotId {
94 self.state.id.get()
95 }
96
97 pub fn invalid(&self) -> SnapshotIdSet {
98 self.state.invalid.borrow().clone()
99 }
100
101 pub fn read_only(&self) -> bool {
102 false
103 }
104
105 pub fn root_transparent_mutable(self: &Arc<Self>) -> Arc<Self> {
106 match &self.parent {
107 Some(weak) => weak
108 .upgrade()
109 .map_or_else(|| self.clone(), |parent| parent.root_transparent_mutable()),
110 None => self.clone(),
111 }
112 }
113
114 pub fn enter<T>(self: &Arc<Self>, f: impl FnOnce() -> T) -> T {
115 let prev = current_snapshot();
116
117 if let Some(ref snapshot) = prev
118 && snapshot.is_same_transparent(self)
119 {
120 return f();
121 }
122
123 enter_snapshot_scope(AnySnapshot::TransparentMutable(self.clone()), f)
124 }
125
126 pub fn take_nested_snapshot(
127 &self,
128 read_observer: Option<ReadObserver>,
129 ) -> Arc<ReadonlySnapshot> {
130 let merged_observer =
131 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
132 ReadonlySnapshot::new(
133 self.state.id.get(),
134 self.state.invalid.borrow().clone(),
135 merged_observer,
136 )
137 }
138
139 pub fn has_pending_changes(&self) -> bool {
140 !self.state.modified.borrow().is_empty()
141 }
142
143 pub fn dispose(&self) {
144 if !self.state.disposed.get() && self.nested_count.get() == 0 {
145 self.state.dispose();
146 }
147 }
148
149 pub fn record_read(&self, state: &dyn StateObject) {
150 self.state.record_read(state);
151 }
152
153 pub fn record_write(&self, state: Arc<dyn StateObject>) {
154 assert!(!self.applied.get(), "Cannot write to an applied snapshot");
155 self.state.record_write(state, self.state.id.get());
156 }
157
158 pub fn close(&self) {
159 self.state.disposed.set(true);
160 }
161
162 pub fn is_disposed(&self) -> bool {
163 self.state.disposed.get()
164 }
165
166 pub fn apply(&self) -> SnapshotApplyResult {
167 if self.state.disposed.get() || self.applied.get() {
168 return SnapshotApplyResult::Failure;
169 }
170
171 self.applied.set(true);
172 SnapshotApplyResult::Success
173 }
174
175 pub fn take_nested_mutable_snapshot(
176 &self,
177 read_observer: Option<ReadObserver>,
178 write_observer: Option<WriteObserver>,
179 ) -> Arc<TransparentObserverMutableSnapshot> {
180 let merged_read =
181 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
182 let merged_write =
183 merge_write_observers(write_observer, self.state.write_observer.borrow().clone());
184
185 let mut invalid = self.state.invalid.borrow().clone();
186 let new_id = self.state.id.get() + 1;
187 invalid = invalid.set(new_id);
188
189 TransparentObserverMutableSnapshot::new(
190 new_id,
191 invalid,
192 merged_read,
193 merged_write,
194 self.parent.clone(),
195 )
196 }
197}
198
199pub struct TransparentObserverSnapshot {
208 state: SnapshotState,
209 parent: Option<Weak<TransparentObserverSnapshot>>,
210 reusable: Cell<bool>,
211}
212
213impl TransparentObserverSnapshot {
214 pub fn new(
215 id: SnapshotId,
216 invalid: SnapshotIdSet,
217 read_observer: Option<ReadObserver>,
218 parent: Option<Weak<TransparentObserverSnapshot>>,
219 ) -> Arc<Self> {
220 Arc::new(Self {
221 state: SnapshotState::new_with_pinning(id, invalid, read_observer, None, false, false),
222 parent,
223 reusable: Cell::new(true),
224 })
225 }
226
227 pub fn can_reuse(&self) -> bool {
229 self.reusable.get()
230 }
231
232 pub fn set_read_observer(&self, observer: Option<ReadObserver>) {
234 assert!(
235 self.can_reuse(),
236 "Cannot change observers on non-reusable snapshot"
237 );
238 *self.state.read_observer.borrow_mut() = observer;
239 }
240
241 pub fn snapshot_id(&self) -> SnapshotId {
242 self.state.id.get()
243 }
244
245 pub fn invalid(&self) -> SnapshotIdSet {
246 self.state.invalid.borrow().clone()
247 }
248
249 pub fn read_only(&self) -> bool {
250 true
251 }
252
253 pub fn root_transparent_readonly(self: &Arc<Self>) -> Arc<Self> {
254 match &self.parent {
255 Some(weak) => weak
256 .upgrade()
257 .map_or_else(|| self.clone(), |parent| parent.root_transparent_readonly()),
258 None => self.clone(),
259 }
260 }
261
262 pub fn enter<T>(self: &Arc<Self>, f: impl FnOnce() -> T) -> T {
263 let previous = current_snapshot();
264
265 if let Some(ref prev_snapshot) = previous
266 && prev_snapshot.is_same_transparent_readonly(self)
267 {
268 return f();
269 }
270
271 enter_snapshot_scope(AnySnapshot::TransparentReadonly(self.clone()), f)
272 }
273
274 pub fn take_nested_snapshot(
275 &self,
276 read_observer: Option<ReadObserver>,
277 ) -> Arc<TransparentObserverSnapshot> {
278 let merged_observer =
279 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
280 TransparentObserverSnapshot::new(
281 self.state.id.get(),
282 self.state.invalid.borrow().clone(),
283 merged_observer,
284 self.parent.clone(),
285 )
286 }
287
288 pub fn has_pending_changes(&self) -> bool {
289 false
290 }
291
292 pub fn dispose(&self) {
293 self.state.dispose();
294 }
295
296 pub fn record_read(&self, state: &dyn StateObject) {
297 self.state.record_read(state);
298 }
299
300 pub fn record_write(&self, _state: Arc<dyn StateObject>) {
301 panic!("Cannot write to a read-only snapshot");
302 }
303
304 pub fn close(&self) {
305 self.state.disposed.set(true);
306 }
307
308 pub fn is_disposed(&self) -> bool {
309 self.state.disposed.get()
310 }
311}
312
313#[cfg(test)]
314#[path = "tests/transparent_tests.rs"]
315mod tests;