nodedb_graph/csr/
compaction.rs1use super::index::CsrIndex;
6use crate::GraphError;
7
8impl CsrIndex {
9 pub fn compact(&mut self) -> Result<(), GraphError> {
20 let n = self.id_to_node.len();
21 let mut new_out_edges: Vec<Vec<(u32, u32)>> = vec![Vec::new(); n];
22 let mut new_in_edges: Vec<Vec<(u32, u32)>> = vec![Vec::new(); n];
23 let mut new_out_collections: Vec<Vec<u32>> = vec![Vec::new(); n];
25 let mut new_in_collections: Vec<Vec<u32>> = vec![Vec::new(); n];
26 let mut new_out_weights: Vec<Vec<f64>> = if self.has_weights {
27 vec![Vec::new(); n]
28 } else {
29 Vec::new()
30 };
31 let mut new_in_weights: Vec<Vec<f64>> = if self.has_weights {
32 vec![Vec::new(); n]
33 } else {
34 Vec::new()
35 };
36
37 for node in 0..n {
39 let node_id = node as u32;
40 let idx = node_id as usize;
41
42 if idx + 1 < self.out_offsets.len() {
44 let start = self.out_offsets[idx] as usize;
45 let end = self.out_offsets[idx + 1] as usize;
46 for i in start..end {
47 let lid = self.out_labels[i];
48 let dst = self.out_targets[i];
49 let coll = self.out_collections.get(i).copied().unwrap_or(0);
50 if !self.deleted_edges.contains(&(node_id, lid, dst, coll)) {
51 new_out_edges[node].push((lid, dst));
52 new_out_collections[node].push(coll);
53 if self.has_weights {
54 let w = self
55 .out_weights
56 .as_ref()
57 .map_or(1.0, |ws| ws.get(i).copied().unwrap_or(1.0));
58 new_out_weights[node].push(w);
59 }
60 }
61 }
62 }
63
64 if idx + 1 < self.in_offsets.len() {
66 let start = self.in_offsets[idx] as usize;
67 let end = self.in_offsets[idx + 1] as usize;
68 for i in start..end {
69 let lid = self.in_labels[i];
70 let src = self.in_targets[i];
71 let coll = self.in_collections.get(i).copied().unwrap_or(0);
72 if !self.deleted_edges.contains(&(src, lid, node_id, coll)) {
73 new_in_edges[node].push((lid, src));
74 new_in_collections[node].push(coll);
75 if self.has_weights {
76 let w = self
77 .in_weights
78 .as_ref()
79 .map_or(1.0, |ws| ws.get(i).copied().unwrap_or(1.0));
80 new_in_weights[node].push(w);
81 }
82 }
83 }
84 }
85 }
86
87 for node in 0..n {
91 for (buf_idx, &(lid, dst)) in self.buffer_out[node].iter().enumerate() {
92 let coll = self.buffer_out_collections[node]
93 .get(buf_idx)
94 .copied()
95 .unwrap_or(0);
96 if !new_out_edges[node]
97 .iter()
98 .zip(new_out_collections[node].iter())
99 .any(|(&(l, d), &c)| l == lid && d == dst && c == coll)
100 {
101 new_out_edges[node].push((lid, dst));
102 new_out_collections[node].push(coll);
103 if self.has_weights {
104 let w = self.buffer_out_weights[node]
105 .get(buf_idx)
106 .copied()
107 .unwrap_or(1.0);
108 new_out_weights[node].push(w);
109 }
110 }
111 }
112 for (buf_idx, &(lid, src)) in self.buffer_in[node].iter().enumerate() {
113 let coll = self.buffer_in_collections[node]
114 .get(buf_idx)
115 .copied()
116 .unwrap_or(0);
117 if !new_in_edges[node]
118 .iter()
119 .zip(new_in_collections[node].iter())
120 .any(|(&(l, s), &c)| l == lid && s == src && c == coll)
121 {
122 new_in_edges[node].push((lid, src));
123 new_in_collections[node].push(coll);
124 if self.has_weights {
125 let w = self.buffer_in_weights[node]
126 .get(buf_idx)
127 .copied()
128 .unwrap_or(1.0);
129 new_in_weights[node].push(w);
130 }
131 }
132 }
133 }
134
135 let memory = &self.memory;
137 let out = Self::build_dense(&new_out_edges, &new_out_collections, memory)?;
138 let in_ = Self::build_dense(&new_in_edges, &new_in_collections, memory)?;
139
140 self.out_offsets = out.offsets;
141 self.out_targets = out.targets.into();
142 self.out_labels = out.labels.into();
143 self.out_collections = out.collections;
144 self.in_offsets = in_.offsets;
145 self.in_targets = in_.targets.into();
146 self.in_labels = in_.labels.into();
147 self.in_collections = in_.collections;
148
149 if self.has_weights {
151 self.out_weights = Some(
152 new_out_weights
153 .into_iter()
154 .flatten()
155 .collect::<Vec<_>>()
156 .into(),
157 );
158 self.in_weights = Some(
159 new_in_weights
160 .into_iter()
161 .flatten()
162 .collect::<Vec<_>>()
163 .into(),
164 );
165 }
166
167 for buf in &mut self.buffer_out {
169 buf.clear();
170 }
171 for buf in &mut self.buffer_in {
172 buf.clear();
173 }
174 for buf in &mut self.buffer_out_collections {
175 buf.clear();
176 }
177 for buf in &mut self.buffer_in_collections {
178 buf.clear();
179 }
180 if self.has_weights {
181 for buf in &mut self.buffer_out_weights {
182 buf.clear();
183 }
184 for buf in &mut self.buffer_in_weights {
185 buf.clear();
186 }
187 }
188 self.deleted_edges.clear();
189 Ok(())
190 }
191}