diff --git a/lib/src/default_index/rev_walk.rs b/lib/src/default_index/rev_walk.rs
index 1333b86d9..92a50f322 100644
--- a/lib/src/default_index/rev_walk.rs
+++ b/lib/src/default_index/rev_walk.rs
@@ -110,16 +110,6 @@ impl
RevWalkWorkItem
{
fn is_wanted(&self) -> bool {
matches!(self.state, RevWalkWorkItemState::Wanted(_))
}
-
- fn map_wanted(self, f: impl FnOnce(T) -> U) -> RevWalkWorkItem
{
- RevWalkWorkItem {
- pos: self.pos,
- state: match self.state {
- RevWalkWorkItemState::Wanted(t) => RevWalkWorkItemState::Wanted(f(t)),
- RevWalkWorkItemState::Unwanted => RevWalkWorkItemState::Unwanted,
- },
- }
- }
}
#[derive(Clone)]
@@ -136,17 +126,6 @@ impl RevWalkQueue {
}
}
- fn map_wanted(self, mut f: impl FnMut(T) -> U) -> RevWalkQueue {
- RevWalkQueue {
- items: self
- .items
- .into_iter()
- .map(|x| x.map_wanted(&mut f))
- .collect(),
- unwanted_count: self.unwanted_count,
- }
- }
-
fn push_wanted(&mut self, pos: P, t: T) {
let state = RevWalkWorkItemState::Wanted(t);
self.items.push(RevWalkWorkItem { pos, state });
@@ -203,34 +182,38 @@ impl RevWalkQueue {
#[must_use]
pub(super) struct RevWalkBuilder<'a> {
index: CompositeIndex<'a>,
- // TODO: Use Vec<_> until queued item type is settled.
- queue: RevWalkQueue,
+ wanted: Vec,
+ unwanted: Vec,
}
impl<'a> RevWalkBuilder<'a> {
pub fn new(index: CompositeIndex<'a>) -> Self {
- let queue = RevWalkQueue::new();
- RevWalkBuilder { index, queue }
+ RevWalkBuilder {
+ index,
+ wanted: Vec::new(),
+ unwanted: Vec::new(),
+ }
}
/// Adds head positions to be included.
pub fn wanted_heads(mut self, positions: impl IntoIterator- ) -> Self {
- self.queue.extend_wanted(positions, ());
+ self.wanted.extend(positions);
self
}
/// Adds root positions to be excluded. The roots precede the heads.
pub fn unwanted_roots(mut self, positions: impl IntoIterator
- ) -> Self {
- self.queue.extend_unwanted(positions);
+ self.unwanted.extend(positions);
self
}
/// Walks ancestors.
pub fn ancestors(self) -> RevWalkAncestors<'a> {
- RevWalkImpl {
- index: self.index,
- queue: self.queue,
- }
+ let index = self.index;
+ let mut queue = RevWalkQueue::new();
+ queue.extend_wanted(self.wanted, ());
+ queue.extend_unwanted(self.unwanted);
+ RevWalkImpl { index, queue }
}
/// Walks ancestors within the `generation_range`.
@@ -240,7 +223,16 @@ impl<'a> RevWalkBuilder<'a> {
self,
generation_range: Range,
) -> RevWalkAncestorsGenerationRange<'a> {
- RevWalkGenerationRangeImpl::new(self.index, self.queue, generation_range)
+ let index = self.index;
+ let mut queue = RevWalkQueue::new();
+ let item_range = RevWalkItemGenerationRange::from_filter_range(generation_range.clone());
+ queue.extend_wanted(self.wanted, Reverse(item_range));
+ queue.extend_unwanted(self.unwanted);
+ RevWalkGenerationRangeImpl {
+ index,
+ queue,
+ generation_end: generation_range.end,
+ }
}
/// Walks ancestors until all of the reachable roots in `root_positions` get
@@ -293,14 +285,20 @@ impl<'a> RevWalkBuilder<'a> {
let root_positions = Vec::from_iter(root_positions);
let entries = self.ancestors_until_roots(&root_positions);
let descendants_index = RevWalkDescendantsIndex::build(index, entries);
+
let mut queue = RevWalkQueue::new();
+ let item_range = RevWalkItemGenerationRange::from_filter_range(generation_range.clone());
for pos in root_positions {
// Do not add unreachable roots which shouldn't be visited
if descendants_index.contains_pos(pos) {
- queue.push_wanted(Reverse(pos), ());
+ queue.push_wanted(Reverse(pos), Reverse(item_range));
}
}
- RevWalkGenerationRangeImpl::new(descendants_index, queue, generation_range)
+ RevWalkGenerationRangeImpl {
+ index: descendants_index,
+ queue,
+ generation_end: generation_range.end,
+ }
}
}
@@ -358,26 +356,6 @@ pub(super) struct RevWalkGenerationRangeImpl<'a, I: RevWalkIndex<'a>> {
}
impl<'a, I: RevWalkIndex<'a>> RevWalkGenerationRangeImpl<'a, I> {
- fn new(index: I, queue: RevWalkQueue, generation_range: Range) -> Self {
- // Translate filter range to item ranges so that overlapped ranges can be
- // merged later.
- //
- // Example: `generation_range = 1..4`
- // (original) (translated)
- // 0 1 2 3 4 0 1 2 3 4
- // *=====o generation_range + generation_end
- // + : : item's generation o=====* : item's range
- let item_range = RevWalkItemGenerationRange {
- start: 0,
- end: u32::saturating_sub(generation_range.end, generation_range.start),
- };
- RevWalkGenerationRangeImpl {
- index,
- queue: queue.map_wanted(|()| Reverse(item_range)),
- generation_end: generation_range.end,
- }
- }
-
fn enqueue_wanted_adjacents(
&mut self,
entry: &IndexEntry<'_>,
@@ -452,6 +430,23 @@ struct RevWalkItemGenerationRange {
}
impl RevWalkItemGenerationRange {
+ /// Translates filter range to item range so that overlapped ranges can be
+ /// merged later.
+ ///
+ /// Example: `generation_range = 1..4`
+ /// ```text
+ /// (original) (translated)
+ /// 0 1 2 3 4 0 1 2 3 4
+ /// *=====o generation_range + generation_end
+ /// + : : item's generation o=====* : item's range
+ /// ```
+ fn from_filter_range(range: Range) -> Self {
+ RevWalkItemGenerationRange {
+ start: 0,
+ end: u32::saturating_sub(range.end, range.start),
+ }
+ }
+
/// Suppose sorted ranges `self, other`, merges them if overlapped.
#[must_use]
fn try_merge_end(self, other: Self) -> Option {