Find the next set of gap ids for a given set of nodes

This commit is contained in:
Jeremy Wall 2022-09-05 10:16:34 -04:00
parent bf5eb0d2b5
commit fdf79c26b1
2 changed files with 117 additions and 0 deletions

View File

@ -152,6 +152,40 @@ where
})
}
/// Find the immediate next non descendant nodes in this graph for the given `search_nodes`.
pub fn find_next_non_descendant_nodes(
&self,
search_nodes: &BTreeSet<Vec<u8>>,
) -> Result<Vec<Node<HW>>> {
let mut stack: Vec<Vec<u8>> = dbg!(self.roots.iter().cloned().collect());
dbg!(search_nodes);
let mut ids = BTreeSet::new();
while !stack.is_empty() {
let node_id = dbg!(stack.pop().unwrap());
let node = self.get_node_by_id(node_id.as_slice())?.unwrap();
let deps = node.dependency_ids();
if dbg!(deps.len()) == 0 {
// This is a leaf node which means it's the beginning of a sub graph
// the search_nodes_are not part of.
ids.insert(node.id().to_owned());
}
for dep in deps {
// We found one of the search roots.
if dbg!(search_nodes.contains(dep.as_slice())) {
// This means that the previous node is a parent of the search_roots.
ids.insert(node.id().to_owned());
continue;
}
stack.push(dep.to_owned())
}
}
let mut result = Vec::new();
for id in ids {
result.push(self.get_node_by_id(id.as_slice())?.unwrap());
}
Ok(result)
}
fn search_graph(&self, root_id: &[u8], search_id: &[u8]) -> Result<bool> {
if root_id == search_id {
return Ok(true);

View File

@ -173,6 +173,89 @@ fn test_node_comparison_no_shared_graph() {
);
}
#[test]
fn test_find_next_missing_nodes_disjoint_graphs_no_deps() {
let mut dag1 = TestDag::new(BTreeMap::new());
let mut dag2 = TestDag::new(BTreeMap::new());
let quake_node_id = dag1.add_node("quake", BTreeSet::new()).unwrap();
let qualm_node_id = dag1.add_node("qualm", BTreeSet::new()).unwrap();
dag2.add_node("quell", BTreeSet::new()).unwrap();
let missing_nodes = dag1
.find_next_non_descendant_nodes(dag2.get_roots())
.unwrap();
assert_eq!(missing_nodes.len(), 2);
let mut found_quake = false;
let mut found_qualm = false;
for node in missing_nodes {
if node.id().to_owned() == quake_node_id {
found_quake = true;
}
if node.id().to_owned() == qualm_node_id {
found_qualm = true;
}
}
assert!(found_quake);
assert!(found_qualm);
}
#[test]
fn test_find_next_missing_nodes_sub_graphs_one_degree_off() {
let mut dag1 = TestDag::new(BTreeMap::new());
let mut dag2 = TestDag::new(BTreeMap::new());
dag1.add_node("quake", BTreeSet::new()).unwrap();
let quake_node_id = dag2.add_node("quake", BTreeSet::new()).unwrap();
let mut deps = BTreeSet::new();
deps.insert(quake_node_id);
let qualm_node_id = dag1.add_node("qualm", deps).unwrap();
let missing_nodes = dag1
.find_next_non_descendant_nodes(dag2.get_roots())
.unwrap();
assert_eq!(missing_nodes.len(), 1);
let mut found_qualm = false;
for node in missing_nodes {
if node.id().to_owned() == qualm_node_id {
found_qualm = true;
}
}
assert!(found_qualm);
}
#[test]
fn test_find_next_missing_nodes_sub_graphs_two_degree_off() {
let mut dag1 = TestDag::new(BTreeMap::new());
let mut dag2 = TestDag::new(BTreeMap::new());
dag1.add_node("quake", BTreeSet::new()).unwrap();
let quake_node_id = dag2.add_node("quake", BTreeSet::new()).unwrap();
let mut deps = BTreeSet::new();
deps.insert(quake_node_id.clone());
let qualm_node_id = dag1.add_node("qualm", deps).unwrap();
deps = BTreeSet::new();
deps.insert(quake_node_id.clone());
deps.insert(qualm_node_id.clone());
let quell_node_id = dag1.add_node("quell", deps).unwrap();
let missing_nodes = dag1
.find_next_non_descendant_nodes(dag2.get_roots())
.unwrap();
assert_eq!(missing_nodes.len(), 2);
let mut found_qualm = false;
let mut found_quell = false;
for node in missing_nodes {
if node.id().to_owned() == qualm_node_id {
found_qualm = true;
}
if node.id().to_owned() == quell_node_id {
found_quell = true;
}
}
assert!(found_qualm);
assert!(found_quell);
}
#[cfg(feature = "cbor")]
mod cbor_serialization_tests {
use super::TestDag;