mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 08:47:12 +03:00
dag: add new range algorithm
Summary: Similar to descendants, the new range algorithm avoids potentially expensive checks about whether high-level segments can be used or not. Practically this is overall an improvement. `cargo bench --bench dag_ops -- range`: Before: range (2 ids) 115.380 ms range (spans) 243.666 ms After: range (2 ids) 123.274 ms range (spans) 23.101 ms It is 100x faster with the range x::y benchmark added later on `git.git`. Reviewed By: sfilipco Differential Revision: D23106175 fbshipit-source-id: 691e0418ba2b7ad9f52ac15b5cd6088ec28d5f48
This commit is contained in:
parent
c2e03b9129
commit
4d798c39d9
@ -1012,7 +1012,34 @@ impl<Store: IdDagStore> IdDag<Store> {
|
|||||||
/// ```plain,ignore
|
/// ```plain,ignore
|
||||||
/// intersect(ancestors(heads), descendants(roots))
|
/// intersect(ancestors(heads), descendants(roots))
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// This is O(flat segments), or O(merges).
|
||||||
pub fn range(&self, roots: impl Into<SpanSet>, heads: impl Into<SpanSet>) -> Result<SpanSet> {
|
pub fn range(&self, roots: impl Into<SpanSet>, heads: impl Into<SpanSet>) -> Result<SpanSet> {
|
||||||
|
let roots = roots.into();
|
||||||
|
if roots.is_empty() {
|
||||||
|
return Ok(SpanSet::empty());
|
||||||
|
}
|
||||||
|
let heads = heads.into();
|
||||||
|
#[cfg(test)]
|
||||||
|
let result_old = self.range_old(roots.clone(), heads.clone())?;
|
||||||
|
let max_head_id = match heads.max() {
|
||||||
|
Some(id) => id,
|
||||||
|
None => return Ok(SpanSet::empty()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let ancestors_of_heads = self.ancestors(heads)?;
|
||||||
|
let descendants_of_roots = self.descendants_up_to(&roots, max_head_id)?;
|
||||||
|
let result = ancestors_of_heads.intersection(&descendants_of_roots);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
{
|
||||||
|
assert_eq!(result.as_spans(), result_old.as_spans());
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
fn range_old(&self, roots: impl Into<SpanSet>, heads: impl Into<SpanSet>) -> Result<SpanSet> {
|
||||||
// Pre-calculate ancestors.
|
// Pre-calculate ancestors.
|
||||||
let heads = heads.into();
|
let heads = heads.into();
|
||||||
let roots = roots.into();
|
let roots = roots.into();
|
||||||
|
Loading…
Reference in New Issue
Block a user