1use std::mem;
12
13pub struct Heap<T> {
14 items: Vec<(T, usize)>,
17
18 index: Vec<SlabSlot<usize>>,
21 next_index: usize,
22}
23
24enum SlabSlot<T> {
25 Empty { next: usize },
26 Full { value: T },
27}
28
29pub struct Slot {
30 idx: usize,
31}
32
33impl<T: Ord> Heap<T> {
34 pub fn new() -> Heap<T> {
35 Heap {
36 items: Vec::new(),
37 index: Vec::new(),
38 next_index: 0,
39 }
40 }
41
42 pub fn push(&mut self, t: T) -> Slot {
48 self.assert_consistent();
49 let len = self.items.len();
50 let slot = SlabSlot::Full { value: len };
51 let slot_idx = if self.next_index == self.index.len() {
52 self.next_index += 1;
53 self.index.push(slot);
54 self.index.len() - 1
55 } else {
56 match mem::replace(&mut self.index[self.next_index], slot) {
57 SlabSlot::Empty { next } => mem::replace(&mut self.next_index, next),
58 SlabSlot::Full { .. } => panic!(),
59 }
60 };
61 self.items.push((t, slot_idx));
62 self.percolate_up(len);
63 self.assert_consistent();
64 Slot { idx: slot_idx }
65 }
66
67 pub fn peek(&self) -> Option<&T> {
68 self.assert_consistent();
69 self.items.get(0).map(|i| &i.0)
70 }
71
72 pub fn pop(&mut self) -> Option<T> {
73 self.assert_consistent();
74 if self.items.is_empty() {
75 return None;
76 }
77 let slot = Slot {
78 idx: self.items[0].1,
79 };
80 Some(self.remove(slot))
81 }
82
83 pub fn remove(&mut self, slot: Slot) -> T {
84 self.assert_consistent();
85 let empty = SlabSlot::Empty {
86 next: self.next_index,
87 };
88 let idx = match mem::replace(&mut self.index[slot.idx], empty) {
89 SlabSlot::Full { value } => value,
90 SlabSlot::Empty { .. } => panic!(),
91 };
92 self.next_index = slot.idx;
93 let (item, slot_idx) = self.items.swap_remove(idx);
94 debug_assert_eq!(slot.idx, slot_idx);
95 if idx < self.items.len() {
96 set_index(&mut self.index, self.items[idx].1, idx);
97 if self.items[idx].0 < item {
98 self.percolate_up(idx);
99 } else {
100 self.percolate_down(idx);
101 }
102 }
103 self.assert_consistent();
104 item
105 }
106
107 fn percolate_up(&mut self, mut idx: usize) -> usize {
108 while idx > 0 {
109 let parent = (idx - 1) / 2;
110 if self.items[idx].0 >= self.items[parent].0 {
111 break;
112 }
113 let (a, b) = self.items.split_at_mut(idx);
114 mem::swap(&mut a[parent], &mut b[0]);
115 set_index(&mut self.index, a[parent].1, parent);
116 set_index(&mut self.index, b[0].1, idx);
117 idx = parent;
118 }
119 idx
120 }
121
122 fn percolate_down(&mut self, mut idx: usize) -> usize {
123 loop {
124 let left = 2 * idx + 1;
125 let right = 2 * idx + 2;
126
127 let mut swap_left = true;
128 match (self.items.get(left), self.items.get(right)) {
129 (Some(left), None) => {
130 if left.0 >= self.items[idx].0 {
131 break;
132 }
133 }
134 (Some(left), Some(right)) => {
135 if left.0 < self.items[idx].0 {
136 if right.0 < left.0 {
137 swap_left = false;
138 }
139 } else if right.0 < self.items[idx].0 {
140 swap_left = false;
141 } else {
142 break;
143 }
144 }
145
146 (None, None) => break,
147 (None, Some(_right)) => panic!("not possible"),
148 }
149
150 let (a, b) = if swap_left {
151 self.items.split_at_mut(left)
152 } else {
153 self.items.split_at_mut(right)
154 };
155 mem::swap(&mut a[idx], &mut b[0]);
156 set_index(&mut self.index, a[idx].1, idx);
157 set_index(&mut self.index, b[0].1, a.len());
158 idx = a.len();
159 }
160 idx
161 }
162
163 fn assert_consistent(&self) {
164 if !cfg!(assert_timer_heap_consistent) {
165 return;
166 }
167
168 assert_eq!(
169 self.items.len(),
170 self.index
171 .iter()
172 .filter(|slot| {
173 match **slot {
174 SlabSlot::Full { .. } => true,
175 SlabSlot::Empty { .. } => false,
176 }
177 })
178 .count()
179 );
180
181 for (i, &(_, j)) in self.items.iter().enumerate() {
182 let index = match self.index[j] {
183 SlabSlot::Full { value } => value,
184 SlabSlot::Empty { .. } => panic!(),
185 };
186 if index != i {
187 panic!(
188 "self.index[j] != i : i={} j={} self.index[j]={}",
189 i, j, index
190 );
191 }
192 }
193
194 for (i, &(ref item, _)) in self.items.iter().enumerate() {
195 if i > 0 {
196 assert!(*item >= self.items[(i - 1) / 2].0, "bad at index: {}", i);
197 }
198 if let Some(left) = self.items.get(2 * i + 1) {
199 assert!(*item <= left.0, "bad left at index: {}", i);
200 }
201 if let Some(right) = self.items.get(2 * i + 2) {
202 assert!(*item <= right.0, "bad right at index: {}", i);
203 }
204 }
205 }
206}
207
208fn set_index<T>(slab: &mut Vec<SlabSlot<T>>, slab_slot: usize, val: T) {
209 match slab[slab_slot] {
210 SlabSlot::Full { ref mut value } => *value = val,
211 SlabSlot::Empty { .. } => panic!(),
212 }
213}
214
215#[cfg(test)]
216mod tests {
217 use super::Heap;
218
219 #[test]
220 fn simple() {
221 let mut h = Heap::new();
222 h.push(1);
223 h.push(2);
224 h.push(8);
225 h.push(4);
226 assert_eq!(h.pop(), Some(1));
227 assert_eq!(h.pop(), Some(2));
228 assert_eq!(h.pop(), Some(4));
229 assert_eq!(h.pop(), Some(8));
230 assert_eq!(h.pop(), None);
231 assert_eq!(h.pop(), None);
232 }
233
234 #[test]
235 fn simple2() {
236 let mut h = Heap::new();
237 h.push(5);
238 h.push(4);
239 h.push(3);
240 h.push(2);
241 h.push(1);
242 assert_eq!(h.pop(), Some(1));
243 h.push(8);
244 assert_eq!(h.pop(), Some(2));
245 h.push(1);
246 assert_eq!(h.pop(), Some(1));
247 assert_eq!(h.pop(), Some(3));
248 assert_eq!(h.pop(), Some(4));
249 h.push(5);
250 assert_eq!(h.pop(), Some(5));
251 assert_eq!(h.pop(), Some(5));
252 assert_eq!(h.pop(), Some(8));
253 }
254
255 #[test]
256 fn remove() {
257 let mut h = Heap::new();
258 h.push(5);
259 h.push(4);
260 h.push(3);
261 let two = h.push(2);
262 h.push(1);
263 assert_eq!(h.pop(), Some(1));
264 assert_eq!(h.remove(two), 2);
265 h.push(1);
266 assert_eq!(h.pop(), Some(1));
267 assert_eq!(h.pop(), Some(3));
268 }
269
270 fn vec2heap<T: Ord>(v: Vec<T>) -> Heap<T> {
271 let mut h = Heap::new();
272 for t in v {
273 h.push(t);
274 }
275 return h;
276 }
277
278 #[test]
279 fn test_peek_and_pop() {
280 let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
281 let mut sorted = data.clone();
282 sorted.sort();
283 let mut heap = vec2heap(data);
284 while heap.peek().is_some() {
285 assert_eq!(heap.peek().unwrap(), sorted.first().unwrap());
286 assert_eq!(heap.pop().unwrap(), sorted.remove(0));
287 }
288 }
289
290 #[test]
291 fn test_push() {
292 let mut heap = Heap::new();
293 heap.push(-2);
294 heap.push(-4);
295 heap.push(-9);
296 assert!(*heap.peek().unwrap() == -9);
297 heap.push(-11);
298 assert!(*heap.peek().unwrap() == -11);
299 heap.push(-5);
300 assert!(*heap.peek().unwrap() == -11);
301 heap.push(-27);
302 assert!(*heap.peek().unwrap() == -27);
303 heap.push(-3);
304 assert!(*heap.peek().unwrap() == -27);
305 heap.push(-103);
306 assert!(*heap.peek().unwrap() == -103);
307 }
308
309 fn check_to_vec(mut data: Vec<i32>) {
310 let mut heap = Heap::new();
311 for data in data.iter() {
312 heap.push(*data);
313 }
314 data.sort();
315 let mut v = Vec::new();
316 while let Some(i) = heap.pop() {
317 v.push(i);
318 }
319 assert_eq!(v, data);
320 }
321
322 #[test]
323 fn test_to_vec() {
324 check_to_vec(vec![]);
325 check_to_vec(vec![5]);
326 check_to_vec(vec![3, 2]);
327 check_to_vec(vec![2, 3]);
328 check_to_vec(vec![5, 1, 2]);
329 check_to_vec(vec![1, 100, 2, 3]);
330 check_to_vec(vec![1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
331 check_to_vec(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
332 check_to_vec(vec![9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
333 check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
334 check_to_vec(vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
335 check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
336 check_to_vec(vec![5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
337 }
338
339 #[test]
340 fn test_empty_pop() {
341 let mut heap = Heap::<i32>::new();
342 assert!(heap.pop().is_none());
343 }
344
345 #[test]
346 fn test_empty_peek() {
347 let empty = Heap::<i32>::new();
348 assert!(empty.peek().is_none());
349 }
350}