weavatrix_graph/working/
mutate.rs1use super::{StableEdgeKey, StableNodeKey, WorkingGraph};
2use crate::graph::validate::{validate_edge, validate_node};
3use crate::{Edge, GraphError, Node, Result};
4
5impl WorkingGraph {
6 pub fn remove_edge(&mut self, key: StableEdgeKey) -> Option<Edge> {
7 let endpoints = self.edge_endpoints(key)?;
8 let edge = self.edge_slot_mut(key)?.value.take()?.value;
9 self.node_slot_mut(endpoints.source())?
10 .outgoing
11 .retain(|candidate| *candidate != key);
12 self.node_slot_mut(endpoints.target())?
13 .incoming
14 .retain(|candidate| *candidate != key);
15 self.edge_count -= 1;
16 self.retire_edge_slot(key);
17 Some(edge)
18 }
19
20 pub fn remove_node(&mut self, key: StableNodeKey) -> Option<Node> {
21 let slot = self.node_slot(key)?;
22 let id = slot.value.as_ref()?.id.clone();
23 let mut incident = slot.outgoing.clone();
24 incident.extend(slot.incoming.iter().copied());
25 incident.sort_unstable();
26 incident.dedup();
27 for edge in incident {
28 self.remove_edge(edge);
29 }
30
31 let node = self.node_slot_mut(key)?.value.take()?;
32 self.node_by_id.remove(&id);
33 self.node_count -= 1;
34 self.retire_node_slot(key);
35 Some(node)
36 }
37
38 pub fn replace_node(&mut self, key: StableNodeKey, node: Node) -> Result<Option<Node>> {
44 validate_node(&node)?;
45 let Some(current) = self.node(key) else {
46 return Ok(None);
47 };
48 let old_id = current.id.clone();
49 if self
50 .node_by_id
51 .get(&node.id)
52 .is_some_and(|existing| *existing != key)
53 {
54 return Err(GraphError::ConflictingNode {
55 id: node.id.to_string(),
56 });
57 }
58
59 if old_id != node.id {
60 let new_id = node.id.clone();
61 let Some(incident) = self.node_slot(key).map(|slot| {
62 let mut keys = slot.outgoing.clone();
63 keys.extend(slot.incoming.iter().copied());
64 keys.sort_unstable();
65 keys.dedup();
66 keys
67 }) else {
68 return Ok(None);
69 };
70 for edge in incident {
71 if let Some(working) = self
72 .edge_slot_mut(edge)
73 .and_then(|slot| slot.value.as_mut())
74 {
75 if working.source == key {
76 working.value.source = new_id.clone();
77 }
78 if working.target == key {
79 working.value.target = new_id.clone();
80 }
81 }
82 }
83 self.node_by_id.remove(&old_id);
84 self.node_by_id.insert(new_id, key);
85 }
86 Ok(self
87 .node_slot_mut(key)
88 .and_then(|slot| slot.value.replace(node)))
89 }
90
91 pub fn replace_edge(&mut self, key: StableEdgeKey, edge: Edge) -> Result<Option<Edge>> {
97 validate_edge(&edge)?;
98 let Some(old_endpoints) = self.edge_endpoints(key) else {
99 return Ok(None);
100 };
101 let source =
102 self.node_key(edge.source.as_str())
103 .ok_or_else(|| GraphError::MissingEdgeSource {
104 id: edge.source.to_string(),
105 })?;
106 let target =
107 self.node_key(edge.target.as_str())
108 .ok_or_else(|| GraphError::MissingEdgeTarget {
109 id: edge.target.to_string(),
110 })?;
111
112 if let Some(slot) = self.node_slot_mut(old_endpoints.source()) {
113 slot.outgoing.retain(|candidate| *candidate != key);
114 }
115 if let Some(slot) = self.node_slot_mut(old_endpoints.target()) {
116 slot.incoming.retain(|candidate| *candidate != key);
117 }
118 if let Some(slot) = self.node_slot_mut(source) {
119 slot.outgoing.push(key);
120 }
121 if let Some(slot) = self.node_slot_mut(target) {
122 slot.incoming.push(key);
123 }
124
125 let Some(working) = self.edge_slot_mut(key).and_then(|slot| slot.value.as_mut()) else {
126 return Ok(None);
127 };
128 working.source = source;
129 working.target = target;
130 Ok(Some(std::mem::replace(&mut working.value, edge)))
131 }
132
133 fn retire_node_slot(&mut self, key: StableNodeKey) {
134 let slot = &mut self.nodes[key.index()];
135 slot.outgoing.clear();
136 slot.incoming.clear();
137 if let Some(generation) = slot.generation.checked_add(1) {
138 slot.generation = generation;
139 self.free_nodes.push(key.slot());
140 }
141 }
142
143 fn retire_edge_slot(&mut self, key: StableEdgeKey) {
144 let slot = &mut self.edges[key.index()];
145 if let Some(generation) = slot.generation.checked_add(1) {
146 slot.generation = generation;
147 self.free_edges.push(key.slot());
148 }
149 }
150}