1use crate::mesh::INVALID;
15
16pub const INVALID_HANDLE: i32 = 0x0fff_ffff;
17
18struct Heap {
20 nodes: Vec<i32>,
22 handles: Vec<(u32, i32)>,
24 size: usize,
25 max: usize,
26 free_list: i32,
27 initialized: bool,
28 leq: fn(u32, u32) -> bool,
30}
31
32impl Heap {
33 fn new(size: usize, leq: fn(u32, u32) -> bool) -> Self {
34 let mut nodes = vec![0i32; size + 2];
35 let mut handles = vec![(INVALID, 0i32); size + 2];
36 nodes[1] = 1;
38 handles[1] = (INVALID, 1);
39 Heap {
40 nodes,
41 handles,
42 size: 0,
43 max: size,
44 free_list: 0,
45 initialized: false,
46 leq,
47 }
48 }
49
50 #[inline]
51 fn key_of(&self, handle: i32) -> u32 {
52 self.handles[handle as usize].0
53 }
54
55 fn float_down(&mut self, mut curr: usize) {
56 let h_curr = self.nodes[curr];
57 loop {
58 let mut child = curr << 1;
59 if child < self.size {
60 let child_key = self.key_of(self.nodes[child + 1]);
61 let child_key0 = self.key_of(self.nodes[child]);
62 if (self.leq)(child_key, child_key0) {
63 child += 1;
64 }
65 }
66 let h_child = self.nodes[child];
67 if child > self.size || (self.leq)(self.key_of(h_curr), self.key_of(h_child)) {
68 self.nodes[curr] = h_curr;
69 self.handles[h_curr as usize].1 = curr as i32;
70 break;
71 }
72 self.nodes[curr] = h_child;
73 self.handles[h_child as usize].1 = curr as i32;
74 curr = child;
75 }
76 }
77
78 fn float_up(&mut self, mut curr: usize) {
79 let h_curr = self.nodes[curr];
80 loop {
81 let parent = curr >> 1;
82 let h_parent = self.nodes[parent];
83 if parent == 0 || (self.leq)(self.key_of(h_parent), self.key_of(h_curr)) {
84 self.nodes[curr] = h_curr;
85 self.handles[h_curr as usize].1 = curr as i32;
86 break;
87 }
88 self.nodes[curr] = h_parent;
89 self.handles[h_parent as usize].1 = curr as i32;
90 curr = parent;
91 }
92 }
93
94 fn init(&mut self) {
95 for i in (1..=self.size).rev() {
96 self.float_down(i);
97 }
98 self.initialized = true;
99 }
100
101 fn insert(&mut self, key: u32) -> i32 {
102 self.size += 1;
103 let curr = self.size;
104
105 if curr * 2 > self.max {
107 self.max <<= 1;
108 self.nodes.resize(self.max + 2, 0);
109 self.handles.resize(self.max + 2, (INVALID, 0));
110 }
111
112 let free_handle = if self.free_list == 0 {
113 curr as i32
114 } else {
115 let f = self.free_list;
116 self.free_list = self.handles[f as usize].1;
117 f
118 };
119
120 self.nodes[curr] = free_handle;
121 self.handles[free_handle as usize] = (key, curr as i32);
122
123 if self.initialized {
124 self.float_up(curr);
125 }
126
127 free_handle
128 }
129
130 fn extract_min(&mut self) -> u32 {
131 let h_min = self.nodes[1];
132 let min_key = self.handles[h_min as usize].0;
133
134 if self.size > 0 {
135 self.nodes[1] = self.nodes[self.size];
136 self.handles[self.nodes[1] as usize].1 = 1;
137
138 self.handles[h_min as usize].0 = INVALID;
139 self.handles[h_min as usize].1 = self.free_list;
140 self.free_list = h_min;
141
142 self.size -= 1;
143 if self.size > 0 {
144 self.float_down(1);
145 }
146 }
147
148 min_key
149 }
150
151 fn delete(&mut self, h_curr: i32) {
152 debug_assert!(self.handles[h_curr as usize].0 != INVALID);
153 let curr = self.handles[h_curr as usize].1 as usize;
154
155 self.nodes[curr] = self.nodes[self.size];
156 self.handles[self.nodes[curr] as usize].1 = curr as i32;
157
158 if curr <= self.size {
159 self.size -= 1;
160 if curr <= 1 {
161 self.float_down(curr);
162 } else {
163 let parent_key = self.key_of(self.nodes[curr >> 1]);
164 let curr_key = self.key_of(self.nodes[curr]);
165 if (self.leq)(parent_key, curr_key) {
166 self.float_down(curr);
167 } else {
168 self.float_up(curr);
169 }
170 }
171 } else {
172 self.size -= 1;
173 }
174
175 self.handles[h_curr as usize].0 = INVALID;
176 self.handles[h_curr as usize].1 = self.free_list;
177 self.free_list = h_curr;
178 }
179
180 #[inline]
181 fn minimum(&self) -> u32 {
182 self.handles[self.nodes[1] as usize].0
183 }
184
185 #[inline]
186 fn is_empty(&self) -> bool {
187 self.size == 0
188 }
189}
190
191pub struct PriorityQ {
193 heap: Heap,
194 keys: Vec<u32>,
196 order: Vec<usize>,
198 size: usize,
199 max: usize,
200 initialized: bool,
201 leq: fn(u32, u32) -> bool,
202}
203
204impl PriorityQ {
205 pub fn new(size: usize, leq: fn(u32, u32) -> bool) -> Self {
206 PriorityQ {
207 heap: Heap::new(size, leq),
208 keys: Vec::with_capacity(size),
209 order: Vec::new(),
210 size: 0,
211 max: size,
212 initialized: false,
213 leq,
214 }
215 }
216
217 pub fn init(&mut self) -> bool {
220 self.order = (0..self.size).collect();
222
223 let keys = &self.keys;
225 let leq = self.leq;
226 self.order.sort_unstable_by(|&a, &b| {
227 if (leq)(keys[a], keys[b]) {
229 std::cmp::Ordering::Greater
230 } else {
231 std::cmp::Ordering::Less
232 }
233 });
234
235 self.max = self.size;
236 self.initialized = true;
237 self.heap.init();
238 true
239 }
240
241 pub fn insert(&mut self, key: u32) -> i32 {
244 if self.initialized {
245 return self.heap.insert(key);
246 }
247
248 let curr = self.size;
249 self.size += 1;
250
251 if self.size > self.max {
252 self.max <<= 1;
253 }
254
255 if curr >= self.keys.len() {
256 self.keys.push(key);
257 } else {
258 self.keys[curr] = key;
259 }
260
261 -(curr as i32 + 1)
263 }
264
265 pub fn extract_min(&mut self) -> u32 {
267 if self.size == 0 {
268 return self.heap.extract_min();
269 }
270
271 let sort_min = self.keys[self.order[self.size - 1]];
272
273 if !self.heap.is_empty() {
274 let heap_min = self.heap.minimum();
275 if (self.leq)(heap_min, sort_min) {
276 return self.heap.extract_min();
277 }
278 }
279
280 loop {
282 self.size -= 1;
283 if self.size == 0 || self.keys[self.order[self.size - 1]] != INVALID {
284 break;
285 }
286 }
287
288 sort_min
289 }
290
291 pub fn minimum(&self) -> u32 {
293 if self.size == 0 {
294 return self.heap.minimum();
295 }
296
297 let sort_min = self.keys[self.order[self.size - 1]];
298
299 if !self.heap.is_empty() {
300 let heap_min = self.heap.minimum();
301 if (self.leq)(heap_min, sort_min) {
302 return heap_min;
303 }
304 }
305
306 sort_min
307 }
308
309 pub fn is_empty(&self) -> bool {
311 self.size == 0 && self.heap.is_empty()
312 }
313
314 pub fn delete(&mut self, handle: i32) {
316 if handle >= 0 {
317 self.heap.delete(handle);
318 return;
319 }
320
321 let curr = (-(handle + 1)) as usize;
322 debug_assert!(curr < self.keys.len() && self.keys[curr] != INVALID);
323 self.keys[curr] = INVALID;
324
325 while self.size > 0 && self.keys[self.order[self.size - 1]] == INVALID {
327 self.size -= 1;
328 }
329 }
330}
331
332#[cfg(test)]
333mod tests {
334 use super::*;
335 use crate::geom::vert_leq;
336
337 fn leq_u32(a: u32, b: u32) -> bool {
338 a <= b
339 }
340
341 #[test]
342 fn heap_basic() {
343 let mut h = Heap::new(8, leq_u32);
344 h.init();
345 h.insert(3);
346 h.insert(1);
347 h.insert(2);
348 assert_eq!(h.minimum(), 1);
349 assert_eq!(h.extract_min(), 1);
350 assert_eq!(h.extract_min(), 2);
351 assert_eq!(h.extract_min(), 3);
352 assert!(h.is_empty());
353 }
354
355 #[test]
356 fn pq_pre_init_insert_then_extract() {
357 let mut pq = PriorityQ::new(8, leq_u32);
358 pq.insert(5);
359 pq.insert(2);
360 pq.insert(8);
361 pq.insert(1);
362 pq.init();
363
364 assert_eq!(pq.extract_min(), 1);
365 assert_eq!(pq.extract_min(), 2);
366 assert_eq!(pq.extract_min(), 5);
367 assert_eq!(pq.extract_min(), 8);
368 assert!(pq.is_empty());
369 }
370
371 #[test]
372 fn pq_delete_from_sort_array() {
373 let mut pq = PriorityQ::new(8, leq_u32);
374 let h1 = pq.insert(10);
375 let _h2 = pq.insert(5);
376 let h3 = pq.insert(7);
377 pq.init();
378 pq.delete(h1);
379 assert_eq!(pq.extract_min(), 5);
380 assert_eq!(pq.extract_min(), 7);
381 assert!(pq.is_empty());
382 }
383
384 #[test]
385 fn pq_post_init_insert() {
386 let mut pq = PriorityQ::new(4, leq_u32);
387 pq.insert(3);
388 pq.init();
389 pq.insert(1); assert_eq!(pq.minimum(), 1);
391 assert_eq!(pq.extract_min(), 1);
392 assert_eq!(pq.extract_min(), 3);
393 }
394}