use std::collections::VecDeque;
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(u8)]
pub enum PriorityLevel {
Lowest,
Low,
Medium,
High,
Highest,
Immediate,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct PriorityQueue<E> {
storage: [VecDeque<E>; 6],
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct PropagatorInfo {
pub(crate) enqueued: bool,
pub(crate) priority: PriorityLevel,
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub(crate) struct PropagatorQueue {
queue: PriorityQueue<u32>,
pub(crate) info: Vec<PropagatorInfo>,
}
impl<E> PriorityQueue<E> {
pub(crate) fn insert(&mut self, priority: PriorityLevel, elem: E) {
let i = priority as usize;
debug_assert!((0..=5).contains(&i));
self.storage[i].push_back(elem);
}
pub(crate) fn pop(&mut self) -> Option<E> {
for queue in self.storage.iter_mut().rev() {
if !queue.is_empty() {
return queue.pop_front();
}
}
None
}
}
impl<E> Default for PriorityQueue<E> {
fn default() -> Self {
Self {
storage: Default::default(),
}
}
}
impl PropagatorQueue {
pub(crate) fn enqueue_propagator(&mut self, prop: u32) {
if !self.info[prop as usize].enqueued {
self.info[prop as usize].enqueued = true;
self.queue.insert(self.info[prop as usize].priority, prop);
}
}
pub(crate) fn pop(&mut self) -> Option<u32> {
self.queue
.pop()
.inspect(|p| self.info[*p as usize].enqueued = false)
}
}
#[cfg(test)]
mod test {
#[test]
fn priority_order() {
use crate::solver::queue::PriorityLevel::*;
assert!(Immediate > Highest);
assert!(Highest > High);
assert!(High > Medium);
assert!(Medium > Low);
assert!(Low > Lowest);
}
}