diff --git a/Cargo.toml b/Cargo.toml index b063356..17d64d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grapherity" -version = "0.2.1" +version = "0.2.2" authors = ["Stefan Müller"] edition = "2024" rust-version = "1.85.0" diff --git a/src/algorithms.rs b/src/algorithms.rs index 730ed4c..b974441 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -122,12 +122,12 @@ where G: GraphTopology, { let mut predecessors = graph.vertex_map(None); - let (distances, _) = bfs_impl(graph, source, |neighbor, predecessor| { + let result = bfs_impl(graph, source, |neighbor, predecessor| { predecessors[neighbor] = Some(predecessor); true }); BfsResult { - distances, + distances: result.distances, predecessors, } } @@ -136,7 +136,7 @@ pub fn bfs_distances(graph: &G, source: G::Vertex) -> VertexMap(graph: &G, source: G::Vertex, target: G::Vertex) -> Option @@ -154,14 +154,15 @@ where if predicate(source) { return Some((source, 0)); } - bfs_impl(graph, source, |neighbor, _| !predicate(neighbor)).1 + bfs_impl(graph, source, |neighbor, _| !predicate(neighbor)).found } -fn bfs_impl( - graph: &G, - source: G::Vertex, - mut on_discover: F, -) -> (VertexMap>, Option<(G::Vertex, u32)>) +struct BfsImplResult { + distances: VertexMap>, + found: Option<(V, u32)>, +} + +fn bfs_impl(graph: &G, source: G::Vertex, mut on_discover: F) -> BfsImplResult where G: GraphTopology, F: FnMut(G::Vertex, G::Vertex) -> bool, @@ -178,13 +179,19 @@ where let distance = distances[v].unwrap() + 1; distances[neighbor] = Some(distance); if !on_discover(neighbor, v) { - return (distances, Some((neighbor, distance))); + return BfsImplResult { + distances, + found: Some((neighbor, distance)), + }; } queue.push_back(neighbor); } } } - (distances, None) + BfsImplResult { + distances, + found: None, + } } pub struct DfsResult { @@ -197,12 +204,12 @@ where G: GraphTopology, { let mut predecessors = graph.vertex_map(None); - let (visited, _) = dfs_impl(graph, source, |neighbor, predecessor| { + let result = dfs_impl(graph, source, |neighbor, predecessor| { predecessors[neighbor] = Some(predecessor); true }); DfsResult { - visited, + visited: result.visited, predecessors, } } @@ -211,7 +218,7 @@ pub fn dfs_visited(graph: &G, source: G::Vertex) -> VertexMap(graph: &G, source: G::Vertex, target: G::Vertex) -> bool @@ -229,14 +236,15 @@ where if predicate(source) { return Some(source); } - dfs_impl(graph, source, |neighbor, _| !predicate(neighbor)).1 + dfs_impl(graph, source, |neighbor, _| !predicate(neighbor)).found } -fn dfs_impl( - graph: &G, - source: G::Vertex, - mut on_discover: F, -) -> (VertexMap, Option) +struct DfsImplResult { + visited: VertexMap, + found: Option, +} + +fn dfs_impl(graph: &G, source: G::Vertex, mut on_discover: F) -> DfsImplResult where G: GraphTopology, F: FnMut(G::Vertex, G::Vertex) -> bool, @@ -248,7 +256,10 @@ where while let Some((v, predecessor)) = stack.pop() { if let Some(p) = predecessor { if !on_discover(v, p) { - return (visited, Some(v)); + return DfsImplResult { + visited, + found: Some(v), + }; } } for neighbor in graph.adjacent_vertices(v) { @@ -258,7 +269,10 @@ where } } } - (visited, None) + DfsImplResult { + visited, + found: None, + } } pub fn dfs_find_path(graph: &G, source: G::Vertex, target: G::Vertex) -> Option> diff --git a/src/maps.rs b/src/maps.rs index b7c24ef..1bda1a1 100644 --- a/src/maps.rs +++ b/src/maps.rs @@ -13,11 +13,17 @@ impl VertexMap { } } - // Reads beyond len() are valid and return the default value. - pub fn len(&self) -> usize { - self.inner.len() + // Reads beyond 'capacity' are valid and return the default value. + pub fn capacity(&self) -> usize { + self.inner.capacity() } + #[deprecated(since = "0.2.2", note = "use 'capacity' instead")] + pub fn len(&self) -> usize { + self.capacity() + } + + pub fn sync>(&mut self, graph: &G) { self.inner.resize(graph.vertex_capacity()); } @@ -48,9 +54,14 @@ impl EdgeMap { } } - // Reads beyond len() are valid and return the default value. + // Reads beyond 'capacity' are valid and return the default value. + pub fn capacity(&self) -> usize { + self.inner.capacity() + } + + #[deprecated(since = "0.2.2", note = "use 'capacity' instead")] pub fn len(&self) -> usize { - self.inner.len() + self.capacity() } pub fn sync>(&mut self, graph: &G) { @@ -87,7 +98,7 @@ impl EntityMap { } } - pub fn len(&self) -> usize { + pub fn capacity(&self) -> usize { self.data.len() } diff --git a/src/testing/maps_testing.rs b/src/testing/maps_testing.rs index 202b2db..e8b5362 100644 --- a/src/testing/maps_testing.rs +++ b/src/testing/maps_testing.rs @@ -53,16 +53,16 @@ macro_rules! vertex_map_tests { let mut graph = <$T>::new(); graph.add_vertex(); let mut map = graph.vertex_map(42); - let initial_len = map.len(); - while graph.vertex_capacity() <= initial_len { + let capacity_before = map.capacity(); + while graph.vertex_capacity() <= capacity_before { graph.add_vertex(); } assert!( - map.len() < graph.vertex_capacity(), + map.capacity() < graph.vertex_capacity(), "precondition: map is stale before sync" ); map.sync(&graph); - assert_eq!(map.len(), graph.vertex_capacity()); + assert_eq!(map.capacity(), graph.vertex_capacity()); } #[test] @@ -109,7 +109,7 @@ macro_rules! vertex_map_deletion_tests { let capacity_before = graph.vertex_capacity(); graph.delete_vertex(v2); map.sync(&graph); - assert_eq!(map.len(), capacity_before); + assert_eq!(map.capacity(), capacity_before); assert_eq!(map[v1], 5); } @@ -197,16 +197,16 @@ macro_rules! edge_map_tests { let v2 = graph.add_vertex(); graph.add_edge(v1, v2); let mut map = graph.edge_map(42); - let initial_len = map.len(); - while graph.edge_capacity() <= initial_len { + let capacity_before = map.capacity(); + while graph.edge_capacity() <= capacity_before { graph.add_edge(v1, v2); } assert!( - map.len() < graph.edge_capacity(), + map.capacity() < graph.edge_capacity(), "precondition: map is stale before sync" ); map.sync(&graph); - assert_eq!(map.len(), graph.edge_capacity()); + assert_eq!(map.capacity(), graph.edge_capacity()); } #[test] @@ -259,7 +259,7 @@ macro_rules! edge_map_deletion_tests { let capacity_before = graph.edge_capacity(); graph.delete_edge(e2); map.sync(&graph); - assert_eq!(map.len(), capacity_before); + assert_eq!(map.capacity(), capacity_before); assert_eq!(map[e1], 5); }