use super::{Graph, GraphError, Revision, NULL_REVISION};
use std::collections::HashSet;
fn remove_parents(
graph: &impl Graph,
rev: Revision,
set: &mut HashSet<Revision>,
) -> Result<(), GraphError> {
for parent in graph.parents(rev)?.iter() {
if *parent != NULL_REVISION {
set.remove(parent);
}
}
Ok(())
}
pub fn heads<'a>(
graph: &impl Graph,
iter_revs: impl Clone + Iterator<Item = &'a Revision>,
) -> Result<HashSet<Revision>, GraphError> {
let mut heads: HashSet<Revision> = iter_revs.clone().cloned().collect();
heads.remove(&NULL_REVISION);
for rev in iter_revs {
if *rev != NULL_REVISION {
remove_parents(graph, *rev, &mut heads)?;
}
}
Ok(heads)
}
pub fn retain_heads(
graph: &impl Graph,
revs: &mut HashSet<Revision>,
) -> Result<(), GraphError> {
revs.remove(&NULL_REVISION);
let as_vec: Vec<Revision> = revs.iter().cloned().collect();
for rev in as_vec {
if rev != NULL_REVISION {
remove_parents(graph, rev, revs)?;
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::testing::SampleGraph;
fn retain_heads_sorted(
graph: &impl Graph,
revs: &[Revision],
) -> Result<Vec<Revision>, GraphError> {
let mut revs: HashSet<Revision> = revs.iter().cloned().collect();
retain_heads(graph, &mut revs)?;
let mut as_vec: Vec<Revision> = revs.iter().cloned().collect();
as_vec.sort();
Ok(as_vec)
}
#[test]
fn test_retain_heads() -> Result<(), GraphError> {
assert_eq!(retain_heads_sorted(&SampleGraph, &[4, 5, 6])?, vec![5, 6]);
assert_eq!(
retain_heads_sorted(&SampleGraph, &[4, 1, 6, 12, 0])?,
vec![1, 6, 12]
);
assert_eq!(
retain_heads_sorted(&SampleGraph, &[1, 2, 3, 4, 5, 6, 7, 8, 9])?,
vec![3, 5, 8, 9]
);
Ok(())
}
fn heads_sorted(
graph: &impl Graph,
revs: &[Revision],
) -> Result<Vec<Revision>, GraphError> {
let heads = heads(graph, revs.iter())?;
let mut as_vec: Vec<Revision> = heads.iter().cloned().collect();
as_vec.sort();
Ok(as_vec)
}
#[test]
fn test_heads() -> Result<(), GraphError> {
assert_eq!(heads_sorted(&SampleGraph, &[4, 5, 6])?, vec![5, 6]);
assert_eq!(
heads_sorted(&SampleGraph, &[4, 1, 6, 12, 0])?,
vec![1, 6, 12]
);
assert_eq!(
heads_sorted(&SampleGraph, &[1, 2, 3, 4, 5, 6, 7, 8, 9])?,
vec![3, 5, 8, 9]
);
Ok(())
}
}