diff --git a/src/algorithms/graph_coarsening.rs b/src/algorithms/graph_coarsening.rs index 41ee843..04f4890 100644 --- a/src/algorithms/graph_coarsening.rs +++ b/src/algorithms/graph_coarsening.rs @@ -324,22 +324,20 @@ impl<'b> CloudPartition<'b> { fn cloud_partition<'a>(&mut self, graph: &'a Graph, visited: &'a mut FastBitvec) { let log = (graph.nodes as f32).log2() as usize; + let mut bfs_visited = FastBitvec::new(graph.nodes); while let Some(node) = visited.choice_0() { if graph.deleted.get(node) { visited.set(node, true); continue; } + self.start.set(node, true); let mut subgraph = Vec::new(); - let mut bfs_visited = FastBitvec::new(graph.nodes); - - StandardBFS::new_with_depth(&self.g_1, node, &mut bfs_visited, log) - .enumerate() - .map(|(_, n)| n) - .for_each(|n| { - visited.set(n, true); - subgraph.push(n); - }); + + StandardBFS::new_with_depth(&self.g_1, node, &mut bfs_visited, log).for_each(|n| { + visited.set(n, true); + subgraph.push(n); + }); if subgraph.len() >= log { subgraph.iter().for_each(|n| { @@ -507,8 +505,8 @@ impl<'a> GraphCoarsening<'a> { )); } } - discovered.bitvec.fill(false); } + discovered.bitvec.fill(false); } } } diff --git a/src/data_structures/bitvec.rs b/src/data_structures/bitvec.rs index 44566fd..cc94100 100644 --- a/src/data_structures/bitvec.rs +++ b/src/data_structures/bitvec.rs @@ -1,6 +1,7 @@ use bitvec::prelude::*; #[derive(Debug, PartialEq, Clone, Eq)] +/// A bit vector that allows to get the first 0 and the first 1 in O(1) time. pub struct FastBitvec { pub bitvec: BitVec, first_zero: Option, @@ -8,6 +9,14 @@ pub struct FastBitvec { } impl FastBitvec { + /// Create a new FastBitvec with a given size. + /// # Example + /// ``` + /// use star::data_structures::bitvec::FastBitvec; + /// let bitvec = FastBitvec::new(10); + /// assert_eq!(bitvec.size(), 10); + /// ``` + pub fn new(size: usize) -> Self { Self { bitvec: bitvec![0; size], @@ -16,10 +25,25 @@ impl FastBitvec { } } + /// Get the size of a bit vector. + /// # Example + /// ``` + /// use star::data_structures::bitvec::FastBitvec; + /// let bitvec = FastBitvec::new(10); + /// assert_eq!(bitvec.size(), 10); + /// ``` pub fn size(&self) -> usize { self.bitvec.len() } + /// Set a value in a bit vector at a given index. + /// # Example + /// ``` + /// use star::data_structures::bitvec::FastBitvec; + /// let mut bitvec = FastBitvec::new(10); + /// bitvec.set(0, true); + /// assert_eq!(bitvec.get(0), true); + /// ``` pub fn set(&mut self, index: usize, value: bool) { self.bitvec.set(index, value); @@ -39,6 +63,10 @@ impl FastBitvec { self.first_one = Some(index); } + if value && self.first_one.is_some() && index < self.first_one.unwrap() { + self.first_one = Some(index); + } + if !value && self.first_one == Some(index) { let mut next_one = None; @@ -50,25 +78,101 @@ impl FastBitvec { } self.first_one = next_one; } + + if !value && self.first_zero.is_some() && index < self.first_zero.unwrap() { + self.first_zero = Some(index); + } } + /// Get a value from a bit vector at a given index. + /// # Example + /// ``` + /// use star::data_structures::bitvec::FastBitvec; + /// let mut bitvec = FastBitvec::new(10); + /// bitvec.set(0, true); + /// assert_eq!(bitvec.get(0), true); + /// ``` pub fn get(&self, index: usize) -> bool { *self.bitvec.get(index).as_deref().unwrap() } + /// Iterate over all ones in a bit vector. + /// # Example + /// ``` + /// use star::data_structures::bitvec::FastBitvec; + /// let mut bitvec = FastBitvec::new(10); + /// bitvec.set(0, true); + /// let mut iter = bitvec.iter_1(); + /// assert_eq!(iter.next(), Some(0)); + /// ``` pub fn iter_1(&self) -> impl Iterator + '_ { self.bitvec.iter_ones() } + /// Iterate over all zeros in a bit vector. + /// # Example + /// ``` + /// use star::data_structures::bitvec::FastBitvec; + /// let mut bitvec = FastBitvec::new(10); + /// let mut iter = bitvec.iter_0(); + /// assert_eq!(iter.next(), Some(0)); + /// ``` pub fn iter_0(&self) -> impl Iterator + '_ { self.bitvec.iter_zeros() } + /// Get the first zero in a bit vector. + /// # Example + /// ``` + /// use star::data_structures::bitvec::FastBitvec; + /// let mut bitvec = FastBitvec::new(10); + /// bitvec.set(0, true); + /// assert_eq!(bitvec.choice_0(), Some(1)); + /// ``` pub fn choice_0(&self) -> Option { self.first_zero } + /// Get the first one in a bit vector. + /// # Example + /// ``` + /// use star::data_structures::bitvec::FastBitvec; + /// let mut bitvec = FastBitvec::new(10); + /// bitvec.set(0, true); + /// assert_eq!(bitvec.choice_1(), Some(0)); + /// ``` pub fn choice_1(&self) -> Option { self.first_one } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_fast_bitvec() { + let mut bitvec = FastBitvec::new(10); + assert_eq!(bitvec.size(), 10); + + bitvec.set(0, true); + assert_eq!(bitvec.get(0), true); + assert_eq!(bitvec.choice_1(), Some(0)); + assert_eq!(bitvec.choice_0(), Some(1)); + + bitvec.set(1, true); + assert_eq!(bitvec.get(1), true); + assert_eq!(bitvec.choice_1(), Some(0)); + assert_eq!(bitvec.choice_0(), Some(2)); + + bitvec.set(0, false); + assert_eq!(bitvec.get(0), false); + assert_eq!(bitvec.choice_1(), Some(1)); + assert_eq!(bitvec.choice_0(), Some(0)); + + bitvec.set(1, false); + assert_eq!(bitvec.get(1), false); + assert_eq!(bitvec.choice_1(), None); + assert_eq!(bitvec.choice_0(), Some(0)); + } +} diff --git a/src/data_structures/graph.rs b/src/data_structures/graph.rs index 193b108..2c64565 100644 --- a/src/data_structures/graph.rs +++ b/src/data_structures/graph.rs @@ -323,7 +323,7 @@ impl Graph { let file = File::create(path)?; let mut writer = BufWriter::new(file); - writer.write_all(format!("{}\n", self.nodes).as_bytes())?; + writer.write_all(format!("{}\n", self.nodes - self.deleted.iter_1().count()).as_bytes())?; let num_edges = self.edges.iter().fold(0, |acc, e| acc + e.len());