sim_lib_mutation/managed/
object.rs1#[derive(Clone, Debug, Eq, PartialEq)]
7pub struct ManagedNode<R> {
8 role: ManagedRole<R>,
9 edges: EdgeAllocator,
10 limits: EdgeLimits,
11 strong: BTreeMap<EdgeId, ManagedId>,
12 weak: BTreeMap<EdgeId, ManagedId>,
13 ephemerons: BTreeMap<EdgeId, (ManagedId, ManagedId)>,
14}
15pub trait RoleBearingManagedObject: ManagedObject {
17 type Role;
19 fn managed_role(&self) -> &Self::Role;
21 fn replace_managed_role(&mut self, role: Self::Role) -> Self::Role;
23}
24
25impl<R> ManagedNode<R> {
26 pub const fn new(role: R) -> Self {
28 Self::with_edge_limits(role, EdgeLimits::DEFAULT)
29 }
30
31 pub const fn with_edge_limits(role: R, limits: EdgeLimits) -> Self {
33 Self {
34 role: ManagedRole::new(role),
35 edges: EdgeAllocator::new(),
36 limits,
37 strong: BTreeMap::new(),
38 weak: BTreeMap::new(),
39 ephemerons: BTreeMap::new(),
40 }
41 }
42
43 pub fn edge_snapshot(&self) -> Vec<EdgeSnapshot> {
45 let mut result = self
46 .strong
47 .iter()
48 .map(|(&edge, &target)| EdgeSnapshot::Strong { edge, target })
49 .chain(
50 self.weak
51 .iter()
52 .map(|(&edge, &target)| EdgeSnapshot::Weak { edge, target }),
53 )
54 .chain(
55 self.ephemerons
56 .iter()
57 .map(|(&edge, &(key, value))| EdgeSnapshot::Ephemeron { edge, key, value }),
58 )
59 .collect::<Vec<_>>();
60 result.sort_unstable_by_key(|entry| entry.id());
61 result
62 }
63
64 fn edge_kind(&self, edge: EdgeId) -> Option<EdgeKind> {
65 self.strong
66 .contains_key(&edge)
67 .then_some(EdgeKind::Strong)
68 .or_else(|| self.weak.contains_key(&edge).then_some(EdgeKind::Weak))
69 .or_else(|| {
70 self.ephemerons
71 .contains_key(&edge)
72 .then_some(EdgeKind::Ephemeron)
73 })
74 }
75
76 fn admit(&self, kind: EdgeKind) -> Result<(), EdgeAllocationError> {
77 let total = self.strong.len() + self.weak.len() + self.ephemerons.len();
78 if total >= self.limits.total() {
79 return Err(EdgeAllocationError::CapacityExceeded {
80 kind,
81 cap: self.limits.total(),
82 });
83 }
84 let count = match kind {
85 EdgeKind::Strong => self.strong.len(),
86 EdgeKind::Weak => self.weak.len(),
87 EdgeKind::Ephemeron => self.ephemerons.len(),
88 };
89 let cap = self.limits.for_kind(kind);
90 if count >= cap {
91 return Err(EdgeAllocationError::CapacityExceeded { kind, cap });
92 }
93 Ok(())
94 }
95
96 pub const fn role(&self) -> &R {
98 self.role.role()
99 }
100
101 pub fn replace_role(&mut self, role: R) -> R {
103 self.role.replace_role(role)
104 }
105
106 pub fn insert_strong(&mut self, target: ManagedId) -> Result<EdgeId, StrongEdgeMutationError> {
108 self.admit(EdgeKind::Strong)?;
109 let edge = self.edges.allocate(EdgeKind::Strong)?.id();
110 let previous = self.strong.insert(edge, target);
111 debug_assert!(previous.is_none(), "fresh edge identity must be vacant");
112 Ok(edge)
113 }
114
115 pub fn replace_strong(
117 &mut self,
118 edge: EdgeId,
119 expected: ManagedId,
120 replacement: ManagedId,
121 ) -> Result<(), StrongEdgeMutationError> {
122 if let Some(actual) = self
123 .edge_kind(edge)
124 .filter(|kind| *kind != EdgeKind::Strong)
125 {
126 return Err(StrongEdgeMutationError::WrongKind { edge, actual });
127 }
128 let target = self
129 .strong
130 .get_mut(&edge)
131 .ok_or(StrongEdgeMutationError::UnknownEdge(edge))?;
132 if *target != expected {
133 return Err(StrongEdgeMutationError::TargetChanged {
134 expected,
135 actual: *target,
136 });
137 }
138 *target = replacement;
139 Ok(())
140 }
141
142 pub fn remove_strong(
144 &mut self,
145 edge: EdgeId,
146 expected: ManagedId,
147 ) -> Result<ManagedId, StrongEdgeMutationError> {
148 if let Some(actual) = self
149 .edge_kind(edge)
150 .filter(|kind| *kind != EdgeKind::Strong)
151 {
152 return Err(StrongEdgeMutationError::WrongKind { edge, actual });
153 }
154 let actual = self
155 .strong
156 .get(&edge)
157 .copied()
158 .ok_or(StrongEdgeMutationError::UnknownEdge(edge))?;
159 if actual != expected {
160 return Err(StrongEdgeMutationError::TargetChanged { expected, actual });
161 }
162 Ok(self
163 .strong
164 .remove(&edge)
165 .expect("edge checked immediately before removal"))
166 }
167
168 pub fn insert_weak(&mut self, target: ManagedId) -> Result<EdgeId, WeakEdgeMutationError> {
170 self.admit(EdgeKind::Weak)?;
171 let edge = self.edges.allocate(EdgeKind::Weak)?.id();
172 let previous = self.weak.insert(edge, target);
173 debug_assert!(previous.is_none(), "fresh edge identity must be vacant");
174 Ok(edge)
175 }
176
177 pub fn replace_weak(
179 &mut self,
180 edge: EdgeId,
181 expected: ManagedId,
182 replacement: ManagedId,
183 ) -> Result<(), WeakEdgeMutationError> {
184 if let Some(actual) = self.edge_kind(edge).filter(|kind| *kind != EdgeKind::Weak) {
185 return Err(WeakEdgeMutationError::WrongKind { edge, actual });
186 }
187 let target = self
188 .weak
189 .get_mut(&edge)
190 .ok_or(WeakEdgeMutationError::UnknownEdge(edge))?;
191 if *target != expected {
192 return Err(WeakEdgeMutationError::TargetChanged {
193 expected,
194 actual: *target,
195 });
196 }
197 *target = replacement;
198 Ok(())
199 }
200
201 pub fn remove_weak(
203 &mut self,
204 edge: EdgeId,
205 expected: ManagedId,
206 ) -> Result<ManagedId, WeakEdgeMutationError> {
207 if let Some(actual) = self.edge_kind(edge).filter(|kind| *kind != EdgeKind::Weak) {
208 return Err(WeakEdgeMutationError::WrongKind { edge, actual });
209 }
210 let actual = self
211 .weak
212 .get(&edge)
213 .copied()
214 .ok_or(WeakEdgeMutationError::UnknownEdge(edge))?;
215 if actual != expected {
216 return Err(WeakEdgeMutationError::TargetChanged { expected, actual });
217 }
218 Ok(self
219 .weak
220 .remove(&edge)
221 .expect("edge checked immediately before removal"))
222 }
223
224 pub fn insert_ephemeron(
226 &mut self,
227 key: ManagedId,
228 value: ManagedId,
229 ) -> Result<EdgeId, EphemeronMutationError> {
230 self.admit(EdgeKind::Ephemeron)?;
231 let edge = self.edges.allocate(EdgeKind::Ephemeron)?.id();
232 let previous = self.ephemerons.insert(edge, (key, value));
233 debug_assert!(previous.is_none(), "fresh edge identity must be vacant");
234 Ok(edge)
235 }
236
237 pub fn replace_ephemeron(
239 &mut self,
240 edge: EdgeId,
241 expected: (ManagedId, ManagedId),
242 replacement: (ManagedId, ManagedId),
243 ) -> Result<(), EphemeronMutationError> {
244 if let Some(actual) = self
245 .edge_kind(edge)
246 .filter(|kind| *kind != EdgeKind::Ephemeron)
247 {
248 return Err(EphemeronMutationError::WrongKind { edge, actual });
249 }
250 let entry = self
251 .ephemerons
252 .get_mut(&edge)
253 .ok_or(EphemeronMutationError::UnknownEdge(edge))?;
254 if *entry != expected {
255 return Err(EphemeronMutationError::EntryChanged {
256 expected_key: expected.0,
257 expected_value: expected.1,
258 actual_key: entry.0,
259 actual_value: entry.1,
260 });
261 }
262 *entry = replacement;
263 Ok(())
264 }
265
266 pub fn remove_ephemeron(
268 &mut self,
269 edge: EdgeId,
270 expected: (ManagedId, ManagedId),
271 ) -> Result<(ManagedId, ManagedId), EphemeronMutationError> {
272 if let Some(actual) = self
273 .edge_kind(edge)
274 .filter(|kind| *kind != EdgeKind::Ephemeron)
275 {
276 return Err(EphemeronMutationError::WrongKind { edge, actual });
277 }
278 let actual = self
279 .ephemerons
280 .get(&edge)
281 .copied()
282 .ok_or(EphemeronMutationError::UnknownEdge(edge))?;
283 if actual != expected {
284 return Err(EphemeronMutationError::EntryChanged {
285 expected_key: expected.0,
286 expected_value: expected.1,
287 actual_key: actual.0,
288 actual_value: actual.1,
289 });
290 }
291 Ok(self
292 .ephemerons
293 .remove(&edge)
294 .expect("entry checked immediately before removal"))
295 }
296}
297
298impl<R> ManagedObject for ManagedNode<R> {
299 fn trace_edges(&self, visitor: &mut dyn EdgeVisitor) {
300 let mut edges = self
301 .strong
302 .iter()
303 .map(|(&edge, &target)| (edge, EdgeKind::Strong, target, target))
304 .chain(
305 self.weak
306 .iter()
307 .map(|(&edge, &target)| (edge, EdgeKind::Weak, target, target)),
308 )
309 .chain(
310 self.ephemerons
311 .iter()
312 .map(|(&edge, &(key, value))| (edge, EdgeKind::Ephemeron, key, value)),
313 )
314 .collect::<Vec<_>>();
315 edges.sort_unstable_by_key(|entry| entry.0);
316 for (edge, kind, first, second) in edges {
317 match kind {
318 EdgeKind::Strong => visitor.strong(edge, first),
319 EdgeKind::Weak => visitor.weak(edge, first),
320 EdgeKind::Ephemeron => visitor.ephemeron(edge, first, second),
321 }
322 }
323 }
324
325 fn clear_weak_edge(&mut self, edge: EdgeId, expected: ManagedId) -> bool {
326 if self.weak.get(&edge) != Some(&expected) {
327 return false;
328 }
329 self.weak.remove(&edge).is_some()
330 }
331
332 fn clear_ephemeron_edge(
333 &mut self,
334 edge: EdgeId,
335 expected_key: ManagedId,
336 expected_value: ManagedId,
337 ) -> bool {
338 if self.ephemerons.get(&edge) != Some(&(expected_key, expected_value)) {
339 return false;
340 }
341 self.ephemerons.remove(&edge).is_some()
342 }
343}
344
345impl<R> RoleBearingManagedObject for ManagedNode<R> {
346 type Role = R;
347
348 fn managed_role(&self) -> &Self::Role {
349 self.role()
350 }
351
352 fn replace_managed_role(&mut self, role: Self::Role) -> Self::Role {
353 self.replace_role(role)
354 }
355}