dag: make ToIdSet async

Summary: This will make it easier to make IdConvert async.

Reviewed By: sfilipco

Differential Revision: D25345232

fbshipit-source-id: b8967ea51a6141a95070006a289dd724522f8e18
This commit is contained in:
Jun Wu 2020-12-10 12:32:23 -08:00 committed by Facebook GitHub Bot
parent f854d2e03e
commit 53bdae78d9
4 changed files with 34 additions and 32 deletions

View File

@ -136,7 +136,7 @@ py_class!(pub class commits |py| {
Some(map) => map,
None => self.inner(py).borrow().id_map_snapshot().map_pyerr(py)?,
};
Ok(Spans(id_map.to_id_set(&set.0).map_pyerr(py)?))
Ok(Spans(block_on(id_map.to_id_set(&set.0)).map_pyerr(py)?))
}
/// Convert IdSet to Set. For compatibility with legacy code only.

View File

@ -364,7 +364,7 @@ where
{
return Ok(set);
}
let spans = self.to_id_set(&set)?;
let spans = self.to_id_set(&set).await?;
let spans = self.dag().ancestors(spans)?;
let result = NameSet::from_spans_dag(spans, self)?;
result.hints().add_flags(Flags::ANCESTORS);
@ -378,7 +378,7 @@ where
async fn parents(&self, set: NameSet) -> Result<NameSet> {
// Preserve ANCESTORS flag. If ancestors(x) == x, then ancestors(parents(x)) == parents(x).
let flags = extract_ancestor_flag_if_compatible(set.hints(), self.dag_snapshot()?);
let spans = self.dag().parents(self.to_id_set(&set)?)?;
let spans = self.dag().parents(self.to_id_set(&set).await?)?;
let result = NameSet::from_spans_dag(spans, self)?;
result.hints().add_flags(flags);
#[cfg(test)]
@ -411,7 +411,7 @@ where
// heads_ancestors is faster.
return self.heads_ancestors(set).await;
}
let spans = self.dag().heads(self.to_id_set(&set)?)?;
let spans = self.dag().heads(self.to_id_set(&set).await?)?;
let result = NameSet::from_spans_dag(spans, self)?;
#[cfg(test)]
{
@ -422,7 +422,7 @@ where
/// Calculates children of the given set.
async fn children(&self, set: NameSet) -> Result<NameSet> {
let spans = self.dag().children(self.to_id_set(&set)?)?;
let spans = self.dag().children(self.to_id_set(&set).await?)?;
let result = NameSet::from_spans_dag(spans, self)?;
Ok(result)
}
@ -430,7 +430,7 @@ where
/// Calculates roots of the given set.
async fn roots(&self, set: NameSet) -> Result<NameSet> {
let flags = extract_ancestor_flag_if_compatible(set.hints(), self.dag_snapshot()?);
let spans = self.dag().roots(self.to_id_set(&set)?)?;
let spans = self.dag().roots(self.to_id_set(&set).await?)?;
let result = NameSet::from_spans_dag(spans, self)?;
result.hints().add_flags(flags);
#[cfg(test)]
@ -446,7 +446,7 @@ where
/// If there are multiple greatest common ancestors, pick one arbitrarily.
/// Use `gca_all` to get all of them.
async fn gca_one(&self, set: NameSet) -> Result<Option<VertexName>> {
let result: Option<VertexName> = match self.dag().gca_one(self.to_id_set(&set)?)? {
let result: Option<VertexName> = match self.dag().gca_one(self.to_id_set(&set).await?)? {
None => None,
Some(id) => Some(self.map().vertex_name(id)?),
};
@ -460,7 +460,7 @@ where
/// Calculates all "greatest common ancestor"s of the given set.
/// `gca_one` is faster if an arbitrary answer is ok.
async fn gca_all(&self, set: NameSet) -> Result<NameSet> {
let spans = self.dag().gca_all(self.to_id_set(&set)?)?;
let spans = self.dag().gca_all(self.to_id_set(&set).await?)?;
let result = NameSet::from_spans_dag(spans, self)?;
#[cfg(test)]
{
@ -471,7 +471,7 @@ where
/// Calculates all common ancestors of the given set.
async fn common_ancestors(&self, set: NameSet) -> Result<NameSet> {
let spans = self.dag().common_ancestors(self.to_id_set(&set)?)?;
let spans = self.dag().common_ancestors(self.to_id_set(&set).await?)?;
let result = NameSet::from_spans_dag(spans, self)?;
result.hints().add_flags(Flags::ANCESTORS);
#[cfg(test)]
@ -506,7 +506,7 @@ where
/// an ancestor of X, but not the immediate ancestor, `heads` will include
/// Y while this function won't.
async fn heads_ancestors(&self, set: NameSet) -> Result<NameSet> {
let spans = self.dag().heads_ancestors(self.to_id_set(&set)?)?;
let spans = self.dag().heads_ancestors(self.to_id_set(&set).await?)?;
let result = NameSet::from_spans_dag(spans, self)?;
#[cfg(test)]
{
@ -521,8 +521,8 @@ where
/// Calculates the "dag range" - vertexes reachable from both sides.
async fn range(&self, roots: NameSet, heads: NameSet) -> Result<NameSet> {
let roots = self.to_id_set(&roots)?;
let heads = self.to_id_set(&heads)?;
let roots = self.to_id_set(&roots).await?;
let heads = self.to_id_set(&heads).await?;
let spans = self.dag().range(roots, heads)?;
let result = NameSet::from_spans_dag(spans, self)?;
Ok(result)
@ -530,7 +530,7 @@ where
/// Calculates the descendants of the given set.
async fn descendants(&self, set: NameSet) -> Result<NameSet> {
let spans = self.dag().descendants(self.to_id_set(&set)?)?;
let spans = self.dag().descendants(self.to_id_set(&set).await?)?;
let result = NameSet::from_spans_dag(spans, self)?;
Ok(result)
}

View File

@ -294,9 +294,10 @@ where
}
}
#[async_trait::async_trait]
pub trait ToIdSet {
/// Converts [`NameSet`] to [`SpanSet`].
fn to_id_set(&self, set: &NameSet) -> Result<IdSet>;
async fn to_id_set(&self, set: &NameSet) -> Result<IdSet>;
}
pub trait ToSet {
@ -349,7 +350,7 @@ pub trait Open: Clone {
fn open(&self) -> Result<Self::OpenTarget>;
}
/// Faillible clone.
/// Fallible clone.
pub trait TryClone {
fn try_clone(&self) -> Result<Self>
where
@ -362,9 +363,10 @@ impl<T: Clone> TryClone for T {
}
}
#[async_trait::async_trait]
impl<T: IdConvert + IdMapSnapshot> ToIdSet for T {
/// Converts [`NameSet`] to [`IdSet`].
fn to_id_set(&self, set: &NameSet) -> Result<IdSet> {
async fn to_id_set(&self, set: &NameSet) -> Result<IdSet> {
// Fast path: extract IdSet from IdStaticSet.
if let Some(set) = set.as_any().downcast_ref::<IdStaticSet>() {
let snapshot = self.id_map_snapshot()?;

View File

@ -1006,7 +1006,7 @@ impl DagAlgorithm for RevlogIndex {
if set.hints().contains(Flags::ANCESTORS) {
return Ok(set);
}
let id_set = self.to_id_set(&set)?;
let id_set = self.to_id_set(&set).await?;
if id_set.is_empty() {
return Ok(Set::empty());
}
@ -1047,7 +1047,7 @@ impl DagAlgorithm for RevlogIndex {
/// Calculates parents.
async fn parents(&self, set: Set) -> dag::Result<Set> {
let id_set = self.to_id_set(&set)?;
let id_set = self.to_id_set(&set).await?;
if id_set.is_empty() {
return Ok(Set::empty());
}
@ -1086,7 +1086,7 @@ impl DagAlgorithm for RevlogIndex {
/// Calculates children of the given set.
async fn children(&self, set: Set) -> dag::Result<Set> {
let id_set = self.to_id_set(&set)?;
let id_set = self.to_id_set(&set).await?;
if id_set.is_empty() {
return Ok(Set::empty());
}
@ -1117,7 +1117,7 @@ impl DagAlgorithm for RevlogIndex {
/// Calculates roots of the given set.
async fn roots(&self, set: Set) -> dag::Result<Set> {
let id_set = self.to_id_set(&set)?;
let id_set = self.to_id_set(&set).await?;
if id_set.is_empty() {
return Ok(Set::empty());
}
@ -1150,7 +1150,7 @@ impl DagAlgorithm for RevlogIndex {
/// If there are multiple greatest common ancestors, pick one arbitrarily.
/// Use `gca_all` to get all of them.
async fn gca_one(&self, set: Set) -> dag::Result<Option<Vertex>> {
let id_set = self.to_id_set(&set)?;
let id_set = self.to_id_set(&set).await?;
let mut revs: Vec<u32> = id_set.iter().map(|id| id.0 as u32).collect();
while revs.len() > 1 {
let mut new_revs = Vec::new();
@ -1178,7 +1178,7 @@ impl DagAlgorithm for RevlogIndex {
/// Calculates all "greatest common ancestor"s of the given set.
/// `gca_one` is faster if an arbitrary answer is ok.
async fn gca_all(&self, set: Set) -> dag::Result<Set> {
let id_set = self.to_id_set(&set)?;
let id_set = self.to_id_set(&set).await?;
// XXX: Limited by gca_revs implementation detail.
if id_set.count() > 6 {
return Err(Error::Unsupported(format!(
@ -1208,7 +1208,7 @@ impl DagAlgorithm for RevlogIndex {
/// Find Y, which is the smallest subset of set X, where `ancestors(Y)` is
/// `ancestors(X)`.
async fn heads_ancestors(&self, set: Set) -> dag::Result<Set> {
let id_set = self.to_id_set(&set)?;
let id_set = self.to_id_set(&set).await?;
if id_set.is_empty() {
return Ok(Set::empty());
}
@ -1270,8 +1270,8 @@ impl DagAlgorithm for RevlogIndex {
/// Calculates the "dag range" - vertexes reachable from both sides.
async fn range(&self, roots: Set, heads: Set) -> dag::Result<Set> {
let root_ids = self.to_id_set(&roots)?;
let head_ids = self.to_id_set(&heads)?;
let root_ids = self.to_id_set(&roots).await?;
let head_ids = self.to_id_set(&heads).await?;
let root_revs: Vec<u32> = root_ids.into_iter().map(|i| i.0 as u32).collect();
let head_revs: Vec<u32> = head_ids.into_iter().map(|i| i.0 as u32).collect();
let result_revs = self.range_revs(&root_revs, &head_revs)?;
@ -1282,8 +1282,8 @@ impl DagAlgorithm for RevlogIndex {
/// Calculate `::reachable - ::unreachable`.
async fn only(&self, reachable: Set, unreachable: Set) -> dag::Result<Set> {
let reachable_ids = self.to_id_set(&reachable)?;
let unreachable_ids = self.to_id_set(&unreachable)?;
let reachable_ids = self.to_id_set(&reachable).await?;
let unreachable_ids = self.to_id_set(&unreachable).await?;
if reachable_ids.is_empty() {
return Ok(Set::empty());
@ -1352,8 +1352,8 @@ impl DagAlgorithm for RevlogIndex {
/// Calculate `::reachable - ::unreachable` and `::unreachable`.
async fn only_both(&self, reachable: Set, unreachable: Set) -> dag::Result<(Set, Set)> {
let reachable_ids = self.to_id_set(&reachable)?;
let unreachable_ids = self.to_id_set(&unreachable)?;
let reachable_ids = self.to_id_set(&reachable).await?;
let unreachable_ids = self.to_id_set(&unreachable).await?;
let reachable_revs = reachable_ids.into_iter().map(|i| i.0 as u32);
let unreachable_revs = unreachable_ids.into_iter().map(|i| i.0 as u32);
@ -1514,7 +1514,7 @@ impl DagAlgorithm for RevlogIndex {
/// Calculates the descendants of the given set.
async fn descendants(&self, set: Set) -> dag::Result<Set> {
let id_set = self.to_id_set(&set)?;
let id_set = self.to_id_set(&set).await?;
if id_set.is_empty() {
return Ok(Set::empty());
}
@ -1552,12 +1552,12 @@ impl DagAlgorithm for RevlogIndex {
}
async fn reachable_roots(&self, roots: Set, heads: Set) -> dag::Result<Set> {
let id_roots = self.to_id_set(&roots)?;
let id_roots = self.to_id_set(&roots).await?;
if id_roots.is_empty() {
return Ok(Set::empty());
}
let id_heads = self.to_id_set(&heads)?;
let id_heads = self.to_id_set(&heads).await?;
if id_heads.is_empty() {
return Ok(Set::empty());
}