bidirected_adjacency_array/
graph.rs1use std::iter;
2
3use tagged_vec::TaggedVec;
4
5use crate::index::{
6 DirectedEdgeIndex, DirectedNodeIndex, EdgeIndex, GraphIndexInteger, NodeIndex,
7 OptionalEdgeIndex,
8};
9
10#[cfg(test)]
11mod tests;
12
13#[derive(Debug)]
14pub struct BidirectedAdjacencyArray<IndexType: GraphIndexInteger, NodeData, EdgeData> {
15 node_array: TaggedVec<DirectedNodeIndex<IndexType>, DirectedEdgeIndex<IndexType>>,
22
23 edge_array: TaggedVec<DirectedEdgeIndex<IndexType>, DirectedNodeIndex<IndexType>>,
28
29 node_data: TaggedVec<NodeIndex<IndexType>, NodeData>,
35
36 edge_data_keys: TaggedVec<DirectedEdgeIndex<IndexType>, EdgeDataKey<IndexType>>,
43
44 edge_data: TaggedVec<EdgeIndex<IndexType>, BidirectedEdgeData<IndexType, EdgeData>>,
48}
49
50#[derive(Debug, Clone, Copy)]
51struct EdgeDataKey<IndexType: GraphIndexInteger> {
52 inverse: DirectedEdgeIndex<IndexType>,
53 data_index: OptionalEdgeIndex<IndexType>,
54}
55
56#[derive(Debug)]
57struct BidirectedEdgeData<IndexType, EdgeData> {
58 forward: DirectedEdgeIndex<IndexType>,
59 reverse: DirectedEdgeIndex<IndexType>,
60 data: EdgeData,
61}
62
63pub struct DirectedEdgeDataView<'a, EdgeData> {
64 forward: bool,
65 data: &'a EdgeData,
66}
67
68pub struct EdgeView<'a, IndexType, EdgeData> {
69 from: DirectedNodeIndex<IndexType>,
70 to: DirectedNodeIndex<IndexType>,
71 data: &'a EdgeData,
72}
73
74#[derive(Debug, Clone, Hash, PartialEq, Eq)]
75pub struct BidirectedEdge<IndexType, EdgeData> {
76 pub from: NodeIndex<IndexType>,
77 pub from_forward: bool,
79 pub to: NodeIndex<IndexType>,
80 pub to_forward: bool,
82 pub data: EdgeData,
83}
84
85impl<IndexType: GraphIndexInteger, NodeData, EdgeData>
86 BidirectedAdjacencyArray<IndexType, NodeData, EdgeData>
87{
88 pub fn new(
89 nodes: TaggedVec<NodeIndex<IndexType>, NodeData>,
90 edges: TaggedVec<EdgeIndex<IndexType>, BidirectedEdge<IndexType, EdgeData>>,
91 ) -> Self {
92 let mut node_array = TaggedVec::from_iter(iter::repeat_n(
93 DirectedEdgeIndex::from_usize(0),
94 nodes.len() * 2 + 1,
95 ));
96
97 for edge in edges.iter_values() {
99 let from_directed_forward =
100 DirectedNodeIndex::from_bidirected(edge.from, edge.from_forward);
101 node_array[from_directed_forward].increment();
102 let from_directed_reverse =
103 DirectedNodeIndex::from_bidirected(edge.to, edge.to_forward).invert();
104 node_array[from_directed_reverse].increment();
105 }
106
107 let directed_edge_count =
109 node_array
110 .iter_values_mut()
111 .fold(DirectedEdgeIndex::zero(), |sum, element| {
112 let sum = sum.add(*element);
113 *element = sum;
114 sum
115 });
116 assert_eq!(
117 directed_edge_count,
118 node_array.iter_values().last().copied().unwrap(),
119 );
120
121 let mut edge_array = TaggedVec::from_iter(iter::repeat_n(
123 DirectedNodeIndex::from_usize(0),
124 directed_edge_count.into_usize(),
125 ));
126 let mut edge_data_keys = TaggedVec::from_iter(iter::repeat_n(
127 EdgeDataKey {
128 inverse: DirectedEdgeIndex::zero(),
129 data_index: OptionalEdgeIndex::new_none(),
130 },
131 directed_edge_count.into_usize(),
132 ));
133 let mut edge_data = TaggedVec::new();
134
135 for (edge_index, edge) in edges.into_iter() {
138 let from_directed_forward =
139 DirectedNodeIndex::from_bidirected(edge.from, edge.from_forward);
140 let to_directed_forward = DirectedNodeIndex::from_bidirected(edge.to, edge.to_forward);
141 let edge_index_forward = {
142 node_array[from_directed_forward].decrement();
143 node_array[from_directed_forward]
144 };
145
146 let from_directed_reverse = to_directed_forward.invert();
147 let to_directed_reverse = from_directed_forward.invert();
148 let edge_index_reverse = {
149 node_array[from_directed_reverse].decrement();
150 node_array[from_directed_reverse]
151 };
152
153 edge_array[edge_index_forward] = to_directed_forward;
154 edge_array[edge_index_reverse] = to_directed_reverse;
155
156 edge_data_keys[edge_index_forward] = EdgeDataKey {
157 inverse: edge_index_reverse,
158 data_index: edge_index.into(),
159 };
160 edge_data_keys[edge_index_reverse] = EdgeDataKey {
161 inverse: edge_index_forward,
162 data_index: OptionalEdgeIndex::new_none(),
163 };
164
165 let data_index = edge_data.push(BidirectedEdgeData {
166 forward: edge_index_forward,
167 reverse: edge_index_reverse,
168 data: edge.data,
169 });
170 assert_eq!(edge_index, data_index);
171 }
172
173 Self {
174 node_array,
175 edge_array,
176 node_data: nodes,
177 edge_data_keys,
178 edge_data,
179 }
180 }
181
182 pub fn node_count(&self) -> usize {
183 self.node_data.len()
184 }
185
186 pub fn edge_count(&self) -> usize {
187 self.edge_data.len()
188 }
189
190 pub fn iter_nodes(&self) -> impl Iterator<Item = NodeIndex<IndexType>> {
191 self.node_data.iter_indices()
192 }
193
194 pub fn iter_edges(&self) -> impl Iterator<Item = EdgeIndex<IndexType>> {
195 self.edge_data.iter_indices()
196 }
197
198 pub fn iter_successors(
199 &self,
200 node: DirectedNodeIndex<IndexType>,
201 ) -> impl Iterator<Item = (DirectedEdgeIndex<IndexType>, DirectedNodeIndex<IndexType>)> {
202 let start = self.node_array[node];
203 let end = self.node_array[node.add(DirectedNodeIndex::from_usize(1))];
204 self.edge_array
205 .iter()
206 .take(end.into_usize())
207 .skip(start.into_usize())
208 .map(|(edge_index, &to_node)| (edge_index, to_node))
209 }
210
211 pub fn node_data(&self, node: NodeIndex<IndexType>) -> &NodeData {
212 &self.node_data[node]
213 }
214
215 pub fn edge(&self, edge: EdgeIndex<IndexType>) -> EdgeView<'_, IndexType, EdgeData> {
216 let bidirected_edge_data = &self.edge_data[edge];
217
218 let forward_to = self.edge_array[bidirected_edge_data.forward];
219 let reverse_to = self.edge_array[bidirected_edge_data.reverse];
220
221 if forward_to == reverse_to {
222 let from = forward_to.invert();
224 let to = forward_to;
225 EdgeView {
226 from,
227 to,
228 data: &bidirected_edge_data.data,
229 }
230 } else if forward_to.invert() == reverse_to {
231 let from = forward_to;
233 let to = forward_to;
234 EdgeView {
235 from,
236 to,
237 data: &bidirected_edge_data.data,
238 }
239 } else {
240 let from = reverse_to.invert();
242 let to = forward_to;
243 EdgeView {
244 from,
245 to,
246 data: &bidirected_edge_data.data,
247 }
248 }
249 }
250
251 pub fn directed_edge_data<'this>(
252 &'this self,
253 edge: DirectedEdgeIndex<IndexType>,
254 ) -> DirectedEdgeDataView<'this, EdgeData> {
255 let key = &self.edge_data_keys[edge];
256 if let Some(data_index) = Option::<EdgeIndex<IndexType>>::from(key.data_index) {
257 DirectedEdgeDataView {
258 forward: true,
259 data: &self.edge_data[data_index].data,
260 }
261 } else {
262 let inverse_key = &self.edge_data_keys[key.inverse];
263 let Some(inverse_data_index) =
264 Option::<EdgeIndex<IndexType>>::from(inverse_key.data_index)
265 else {
266 panic!(
267 "Edge data for edge {:?} and its inverse {:?} are both missing",
268 edge, key.inverse
269 );
270 };
271 DirectedEdgeDataView {
272 forward: false,
273 data: &self.edge_data[inverse_data_index].data,
274 }
275 }
276 }
277}
278
279impl<'a, EdgeData> DirectedEdgeDataView<'a, EdgeData> {
280 pub fn is_forward(&self) -> bool {
281 self.forward
282 }
283
284 pub fn data(&self) -> &EdgeData {
285 self.data
286 }
287}
288
289impl<'a, IndexType, EdgeData> EdgeView<'a, IndexType, EdgeData> {
290 pub fn from(&self) -> DirectedNodeIndex<IndexType>
291 where
292 IndexType: Copy,
293 {
294 self.from
295 }
296
297 pub fn to(&self) -> DirectedNodeIndex<IndexType>
298 where
299 IndexType: Copy,
300 {
301 self.to
302 }
303
304 pub fn data(&self) -> &EdgeData {
305 self.data
306 }
307}