use alloc::vec::Vec;
pub struct FlatQueue<T> {
ids: Vec<T>,
values: Vec<f64>, len: usize,
}
impl<T: Clone> Default for FlatQueue<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Clone> FlatQueue<T> {
pub fn new() -> Self {
Self { ids: Vec::new(), values: Vec::new(), len: 0 }
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn clear(&mut self) {
self.len = 0;
}
pub fn push(&mut self, item: T, priority: f64) {
let mut pos = self.len;
self.len += 1;
if self.ids.len() < self.len {
self.ids.resize(self.len, item.clone());
self.values.resize(self.len, priority);
}
while pos > 0 {
let parent = (pos - 1) >> 1;
let parent_value = self.values[parent];
if priority >= parent_value {
break;
}
self.ids[pos] = self.ids[parent].clone();
self.values[pos] = parent_value;
pos = parent;
}
self.ids[pos] = item;
self.values[pos] = priority;
}
pub fn pop(&mut self) -> Option<T> {
if self.len == 0 {
return None;
}
let top = self.ids[0].clone();
self.len -= 1;
if self.len > 0 {
let id = self.ids[self.len].clone();
let value = self.values[self.len];
let mut pos = 0;
let half_len = self.len >> 1;
while pos < half_len {
let left = (pos << 1) + 1;
let right = left + 1;
let mut child = left;
if right < self.len && self.values[right] < self.values[left] {
child = right;
}
if self.values[child] >= value {
break;
}
self.ids[pos] = self.ids[child].clone();
self.values[pos] = self.values[child];
pos = child;
}
self.ids[pos] = id;
self.values[pos] = value;
}
Some(top)
}
pub fn peek(&self) -> Option<&T> {
if self.len > 0 { Some(&self.ids[0]) } else { None }
}
pub fn peek_value(&self) -> Option<f64> {
if self.len > 0 { Some(self.values[0]) } else { None }
}
pub fn shrink(&mut self) {
self.ids.truncate(self.len);
self.values.truncate(self.len);
}
}