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(crate) fn reads_into(&self, observer: &ReadObserver) -> bool {
76 self.state
77 .read_observer
78 .borrow()
79 .as_ref()
80 .is_some_and(|installed| Arc::ptr_eq(installed, observer))
81 }
82
83 pub fn set_read_observer(&self, observer: Option<ReadObserver>) {
85 assert!(
86 self.can_reuse(),
87 "Cannot change observers on non-reusable snapshot"
88 );
89 *self.state.read_observer.borrow_mut() = observer;
90 }
91
92 pub fn set_write_observer(&self, observer: Option<WriteObserver>) {
94 assert!(
95 self.can_reuse(),
96 "Cannot change observers on non-reusable snapshot"
97 );
98 *self.state.write_observer.borrow_mut() = observer;
99 }
100
101 pub fn snapshot_id(&self) -> SnapshotId {
102 self.state.id.get()
103 }
104
105 pub fn invalid(&self) -> SnapshotIdSet {
106 self.state.invalid.borrow().clone()
107 }
108
109 pub fn read_only(&self) -> bool {
110 false
111 }
112
113 pub fn root_transparent_mutable(self: &Arc<Self>) -> Arc<Self> {
114 match &self.parent {
115 Some(weak) => weak
116 .upgrade()
117 .map_or_else(|| self.clone(), |parent| parent.root_transparent_mutable()),
118 None => self.clone(),
119 }
120 }
121
122 pub fn enter<T>(self: &Arc<Self>, f: impl FnOnce() -> T) -> T {
123 let prev = current_snapshot();
124
125 if let Some(ref snapshot) = prev
126 && snapshot.is_same_transparent(self)
127 {
128 return f();
129 }
130
131 enter_snapshot_scope(AnySnapshot::TransparentMutable(self.clone()), f)
132 }
133
134 pub fn take_nested_snapshot(
135 &self,
136 read_observer: Option<ReadObserver>,
137 ) -> Arc<ReadonlySnapshot> {
138 let merged_observer =
139 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
140 ReadonlySnapshot::new(
141 self.state.id.get(),
142 self.state.invalid.borrow().clone(),
143 merged_observer,
144 )
145 }
146
147 pub fn has_pending_changes(&self) -> bool {
148 !self.state.modified.borrow().is_empty()
149 }
150
151 pub fn dispose(&self) {
152 if !self.state.disposed.get() && self.nested_count.get() == 0 {
153 self.state.dispose();
154 }
155 }
156
157 pub fn record_read(&self, state: &dyn StateObject) {
158 self.state.record_read(state);
159 }
160
161 pub fn record_write(&self, state: Arc<dyn StateObject>) {
162 assert!(!self.applied.get(), "Cannot write to an applied snapshot");
163 self.state.record_write(state, self.state.id.get());
164 }
165
166 pub fn close(&self) {
167 self.state.disposed.set(true);
168 }
169
170 pub fn is_disposed(&self) -> bool {
171 self.state.disposed.get()
172 }
173
174 pub fn apply(&self) -> SnapshotApplyResult {
175 if self.state.disposed.get() || self.applied.get() {
176 return SnapshotApplyResult::Failure;
177 }
178
179 self.applied.set(true);
180 SnapshotApplyResult::Success
181 }
182
183 pub fn take_nested_mutable_snapshot(
184 &self,
185 read_observer: Option<ReadObserver>,
186 write_observer: Option<WriteObserver>,
187 ) -> Arc<TransparentObserverMutableSnapshot> {
188 let merged_read =
189 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
190 let merged_write =
191 merge_write_observers(write_observer, self.state.write_observer.borrow().clone());
192
193 let mut invalid = self.state.invalid.borrow().clone();
194 let new_id = self.state.id.get() + 1;
195 invalid = invalid.set(new_id);
196
197 TransparentObserverMutableSnapshot::new(
198 new_id,
199 invalid,
200 merged_read,
201 merged_write,
202 self.parent.clone(),
203 )
204 }
205}
206
207pub struct TransparentObserverSnapshot {
216 state: SnapshotState,
217 parent: Option<Weak<TransparentObserverSnapshot>>,
218 reusable: Cell<bool>,
219}
220
221impl TransparentObserverSnapshot {
222 pub fn new(
223 id: SnapshotId,
224 invalid: SnapshotIdSet,
225 read_observer: Option<ReadObserver>,
226 parent: Option<Weak<TransparentObserverSnapshot>>,
227 ) -> Arc<Self> {
228 Arc::new(Self {
229 state: SnapshotState::new_with_pinning(id, invalid, read_observer, None, false, false),
230 parent,
231 reusable: Cell::new(true),
232 })
233 }
234
235 pub fn can_reuse(&self) -> bool {
237 self.reusable.get()
238 }
239
240 pub fn set_read_observer(&self, observer: Option<ReadObserver>) {
242 assert!(
243 self.can_reuse(),
244 "Cannot change observers on non-reusable snapshot"
245 );
246 *self.state.read_observer.borrow_mut() = observer;
247 }
248
249 pub fn snapshot_id(&self) -> SnapshotId {
250 self.state.id.get()
251 }
252
253 pub fn invalid(&self) -> SnapshotIdSet {
254 self.state.invalid.borrow().clone()
255 }
256
257 pub fn read_only(&self) -> bool {
258 true
259 }
260
261 pub fn root_transparent_readonly(self: &Arc<Self>) -> Arc<Self> {
262 match &self.parent {
263 Some(weak) => weak
264 .upgrade()
265 .map_or_else(|| self.clone(), |parent| parent.root_transparent_readonly()),
266 None => self.clone(),
267 }
268 }
269
270 pub fn enter<T>(self: &Arc<Self>, f: impl FnOnce() -> T) -> T {
271 let previous = current_snapshot();
272
273 if let Some(ref prev_snapshot) = previous
274 && prev_snapshot.is_same_transparent_readonly(self)
275 {
276 return f();
277 }
278
279 enter_snapshot_scope(AnySnapshot::TransparentReadonly(self.clone()), f)
280 }
281
282 pub fn take_nested_snapshot(
283 &self,
284 read_observer: Option<ReadObserver>,
285 ) -> Arc<TransparentObserverSnapshot> {
286 let merged_observer =
287 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
288 TransparentObserverSnapshot::new(
289 self.state.id.get(),
290 self.state.invalid.borrow().clone(),
291 merged_observer,
292 self.parent.clone(),
293 )
294 }
295
296 pub fn has_pending_changes(&self) -> bool {
297 false
298 }
299
300 pub fn dispose(&self) {
301 self.state.dispose();
302 }
303
304 pub fn record_read(&self, state: &dyn StateObject) {
305 self.state.record_read(state);
306 }
307
308 pub fn record_write(&self, _state: Arc<dyn StateObject>) {
309 panic!("Cannot write to a read-only snapshot");
310 }
311
312 pub fn close(&self) {
313 self.state.disposed.set(true);
314 }
315
316 pub fn is_disposed(&self) -> bool {
317 self.state.disposed.get()
318 }
319}
320
321#[cfg(test)]
322#[path = "tests/transparent_tests.rs"]
323mod tests;