dag: make spanset module private

Summary:
This just renames types so `IdSet` is the recommended name and `SpanSet`
remains an implementation detail.

Reviewed By: sfilipco

Differential Revision: D26203560

fbshipit-source-id: 7ca0262f3ad6d874363c73445f40f8c5bf3dc40e
This commit is contained in:
Jun Wu 2021-02-05 11:50:59 -08:00 committed by Facebook GitHub Bot
parent d6838099d5
commit 9b02ebc711
17 changed files with 127 additions and 130 deletions

View File

@ -7,9 +7,9 @@
use cpython::*;
use dag::spanset::SpanSetIter;
use dag::Id;
use dag::IdSet;
use dag::IdSetIter;
use std::cell::RefCell;
/// A wrapper around [`IdSet`] with Python integration.
@ -123,9 +123,9 @@ py_class!(pub class spans |py| {
}
});
// A wrapper to [`SpanSetIter`].
// A wrapper to [`IdSetIter`].
py_class!(pub class spansiter |py| {
data iter: RefCell<SpanSetIter<IdSet>>;
data iter: RefCell<IdSetIter<IdSet>>;
data ascending: bool;
def __next__(&self) -> PyResult<Option<u64>> {

View File

@ -13,7 +13,7 @@ use dag::ops::DagAlgorithm;
use dag::ops::DagPersistent;
use dag::ops::Persist;
use dag::Set;
use dag::{idmap::IdMap, spanset::SpanSet, Group, Id, IdDag, VertexName};
use dag::{idmap::IdMap, Group, Id, IdDag, IdSet, VertexName};
use minibench::{bench, elapsed};
use tempfile::tempdir;
@ -75,7 +75,7 @@ fn bench_with_iddag<S: IdDagStore + Persist>(get_empty_iddag: impl Fn() -> IdDag
.unwrap();
syncable.sync().unwrap();
let sample_two_ids: Vec<SpanSet> = (0..parents.len() as u64)
let sample_two_ids: Vec<IdSet> = (0..parents.len() as u64)
.step_by(10079)
.flat_map(|i| {
(1..parents.len() as u64)
@ -83,11 +83,11 @@ fn bench_with_iddag<S: IdDagStore + Persist>(get_empty_iddag: impl Fn() -> IdDag
.map(move |j| (Id(i), Id(j)).into())
})
.collect(); // 2679 samples
let sample_one_ids: Vec<SpanSet> = (0..parents.len() as u64)
let sample_one_ids: Vec<IdSet> = (0..parents.len() as u64)
.step_by(153)
.map(|i| SpanSet::from(Id(i)))
.map(|i| IdSet::from(Id(i)))
.collect();
let sample_sets: Vec<SpanSet> = (0..parents.len() as u64)
let sample_sets: Vec<IdSet> = (0..parents.len() as u64)
.step_by(10079)
.flat_map(|i| {
((i + 7919)..parents.len() as u64)

View File

@ -5,14 +5,14 @@
* GNU General Public License version 2.
*/
use dag::{spanset::SpanSet, Id};
use dag::{Id, IdSet};
use minibench::{bench, elapsed};
fn main() {
// Ruby code to generate random SpanSet:
// Ruby code to generate random IdSet:
// 119.times.map{rand(8)+1}.reduce([0]){|a,b|a+[b+a[-1]]}.each_slice(2).map{|x|"#{x*'..='}"}*', '
#[cfg_attr(rustfmt, rustfmt_skip)]
let span1 = SpanSet::from_spans(vec![
let span1 = IdSet::from_spans(vec![
0..=6, 8..=10, 12..=13, 19..=20, 25..=30, 35..=43, 51..=52, 60..=67, 75..=81, 89..=93,
94..=97, 105..=111, 116..=121, 129..=135, 136..=144, 146..=147, 155..=157, 164..=172,
180..=188, 193..=201, 204..=212, 220..=221, 227..=234, 239..=241, 248..=251, 253..=257,
@ -24,7 +24,7 @@ fn main() {
].into_iter().map(|r| Id(*r.start())..=Id(*r.end())));
#[cfg_attr(rustfmt, rustfmt_skip)]
let span2 = SpanSet::from_spans(vec![
let span2 = IdSet::from_spans(vec![
0..=1, 6..=9, 16..=22, 26..=33, 38..=45, 51..=54, 61..=68, 71..=78, 85..=91, 94..=98,
102..=105, 106..=111, 112..=114, 117..=121, 124..=128, 130..=132, 138..=140, 142..=143,
144..=151, 154..=161, 162..=164, 165..=170, 177..=179, 182..=185, 193..=196, 199..=207,

View File

@ -10,7 +10,7 @@ use dag::nameset::SyncNameSetQuery;
use dag::ops::DagAlgorithm;
use dag::ops::IdConvert;
use dag::OnDiskIdDag;
use dag::{ops::DagPersistent, spanset::SpanSet, Id, NameDag, VertexName};
use dag::{ops::DagPersistent, Id, IdSet, NameDag, VertexName};
use nonblocking::non_blocking_result;
use std::collections::HashMap;
use std::collections::HashSet;
@ -130,8 +130,8 @@ impl<T> GeneralTestContext<T> {
self
}
/// Convert a SpanSet (used by IdDag) to plain revs (used by `parents`).
pub fn to_plain_revs(&self, set: &SpanSet) -> Vec<usize> {
/// Convert a IdSet (used by IdDag) to plain revs (used by `parents`).
pub fn to_plain_revs(&self, set: &IdSet) -> Vec<usize> {
set.iter().map(|i| self.idmap[&i]).collect()
}
@ -148,9 +148,9 @@ impl<T> GeneralTestContext<T> {
.collect()
}
/// Convert `usize` plain revs to SpanSet used by IdDag.
pub fn to_dag_revs(&self, revs: &[usize]) -> SpanSet {
/// Convert `usize` plain revs to IdSet used by IdDag.
pub fn to_dag_revs(&self, revs: &[usize]) -> IdSet {
let iter = revs.iter().map(|&i| self.rev_idmap[i].clone());
SpanSet::from_spans(iter)
IdSet::from_spans(iter)
}
}

View File

@ -16,9 +16,9 @@ use crate::ops::Persist;
#[cfg(any(test, feature = "indexedlog-backend"))]
use crate::ops::TryClone;
use crate::segment::{FlatSegment, PreparedFlatSegments, Segment, SegmentFlags};
use crate::spanset::Span;
use crate::spanset::SpanSet;
use crate::Error::Programming;
use crate::IdSet;
use crate::IdSpan;
use crate::Level;
use crate::Result;
use crate::VerLink;
@ -558,9 +558,9 @@ impl<Store: IdDagStore> IdDag<Store> {
// User-facing DAG-related algorithms.
impl<Store: IdDagStore> IdDag<Store> {
/// Return a [`SpanSet`] that covers all ids stored in this [`IdDag`].
pub fn all(&self) -> Result<SpanSet> {
let mut result = SpanSet::empty();
/// Return a [`IdSet`] that covers all ids stored in this [`IdDag`].
pub fn all(&self) -> Result<IdSet> {
let mut result = IdSet::empty();
for &group in Group::ALL.iter().rev() {
let next = self.next_free_id(0, group)?;
if next > group.min_id() {
@ -570,14 +570,14 @@ impl<Store: IdDagStore> IdDag<Store> {
Ok(result)
}
/// Return a [`SpanSet`] that covers all ids stored in the master group.
pub(crate) fn master_group(&self) -> Result<SpanSet> {
/// Return a [`IdSet`] that covers all ids stored in the master group.
pub(crate) fn master_group(&self) -> Result<IdSet> {
let group = Group::MASTER;
let next = self.next_free_id(0, group)?;
if next > group.min_id() {
Ok((group.min_id()..=(next - 1)).into())
} else {
Ok(SpanSet::empty())
Ok(IdSet::empty())
}
}
@ -586,8 +586,8 @@ impl<Store: IdDagStore> IdDag<Store> {
/// ```plain,ignore
/// union(ancestors(i) for i in set)
/// ```
pub fn ancestors(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
let mut set: SpanSet = set.into();
pub fn ancestors(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let mut set: IdSet = set.into();
let tracing_span = debug_span!("ancestors", result = "", set = field::debug(&set));
let _scope = tracing_span.enter();
if set.count() > 2 {
@ -595,7 +595,7 @@ impl<Store: IdDagStore> IdDag<Store> {
set = self.heads_ancestors(set)?;
trace!("ancestors: simplified to {:?}", &set);
}
let mut result = SpanSet::empty();
let mut result = IdSet::empty();
let mut to_visit: BinaryHeap<_> = set.iter().collect();
'outer: while let Some(id) = to_visit.pop() {
if result.contains(id) {
@ -648,11 +648,11 @@ impl<Store: IdDagStore> IdDag<Store> {
}
/// Like `ancestors` but follows only the first parents.
pub fn first_ancestors(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
let set: SpanSet = set.into();
pub fn first_ancestors(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let set: IdSet = set.into();
let tracing_span = debug_span!("first_ancestors", result = "", set = field::debug(&set));
let _scope = tracing_span.enter();
let mut result = SpanSet::empty();
let mut result = IdSet::empty();
let mut to_visit: BinaryHeap<_> = set.iter().collect();
// Lookup flat segments to figure out the first ancestors.
while let Some(id) = to_visit.pop() {
@ -677,8 +677,8 @@ impl<Store: IdDagStore> IdDag<Store> {
/// Calculate merges within the given set.
pub fn merges(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
let mut result = SpanSet::empty();
pub fn merges(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let mut result = IdSet::empty();
let set = set.into();
let tracing_span = debug_span!("merges", result = "", set = field::debug(&set));
@ -690,7 +690,7 @@ impl<Store: IdDagStore> IdDag<Store> {
// Process the given span overlapped with the segment.
// Return the next "high" id for segment lookup.
// Return None if there is no segment to check for the given span.
let mut process_seg = |span: &Span, seg: Segment| -> Result<Option<Id>> {
let mut process_seg = |span: &IdSpan, seg: Segment| -> Result<Option<Id>> {
let seg_span = seg.span()?;
let low = seg_span.low;
if low < span.low {
@ -739,10 +739,10 @@ impl<Store: IdDagStore> IdDag<Store> {
/// Calculate parents of the given set.
///
/// Note: [`SpanSet`] does not preserve order. Use [`IdDag::parent_ids`] if
/// Note: [`IdSet`] does not preserve order. Use [`IdDag::parent_ids`] if
/// order is needed.
pub fn parents(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
let mut result = SpanSet::empty();
pub fn parents(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let mut result = IdSet::empty();
let mut set = set.into();
let tracing_span = debug_span!("parents", result = "", set = field::debug(&set));
@ -755,9 +755,9 @@ impl<Store: IdDagStore> IdDag<Store> {
if let Some(seg) = self.find_segment_by_head_and_level(head, level)? {
let seg_span = seg.span()?;
if set.contains(seg_span) {
let seg_set = SpanSet::from(seg_span);
let seg_set = IdSet::from(seg_span);
let mut parent_set = seg_set.difference(&head.into());
parent_set.push_set(&SpanSet::from_spans(seg.parents()?));
parent_set.push_set(&IdSet::from_spans(seg.parents()?));
set = set.difference(&seg_set);
result = result.union(&parent_set);
trace!("parents: push lv{} {:?}", level, &parent_set);
@ -774,18 +774,18 @@ impl<Store: IdDagStore> IdDag<Store> {
};
let seg_span = seg.span()?;
let seg_low = seg_span.low;
let seg_set: SpanSet = seg_span.into();
let seg_set: IdSet = seg_span.into();
let seg_set = seg_set.intersection(&set);
// Get parents for a linear set (ex. parent(i) is (i - 1)).
fn parents_linear(set: &SpanSet) -> SpanSet {
fn parents_linear(set: &IdSet) -> IdSet {
debug_assert!(!set.contains(Id::MIN));
SpanSet::from_sorted_spans(set.as_spans().iter().map(|s| s.low - 1..=s.high - 1))
IdSet::from_sorted_spans(set.as_spans().iter().map(|s| s.low - 1..=s.high - 1))
}
let parent_set = if seg_set.contains(seg_low) {
let mut parent_set = parents_linear(&seg_set.difference(&SpanSet::from(seg_low)));
parent_set.push_set(&SpanSet::from_spans(seg.parents()?));
let mut parent_set = parents_linear(&seg_set.difference(&IdSet::from(seg_low)));
parent_set.push_set(&IdSet::from_spans(seg.parents()?));
parent_set
} else {
parents_linear(&seg_set)
@ -882,7 +882,7 @@ impl<Store: IdDagStore> IdDag<Store> {
fn to_first_ancestor_nth_known_universally(
&self,
mut id: Id,
heads: SpanSet,
heads: IdSet,
) -> Result<Option<(Id, u64)>> {
let ancestors = self.ancestors(heads.clone())?;
if !ancestors.contains(id) {
@ -930,13 +930,13 @@ impl<Store: IdDagStore> IdDag<Store> {
}
/// Calculate heads of the given set.
pub fn heads(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
pub fn heads(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let set = set.into();
Ok(set.difference(&self.parents(set.clone())?))
}
/// Calculate children for a single `Id`.
pub fn children_id(&self, id: Id) -> Result<SpanSet> {
pub fn children_id(&self, id: Id) -> Result<IdSet> {
let mut result = BTreeSet::new();
for seg in self.store.iter_flat_segments_with_parent(id)? {
let seg = seg?;
@ -948,17 +948,17 @@ impl<Store: IdDagStore> IdDag<Store> {
result.insert(id + 1);
}
}
let result = SpanSet::from_sorted_spans(result.into_iter().rev());
let result = IdSet::from_sorted_spans(result.into_iter().rev());
Ok(result)
}
/// Calculate children of the given set.
pub fn children(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
pub fn children(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let set = set.into();
if set.count() < 5 {
let result =
set.iter()
.fold(Ok(SpanSet::empty()), |acc: Result<SpanSet>, id| match acc {
.fold(Ok(IdSet::empty()), |acc: Result<IdSet>, id| match acc {
Ok(acc) => Ok(acc.union(&self.children_id(id)?)),
Err(err) => Err(err),
})?;
@ -973,7 +973,7 @@ impl<Store: IdDagStore> IdDag<Store> {
}
}
fn children_set(&self, set: SpanSet) -> Result<SpanSet> {
fn children_set(&self, set: IdSet) -> Result<IdSet> {
let tracing_span = debug_span!("children", result = "", set = field::debug(&set));
let _scope = tracing_span.enter();
@ -993,14 +993,14 @@ impl<Store: IdDagStore> IdDag<Store> {
struct Context<'a, Store> {
this: &'a IdDag<Store>,
set: SpanSet,
set: IdSet,
result_lower_bound: Id,
result: SpanSet,
result: IdSet,
}
fn visit_segments<S: IdDagStore>(
ctx: &mut Context<S>,
mut range: Span,
mut range: IdSpan,
level: Level,
) -> Result<()> {
for seg in ctx.this.iter_segments_descending(range.high, level)? {
@ -1013,7 +1013,7 @@ impl<Store: IdDagStore> IdDag<Store> {
if low_id > range.high {
return Ok(());
}
let missing_range = Span::from(low_id..=range.high);
let missing_range = IdSpan::from(low_id..=range.high);
if level > 0 {
visit_segments(ctx, missing_range, level - 1)?;
} else {
@ -1064,7 +1064,7 @@ impl<Store: IdDagStore> IdDag<Store> {
visit_segments(ctx, span, level - 1)?;
continue;
} else {
let seg_children = SpanSet::from_spans(
let seg_children = IdSet::from_spans(
intersection
.as_spans()
.iter()
@ -1093,7 +1093,7 @@ impl<Store: IdDagStore> IdDag<Store> {
this: self,
set,
result_lower_bound,
result: SpanSet::empty(),
result: IdSet::empty(),
};
for span in self.all()?.as_spans() {
@ -1108,7 +1108,7 @@ impl<Store: IdDagStore> IdDag<Store> {
}
/// Calculate roots of the given set.
pub fn roots(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
pub fn roots(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let set = set.into();
Ok(set.difference(&self.children(set.clone())?))
}
@ -1118,7 +1118,7 @@ impl<Store: IdDagStore> IdDag<Store> {
/// If there are no common ancestors, return None.
/// If there are multiple greatest common ancestors, pick one arbitrarily.
/// Use `gca_all` to get all of them.
pub fn gca_one(&self, set: impl Into<SpanSet>) -> Result<Option<Id>> {
pub fn gca_one(&self, set: impl Into<IdSet>) -> Result<Option<Id>> {
let set = set.into();
// The set is sorted in DESC order. Therefore its first item can be used as the result.
Ok(self.common_ancestors(set)?.max())
@ -1126,7 +1126,7 @@ impl<Store: IdDagStore> IdDag<Store> {
/// Calculate all "greatest common ancestor"s of the given set.
/// `gca_one` is faster if an arbitrary answer is ok.
pub fn gca_all(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
pub fn gca_all(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let set = set.into();
self.heads_ancestors(self.common_ancestors(set)?)
}
@ -1136,7 +1136,7 @@ impl<Store: IdDagStore> IdDag<Store> {
/// ```plain,ignore
/// intersect(ancestors(i) for i in set)
/// ```
pub fn common_ancestors(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
pub fn common_ancestors(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let set = set.into();
let result = match set.count() {
0 => set,
@ -1153,7 +1153,7 @@ impl<Store: IdDagStore> IdDag<Store> {
// `common_ancestors(X)` = `common_ancestors(roots(X))`.
let set = self.roots(set)?;
set.iter()
.fold(Ok(SpanSet::full()), |set: Result<SpanSet>, id| {
.fold(Ok(IdSet::full()), |set: Result<IdSet>, id| {
Ok(set?.intersection(&self.ancestors(id)?))
})?
}
@ -1167,7 +1167,7 @@ impl<Store: IdDagStore> IdDag<Store> {
Ok(set.contains(ancestor_id))
}
/// Calculate "heads" of the ancestors of the given [`SpanSet`]. That is,
/// Calculate "heads" of the ancestors of the given [`IdSet`]. That is,
/// Find Y, which is the smallest subset of set X, where `ancestors(Y)` is
/// `ancestors(X)`.
///
@ -1176,10 +1176,10 @@ impl<Store: IdDagStore> IdDag<Store> {
/// This is different from `heads`. In case set contains X and Y, and Y is
/// an ancestor of X, but not the immediate ancestor, `heads` will include
/// Y while this function won't.
pub fn heads_ancestors(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
pub fn heads_ancestors(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let set = set.into();
let mut remaining = set;
let mut result = SpanSet::empty();
let mut result = IdSet::empty();
while let Some(id) = remaining.max() {
result.push_span((id..=id).into());
// Remove ancestors reachable from that head.
@ -1195,14 +1195,14 @@ impl<Store: IdDagStore> IdDag<Store> {
/// ```
///
/// 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<IdSet>, heads: impl Into<IdSet>) -> Result<IdSet> {
let roots = roots.into();
if roots.is_empty() {
return Ok(SpanSet::empty());
return Ok(IdSet::empty());
}
let mut heads = heads.into();
if heads.is_empty() {
return Ok(SpanSet::empty());
return Ok(IdSet::empty());
}
// Remove uninteresting heads. Make `ancestors(heads)` a bit easier.
@ -1229,7 +1229,7 @@ impl<Store: IdDagStore> IdDag<Store> {
/// Logically equivalent to `range(set, all())`.
///
/// This is O(flat segments), or O(merges).
pub fn descendants(&self, set: impl Into<SpanSet>) -> Result<SpanSet> {
pub fn descendants(&self, set: impl Into<IdSet>) -> Result<IdSet> {
let roots = set.into();
let result = self.descendants_intersection(&roots, &self.all()?)?;
Ok(result)
@ -1238,13 +1238,13 @@ impl<Store: IdDagStore> IdDag<Store> {
/// Calculate (descendants(roots) & ancestors).
///
/// This is O(flat segments), or O(merges).
fn descendants_intersection(&self, roots: &SpanSet, ancestors: &SpanSet) -> Result<SpanSet> {
fn descendants_intersection(&self, roots: &IdSet, ancestors: &IdSet) -> Result<IdSet> {
let min_root = match roots.min() {
Some(id) => id,
None => return Ok(SpanSet::empty()),
None => return Ok(IdSet::empty()),
};
let max_root = roots.max().unwrap();
let mut result = SpanSet::empty();
let mut result = IdSet::empty();
// For the master group, use linear scan for flat segments. This is
// usually more efficient, because the master group usually only has 1
@ -1278,7 +1278,7 @@ impl<Store: IdDagStore> IdDag<Store> {
if low > master_max_id {
break;
}
result.push_span_asc(Span::from(low..=span.high.min(master_max_id)));
result.push_span_asc(IdSpan::from(low..=span.high.min(master_max_id)));
}
result = result.intersection(&ancestors);
@ -1291,7 +1291,7 @@ impl<Store: IdDagStore> IdDag<Store> {
// a few heads in the non-master group. It's a waste of time to iterate
// through lots of invisible segments.
let non_master_spans = ancestors.intersection(
&Span::from(Group::NON_MASTER.min_id()..=Group::NON_MASTER.max_id()).into(),
&IdSpan::from(Group::NON_MASTER.min_id()..=Group::NON_MASTER.max_id()).into(),
);
// Visit in ascending order.
let mut span_iter = non_master_spans.as_spans().iter().rev().cloned();
@ -1305,7 +1305,7 @@ impl<Store: IdDagStore> IdDag<Store> {
let seg_span = seg.span()?;
// The overlap part of the flat segment and the span from 'ancestors'.
let mut overlap_span =
Span::from(seg_span.low.max(next_span.low)..=seg_span.high.min(next_span.high));
IdSpan::from(seg_span.low.max(next_span.low)..=seg_span.high.min(next_span.high));
if roots.contains(overlap_span.low) {
// Descendants includes 'overlap_span' since 'low' is in 'roots'.
// (no need to check 'result' - it does not include anything in 'overlap')
@ -1350,7 +1350,7 @@ impl<Store: IdDagStore> IdDag<Store> {
}
}
// Update next_optional_span.
next_optional_span = Span::try_from_bounds(overlap_span.high + 1..=next_span.high)
next_optional_span = IdSpan::try_from_bounds(overlap_span.high + 1..=next_span.high)
.or_else(|| span_iter.next());
}
@ -1417,7 +1417,7 @@ pub enum FirstAncestorConstraint {
/// (at clone time, client gets a sparse idmap including them)
///
/// This also enforces `x` to be part of `ancestors(heads)`.
KnownUniversally { heads: SpanSet },
KnownUniversally { heads: IdSet },
}
impl<Store: IdDagStore + Persist> SyncableIdDag<'_, Store> {

View File

@ -27,7 +27,7 @@ pub mod ops;
pub mod protocol;
pub mod render;
pub mod segment;
pub mod spanset;
mod spanset;
pub mod utils;
mod verlink;
@ -44,7 +44,6 @@ pub use namedag::NameDag;
pub use nameset::NameSet;
pub use ops::DagAlgorithm;
pub use segment::{FlatSegment, PreparedFlatSegments};
pub use spanset::SpanSet;
pub use verlink::VerLink;
pub type Level = u8;
@ -56,7 +55,9 @@ pub type OnDiskIdDag = IdDag<iddagstore::IndexedLogStore>;
#[cfg(any(test, feature = "indexedlog-backend"))]
pub type Dag = NameDag;
pub type Set = NameSet;
pub type IdSet = SpanSet;
pub type IdSet = spanset::SpanSet;
pub type IdSetIter<T> = spanset::SpanSetIter<T>;
pub type IdSpan = spanset::Span;
pub use namedag::MemNameDag as MemDag;
pub use nameset::NameIter as SetIter;
pub type Vertex = VertexName;

View File

@ -38,7 +38,7 @@ use crate::ops::ToIdSet;
use crate::ops::TryClone;
use crate::segment::PreparedFlatSegments;
use crate::segment::SegmentFlags;
use crate::spanset::SpanSet;
use crate::IdSet;
use crate::Result;
use crate::VerLink;
use futures::future::join_all;
@ -313,7 +313,7 @@ where
Ok(set.clone())
} else {
let flags = extract_ancestor_flag_if_compatible(set.hints(), self.dag_version());
let mut spans = SpanSet::empty();
let mut spans = IdSet::empty();
for name in set.iter()? {
let id = self.map().vertex_id(name?).await?;
spans.push(id);
@ -335,7 +335,7 @@ where
Ok(result)
}
/// Returns a [`SpanSet`] that covers all vertexes tracked by this DAG.
/// Returns a set that covers all vertexes tracked by this DAG.
async fn all(&self) -> Result<NameSet> {
let spans = self.dag().all()?;
let result = NameSet::from_spans_dag(spans, self)?;

View File

@ -11,9 +11,9 @@ use super::BoxVertexStream;
use super::{AsyncNameSetQuery, Hints};
use crate::ops::DagAlgorithm;
use crate::ops::IdConvert;
use crate::spanset::SpanSet;
use crate::Group;
use crate::Id;
use crate::IdSet;
use crate::Result;
use crate::VertexName;
use indexmap::IndexSet;
@ -197,7 +197,7 @@ impl IdLazySet {
/// Convert to an IdStaticSet.
pub fn to_static(&self) -> Result<IdStaticSet> {
let inner = self.load_all()?;
let mut spans = SpanSet::empty();
let mut spans = IdSet::empty();
for &id in inner.visited.iter() {
spans.push(id);
}

View File

@ -10,27 +10,27 @@ use super::BoxVertexStream;
use super::{AsyncNameSetQuery, Hints};
use crate::ops::DagAlgorithm;
use crate::ops::IdConvert;
use crate::spanset::Span;
use crate::spanset::{SpanSet, SpanSetIter};
use crate::Group;
use crate::IdSpan;
use crate::Result;
use crate::VertexName;
use crate::{IdSet, IdSetIter};
use nonblocking::non_blocking_result;
use std::any::Any;
use std::fmt;
use std::sync::Arc;
/// A set backed by [`SpanSet`] + [`IdMap`].
/// A set backed by [`IdSet`] + [`IdMap`].
/// Efficient for DAG calculation.
pub struct IdStaticSet {
pub(crate) spans: SpanSet,
pub(crate) spans: IdSet,
pub(crate) map: Arc<dyn IdConvert + Send + Sync>,
pub(crate) dag: Arc<dyn DagAlgorithm + Send + Sync>,
hints: Hints,
}
struct Iter {
iter: SpanSetIter<SpanSet>,
iter: IdSetIter<IdSet>,
map: Arc<dyn IdConvert + Send + Sync>,
reversed: bool,
}
@ -55,7 +55,7 @@ impl Iter {
}
struct DebugSpan {
span: Span,
span: IdSpan,
low_name: Option<VertexName>,
high_name: Option<VertexName>,
}
@ -112,7 +112,7 @@ impl fmt::Debug for IdStaticSet {
impl IdStaticSet {
pub(crate) fn from_spans_idmap_dag(
spans: SpanSet,
spans: IdSet,
map: Arc<dyn IdConvert + Send + Sync>,
dag: Arc<dyn DagAlgorithm + Send + Sync>,
) -> Self {

View File

@ -6,27 +6,27 @@
*/
use super::super::NameDag;
use super::super::SpanSet;
use super::IdStaticSet;
use super::NameSet;
use crate::IdSet;
/// A legacy token that enables conversion between SpanSet (id-based)
/// A legacy token that enables conversion between IdSet (id-based)
/// and NameSet (hash-based). It should not be used for new Rust code.
#[derive(Copy, Clone)]
pub struct LegacyCodeNeedIdAccess;
// This is ideally not provided. However revision numbers in revset still have
// large use-cases in Python and for now we provide this way to convert IdStaticSet
// to SpanSet using "revision" numbers.
impl<'a> From<(LegacyCodeNeedIdAccess, &'a IdStaticSet)> for SpanSet {
fn from(value: (LegacyCodeNeedIdAccess, &'a IdStaticSet)) -> SpanSet {
// to IdSet using "revision" numbers.
impl<'a> From<(LegacyCodeNeedIdAccess, &'a IdStaticSet)> for IdSet {
fn from(value: (LegacyCodeNeedIdAccess, &'a IdStaticSet)) -> IdSet {
let set = value.1;
set.spans.clone()
}
}
impl<'a> From<(LegacyCodeNeedIdAccess, SpanSet, &'a NameDag)> for NameSet {
fn from(value: (LegacyCodeNeedIdAccess, SpanSet, &'a NameDag)) -> NameSet {
impl<'a> From<(LegacyCodeNeedIdAccess, IdSet, &'a NameDag)> for NameSet {
fn from(value: (LegacyCodeNeedIdAccess, IdSet, &'a NameDag)) -> NameSet {
NameSet::from_spans_dag(value.1, value.2).unwrap()
}
}
@ -44,7 +44,7 @@ mod tests {
use LegacyCodeNeedIdAccess as L;
with_dag(|dag| -> Result<()> {
let set1 = r(dag.ancestors("G".into()))?;
let spans: SpanSet = (
let spans: IdSet = (
L,
set1.as_any().downcast_ref::<IdStaticSet>().unwrap().clone(),
)

View File

@ -12,8 +12,8 @@
use crate::ops::DagAlgorithm;
use crate::ops::IdConvert;
use crate::ops::IdMapSnapshot;
use crate::spanset::SpanSet;
use crate::Id;
use crate::IdSet;
use crate::Result;
use crate::VertexName;
use futures::future::BoxFuture;
@ -109,20 +109,17 @@ impl NameSet {
Ok(Self::from_id_iter_idmap_dag(iter, map, dag))
}
/// Creates from [`SpanSet`], [`IdMap`] and [`DagAlgorithm`].
/// Creates from [`IdSet`], [`IdMap`] and [`DagAlgorithm`].
pub fn from_spans_idmap_dag(
spans: SpanSet,
spans: IdSet,
map: Arc<dyn IdConvert + Send + Sync>,
dag: Arc<dyn DagAlgorithm + Send + Sync>,
) -> NameSet {
Self::from_query(IdStaticSet::from_spans_idmap_dag(spans, map, dag))
}
/// Creates from [`SpanSet`] and a struct with snapshot abilities.
pub fn from_spans_dag(
spans: SpanSet,
dag: &(impl DagAlgorithm + IdMapSnapshot),
) -> Result<Self> {
/// Creates from [`IdSet`] and a struct with snapshot abilities.
pub fn from_spans_dag(spans: IdSet, dag: &(impl DagAlgorithm + IdMapSnapshot)) -> Result<Self> {
let map = dag.id_map_snapshot()?;
let dag = dag.dag_snapshot()?;
Ok(Self::from_spans_idmap_dag(spans, map, dag))
@ -399,7 +396,7 @@ impl NameSet {
ids.push(id);
}
ids.sort_unstable_by_key(|i| u64::MAX - i.0);
let spans = SpanSet::from_sorted_spans(ids);
let spans = IdSet::from_sorted_spans(ids);
let flat_set = NameSet::from_spans_idmap_dag(spans, id_map, dag);
flat_set.hints().inherit_flags_min_max_id(self.hints());
Ok(flat_set)

View File

@ -38,7 +38,7 @@ pub trait DagAlgorithm: Send + Sync {
/// Get ordered parent vertexes.
async fn parent_names(&self, name: VertexName) -> Result<Vec<VertexName>>;
/// Returns a [`SpanSet`] that covers all vertexes tracked by this DAG.
/// Returns a set that covers all vertexes tracked by this DAG.
async fn all(&self) -> Result<NameSet>;
/// Calculates all ancestors reachable from any name from the given set.
@ -352,12 +352,12 @@ where
#[async_trait::async_trait]
pub trait ToIdSet {
/// Converts [`NameSet`] to [`SpanSet`].
/// Converts [`NameSet`] to [`IdSet`].
async fn to_id_set(&self, set: &NameSet) -> Result<IdSet>;
}
pub trait ToSet {
/// Converts [`SpanSet`] to [`NameSet`].
/// Converts [`IdSet`] to [`NameSet`].
fn to_set(&self, set: &IdSet) -> Result<NameSet>;
}
@ -459,7 +459,7 @@ impl IdMapSnapshot for Arc<dyn IdConvert + Send + Sync> {
}
impl<T: IdMapSnapshot + DagAlgorithm> ToSet for T {
/// Converts [`SpanSet`] to [`NameSet`].
/// Converts [`IdSet`] to [`NameSet`].
fn to_set(&self, set: &IdSet) -> Result<NameSet> {
NameSet::from_spans_dag(set.clone(), self)
}

View File

@ -21,11 +21,11 @@ use crate::id::VertexName;
use crate::iddag::{FirstAncestorConstraint, IdDag};
use crate::iddagstore::IdDagStore;
use crate::ops::IdConvert;
use crate::spanset::SpanSet;
use crate::Error;
use crate::Id;
#[cfg(any(test, feature = "indexedlog-backend"))]
use crate::IdMap;
use crate::IdSet;
use crate::Result;
use nonblocking::non_blocking_result;
use serde::{Deserialize, Serialize};
@ -175,7 +175,7 @@ impl<M: IdConvert, DagStore: IdDagStore> Process<RequestNameToLocation, Response
.into_iter()
.map(|s| non_blocking_result(map.vertex_id(s)))
.collect::<Result<Vec<Id>>>()?;
let heads = SpanSet::from_spans(heads);
let heads = IdSet::from_spans(heads);
let path_names = request
.names
.into_iter()

View File

@ -16,7 +16,7 @@
use crate::errors::bug;
use crate::id::Id;
use crate::spanset::Span;
use crate::IdSpan;
use crate::Level;
use crate::Result;
use bitflags::bitflags;
@ -98,7 +98,7 @@ impl Segment {
Ok(len)
}
pub(crate) fn span(&self) -> Result<Span> {
pub(crate) fn span(&self) -> Result<IdSpan> {
let high = self.high()?;
let delta = self.delta()?;
let low = high - delta;

View File

@ -13,10 +13,10 @@ use crate::ops::ImportAscii;
use crate::render::render_namedag;
use crate::DagAlgorithm;
use crate::IdMap;
use crate::IdSet;
use crate::NameDag;
use crate::NameSet;
use crate::Result;
use crate::SpanSet;
use nonblocking::non_blocking_result as r;
use tempfile::tempdir;
pub use test_dag::TestDag;
@ -854,7 +854,7 @@ fn test_segment_ancestors_example1() {
(vec![1..=4], vec![]),
] {
assert_eq!(
dag.gca_all(SpanSet::from_spans(spans))
dag.gca_all(IdSet::from_spans(spans))
.unwrap()
.iter()
.collect::<Vec<Id>>(),
@ -902,8 +902,7 @@ Lv1: R0-7[]"#
let dag = result.name_dag.dag;
let parents =
|spans| -> String { format_set(dag.parents(SpanSet::from_spans(spans)).unwrap()) };
let parents = |spans| -> String { format_set(dag.parents(IdSet::from_spans(spans)).unwrap()) };
let parent_ids = |id| -> String { format!("{:?}", dag.parent_ids(Id(id)).unwrap()) };
let first_ancestor_nth =
|id, n| -> String { format!("{:?}", dag.first_ancestor_nth(Id(id), n).unwrap()) };
@ -972,7 +971,7 @@ fn test_children() {
let result = build_segments(ASCII_DAG1, "L", 3);
let dag = result.name_dag.dag;
let children =
|spans| -> String { format_set(dag.children(SpanSet::from_spans(spans)).unwrap()) };
|spans| -> String { format_set(dag.children(IdSet::from_spans(spans)).unwrap()) };
// See test_parents above for the ASCII DAG.
@ -1031,7 +1030,7 @@ Lv2: R0-2[] R3-6[] R7-9[]"#
);
let dag = result.name_dag.dag;
let heads = |spans| -> String { format_set(dag.heads(SpanSet::from_spans(spans)).unwrap()) };
let heads = |spans| -> String { format_set(dag.heads(IdSet::from_spans(spans)).unwrap()) };
assert_eq!(heads(vec![]), "");
assert_eq!(heads(vec![0..=11]), "2 6 9 10 11");
@ -1064,7 +1063,7 @@ Lv2: R0-2[] R3-6[]"#
);
let dag = result.name_dag.dag;
let roots = |spans| -> String { format_set(dag.roots(SpanSet::from_spans(spans)).unwrap()) };
let roots = |spans| -> String { format_set(dag.roots(IdSet::from_spans(spans)).unwrap()) };
assert_eq!(roots(vec![]), "");
assert_eq!(roots(vec![0..=11]), "0 3 7 8 10");
@ -1103,7 +1102,7 @@ Lv2: R0-3[] R4-6[1]"#
let dag = result.name_dag.dag;
let range = |roots, heads| -> String {
format_set(
dag.range(SpanSet::from_spans(roots), SpanSet::from_spans(heads))
dag.range(IdSet::from_spans(roots), IdSet::from_spans(heads))
.unwrap(),
)
};
@ -1173,7 +1172,7 @@ Lv2: R0-3[] R4-6[1]"#
// Test descendants() and ancestors() against range().
for bits in 0..(1 << 10) {
let mut set = SpanSet::empty();
let mut set = IdSet::empty();
for i in (0..=9).rev() {
if bits & (1 << i) != 0 {
set.push_span(i.into());
@ -1213,7 +1212,7 @@ fn nameset(names: &str) -> NameSet {
NameSet::from_static_names(names)
}
fn format_set(set: SpanSet) -> String {
fn format_set(set: IdSet) -> String {
format!("{:?}", set)
}

View File

@ -39,7 +39,7 @@ impl DagAlgorithm for DummyDag {
Ok(Vec::new())
}
/// Returns a [`SpanSet`] that covers all vertexes tracked by this DAG.
/// Returns a set that covers all vertexes tracked by this DAG.
async fn all(&self) -> Result<NameSet> {
crate::errors::programming("DummyDag does not support all()")
}

View File

@ -1017,7 +1017,7 @@ impl DagAlgorithm for RevlogIndex {
Ok(result)
}
/// Returns a [`SpanSet`] that covers all vertexes tracked by this DAG.
/// Returns a set that covers all vertexes tracked by this DAG.
async fn all(&self) -> dag::Result<Set> {
let id_set = if self.len() == 0 {
IdSet::empty()