diff options
| author | Martin Hafskjold Thoresen <martinhath@gmail.com> | 2017-01-17 18:58:49 +0100 |
|---|---|---|
| committer | Martin Hafskjold Thoresen <martinhath@gmail.com> | 2017-01-17 19:25:48 +0100 |
| commit | 90fbe155f2104c9cbbec5ff1e79ee513e112fa9c (patch) | |
| tree | 0166e1f753a5d497c6d4d75d1681c318417e210f /src/libcollections | |
| parent | fb3483c827e1ef8ad73b200fb73f1dd03994e510 (diff) | |
Fix BinaryHeap place by only constructing vec::PlaceBack once
Diffstat (limited to 'src/libcollections')
| -rw-r--r-- | src/libcollections/binary_heap.rs | 69 |
1 files changed, 24 insertions, 45 deletions
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 8fcc7e0d4da..b7c2a708baf 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -673,7 +673,7 @@ impl<T: Ord> BinaryHeap<T> { // the hole is filled back at the end of its scope, even on panic. // Using a hole reduces the constant factor compared to using swaps, // which involves twice as many moves. - fn sift_up(&mut self, start: usize, pos: usize) { + fn sift_up(&mut self, start: usize, pos: usize) -> usize { unsafe { // Take out the value at `pos` and create a hole. let mut hole = Hole::new(&mut self.data, pos); @@ -685,21 +685,6 @@ impl<T: Ord> BinaryHeap<T> { } hole.move_to(parent); } - } - } - - fn sift_up_ind(&mut self, start: usize, pos: usize) -> usize { - unsafe { - // Take out the value at `pos` and create a hole. - let mut hole = Hole::new(&mut self.data, pos); - - while hole.pos() > start { - let parent = (hole.pos() - 1) / 2; - if hole.element() <= hole.get(parent) { - return hole.pos(); - } - hole.move_to(parent); - } hole.pos() } } @@ -905,19 +890,6 @@ impl<T: Ord> BinaryHeap<T> { } } -impl<T> BinaryHeap<T> -where T: Clone + Ord { - /// kek - #[unstable(feature = "collection_placement", - reason = "placement protocol is subject to change", - issue = "30172")] - pub fn place(&mut self) -> PlaceIn<T> { - PlaceIn { - heap: self, - } - } -} - /// Hole represents a hole in a slice i.e. an index without valid value /// (because it was moved from or duplicated). /// In drop, `Hole` will restore the slice by filling the hole @@ -1222,45 +1194,52 @@ impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BinaryHeap<T> { #[unstable(feature = "collection_placement", reason = "placement protocol is subject to change", issue = "30172")] -pub struct PlaceIn<'a, T: 'a> +pub struct BinaryHeapPlace<'a, T: 'a> where T: Clone + Ord { - heap: &'a mut BinaryHeap<T>, + heap: *mut BinaryHeap<T>, + place: vec::PlaceBack<'a, T>, } #[unstable(feature = "collection_placement", reason = "placement protocol is subject to change", issue = "30172")] -impl<'a, T> Place<T> for PlaceIn<'a, T> +impl<'a, T: 'a> Placer<T> for &'a mut BinaryHeap<T> where T: Clone + Ord { - fn pointer(&mut self) -> *mut T { - self.heap.data.place_back().pointer() + type Place = BinaryHeapPlace<'a, T>; + + fn make_place(self) -> Self::Place { + let ptr = self as *mut BinaryHeap<T>; + let place = Placer::make_place(self.data.place_back()); + BinaryHeapPlace { + heap: ptr, + place: place, + } } } #[unstable(feature = "collection_placement", reason = "placement protocol is subject to change", issue = "30172")] -impl<'a, T> Placer<T> for PlaceIn<'a, T> +impl<'a, T> Place<T> for BinaryHeapPlace<'a, T> where T: Clone + Ord { - type Place = PlaceIn<'a, T>; - - fn make_place(self) -> Self { - let _ = self.heap.data.place_back().make_place(); - self + fn pointer(&mut self) -> *mut T { + self.place.pointer() } } #[unstable(feature = "collection_placement", reason = "placement protocol is subject to change", issue = "30172")] -impl<'a, T> InPlace<T> for PlaceIn<'a, T> +impl<'a, T> InPlace<T> for BinaryHeapPlace<'a, T> where T: Clone + Ord { type Owner = &'a T; unsafe fn finalize(self) -> &'a T { - let len = self.heap.len(); - let _ = self.heap.data.place_back().finalize(); - let i = self.heap.sift_up_ind(0, len); - &mut self.heap.data[i] + self.place.finalize(); + + let heap: &mut BinaryHeap<T> = &mut *self.heap; + let len = heap.len(); + let i = heap.sift_up(0, len - 1); + heap.data.get_unchecked(i) } } |
