diff --git a/lib/src/default_index_store.rs b/lib/src/default_index_store.rs index 29ed09b08..38151fa77 100644 --- a/lib/src/default_index_store.rs +++ b/lib/src/default_index_store.rs @@ -974,17 +974,14 @@ impl<'a> CompositeIndex<'a> { // Walk ancestors of the parents of the candidates. Remove visited commits from // set of candidates. Stop walking when we have gone past the minimum // candidate generation. - let mut visited = HashSet::new(); - while let Some(item) = work.pop() { - if !visited.insert(item.pos) { - continue; - } + while let Some(item) = dedup_pop(&mut work) { if item.generation < min_generation { break; } candidate_positions.remove(&item.pos); let entry = self.entry_by_pos(item.pos); for parent_entry in entry.parents() { + assert!(parent_entry.pos < entry.pos); work.push(IndexPositionByGeneration::from(&parent_entry)); } } @@ -1596,6 +1593,16 @@ impl RevWalkItemGenerationRange { } } +/// Removes the greatest items (including duplicates) from the heap, returns +/// one. +fn dedup_pop(heap: &mut BinaryHeap) -> Option { + let item = heap.pop()?; + while heap.peek() == Some(&item) { + heap.pop().unwrap(); + } + Some(item) +} + impl IndexSegment for ReadonlyIndexImpl { fn segment_num_parent_commits(&self) -> u32 { self.num_parent_commits