dag: make ASCII -> MemNameDag a public API

Summary:
It seems handy to construct a Dag just from ASCII. Therefore move it to a
public interface.

Reviewed By: sfilipco

Differential Revision: D21486525

fbshipit-source-id: de7f4b8dfcbcc486798928d4334c655431373276
This commit is contained in:
Jun Wu 2020-05-11 09:45:32 -07:00 committed by Facebook GitHub Bot
parent a6b7e965f3
commit 60684eb2c5
3 changed files with 40 additions and 15 deletions

View File

@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2018"
[dependencies]
drawdag = { path = "../drawdag" }
indexedlog = { path = "../indexedlog" }
minibytes = { path = "../minibytes" }
vlqencoding = { path = "../vlqencoding" }
@ -18,7 +19,6 @@ tempfile = "3.0.7"
[dev-dependencies]
bindag = { path = "bindag" }
drawdag = { path = "../drawdag" }
minibench = { path = "../minibench" }
once_cell = "1"
quickcheck = "0.9"

View File

@ -278,6 +278,44 @@ impl MemNameDag {
}
}
/// Construct the DAG from an ASCII graph.
/// Useful for testing.
///
/// Panic if the input is invalid.
pub fn from_ascii_with_heads(text: &str, heads: Option<&[impl AsRef<str>]>) -> Result<Self> {
let parents = drawdag::parse(&text);
let heads: Vec<_> = match heads {
Some(heads) => heads
.iter()
.map(|s| VertexName::copy_from(s.as_ref().as_bytes()))
.collect(),
None => {
let mut heads: Vec<_> = parents
.keys()
.map(|s| VertexName::copy_from(s.as_bytes()))
.collect();
heads.sort();
heads
}
};
let parents_func = move |name: VertexName| -> Result<Vec<VertexName>> {
Ok(parents[&String::from_utf8(name.as_ref().to_vec()).unwrap()]
.iter()
.map(|p| VertexName::copy_from(p.as_bytes()))
.collect())
};
let mut dag = Self::new();
dag.add_heads(&parents_func, &heads[..])?;
Ok(dag)
}
/// Construct the DAG from an ASCII graph with all heads included.
pub fn from_ascii(text: &str) -> Result<Self> {
let heads: Option<&[&str]> = None;
Self::from_ascii_with_heads(text, heads)
}
/// Add vertexes and their ancestors to the in-memory DAG.
pub fn add_heads<F>(&mut self, parents: F, heads: &[VertexName]) -> Result<()>
where

View File

@ -52,7 +52,7 @@ static ASCII_DAG5: &str = r#"
#[test]
fn test_mem_namedag() -> Result<()> {
let dag = build_mem_dag(ASCII_DAG1, "L");
let dag = MemNameDag::from_ascii(ASCII_DAG1)?;
assert_eq!(expand(dag.all()?), "L K J I H G F E D C B A");
assert_eq!(expand(dag.ancestors(nameset("H I"))?), "I H G F E D C B A");
assert_eq!(expand(dag.parents(nameset("H I E"))?), "G D B");
@ -917,16 +917,3 @@ pub(crate) fn build_segments(text: &str, heads: &str, segment_size: usize) -> Bu
dir,
}
}
/// Take an ASCII DAG, assign segments from given heads.
/// Return the ASCII DAG and the built MemNameDag.
pub(crate) fn build_mem_dag(text: &str, heads: &str) -> MemNameDag {
let mut dag = MemNameDag::new();
let parents_by_name = get_parents_func_from_ascii(text);
let heads: Vec<_> = heads
.split(' ')
.map(|h| VertexName::copy_from(h.as_bytes()))
.collect();
dag.add_heads(&parents_by_name, &heads).unwrap();
dag
}