@@ -26,20 +26,16 @@ fn peer_nodes_impl(mut graph: impl GraphRef, base_node: NodeId) -> Vec<PeerNode>
2626 let mut nodes = Vec :: new ( ) ;
2727
2828 // Depth 1 paths
29- for parent_side in Side :: iter ( ) {
30- let parent_node = graph. neighbor ( base_node, parent_side) ;
31- if graph. depth ( parent_node) >= graph. depth ( base_node) {
32- continue ;
33- }
29+ for ( parent_side, parent_node) in graph. parents ( base_node) {
3430 for & child_side in & DEPTH1_CHILD_PATHS [ parent_side as usize ] {
35- let peer_node = graph. neighbor ( parent_node, child_side) ;
36- if graph . depth ( peer_node ) == graph . depth ( base_node ) {
37- nodes . push ( PeerNode {
38- node_id : peer_node ,
39- parent_path : ArrayVec :: from_iter ( [ parent_side ] ) ,
40- child_path : ArrayVec :: from_iter ( [ child_side ] ) ,
41- } ) ;
42- }
31+ let Some ( peer_node) = graph. child ( parent_node, child_side) else {
32+ continue ;
33+ } ;
34+ nodes . push ( PeerNode {
35+ node_id : peer_node ,
36+ parent_path : ArrayVec :: from_iter ( [ parent_side ] ) ,
37+ child_path : ArrayVec :: from_iter ( [ child_side ] ) ,
38+ } ) ;
4339 }
4440 }
4541
@@ -53,15 +49,17 @@ fn peer_nodes_impl(mut graph: impl GraphRef, base_node: NodeId) -> Vec<PeerNode>
5349 continue ;
5450 }
5551 for & child_sides in & DEPTH2_CHILD_PATHS [ parent_side0 as usize ] [ parent_side1 as usize ] {
56- let peer_node_parent = graph. neighbor ( parent_node1, child_sides[ 0 ] ) ;
57- let peer_node = graph. neighbor ( peer_node_parent, child_sides[ 1 ] ) ;
58- if graph. depth ( peer_node) == graph. depth ( base_node) {
59- nodes. push ( PeerNode {
60- node_id : peer_node,
61- parent_path : ArrayVec :: from_iter ( [ parent_side0, parent_side1] ) ,
62- child_path : ArrayVec :: from_iter ( child_sides) ,
63- } ) ;
64- }
52+ let Some ( peer_node_parent) = graph. child ( parent_node1, child_sides[ 0 ] ) else {
53+ continue ;
54+ } ;
55+ let Some ( peer_node) = graph. child ( peer_node_parent, child_sides[ 1 ] ) else {
56+ continue ;
57+ } ;
58+ nodes. push ( PeerNode {
59+ node_id : peer_node,
60+ parent_path : ArrayVec :: from_iter ( [ parent_side0, parent_side1] ) ,
61+ child_path : ArrayVec :: from_iter ( child_sides) ,
62+ } ) ;
6563 }
6664 }
6765 }
@@ -168,6 +166,16 @@ trait GraphRef: AsRef<Graph> {
168166 fn depth ( & self , node : NodeId ) -> u32 ;
169167 fn neighbor ( & mut self , node : NodeId , side : Side ) -> NodeId ;
170168 fn parents ( & self , node : NodeId ) -> impl ExactSizeIterator < Item = ( Side , NodeId ) > + use < Self > ;
169+
170+ /// A helper function that returns the node at the particular side if it's a child, or `None` if it's a parent.
171+ fn child ( & mut self , node : NodeId , side : Side ) -> Option < NodeId > {
172+ let candidate_child = self . neighbor ( node, side) ;
173+ if self . depth ( candidate_child) > self . depth ( node) {
174+ Some ( candidate_child)
175+ } else {
176+ None
177+ }
178+ }
171179}
172180
173181/// A `GraphRef` that asserts that all the nodes it needs already exist
@@ -242,11 +250,8 @@ mod tests {
242250 #[ test]
243251 fn peer_traverser_example ( ) {
244252 let mut graph = Graph :: new ( 1 ) ;
245- let base_node = node_from_path (
246- & mut graph,
247- NodeId :: ROOT ,
248- [ Side :: B , Side :: D , Side :: C , Side :: A ] ,
249- ) ;
253+ let base_node_path = [ Side :: B , Side :: D , Side :: C , Side :: A ] ;
254+ let base_node = node_from_path ( & mut graph, NodeId :: ROOT , base_node_path) ;
250255
251256 let expected_paths: & [ ( & [ Side ] , & [ Side ] ) ] = & [
252257 ( & [ Side :: A ] , & [ Side :: B ] ) ,
@@ -265,7 +270,7 @@ mod tests {
265270
266271 let peers = ensure_peer_nodes ( & mut graph, base_node) ;
267272 assert_eq ! ( peers. len( ) , expected_paths. len( ) ) ;
268- for ( peer, expected_path) in peers. into_iter ( ) . zip ( expected_paths) {
273+ for ( peer, expected_path) in peers. iter ( ) . zip ( expected_paths) {
269274 assert_eq ! (
270275 peer. peer_to_shared( ) . collect:: <Vec <_>>( ) ,
271276 expected_path. 0 . to_vec( ) ,
@@ -275,6 +280,28 @@ mod tests {
275280 expected_path. 1 . to_vec( ) ,
276281 ) ;
277282 }
283+
284+ // Assert that the graph isn't expanded any more than necessary by generating
285+ // a reference graph with the same base node and peer nodes manually.
286+ let mut reference_graph = Graph :: new ( 1 ) ;
287+ assert_eq ! (
288+ base_node,
289+ node_from_path( & mut reference_graph, NodeId :: ROOT , base_node_path) ,
290+ "Sanity check for reusing base_node"
291+ ) ;
292+ for peer in & peers {
293+ // Generate the peer node by taking the path from the base node to the peer node via their shared parent.
294+ node_from_path (
295+ & mut reference_graph,
296+ base_node,
297+ peer. parent_path
298+ . iter ( )
299+ . cloned ( )
300+ . chain ( peer. child_path . iter ( ) . cloned ( ) ) ,
301+ ) ;
302+ }
303+
304+ assert_eq ! ( graph. len( ) , reference_graph. len( ) ) ;
278305 }
279306
280307 #[ test]
0 commit comments