Remove scratch graph object

This commit is contained in:
Christopher Berner 2020-01-13 22:43:55 -08:00
parent f6829719e2
commit 69187f6e2d
2 changed files with 17 additions and 27 deletions

@ -7,16 +7,10 @@ pub struct UndirectedGraph {
} }
impl UndirectedGraph { impl UndirectedGraph {
pub fn new() -> UndirectedGraph { pub fn with_capacity(edges: usize) -> UndirectedGraph {
UndirectedGraph { edges: vec![] } UndirectedGraph {
} edges: Vec::with_capacity(edges * 2),
}
pub fn size_in_bytes(&self) -> usize {
size_of::<Self>() + size_of::<(usize, usize)>() * self.edges.len()
}
pub fn reset(&mut self) {
self.edges.clear();
} }
pub fn add_edge(&mut self, node1: u16, node2: u16) { pub fn add_edge(&mut self, node1: u16, node2: u16) {
@ -24,7 +18,7 @@ impl UndirectedGraph {
self.edges.push((node2, node1)); self.edges.push((node2, node1));
} }
pub fn build_graph(&mut self) { pub fn build(&mut self) {
self.edges.sort_unstable(); self.edges.sort_unstable();
} }
@ -51,7 +45,7 @@ impl UndirectedGraph {
return result; return result;
} }
pub fn keys(&self) -> Vec<u16> { pub fn nodes(&self) -> Vec<u16> {
let mut result = vec![]; let mut result = vec![];
for &(node, _) in self.edges.iter() { for &(node, _) in self.edges.iter() {
if result.is_empty() || result[result.len() - 1] != node { if result.is_empty() || result[result.len() - 1] != node {

@ -38,8 +38,6 @@ struct FirstPhaseRowSelectionStats {
end_col: usize, end_col: usize,
start_row: usize, start_row: usize,
rows_with_single_one: Vec<usize>, rows_with_single_one: Vec<usize>,
// Scratch data struct that is reused across calls because it's expensive to construct
scratch_adjacent_nodes: UndirectedGraph,
} }
impl FirstPhaseRowSelectionStats { impl FirstPhaseRowSelectionStats {
@ -54,7 +52,6 @@ impl FirstPhaseRowSelectionStats {
end_col, end_col,
start_row: 0, start_row: 0,
rows_with_single_one: vec![], rows_with_single_one: vec![],
scratch_adjacent_nodes: UndirectedGraph::new(),
}; };
for row in 0..matrix.height() { for row in 0..matrix.height() {
@ -78,7 +75,6 @@ impl FirstPhaseRowSelectionStats {
bytes += self.original_degree.size_in_bytes(); bytes += self.original_degree.size_in_bytes();
bytes += self.ones_per_row.size_in_bytes(); bytes += self.ones_per_row.size_in_bytes();
bytes += self.ones_histogram.size_in_bytes(); bytes += self.ones_histogram.size_in_bytes();
bytes += self.scratch_adjacent_nodes.size_in_bytes();
bytes bytes
} }
@ -165,11 +161,11 @@ impl FirstPhaseRowSelectionStats {
#[inline(never)] #[inline(never)]
fn first_phase_graph_substep_build_adjacency<T: BinaryMatrix>( fn first_phase_graph_substep_build_adjacency<T: BinaryMatrix>(
&mut self, &self,
rows_with_two_ones: &[usize], rows_with_two_ones: &[usize],
matrix: &T, matrix: &T,
) { ) -> UndirectedGraph {
self.scratch_adjacent_nodes.reset(); let mut graph = UndirectedGraph::with_capacity(rows_with_two_ones.len());
for row in rows_with_two_ones.iter() { for row in rows_with_two_ones.iter() {
let mut ones = [0; 2]; let mut ones = [0; 2];
@ -190,28 +186,28 @@ impl FirstPhaseRowSelectionStats {
} }
} }
assert_eq!(found, 2); assert_eq!(found, 2);
self.scratch_adjacent_nodes graph.add_edge(ones[0] as u16, ones[1] as u16);
.add_edge(ones[0] as u16, ones[1] as u16);
} }
self.scratch_adjacent_nodes.build_graph(); graph.build();
return graph;
} }
#[inline(never)] #[inline(never)]
fn first_phase_graph_substep<T: BinaryMatrix>( fn first_phase_graph_substep<T: BinaryMatrix>(
&mut self, &self,
start_row: usize, start_row: usize,
end_row: usize, end_row: usize,
rows_with_two_ones: &[usize], rows_with_two_ones: &[usize],
matrix: &T, matrix: &T,
) -> usize { ) -> usize {
self.first_phase_graph_substep_build_adjacency(rows_with_two_ones, matrix); let graph = self.first_phase_graph_substep_build_adjacency(rows_with_two_ones, matrix);
let mut visited = BoolArrayMap::new(start_row, end_row); let mut visited = BoolArrayMap::new(start_row, end_row);
let mut examplar_largest_component_node = None; let mut examplar_largest_component_node = None;
let mut largest_component_size = 0; let mut largest_component_size = 0;
let mut node_queue = Vec::with_capacity(10); let mut node_queue = Vec::with_capacity(10);
for key in self.scratch_adjacent_nodes.keys() { for key in graph.nodes() {
let mut component_size = 0; let mut component_size = 0;
// We can choose any edge (row) that connects this col to another in the graph // We can choose any edge (row) that connects this col to another in the graph
let mut examplar_node = None; let mut examplar_node = None;
@ -225,7 +221,7 @@ impl FirstPhaseRowSelectionStats {
} }
visited.insert(node as usize, true); visited.insert(node as usize, true);
component_size += 1; component_size += 1;
for next_node in self.scratch_adjacent_nodes.get_adjacent_nodes(node) { for next_node in graph.get_adjacent_nodes(node) {
node_queue.push(next_node); node_queue.push(next_node);
examplar_node = Some(node); examplar_node = Some(node);
} }
@ -301,7 +297,7 @@ impl FirstPhaseRowSelectionStats {
// selects from [start_row, end_row) reading [start_col, end_col) // selects from [start_row, end_row) reading [start_col, end_col)
// Returns (the chosen row, and "r" number of non-zero values the row has) // Returns (the chosen row, and "r" number of non-zero values the row has)
pub fn first_phase_selection<T: BinaryMatrix>( pub fn first_phase_selection<T: BinaryMatrix>(
&mut self, &self,
start_row: usize, start_row: usize,
end_row: usize, end_row: usize,
matrix: &T, matrix: &T,