1 //! Graph traits for associated data and graph construction.
2 
3 use crate::graph::IndexType;
4 #[cfg(feature = "graphmap")]
5 use crate::graphmap::{GraphMap, NodeTrait};
6 #[cfg(feature = "stable_graph")]
7 use crate::stable_graph::StableGraph;
8 use crate::visit::{Data, NodeCount, NodeIndexable, Reversed};
9 use crate::EdgeType;
10 use crate::Graph;
11 
12 trait_template! {
13     /// Access node and edge weights (associated data).
14 #[allow(clippy::needless_arbitrary_self_type)]
15 pub trait DataMap : Data {
16     @section self
17     fn node_weight(self: &Self, id: Self::NodeId) -> Option<&Self::NodeWeight>;
18     fn edge_weight(self: &Self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>;
19 }
20 }
21 
22 macro_rules! access0 {
23     ($e:expr) => {
24         $e.0
25     };
26 }
27 
28 DataMap! {delegate_impl []}
29 DataMap! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
30 DataMap! {delegate_impl [[G], G, Reversed<G>, access0]}
31 
32 trait_template! {
33     /// Access node and edge weights mutably.
34 #[allow(clippy::needless_arbitrary_self_type)]
35 pub trait DataMapMut : DataMap {
36     @section self
37     fn node_weight_mut(self: &mut Self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>;
38     fn edge_weight_mut(self: &mut Self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>;
39 }
40 }
41 
42 DataMapMut! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
43 DataMapMut! {delegate_impl [[G], G, Reversed<G>, access0]}
44 
45 /// A graph that can be extended with further nodes and edges
46 pub trait Build: Data + NodeCount {
add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId47     fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId;
48     /// Add a new edge. If parallel edges (duplicate) are not allowed and
49     /// the edge already exists, return `None`.
add_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Option<Self::EdgeId>50     fn add_edge(
51         &mut self,
52         a: Self::NodeId,
53         b: Self::NodeId,
54         weight: Self::EdgeWeight,
55     ) -> Option<Self::EdgeId> {
56         Some(self.update_edge(a, b, weight))
57     }
58     /// Add or update the edge from `a` to `b`. Return the id of the affected
59     /// edge.
update_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Self::EdgeId60     fn update_edge(
61         &mut self,
62         a: Self::NodeId,
63         b: Self::NodeId,
64         weight: Self::EdgeWeight,
65     ) -> Self::EdgeId;
66 }
67 
68 /// A graph that can be created
69 pub trait Create: Build + Default {
with_capacity(nodes: usize, edges: usize) -> Self70     fn with_capacity(nodes: usize, edges: usize) -> Self;
71 }
72 
73 impl<N, E, Ty, Ix> Data for Graph<N, E, Ty, Ix>
74 where
75     Ix: IndexType,
76 {
77     type NodeWeight = N;
78     type EdgeWeight = E;
79 }
80 
81 impl<N, E, Ty, Ix> DataMap for Graph<N, E, Ty, Ix>
82 where
83     Ty: EdgeType,
84     Ix: IndexType,
85 {
node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight>86     fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
87         self.node_weight(id)
88     }
edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>89     fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
90         self.edge_weight(id)
91     }
92 }
93 
94 impl<N, E, Ty, Ix> DataMapMut for Graph<N, E, Ty, Ix>
95 where
96     Ty: EdgeType,
97     Ix: IndexType,
98 {
node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>99     fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
100         self.node_weight_mut(id)
101     }
edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>102     fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
103         self.edge_weight_mut(id)
104     }
105 }
106 
107 #[cfg(feature = "stable_graph")]
108 impl<N, E, Ty, Ix> DataMap for StableGraph<N, E, Ty, Ix>
109 where
110     Ty: EdgeType,
111     Ix: IndexType,
112 {
node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight>113     fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
114         self.node_weight(id)
115     }
edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>116     fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
117         self.edge_weight(id)
118     }
119 }
120 
121 #[cfg(feature = "stable_graph")]
122 impl<N, E, Ty, Ix> DataMapMut for StableGraph<N, E, Ty, Ix>
123 where
124     Ty: EdgeType,
125     Ix: IndexType,
126 {
node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>127     fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
128         self.node_weight_mut(id)
129     }
edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>130     fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
131         self.edge_weight_mut(id)
132     }
133 }
134 
135 impl<N, E, Ty, Ix> Build for Graph<N, E, Ty, Ix>
136 where
137     Ty: EdgeType,
138     Ix: IndexType,
139 {
add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId140     fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
141         self.add_node(weight)
142     }
add_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Option<Self::EdgeId>143     fn add_edge(
144         &mut self,
145         a: Self::NodeId,
146         b: Self::NodeId,
147         weight: Self::EdgeWeight,
148     ) -> Option<Self::EdgeId> {
149         Some(self.add_edge(a, b, weight))
150     }
update_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Self::EdgeId151     fn update_edge(
152         &mut self,
153         a: Self::NodeId,
154         b: Self::NodeId,
155         weight: Self::EdgeWeight,
156     ) -> Self::EdgeId {
157         self.update_edge(a, b, weight)
158     }
159 }
160 
161 #[cfg(feature = "stable_graph")]
162 impl<N, E, Ty, Ix> Build for StableGraph<N, E, Ty, Ix>
163 where
164     Ty: EdgeType,
165     Ix: IndexType,
166 {
add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId167     fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
168         self.add_node(weight)
169     }
add_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Option<Self::EdgeId>170     fn add_edge(
171         &mut self,
172         a: Self::NodeId,
173         b: Self::NodeId,
174         weight: Self::EdgeWeight,
175     ) -> Option<Self::EdgeId> {
176         Some(self.add_edge(a, b, weight))
177     }
update_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Self::EdgeId178     fn update_edge(
179         &mut self,
180         a: Self::NodeId,
181         b: Self::NodeId,
182         weight: Self::EdgeWeight,
183     ) -> Self::EdgeId {
184         self.update_edge(a, b, weight)
185     }
186 }
187 
188 #[cfg(feature = "graphmap")]
189 impl<N, E, Ty> Build for GraphMap<N, E, Ty>
190 where
191     Ty: EdgeType,
192     N: NodeTrait,
193 {
add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId194     fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
195         self.add_node(weight)
196     }
add_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Option<Self::EdgeId>197     fn add_edge(
198         &mut self,
199         a: Self::NodeId,
200         b: Self::NodeId,
201         weight: Self::EdgeWeight,
202     ) -> Option<Self::EdgeId> {
203         if self.contains_edge(a, b) {
204             None
205         } else {
206             let r = self.add_edge(a, b, weight);
207             debug_assert!(r.is_none());
208             Some((a, b))
209         }
210     }
update_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Self::EdgeId211     fn update_edge(
212         &mut self,
213         a: Self::NodeId,
214         b: Self::NodeId,
215         weight: Self::EdgeWeight,
216     ) -> Self::EdgeId {
217         self.add_edge(a, b, weight);
218         (a, b)
219     }
220 }
221 
222 impl<N, E, Ty, Ix> Create for Graph<N, E, Ty, Ix>
223 where
224     Ty: EdgeType,
225     Ix: IndexType,
226 {
with_capacity(nodes: usize, edges: usize) -> Self227     fn with_capacity(nodes: usize, edges: usize) -> Self {
228         Self::with_capacity(nodes, edges)
229     }
230 }
231 
232 #[cfg(feature = "stable_graph")]
233 impl<N, E, Ty, Ix> Create for StableGraph<N, E, Ty, Ix>
234 where
235     Ty: EdgeType,
236     Ix: IndexType,
237 {
with_capacity(nodes: usize, edges: usize) -> Self238     fn with_capacity(nodes: usize, edges: usize) -> Self {
239         Self::with_capacity(nodes, edges)
240     }
241 }
242 
243 #[cfg(feature = "graphmap")]
244 impl<N, E, Ty> Create for GraphMap<N, E, Ty>
245 where
246     Ty: EdgeType,
247     N: NodeTrait,
248 {
with_capacity(nodes: usize, edges: usize) -> Self249     fn with_capacity(nodes: usize, edges: usize) -> Self {
250         Self::with_capacity(nodes, edges)
251     }
252 }
253 
254 /// A graph element.
255 ///
256 /// A sequence of Elements, for example an iterator, is laid out as follows:
257 /// Nodes are implicitly given the index of their appearance in the sequence.
258 /// The edges’ source and target fields refer to these indices.
259 #[derive(Clone, Debug, PartialEq, Eq)]
260 pub enum Element<N, E> {
261     /// A graph node.
262     Node { weight: N },
263     /// A graph edge.
264     Edge {
265         source: usize,
266         target: usize,
267         weight: E,
268     },
269 }
270 
271 /// Create a graph from an iterator of elements.
272 pub trait FromElements: Create {
from_elements<I>(iterable: I) -> Self where Self: Sized, I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,273     fn from_elements<I>(iterable: I) -> Self
274     where
275         Self: Sized,
276         I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
277     {
278         let mut gr = Self::with_capacity(0, 0);
279         // usize -> NodeId map
280         let mut map = Vec::new();
281         for element in iterable {
282             match element {
283                 Element::Node { weight } => {
284                     map.push(gr.add_node(weight));
285                 }
286                 Element::Edge {
287                     source,
288                     target,
289                     weight,
290                 } => {
291                     gr.add_edge(map[source], map[target], weight);
292                 }
293             }
294         }
295         gr
296     }
297 }
298 
from_elements_indexable<G, I>(iterable: I) -> G where G: Create + NodeIndexable, I: IntoIterator<Item = Element<G::NodeWeight, G::EdgeWeight>>,299 fn from_elements_indexable<G, I>(iterable: I) -> G
300 where
301     G: Create + NodeIndexable,
302     I: IntoIterator<Item = Element<G::NodeWeight, G::EdgeWeight>>,
303 {
304     let mut gr = G::with_capacity(0, 0);
305     let map = |gr: &G, i| gr.from_index(i);
306     for element in iterable {
307         match element {
308             Element::Node { weight } => {
309                 gr.add_node(weight);
310             }
311             Element::Edge {
312                 source,
313                 target,
314                 weight,
315             } => {
316                 let from = map(&gr, source);
317                 let to = map(&gr, target);
318                 gr.add_edge(from, to, weight);
319             }
320         }
321     }
322     gr
323 }
324 
325 impl<N, E, Ty, Ix> FromElements for Graph<N, E, Ty, Ix>
326 where
327     Ty: EdgeType,
328     Ix: IndexType,
329 {
from_elements<I>(iterable: I) -> Self where Self: Sized, I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,330     fn from_elements<I>(iterable: I) -> Self
331     where
332         Self: Sized,
333         I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
334     {
335         from_elements_indexable(iterable)
336     }
337 }
338 
339 #[cfg(feature = "stable_graph")]
340 impl<N, E, Ty, Ix> FromElements for StableGraph<N, E, Ty, Ix>
341 where
342     Ty: EdgeType,
343     Ix: IndexType,
344 {
from_elements<I>(iterable: I) -> Self where Self: Sized, I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,345     fn from_elements<I>(iterable: I) -> Self
346     where
347         Self: Sized,
348         I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
349     {
350         from_elements_indexable(iterable)
351     }
352 }
353 
354 #[cfg(feature = "graphmap")]
355 impl<N, E, Ty> FromElements for GraphMap<N, E, Ty>
356 where
357     Ty: EdgeType,
358     N: NodeTrait,
359 {
from_elements<I>(iterable: I) -> Self where Self: Sized, I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,360     fn from_elements<I>(iterable: I) -> Self
361     where
362         Self: Sized,
363         I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
364     {
365         from_elements_indexable(iterable)
366     }
367 }
368 
369 /// Iterator adaptors for iterators of `Element`.
370 pub trait ElementIterator<N, E>: Iterator<Item = Element<N, E>> {
371     /// Create an iterator adaptor that filters graph elements.
372     ///
373     /// The function `f` is called with each element and if its return value
374     /// is `true` the element is accepted and if `false` it is removed.
375     /// `f` is called with mutable references to the node and edge weights,
376     /// so that they can be mutated (but the edge endpoints can not).
377     ///
378     /// This filter adapts the edge source and target indices in the
379     /// stream so that they are correct after the removals.
filter_elements<F>(self, f: F) -> FilterElements<Self, F> where Self: Sized, F: FnMut(Element<&mut N, &mut E>) -> bool,380     fn filter_elements<F>(self, f: F) -> FilterElements<Self, F>
381     where
382         Self: Sized,
383         F: FnMut(Element<&mut N, &mut E>) -> bool,
384     {
385         FilterElements {
386             iter: self,
387             node_index: 0,
388             map: Vec::new(),
389             f,
390         }
391     }
392 }
393 
394 impl<N, E, I: ?Sized> ElementIterator<N, E> for I where I: Iterator<Item = Element<N, E>> {}
395 
396 /// An iterator that filters graph elements.
397 ///
398 /// See [`.filter_elements()`][1] for more information.
399 ///
400 /// [1]: trait.ElementIterator.html#method.filter_elements
401 #[derive(Debug, Clone)]
402 pub struct FilterElements<I, F> {
403     iter: I,
404     node_index: usize,
405     map: Vec<usize>,
406     f: F,
407 }
408 
409 impl<I, F, N, E> Iterator for FilterElements<I, F>
410 where
411     I: Iterator<Item = Element<N, E>>,
412     F: FnMut(Element<&mut N, &mut E>) -> bool,
413 {
414     type Item = Element<N, E>;
415 
next(&mut self) -> Option<Self::Item>416     fn next(&mut self) -> Option<Self::Item> {
417         loop {
418             let mut elt = match self.iter.next() {
419                 None => return None,
420                 Some(elt) => elt,
421             };
422             let keep = (self.f)(match elt {
423                 Element::Node { ref mut weight } => Element::Node { weight },
424                 Element::Edge {
425                     source,
426                     target,
427                     ref mut weight,
428                 } => Element::Edge {
429                     source,
430                     target,
431                     weight,
432                 },
433             });
434             let is_node = if let Element::Node { .. } = elt {
435                 true
436             } else {
437                 false
438             };
439             if !keep && is_node {
440                 self.map.push(self.node_index);
441             }
442             if is_node {
443                 self.node_index += 1;
444             }
445             if !keep {
446                 continue;
447             }
448 
449             // map edge parts
450             match elt {
451                 Element::Edge {
452                     ref mut source,
453                     ref mut target,
454                     ..
455                 } => {
456                     // Find the node indices in the map of removed ones.
457                     // If a node was removed, the edge is as well.
458                     // Otherwise the counts are adjusted by the number of nodes
459                     // removed.
460                     // Example: map: [1, 3, 4, 6]
461                     // binary search for 2, result is Err(1). One node has been
462                     // removed before 2.
463                     match self.map.binary_search(source) {
464                         Ok(_) => continue,
465                         Err(i) => *source -= i,
466                     }
467                     match self.map.binary_search(target) {
468                         Ok(_) => continue,
469                         Err(i) => *target -= i,
470                     }
471                 }
472                 Element::Node { .. } => {}
473             }
474             return Some(elt);
475         }
476     }
size_hint(&self) -> (usize, Option<usize>)477     fn size_hint(&self) -> (usize, Option<usize>) {
478         let (_, upper) = self.iter.size_hint();
479         (0, upper)
480     }
481 }
482