Skip to content

Commit acd39b8

Browse files
thestingerbrson
authored andcommitted
---
yaml --- r: 34159 b: refs/heads/snap-stage3 c: b3463ea h: refs/heads/master i: 34157: fa5077c 34155: 981eed2 34151: 6b0c52e 34143: e22c2dc v: v3
1 parent d070fed commit acd39b8

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: cd6f24f9d14ac90d167386a56e7a6ac1f0318195
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 6c433f22a152f6825f3610382176aaa191ebf7cb
4+
refs/heads/snap-stage3: b3463ea65773972e4b5ec9ba4ef35b5f9e595284
55
refs/heads/try: d324a424d8f84b1eb049b12cf34182bda91b0024
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libstd/priority_queue.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11

22
/// A priority queue implemented with a binary heap
33
use core::cmp::Ord;
4+
use ptr::addr_of;
45

5-
pub struct PriorityQueue <T: Copy Ord>{
6+
#[abi = "rust-intrinsic"]
7+
extern "C" mod rusti {
8+
fn move_val_init<T>(dst: &mut T, -src: T);
9+
}
10+
11+
pub struct PriorityQueue <T: Ord>{
612
priv data: ~[T],
713
}
814

9-
impl <T: Copy Ord> PriorityQueue<T> {
15+
impl <T: Ord> PriorityQueue<T> {
1016
/// Returns the greatest item in the queue - fails if empty
1117
pure fn top(&self) -> &self/T { &self.data[0] }
1218

@@ -97,38 +103,46 @@ impl <T: Copy Ord> PriorityQueue<T> {
97103
q
98104
}
99105

100-
priv fn siftup(&mut self, start: uint, pos: uint) {
106+
// The implementations of siftup and siftdown use unsafe blocks in order to
107+
// move an element out of the vector (leaving behind a junk element), shift
108+
// along the others and move it back into the vector over the junk element.
109+
// This reduces the constant factor compared to using swaps, which involves
110+
// twice as many moves.
111+
112+
priv fn siftup(&mut self, start: uint, pos: uint) unsafe {
101113
let mut pos = pos;
102-
let new = self.data[pos];
114+
let new = move *addr_of(&self.data[pos]);
103115

104116
while pos > start {
105117
let parent = (pos - 1) >> 1;
106118
if new > self.data[parent] {
107-
self.data[pos] = self.data[parent];
119+
rusti::move_val_init(&mut self.data[pos],
120+
move *addr_of(&self.data[parent]));
108121
pos = parent;
109122
loop
110123
}
111124
break
112125
}
113-
self.data[pos] = new;
126+
rusti::move_val_init(&mut self.data[pos], move new);
114127
}
115128

116-
priv fn siftdown_range(&mut self, pos: uint, end: uint) {
129+
priv fn siftdown_range(&mut self, pos: uint, end: uint) unsafe {
117130
let mut pos = pos;
118131
let start = pos;
119-
let new = self.data[pos];
132+
let new = move *addr_of(&self.data[pos]);
120133

121134
let mut child = 2 * pos + 1;
122135
while child < end {
123136
let right = child + 1;
124137
if right < end && !(self.data[child] > self.data[right]) {
125138
child = right;
126139
}
127-
self.data[pos] = self.data[child];
140+
rusti::move_val_init(&mut self.data[pos],
141+
move *addr_of(&self.data[child]));
128142
pos = child;
129143
child = 2 * pos + 1;
130144
}
131-
self.data[pos] = new;
145+
rusti::move_val_init(&mut self.data[pos], move new);
132146
self.siftup(start, pos);
133147
}
134148

0 commit comments

Comments
 (0)