Skip to content

Commit 90fbe15

Browse files
author
Martin Hafskjold Thoresen
committed
Fix BinaryHeap place by only constructing vec::PlaceBack once
1 parent fb3483c commit 90fbe15

File tree

2 files changed

+29
-50
lines changed

2 files changed

+29
-50
lines changed

src/libcollections/binary_heap.rs

+24-45
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ impl<T: Ord> BinaryHeap<T> {
673673
// the hole is filled back at the end of its scope, even on panic.
674674
// Using a hole reduces the constant factor compared to using swaps,
675675
// which involves twice as many moves.
676-
fn sift_up(&mut self, start: usize, pos: usize) {
676+
fn sift_up(&mut self, start: usize, pos: usize) -> usize {
677677
unsafe {
678678
// Take out the value at `pos` and create a hole.
679679
let mut hole = Hole::new(&mut self.data, pos);
@@ -685,21 +685,6 @@ impl<T: Ord> BinaryHeap<T> {
685685
}
686686
hole.move_to(parent);
687687
}
688-
}
689-
}
690-
691-
fn sift_up_ind(&mut self, start: usize, pos: usize) -> usize {
692-
unsafe {
693-
// Take out the value at `pos` and create a hole.
694-
let mut hole = Hole::new(&mut self.data, pos);
695-
696-
while hole.pos() > start {
697-
let parent = (hole.pos() - 1) / 2;
698-
if hole.element() <= hole.get(parent) {
699-
return hole.pos();
700-
}
701-
hole.move_to(parent);
702-
}
703688
hole.pos()
704689
}
705690
}
@@ -905,19 +890,6 @@ impl<T: Ord> BinaryHeap<T> {
905890
}
906891
}
907892

908-
impl<T> BinaryHeap<T>
909-
where T: Clone + Ord {
910-
/// kek
911-
#[unstable(feature = "collection_placement",
912-
reason = "placement protocol is subject to change",
913-
issue = "30172")]
914-
pub fn place(&mut self) -> PlaceIn<T> {
915-
PlaceIn {
916-
heap: self,
917-
}
918-
}
919-
}
920-
921893
/// Hole represents a hole in a slice i.e. an index without valid value
922894
/// (because it was moved from or duplicated).
923895
/// 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> {
12221194
#[unstable(feature = "collection_placement",
12231195
reason = "placement protocol is subject to change",
12241196
issue = "30172")]
1225-
pub struct PlaceIn<'a, T: 'a>
1197+
pub struct BinaryHeapPlace<'a, T: 'a>
12261198
where T: Clone + Ord {
1227-
heap: &'a mut BinaryHeap<T>,
1199+
heap: *mut BinaryHeap<T>,
1200+
place: vec::PlaceBack<'a, T>,
12281201
}
12291202

12301203
#[unstable(feature = "collection_placement",
12311204
reason = "placement protocol is subject to change",
12321205
issue = "30172")]
1233-
impl<'a, T> Place<T> for PlaceIn<'a, T>
1206+
impl<'a, T: 'a> Placer<T> for &'a mut BinaryHeap<T>
12341207
where T: Clone + Ord {
1235-
fn pointer(&mut self) -> *mut T {
1236-
self.heap.data.place_back().pointer()
1208+
type Place = BinaryHeapPlace<'a, T>;
1209+
1210+
fn make_place(self) -> Self::Place {
1211+
let ptr = self as *mut BinaryHeap<T>;
1212+
let place = Placer::make_place(self.data.place_back());
1213+
BinaryHeapPlace {
1214+
heap: ptr,
1215+
place: place,
1216+
}
12371217
}
12381218
}
12391219

12401220
#[unstable(feature = "collection_placement",
12411221
reason = "placement protocol is subject to change",
12421222
issue = "30172")]
1243-
impl<'a, T> Placer<T> for PlaceIn<'a, T>
1223+
impl<'a, T> Place<T> for BinaryHeapPlace<'a, T>
12441224
where T: Clone + Ord {
1245-
type Place = PlaceIn<'a, T>;
1246-
1247-
fn make_place(self) -> Self {
1248-
let _ = self.heap.data.place_back().make_place();
1249-
self
1225+
fn pointer(&mut self) -> *mut T {
1226+
self.place.pointer()
12501227
}
12511228
}
12521229

12531230
#[unstable(feature = "collection_placement",
12541231
reason = "placement protocol is subject to change",
12551232
issue = "30172")]
1256-
impl<'a, T> InPlace<T> for PlaceIn<'a, T>
1233+
impl<'a, T> InPlace<T> for BinaryHeapPlace<'a, T>
12571234
where T: Clone + Ord {
12581235
type Owner = &'a T;
12591236

12601237
unsafe fn finalize(self) -> &'a T {
1261-
let len = self.heap.len();
1262-
let _ = self.heap.data.place_back().finalize();
1263-
let i = self.heap.sift_up_ind(0, len);
1264-
&mut self.heap.data[i]
1238+
self.place.finalize();
1239+
1240+
let heap: &mut BinaryHeap<T> = &mut *self.heap;
1241+
let len = heap.len();
1242+
let i = heap.sift_up(0, len - 1);
1243+
heap.data.get_unchecked(i)
12651244
}
12661245
}

src/libcollectionstest/binary_heap.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -314,20 +314,20 @@ fn test_extend_specialization() {
314314
#[test]
315315
fn test_placement() {
316316
let mut a = BinaryHeap::new();
317-
a.place() <- 2;
318-
a.place() <- 4;
319-
a.place() <- 3;
317+
&mut a <- 2;
318+
&mut a <- 4;
319+
&mut a <- 3;
320320
assert_eq!(a.peek(), Some(&4));
321321
assert_eq!(a.len(), 3);
322-
a.place() <- 1;
322+
&mut a <- 1;
323323
assert_eq!(a.into_sorted_vec(), vec![1, 2, 3, 4]);
324324
}
325325

326326
#[test]
327327
fn test_placement_panic() {
328328
let mut heap = BinaryHeap::from(vec![1, 2, 3]);
329329
fn mkpanic() -> usize { panic!() }
330-
let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { heap.place() <- mkpanic(); }));
330+
let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { &mut heap <- mkpanic(); }));
331331
assert_eq!(heap.len(), 3);
332332
}
333333

0 commit comments

Comments
 (0)