1use crate::data::{Build, DataMap, DataMapMut};
3use crate::iter_format::NoPretty;
4use crate::visit::{
5 self, EdgeCount, EdgeRef, GetAdjacencyMatrix, IntoEdgeReferences, IntoNeighbors, NodeCount,
6};
7use fixedbitset::FixedBitSet;
8use std::fmt;
9use std::ops::Range;
10
11#[doc(no_inline)]
12pub use crate::graph::{DefaultIx, IndexType};
13
14pub type NodeIndex<Ix = DefaultIx> = Ix;
16
17#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
19pub struct EdgeIndex<Ix = DefaultIx>
20where
21 Ix: IndexType,
22{
23 from: NodeIndex<Ix>,
25 successor_index: usize,
27}
28
29iterator_wrap! {
30impl (Iterator) for
31#[derive(Debug, Clone)]
35struct OutgoingEdgeIndices <Ix> where { Ix: IndexType }
36item: EdgeIndex<Ix>,
37iter: std::iter::Map<std::iter::Zip<Range<usize>, std::iter::Repeat<NodeIndex<Ix>>>, fn((usize, NodeIndex<Ix>)) -> EdgeIndex<Ix>>,
38}
39
40#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
42struct WSuc<E, Ix: IndexType> {
43 suc: Ix,
45 weight: E,
47}
48
49type Row<E, Ix> = Vec<WSuc<E, Ix>>;
51type RowIter<'a, E, Ix> = std::slice::Iter<'a, WSuc<E, Ix>>;
52
53iterator_wrap! {
54impl (Iterator DoubleEndedIterator ExactSizeIterator) for
55#[derive(Debug, Clone)]
57struct Neighbors<'a, E, Ix> where { Ix: IndexType }
58item: NodeIndex<Ix>,
59iter: std::iter::Map<RowIter<'a, E, Ix>, fn(&WSuc<E, Ix>) -> NodeIndex<Ix>>,
60}
61
62#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
64pub struct EdgeReference<'a, E, Ix: IndexType> {
65 id: EdgeIndex<Ix>,
67 edge: &'a WSuc<E, Ix>,
69}
70
71impl<E, Ix: IndexType> Copy for EdgeReference<'_, E, Ix> {}
72impl<E, Ix: IndexType> Clone for EdgeReference<'_, E, Ix> {
73 fn clone(&self) -> Self {
74 *self
75 }
76}
77
78impl<E, Ix: IndexType> visit::EdgeRef for EdgeReference<'_, E, Ix> {
79 type NodeId = NodeIndex<Ix>;
80 type EdgeId = EdgeIndex<Ix>;
81 type Weight = E;
82 fn source(&self) -> Self::NodeId {
83 self.id.from
84 }
85 fn target(&self) -> Self::NodeId {
86 self.edge.suc
87 }
88 fn id(&self) -> Self::EdgeId {
89 self.id
90 }
91 fn weight(&self) -> &Self::Weight {
92 &self.edge.weight
93 }
94}
95
96#[derive(Debug, Clone)]
97pub struct EdgeIndices<'a, E, Ix: IndexType> {
98 rows: std::iter::Enumerate<std::slice::Iter<'a, Row<E, Ix>>>,
99 row_index: usize,
100 row_len: usize,
101 cur: usize,
102}
103
104impl<E, Ix: IndexType> Iterator for EdgeIndices<'_, E, Ix> {
105 type Item = EdgeIndex<Ix>;
106 fn next(&mut self) -> Option<EdgeIndex<Ix>> {
107 loop {
108 if self.cur < self.row_len {
109 let res = self.cur;
110 self.cur += 1;
111 return Some(EdgeIndex {
112 from: Ix::new(self.row_index),
113 successor_index: res,
114 });
115 } else {
116 match self.rows.next() {
117 Some((index, row)) => {
118 self.row_index = index;
119 self.cur = 0;
120 self.row_len = row.len();
121 }
122 None => return None,
123 }
124 }
125 }
126 }
127}
128
129iterator_wrap! {
130 impl (Iterator DoubleEndedIterator ExactSizeIterator) for
131 #[derive(Debug, Clone)]
133 struct NodeIndices <Ix> where {}
134 item: Ix,
135 iter: std::iter::Map<Range<usize>, fn(usize) -> Ix>,
136}
137
138#[derive(Clone, Default)]
155pub struct List<E, Ix = DefaultIx>
156where
157 Ix: IndexType,
158{
159 suc: Vec<Row<E, Ix>>,
160}
161
162impl<E, Ix: IndexType> List<E, Ix> {
163 pub fn new() -> List<E, Ix> {
165 List { suc: Vec::new() }
166 }
167
168 pub fn with_capacity(nodes: usize) -> List<E, Ix> {
170 List {
171 suc: Vec::with_capacity(nodes),
172 }
173 }
174
175 pub fn clear(&mut self) {
177 self.suc.clear()
178 }
179
180 pub fn edge_count(&self) -> usize {
184 self.suc.iter().map(|x| x.len()).sum()
185 }
186
187 pub fn add_node(&mut self) -> NodeIndex<Ix> {
190 let i = self.suc.len();
191 self.suc.push(Vec::new());
192 Ix::new(i)
193 }
194
195 pub fn add_node_with_capacity(&mut self, successors: usize) -> NodeIndex<Ix> {
198 let i = self.suc.len();
199 self.suc.push(Vec::with_capacity(successors));
200 Ix::new(i)
201 }
202
203 pub fn add_node_from_edges<I: Iterator<Item = (NodeIndex<Ix>, E)>>(
206 &mut self,
207 edges: I,
208 ) -> NodeIndex<Ix> {
209 let i = self.suc.len();
210 self.suc
211 .push(edges.map(|(suc, weight)| WSuc { suc, weight }).collect());
212 Ix::new(i)
213 }
214
215 pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
227 if b.index() >= self.suc.len() {
228 panic!(
229 "{} is not a valid node index for a {} nodes adjacency list",
230 b.index(),
231 self.suc.len()
232 );
233 }
234 let row = &mut self.suc[a.index()];
235 let rank = row.len();
236 row.push(WSuc { suc: b, weight });
237 EdgeIndex {
238 from: a,
239 successor_index: rank,
240 }
241 }
242
243 fn get_edge(&self, e: EdgeIndex<Ix>) -> Option<&WSuc<E, Ix>> {
244 self.suc
245 .get(e.from.index())
246 .and_then(|row| row.get(e.successor_index))
247 }
248
249 fn get_edge_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut WSuc<E, Ix>> {
250 self.suc
251 .get_mut(e.from.index())
252 .and_then(|row| row.get_mut(e.successor_index))
253 }
254
255 pub fn edge_endpoints(&self, e: EdgeIndex<Ix>) -> Option<(NodeIndex<Ix>, NodeIndex<Ix>)> {
259 self.get_edge(e).map(|x| (e.from, x.suc))
260 }
261
262 pub fn edge_indices_from(&self, a: NodeIndex<Ix>) -> OutgoingEdgeIndices<Ix> {
263 let proj: fn((usize, NodeIndex<Ix>)) -> EdgeIndex<Ix> =
264 |(successor_index, from)| EdgeIndex {
265 from,
266 successor_index,
267 };
268 let iter = (0..(self.suc[a.index()].len()))
269 .zip(std::iter::repeat(a))
270 .map(proj);
271 OutgoingEdgeIndices { iter }
272 }
273
274 pub fn contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
278 match self.suc.get(a.index()) {
279 None => false,
280 Some(row) => row.iter().any(|x| x.suc == b),
281 }
282 }
283
284 pub fn find_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Option<EdgeIndex<Ix>> {
288 self.suc.get(a.index()).and_then(|row| {
289 row.iter()
290 .enumerate()
291 .find(|(_, x)| x.suc == b)
292 .map(|(i, _)| EdgeIndex {
293 from: a,
294 successor_index: i,
295 })
296 })
297 }
298
299 pub fn node_indices(&self) -> NodeIndices<Ix> {
303 NodeIndices {
304 iter: (0..self.suc.len()).map(Ix::new),
305 }
306 }
307
308 pub fn edge_indices(&self) -> EdgeIndices<E, Ix> {
312 EdgeIndices {
313 rows: self.suc.iter().enumerate(),
314 row_index: 0,
315 row_len: 0,
316 cur: 0,
317 }
318 }
319}
320
321pub type UnweightedList<Ix> = List<(), Ix>;
323
324impl<E, Ix: IndexType> Build for List<E, Ix> {
325 fn add_node(&mut self, _weight: ()) -> NodeIndex<Ix> {
328 self.add_node()
329 }
330
331 fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> Option<EdgeIndex<Ix>> {
343 Some(self.add_edge(a, b, weight))
344 }
345
346 fn update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
355 let row = &mut self.suc[a.index()];
356 for (i, info) in row.iter_mut().enumerate() {
357 if info.suc == b {
358 info.weight = weight;
359 return EdgeIndex {
360 from: a,
361 successor_index: i,
362 };
363 }
364 }
365 let rank = row.len();
366 row.push(WSuc { suc: b, weight });
367 EdgeIndex {
368 from: a,
369 successor_index: rank,
370 }
371 }
372}
373
374impl<E, Ix> fmt::Debug for EdgeReferences<'_, E, Ix>
375where
376 E: fmt::Debug,
377 Ix: IndexType,
378{
379 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
380 let mut edge_list = f.debug_list();
381 let iter: Self = self.clone();
382 for e in iter {
383 if std::mem::size_of::<E>() != 0 {
384 edge_list.entry(&(
385 NoPretty((e.source().index(), e.target().index())),
386 e.weight(),
387 ));
388 } else {
389 edge_list.entry(&NoPretty((e.source().index(), e.target().index())));
390 }
391 }
392 edge_list.finish()
393 }
394}
395
396impl<E, Ix> fmt::Debug for List<E, Ix>
397where
398 E: fmt::Debug,
399 Ix: IndexType,
400{
401 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
402 let mut fmt_struct = f.debug_struct("adj::List");
403 fmt_struct.field("node_count", &self.node_count());
404 fmt_struct.field("edge_count", &self.edge_count());
405 if self.edge_count() > 0 {
406 fmt_struct.field("edges", &self.edge_references());
407 }
408 fmt_struct.finish()
409 }
410}
411
412impl<E, Ix> visit::GraphBase for List<E, Ix>
413where
414 Ix: IndexType,
415{
416 type NodeId = NodeIndex<Ix>;
417 type EdgeId = EdgeIndex<Ix>;
418}
419
420impl<E, Ix> visit::Visitable for List<E, Ix>
421where
422 Ix: IndexType,
423{
424 type Map = FixedBitSet;
425 fn visit_map(&self) -> FixedBitSet {
426 FixedBitSet::with_capacity(self.node_count())
427 }
428 fn reset_map(&self, map: &mut Self::Map) {
429 map.clear();
430 map.grow(self.node_count());
431 }
432}
433
434impl<E, Ix: IndexType> visit::IntoNodeIdentifiers for &List<E, Ix> {
435 type NodeIdentifiers = NodeIndices<Ix>;
436 fn node_identifiers(self) -> NodeIndices<Ix> {
437 self.node_indices()
438 }
439}
440
441impl<Ix: IndexType> visit::NodeRef for NodeIndex<Ix> {
442 type NodeId = NodeIndex<Ix>;
443 type Weight = ();
444 fn id(&self) -> Self::NodeId {
445 *self
446 }
447 fn weight(&self) -> &Self::Weight {
448 &()
449 }
450}
451
452impl<Ix: IndexType, E> visit::IntoNodeReferences for &List<E, Ix> {
453 type NodeRef = NodeIndex<Ix>;
454 type NodeReferences = NodeIndices<Ix>;
455 fn node_references(self) -> Self::NodeReferences {
456 self.node_indices()
457 }
458}
459
460impl<E, Ix: IndexType> visit::Data for List<E, Ix> {
461 type NodeWeight = ();
462 type EdgeWeight = E;
463}
464
465impl<'a, E, Ix: IndexType> IntoNeighbors for &'a List<E, Ix> {
466 type Neighbors = Neighbors<'a, E, Ix>;
467 fn neighbors(self, a: NodeIndex<Ix>) -> Self::Neighbors {
472 let proj: fn(&WSuc<E, Ix>) -> NodeIndex<Ix> = |x| x.suc;
473 let iter = self.suc[a.index()].iter().map(proj);
474 Neighbors { iter }
475 }
476}
477
478type SomeIter<'a, E, Ix> = std::iter::Map<
479 std::iter::Zip<std::iter::Enumerate<RowIter<'a, E, Ix>>, std::iter::Repeat<Ix>>,
480 fn(((usize, &'a WSuc<E, Ix>), Ix)) -> EdgeReference<'a, E, Ix>,
481>;
482
483iterator_wrap! {
484impl (Iterator) for
485struct EdgeReferences<'a, E, Ix> where { Ix: IndexType }
487item: EdgeReference<'a, E, Ix>,
488iter: std::iter::FlatMap<
489 std::iter::Enumerate<
490 std::slice::Iter<'a, Row<E, Ix>>
491 >,
492 SomeIter<'a, E, Ix>,
493 fn(
494 (usize, &'a Vec<WSuc<E, Ix>>)
495 ) -> SomeIter<'a, E, Ix>,
496>,
497}
498
499impl<E, Ix: IndexType> Clone for EdgeReferences<'_, E, Ix> {
500 fn clone(&self) -> Self {
501 EdgeReferences {
502 iter: self.iter.clone(),
503 }
504 }
505}
506
507fn proj1<E, Ix: IndexType>(
508 ((successor_index, edge), from): ((usize, &WSuc<E, Ix>), Ix),
509) -> EdgeReference<E, Ix> {
510 let id = EdgeIndex {
511 from,
512 successor_index,
513 };
514 EdgeReference { id, edge }
515}
516fn proj2<E, Ix: IndexType>((row_index, row): (usize, &Vec<WSuc<E, Ix>>)) -> SomeIter<E, Ix> {
517 row.iter()
518 .enumerate()
519 .zip(std::iter::repeat(Ix::new(row_index)))
520 .map(proj1 as _)
521}
522
523impl<'a, Ix: IndexType, E> visit::IntoEdgeReferences for &'a List<E, Ix> {
524 type EdgeRef = EdgeReference<'a, E, Ix>;
525 type EdgeReferences = EdgeReferences<'a, E, Ix>;
526 fn edge_references(self) -> Self::EdgeReferences {
527 let iter = self.suc.iter().enumerate().flat_map(proj2 as _);
528 EdgeReferences { iter }
529 }
530}
531
532iterator_wrap! {
533impl (Iterator) for
534#[derive(Debug, Clone)]
536struct OutgoingEdgeReferences<'a, E, Ix> where { Ix: IndexType }
537item: EdgeReference<'a, E, Ix>,
538iter: SomeIter<'a, E, Ix>,
539}
540
541impl<'a, Ix: IndexType, E> visit::IntoEdges for &'a List<E, Ix> {
542 type Edges = OutgoingEdgeReferences<'a, E, Ix>;
543 fn edges(self, a: Self::NodeId) -> Self::Edges {
544 let iter = self.suc[a.index()]
545 .iter()
546 .enumerate()
547 .zip(std::iter::repeat(a))
548 .map(proj1 as _);
549 OutgoingEdgeReferences { iter }
550 }
551}
552
553impl<E, Ix: IndexType> visit::GraphProp for List<E, Ix> {
554 type EdgeType = crate::Directed;
555 fn is_directed(&self) -> bool {
556 true
557 }
558}
559
560impl<E, Ix: IndexType> NodeCount for List<E, Ix> {
561 fn node_count(&self) -> usize {
565 self.suc.len()
566 }
567}
568
569impl<E, Ix: IndexType> EdgeCount for List<E, Ix> {
570 fn edge_count(&self) -> usize {
574 List::edge_count(self)
575 }
576}
577
578impl<E, Ix: IndexType> visit::NodeIndexable for List<E, Ix> {
579 fn node_bound(&self) -> usize {
580 self.node_count()
581 }
582 #[inline]
583 fn to_index(&self, a: Self::NodeId) -> usize {
584 a.index()
585 }
586 #[inline]
587 fn from_index(&self, i: usize) -> Self::NodeId {
588 Ix::new(i)
589 }
590}
591
592impl<E, Ix: IndexType> visit::NodeCompactIndexable for List<E, Ix> {}
593
594impl<E, Ix: IndexType> DataMap for List<E, Ix> {
595 fn node_weight(&self, n: Self::NodeId) -> Option<&()> {
596 if n.index() < self.suc.len() {
597 Some(&())
598 } else {
599 None
600 }
601 }
602
603 fn edge_weight(&self, e: EdgeIndex<Ix>) -> Option<&E> {
607 self.get_edge(e).map(|x| &x.weight)
608 }
609}
610
611impl<E, Ix: IndexType> DataMapMut for List<E, Ix> {
612 fn node_weight_mut(&mut self, n: Self::NodeId) -> Option<&mut ()> {
613 if n.index() < self.suc.len() {
614 let b = Box::new(());
617 Some(Box::leak(b))
618 } else {
619 None
620 }
621 }
622 fn edge_weight_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut E> {
626 self.get_edge_mut(e).map(|x| &mut x.weight)
627 }
628}
629
630impl<E, Ix> GetAdjacencyMatrix for List<E, Ix>
633where
634 Ix: IndexType,
635{
636 type AdjMatrix = FixedBitSet;
637
638 fn adjacency_matrix(&self) -> FixedBitSet {
639 let n = self.node_count();
640 let mut matrix = FixedBitSet::with_capacity(n * n);
641 for edge in self.edge_references() {
642 let i = edge.source().index() * n + edge.target().index();
643 matrix.put(i);
644 }
645 matrix
646 }
647
648 fn is_adjacent(&self, matrix: &FixedBitSet, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
649 let n = self.node_count();
650 let index = n * a.index() + b.index();
651 matrix.contains(index)
652 }
653}