Skip to content

Commit

Permalink
Merge pull request #46 from thm-mni-ii/45-bugfix
Browse files Browse the repository at this point in the history
fixed bugs
  • Loading branch information
jmeintrup authored Apr 24, 2024
2 parents ee507c7 + 81ffb97 commit 3a5e906
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 11 deletions.
18 changes: 8 additions & 10 deletions src/algorithms/graph_coarsening.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down Expand Up @@ -507,8 +505,8 @@ impl<'a> GraphCoarsening<'a> {
));
}
}
discovered.bitvec.fill(false);
}
discovered.bitvec.fill(false);
}
}
}
Expand Down
104 changes: 104 additions & 0 deletions src/data_structures/bitvec.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
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<usize>,
first_one: Option<usize>,
}

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],
Expand All @@ -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);

Expand All @@ -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;

Expand All @@ -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<Item = usize> + '_ {
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<Item = usize> + '_ {
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<usize> {
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<usize> {
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));
}
}
2 changes: 1 addition & 1 deletion src/data_structures/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down

0 comments on commit 3a5e906

Please sign in to comment.