Skip to content

Commit 81fcdd4

Browse files
committed
BinaryHeap: Simplify sift down
Sift down was doing all too much work: it can stop directly when the current element obeys the heap property in relation to its children. In the old code, sift down didn't compare the element to sift down at all, so it was maximally sifted down and relied on the sift up call to put it in the correct location. This should speed up heapify and .pop(). Also rename Hole::removed() to Hole::element()
1 parent 792a9f1 commit 81fcdd4

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

src/libcollections/binary_heap.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -521,29 +521,30 @@ impl<T: Ord> BinaryHeap<T> {
521521

522522
while hole.pos() > start {
523523
let parent = (hole.pos() - 1) / 2;
524-
if hole.removed() <= hole.get(parent) { break }
524+
if hole.element() <= hole.get(parent) { break; }
525525
hole.move_to(parent);
526526
}
527527
}
528528
}
529529

530-
fn sift_down_range(&mut self, mut pos: usize, end: usize) {
531-
let start = pos;
530+
/// Take an element at `pos` and move it down the heap,
531+
/// while its children are larger.
532+
fn sift_down_range(&mut self, pos: usize, end: usize) {
532533
unsafe {
533534
let mut hole = Hole::new(&mut self.data, pos);
534535
let mut child = 2 * pos + 1;
535536
while child < end {
536537
let right = child + 1;
538+
// compare with the greater of the two children
537539
if right < end && !(hole.get(child) > hole.get(right)) {
538540
child = right;
539541
}
542+
// if we are already in order, stop.
543+
if hole.element() >= hole.get(child) { break; }
540544
hole.move_to(child);
541545
child = 2 * hole.pos() + 1;
542546
}
543-
544-
pos = hole.pos;
545547
}
546-
self.sift_up(start, pos);
547548
}
548549

549550
fn sift_down(&mut self, pos: usize) {
@@ -605,7 +606,7 @@ impl<'a, T> Hole<'a, T> {
605606

606607
/// Return a reference to the element removed
607608
#[inline(always)]
608-
fn removed(&self) -> &T {
609+
fn element(&self) -> &T {
609610
self.elt.as_ref().unwrap()
610611
}
611612

0 commit comments

Comments
 (0)