mirror of
https://github.com/martinvonz/jj.git
synced 2025-02-08 21:48:08 +00:00
index: return early from RevWalk if items get filled with unwanted
This commit is contained in:
parent
2a00481ec5
commit
f4953cdb60
1 changed files with 23 additions and 2 deletions
|
@ -990,6 +990,7 @@ impl RevWalkWorkItem<'_> {
|
||||||
pub struct RevWalk<'a> {
|
pub struct RevWalk<'a> {
|
||||||
index: CompositeIndex<'a>,
|
index: CompositeIndex<'a>,
|
||||||
items: BinaryHeap<RevWalkWorkItem<'a>>,
|
items: BinaryHeap<RevWalkWorkItem<'a>>,
|
||||||
|
unwanted_count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RevWalk<'a> {
|
impl<'a> RevWalk<'a> {
|
||||||
|
@ -997,6 +998,7 @@ impl<'a> RevWalk<'a> {
|
||||||
Self {
|
Self {
|
||||||
index,
|
index,
|
||||||
items: BinaryHeap::new(),
|
items: BinaryHeap::new(),
|
||||||
|
unwanted_count: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1012,11 +1014,21 @@ impl<'a> RevWalk<'a> {
|
||||||
entry: IndexEntryByPosition(self.index.entry_by_pos(pos)),
|
entry: IndexEntryByPosition(self.index.entry_by_pos(pos)),
|
||||||
state: RevWalkWorkItemState::Unwanted,
|
state: RevWalkWorkItemState::Unwanted,
|
||||||
});
|
});
|
||||||
|
self.unwanted_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop(&mut self) -> Option<RevWalkWorkItem<'a>> {
|
||||||
|
if let Some(x) = self.items.pop() {
|
||||||
|
self.unwanted_count -= !x.is_wanted() as usize;
|
||||||
|
Some(x)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop_eq(&mut self, entry: &IndexEntry<'_>) -> Option<RevWalkWorkItem<'a>> {
|
fn pop_eq(&mut self, entry: &IndexEntry<'_>) -> Option<RevWalkWorkItem<'a>> {
|
||||||
if let Some(x) = self.items.peek() {
|
if let Some(x) = self.items.peek() {
|
||||||
(&x.entry.0 == entry).then(|| self.items.pop().unwrap())
|
(&x.entry.0 == entry).then(|| self.pop().unwrap())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -1033,19 +1045,28 @@ impl<'a> Iterator for RevWalk<'a> {
|
||||||
type Item = IndexEntry<'a>;
|
type Item = IndexEntry<'a>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
while let Some(item) = self.items.pop() {
|
while let Some(item) = self.pop() {
|
||||||
self.skip_while_eq(&item.entry.0);
|
self.skip_while_eq(&item.entry.0);
|
||||||
if item.is_wanted() {
|
if item.is_wanted() {
|
||||||
for parent_pos in item.entry.0.parent_positions() {
|
for parent_pos in item.entry.0.parent_positions() {
|
||||||
self.add_wanted(parent_pos);
|
self.add_wanted(parent_pos);
|
||||||
}
|
}
|
||||||
return Some(item.entry.0);
|
return Some(item.entry.0);
|
||||||
|
} else if self.items.len() == self.unwanted_count {
|
||||||
|
// No more wanted entries to walk
|
||||||
|
debug_assert!(!self.items.iter().any(|x| x.is_wanted()));
|
||||||
|
return None;
|
||||||
} else {
|
} else {
|
||||||
for parent_pos in item.entry.0.parent_positions() {
|
for parent_pos in item.entry.0.parent_positions() {
|
||||||
self.add_unwanted(parent_pos);
|
self.add_unwanted(parent_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug_assert_eq!(
|
||||||
|
self.items.iter().filter(|x| !x.is_wanted()).count(),
|
||||||
|
self.unwanted_count
|
||||||
|
);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue