Add reserve_vertices and reserve_edges to GraphTopologyAddition
This commit is contained in:
@@ -212,6 +212,14 @@ impl GraphTopologyAddition for AppendGraph {
|
|||||||
self.incidences.capacity() / 2
|
self.incidences.capacity() / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reserve_vertices(&mut self, additional: usize) {
|
||||||
|
self.vertices.reserve(additional);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_edges(&mut self, additional: usize) {
|
||||||
|
self.incidences.reserve(additional * 2);
|
||||||
|
}
|
||||||
|
|
||||||
fn add_vertex(&mut self) -> Self::Vertex {
|
fn add_vertex(&mut self) -> Self::Vertex {
|
||||||
self.vertices.push(VertexIncidenceHeader {
|
self.vertices.push(VertexIncidenceHeader {
|
||||||
incidence_count: 0,
|
incidence_count: 0,
|
||||||
|
|||||||
@@ -317,6 +317,14 @@ impl GraphTopologyAddition for Graph {
|
|||||||
self.incidences.capacity() / 2
|
self.incidences.capacity() / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reserve_vertices(&mut self, additional: usize) {
|
||||||
|
self.vertices.reserve(additional);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_edges(&mut self, additional: usize) {
|
||||||
|
self.incidences.reserve(additional * 2);
|
||||||
|
}
|
||||||
|
|
||||||
fn add_vertex(&mut self) -> Self::Vertex {
|
fn add_vertex(&mut self) -> Self::Vertex {
|
||||||
self.vertices.insert(VertexIncidenceHeader {
|
self.vertices.insert(VertexIncidenceHeader {
|
||||||
incidence_count: 0,
|
incidence_count: 0,
|
||||||
|
|||||||
@@ -852,7 +852,6 @@ macro_rules! graph_topology_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn incidence_cursor_copy() {
|
fn incidence_cursor_copy() {
|
||||||
use $crate::traits::{GraphTopology, IncidenceCursor};
|
use $crate::traits::{GraphTopology, IncidenceCursor};
|
||||||
// Constructs a graph with two vertices connected to `v`.
|
|
||||||
let mut graph = <$T>::new();
|
let mut graph = <$T>::new();
|
||||||
let v = graph.add_vertex();
|
let v = graph.add_vertex();
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
@@ -909,6 +908,90 @@ macro_rules! graph_topology_tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve_vertices_increases_capacity() {
|
||||||
|
use $crate::traits::GraphTopologyAddition;
|
||||||
|
let mut graph = <$T>::new();
|
||||||
|
let capacity_before = graph.vertex_capacity();
|
||||||
|
graph.reserve_vertices(capacity_before + 10);
|
||||||
|
assert!(
|
||||||
|
graph.vertex_capacity() > capacity_before,
|
||||||
|
"expected sufficient capacity increase after reserve"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve_vertices_prevents_reallocation_on_add() {
|
||||||
|
use $crate::traits::GraphTopologyAddition;
|
||||||
|
let mut graph = <$T>::new();
|
||||||
|
graph.reserve_vertices(10);
|
||||||
|
let capacity_before = graph.vertex_capacity();
|
||||||
|
for _ in 0..10 {
|
||||||
|
graph.add_vertex();
|
||||||
|
}
|
||||||
|
assert_eq!(
|
||||||
|
graph.vertex_capacity(),
|
||||||
|
capacity_before,
|
||||||
|
"writes within reserved capacity should not reallocate"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve_vertices_does_not_affect_edge_capacity() {
|
||||||
|
use $crate::traits::GraphTopologyAddition;
|
||||||
|
let mut graph = <$T>::new();
|
||||||
|
let capacity_before = graph.edge_capacity();
|
||||||
|
graph.reserve_vertices(10);
|
||||||
|
assert_eq!(
|
||||||
|
graph.edge_capacity(),
|
||||||
|
capacity_before,
|
||||||
|
"reserve_vertices must not change edge capacity"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve_edges_increases_capacity() {
|
||||||
|
use $crate::traits::GraphTopologyAddition;
|
||||||
|
let mut graph = <$T>::new();
|
||||||
|
let capacity_before = graph.edge_capacity();
|
||||||
|
graph.reserve_edges(capacity_before + 10);
|
||||||
|
assert!(
|
||||||
|
graph.edge_capacity() > capacity_before,
|
||||||
|
"expected sufficient capacity increase after reserve"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve_edges_prevents_reallocation_on_add() {
|
||||||
|
use $crate::traits::GraphTopologyAddition;
|
||||||
|
let mut graph = <$T>::new();
|
||||||
|
let v1 = graph.add_vertex();
|
||||||
|
let v2 = graph.add_vertex();
|
||||||
|
graph.reserve_edges(10);
|
||||||
|
let capacity_before = graph.edge_capacity();
|
||||||
|
for _ in 0..10 {
|
||||||
|
graph.add_edge(v1, v2);
|
||||||
|
}
|
||||||
|
assert_eq!(
|
||||||
|
graph.edge_capacity(),
|
||||||
|
capacity_before,
|
||||||
|
"writes within reserved capacity should not reallocate"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve_edges_does_not_affect_vertex_capacity() {
|
||||||
|
use $crate::traits::GraphTopologyAddition;
|
||||||
|
let mut graph = <$T>::new();
|
||||||
|
let capacity_before = graph.vertex_capacity();
|
||||||
|
graph.reserve_edges(10);
|
||||||
|
assert_eq!(
|
||||||
|
graph.vertex_capacity(),
|
||||||
|
capacity_before,
|
||||||
|
"reserve_edges must not change vertex capacity"
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-1
@@ -174,7 +174,6 @@ pub trait GraphTopology {
|
|||||||
fn incidence_cursor(&self, v: Self::Vertex) -> Self::IncidenceCursor;
|
fn incidence_cursor(&self, v: Self::Vertex) -> Self::IncidenceCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add functions to reserve memory for vertices and edges.
|
|
||||||
/// A trait that adds construction operations to an undirected graph topology.
|
/// A trait that adds construction operations to an undirected graph topology.
|
||||||
///
|
///
|
||||||
/// This trait provides methods for addition of vertices and edges, and capacity management in an
|
/// This trait provides methods for addition of vertices and edges, and capacity management in an
|
||||||
@@ -186,6 +185,20 @@ pub trait GraphTopologyAddition: GraphTopology {
|
|||||||
/// Returns the total number of edges the graph can hold without reallocating.
|
/// Returns the total number of edges the graph can hold without reallocating.
|
||||||
fn edge_capacity(&self) -> usize;
|
fn edge_capacity(&self) -> usize;
|
||||||
|
|
||||||
|
/// Reserves capacity for at least `additional` more vertices. Does nothing if capacity is
|
||||||
|
/// already sufficient.
|
||||||
|
///
|
||||||
|
/// Use this before adding multiple vertices to avoid incremental growth on each call to
|
||||||
|
/// [`add_vertex`].
|
||||||
|
fn reserve_vertices(&mut self, additional: usize);
|
||||||
|
|
||||||
|
/// Reserves capacity for at least `additional` more edges. Does nothing if capacity is already
|
||||||
|
/// sufficient.
|
||||||
|
///
|
||||||
|
/// Use this before adding multiple edges to avoid incremental growth on each call to
|
||||||
|
/// [`add_edge`].
|
||||||
|
fn reserve_edges(&mut self, additional: usize);
|
||||||
|
|
||||||
/// Adds a new isolated vertex and returns its handle.
|
/// Adds a new isolated vertex and returns its handle.
|
||||||
fn add_vertex(&mut self) -> Self::Vertex;
|
fn add_vertex(&mut self) -> Self::Vertex;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user