From 53bdae78d94575faab95212da3846ae8e5e412eb Mon Sep 17 00:00:00 2001 From: Jun Wu Date: Thu, 10 Dec 2020 12:32:23 -0800 Subject: [PATCH] dag: make ToIdSet async Summary: This will make it easier to make IdConvert async. Reviewed By: sfilipco Differential Revision: D25345232 fbshipit-source-id: b8967ea51a6141a95070006a289dd724522f8e18 --- .../bindings/modules/pydag/src/commits.rs | 2 +- eden/scm/lib/dag/src/namedag.rs | 24 +++++++------- eden/scm/lib/dag/src/ops.rs | 8 +++-- eden/scm/lib/revlogindex/src/revlogindex.rs | 32 +++++++++---------- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/eden/scm/edenscmnative/bindings/modules/pydag/src/commits.rs b/eden/scm/edenscmnative/bindings/modules/pydag/src/commits.rs index ce4b9478b3..1532a87cda 100644 --- a/eden/scm/edenscmnative/bindings/modules/pydag/src/commits.rs +++ b/eden/scm/edenscmnative/bindings/modules/pydag/src/commits.rs @@ -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. diff --git a/eden/scm/lib/dag/src/namedag.rs b/eden/scm/lib/dag/src/namedag.rs index dc54d29afe..03940d165c 100644 --- a/eden/scm/lib/dag/src/namedag.rs +++ b/eden/scm/lib/dag/src/namedag.rs @@ -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 { // 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 { - 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 { 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> { - let result: Option = match self.dag().gca_one(self.to_id_set(&set)?)? { + let result: Option = 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 { - 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 { - 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 { - 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 { - 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 { - 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) } diff --git a/eden/scm/lib/dag/src/ops.rs b/eden/scm/lib/dag/src/ops.rs index f8e7de3e8a..086ff9465c 100644 --- a/eden/scm/lib/dag/src/ops.rs +++ b/eden/scm/lib/dag/src/ops.rs @@ -294,9 +294,10 @@ where } } +#[async_trait::async_trait] pub trait ToIdSet { /// Converts [`NameSet`] to [`SpanSet`]. - fn to_id_set(&self, set: &NameSet) -> Result; + async fn to_id_set(&self, set: &NameSet) -> Result; } pub trait ToSet { @@ -349,7 +350,7 @@ pub trait Open: Clone { fn open(&self) -> Result; } -/// Faillible clone. +/// Fallible clone. pub trait TryClone { fn try_clone(&self) -> Result where @@ -362,9 +363,10 @@ impl TryClone for T { } } +#[async_trait::async_trait] impl ToIdSet for T { /// Converts [`NameSet`] to [`IdSet`]. - fn to_id_set(&self, set: &NameSet) -> Result { + async fn to_id_set(&self, set: &NameSet) -> Result { // Fast path: extract IdSet from IdStaticSet. if let Some(set) = set.as_any().downcast_ref::() { let snapshot = self.id_map_snapshot()?; diff --git a/eden/scm/lib/revlogindex/src/revlogindex.rs b/eden/scm/lib/revlogindex/src/revlogindex.rs index 15d36f021b..e216fde577 100644 --- a/eden/scm/lib/revlogindex/src/revlogindex.rs +++ b/eden/scm/lib/revlogindex/src/revlogindex.rs @@ -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 { - 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 { - 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 { - 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> { - let id_set = self.to_id_set(&set)?; + let id_set = self.to_id_set(&set).await?; let mut revs: Vec = 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 { - 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 { - 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 { - 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 = root_ids.into_iter().map(|i| i.0 as u32).collect(); let head_revs: Vec = 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 { - 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 { - 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 { - 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()); }