weavatrix_graph/working/
freeze.rs1use super::{StableEdgeKey, StableNodeKey, WorkingGraph};
2use crate::{EdgeIndex, Graph, NodeIndex, Result};
3use std::collections::HashMap;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct FreezeMap {
7 nodes: HashMap<StableNodeKey, NodeIndex>,
8 edges: HashMap<StableEdgeKey, EdgeIndex>,
9}
10
11impl FreezeMap {
12 #[must_use]
13 pub fn node(&self, key: StableNodeKey) -> Option<NodeIndex> {
14 self.nodes.get(&key).copied()
15 }
16
17 #[must_use]
18 pub fn edge(&self, key: StableEdgeKey) -> Option<EdgeIndex> {
19 self.edges.get(&key).copied()
20 }
21}
22
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct FrozenGraph {
25 graph: Graph,
26 indices: FreezeMap,
27}
28
29impl FrozenGraph {
30 #[must_use]
31 pub const fn graph(&self) -> &Graph {
32 &self.graph
33 }
34
35 #[must_use]
36 pub const fn indices(&self) -> &FreezeMap {
37 &self.indices
38 }
39
40 #[must_use]
41 pub fn into_parts(self) -> (Graph, FreezeMap) {
42 (self.graph, self.indices)
43 }
44}
45
46impl WorkingGraph {
47 pub fn freeze(self) -> Result<FrozenGraph> {
53 let mut keyed_nodes = self
54 .nodes
55 .into_iter()
56 .enumerate()
57 .filter_map(|(slot, entry)| {
58 Some((
59 StableNodeKey::new(u32::try_from(slot).ok()?, entry.generation),
60 entry.value?,
61 ))
62 })
63 .collect::<Vec<_>>();
64 keyed_nodes.sort_unstable_by(|left, right| left.1.id.cmp(&right.1.id));
65
66 let mut node_map = HashMap::with_capacity(keyed_nodes.len());
67 let mut nodes = Vec::with_capacity(keyed_nodes.len());
68 for (index, (key, node)) in keyed_nodes.into_iter().enumerate() {
69 let index =
70 u32::try_from(index).map_err(|_| crate::GraphError::IndexCapacityExceeded {
71 category: "frozen nodes",
72 count: nodes.len(),
73 })?;
74 node_map.insert(key, NodeIndex::new(index));
75 nodes.push(node);
76 }
77
78 let mut keyed_edges = self
79 .edges
80 .into_iter()
81 .enumerate()
82 .filter_map(|(slot, entry)| {
83 Some((
84 StableEdgeKey::new(u32::try_from(slot).ok()?, entry.generation),
85 entry.value?.value,
86 ))
87 })
88 .collect::<Vec<_>>();
89 keyed_edges.sort_unstable_by(|left, right| left.1.cmp(&right.1));
90
91 let mut edge_map = HashMap::with_capacity(keyed_edges.len());
92 let mut edges = Vec::with_capacity(keyed_edges.len());
93 for (key, edge) in keyed_edges {
94 let index = if edges.last() == Some(&edge) {
95 edges.len() - 1
96 } else {
97 edges.push(edge);
98 edges.len() - 1
99 };
100 let index =
101 u32::try_from(index).map_err(|_| crate::GraphError::IndexCapacityExceeded {
102 category: "frozen edges",
103 count: edges.len(),
104 })?;
105 edge_map.insert(key, EdgeIndex::new(index));
106 }
107
108 let graph = Graph::from_validated_sorted_parts(nodes, edges)?;
109 Ok(FrozenGraph {
110 graph,
111 indices: FreezeMap {
112 nodes: node_map,
113 edges: edge_map,
114 },
115 })
116 }
117}