2323use std:: fmt:: Debug ;
2424
2525use rustc_index:: bit_set:: DenseBitSet ;
26+ use rustc_index:: { Idx , IndexSlice , IndexVec } ;
2627use tracing:: debug;
2728
2829#[ cfg( test) ]
@@ -45,13 +46,13 @@ mod tests;
4546/// and does not implement those traits, so it has its own implementations of a
4647/// few basic graph algorithms.
4748pub struct LinkedGraph < N , E > {
48- nodes : Vec < Node < N > > ,
49+ nodes : IndexVec < NodeIndex , Node < N > > ,
4950 edges : Vec < Edge < E > > ,
5051}
5152
5253pub struct Node < N > {
5354 first_edge : [ EdgeIndex ; 2 ] , // see module comment
54- pub data : N ,
55+ pub data : Option < N > ,
5556}
5657
5758#[ derive( Debug ) ]
@@ -62,7 +63,7 @@ pub struct Edge<E> {
6263 pub data : E ,
6364}
6465
65- #[ derive( Copy , Clone , PartialEq , Debug ) ]
66+ #[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug ) ]
6667pub struct NodeIndex ( pub usize ) ;
6768
6869#[ derive( Copy , Clone , PartialEq , Debug ) ]
@@ -87,19 +88,29 @@ impl NodeIndex {
8788 }
8889}
8990
91+ impl Idx for NodeIndex {
92+ fn new ( idx : usize ) -> NodeIndex {
93+ NodeIndex ( idx)
94+ }
95+
96+ fn index ( self ) -> usize {
97+ self . 0
98+ }
99+ }
100+
90101impl < N : Debug , E : Debug > LinkedGraph < N , E > {
91102 pub fn new ( ) -> Self {
92- Self { nodes : Vec :: new ( ) , edges : Vec :: new ( ) }
103+ Self { nodes : IndexVec :: new ( ) , edges : Vec :: new ( ) }
93104 }
94105
95106 pub fn with_capacity ( nodes : usize , edges : usize ) -> Self {
96- Self { nodes : Vec :: with_capacity ( nodes) , edges : Vec :: with_capacity ( edges) }
107+ Self { nodes : IndexVec :: with_capacity ( nodes) , edges : Vec :: with_capacity ( edges) }
97108 }
98109
99110 // # Simple accessors
100111
101112 #[ inline]
102- pub fn all_nodes ( & self ) -> & [ Node < N > ] {
113+ pub fn all_nodes ( & self ) -> & IndexSlice < NodeIndex , Node < N > > {
103114 & self . nodes
104115 }
105116
@@ -124,22 +135,34 @@ impl<N: Debug, E: Debug> LinkedGraph<N, E> {
124135 NodeIndex ( self . nodes . len ( ) )
125136 }
126137
138+ fn ensure_node ( & mut self , idx : NodeIndex ) -> & mut Node < N > {
139+ self . nodes . ensure_contains_elem ( idx, || Node {
140+ first_edge : [ INVALID_EDGE_INDEX , INVALID_EDGE_INDEX ] ,
141+ data : None ,
142+ } )
143+ }
144+
145+ pub fn add_node_with_idx ( & mut self , idx : NodeIndex , data : N ) {
146+ let old_data = self . ensure_node ( idx) . data . replace ( data) ;
147+ debug_assert ! ( old_data. is_none( ) ) ;
148+ }
149+
127150 pub fn add_node ( & mut self , data : N ) -> NodeIndex {
128151 let idx = self . next_node_index ( ) ;
129- self . nodes . push ( Node { first_edge : [ INVALID_EDGE_INDEX , INVALID_EDGE_INDEX ] , data } ) ;
152+ self . add_node_with_idx ( idx , data) ;
130153 idx
131154 }
132155
133156 pub fn mut_node_data ( & mut self , idx : NodeIndex ) -> & mut N {
134- & mut self . nodes [ idx. 0 ] . data
157+ self . nodes [ idx] . data . as_mut ( ) . unwrap ( )
135158 }
136159
137160 pub fn node_data ( & self , idx : NodeIndex ) -> & N {
138- & self . nodes [ idx. 0 ] . data
161+ self . nodes [ idx] . data . as_ref ( ) . unwrap ( )
139162 }
140163
141164 pub fn node ( & self , idx : NodeIndex ) -> & Node < N > {
142- & self . nodes [ idx. 0 ]
165+ & self . nodes [ idx]
143166 }
144167
145168 // # Edge construction and queries
@@ -154,16 +177,16 @@ impl<N: Debug, E: Debug> LinkedGraph<N, E> {
154177 let idx = self . next_edge_index ( ) ;
155178
156179 // read current first of the list of edges from each node
157- let source_first = self . nodes [ source. 0 ] . first_edge [ OUTGOING . repr ] ;
158- let target_first = self . nodes [ target. 0 ] . first_edge [ INCOMING . repr ] ;
180+ let source_first = self . ensure_node ( source) . first_edge [ OUTGOING . repr ] ;
181+ let target_first = self . ensure_node ( target) . first_edge [ INCOMING . repr ] ;
159182
160183 // create the new edge, with the previous firsts from each node
161184 // as the next pointers
162185 self . edges . push ( Edge { next_edge : [ source_first, target_first] , source, target, data } ) ;
163186
164187 // adjust the firsts for each node target be the next object.
165- self . nodes [ source. 0 ] . first_edge [ OUTGOING . repr ] = idx;
166- self . nodes [ target. 0 ] . first_edge [ INCOMING . repr ] = idx;
188+ self . nodes [ source] . first_edge [ OUTGOING . repr ] = idx;
189+ self . nodes [ target] . first_edge [ INCOMING . repr ] = idx;
167190
168191 idx
169192 }
0 commit comments