use crate::PriorityQueue;
pub trait PriorityQueueDecKey<N, K>: PriorityQueue<N, K>
where
N: Clone,
K: PartialOrd + Clone,
{
fn contains(&self, node: &N) -> bool;
fn key_of(&self, node: &N) -> Option<K>;
fn decrease_key(&mut self, node: &N, decreased_key: K);
fn update_key(&mut self, node: &N, new_key: K) -> ResUpdateKey;
#[inline(always)]
fn try_decrease_key(&mut self, node: &N, new_key: K) -> ResTryDecreaseKey {
let old_key = self.key_of(node).expect("node must exist on the heap.");
if new_key < old_key {
self.decrease_key(node, new_key);
ResTryDecreaseKey::Decreased
} else {
ResTryDecreaseKey::Unchanged
}
}
#[inline(always)]
fn decrease_key_or_push(&mut self, node: &N, key: K) -> ResDecreaseKeyOrPush {
if self.contains(node) {
self.decrease_key(node, key);
ResDecreaseKeyOrPush::Decreased
} else {
self.push(node.clone(), key.clone());
ResDecreaseKeyOrPush::Pushed
}
}
fn update_key_or_push(&mut self, node: &N, key: K) -> ResUpdateKeyOrPush {
if self.contains(node) {
self.update_key(node, key).into()
} else {
self.push(node.clone(), key.clone());
ResUpdateKeyOrPush::Pushed
}
}
#[inline(always)]
fn try_decrease_key_or_push(&mut self, node: &N, key: K) -> ResTryDecreaseKeyOrPush {
match self.key_of(node) {
Some(old_key) => {
if key < old_key {
self.decrease_key(node, key);
ResTryDecreaseKeyOrPush::Decreased
} else {
ResTryDecreaseKeyOrPush::Unchanged
}
}
None => {
self.push(node.clone(), key.clone());
ResTryDecreaseKeyOrPush::Pushed
}
}
}
fn remove(&mut self, node: &N) -> K;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResUpdateKey {
Decreased,
Increased,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResTryDecreaseKey {
Decreased,
Unchanged,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResDecreaseKeyOrPush {
Pushed,
Decreased,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResUpdateKeyOrPush {
Pushed,
Decreased,
Increased,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResTryDecreaseKeyOrPush {
Pushed,
Decreased,
Unchanged,
}
impl From<ResUpdateKey> for ResUpdateKeyOrPush {
fn from(value: ResUpdateKey) -> Self {
match value {
ResUpdateKey::Decreased => Self::Decreased,
ResUpdateKey::Increased => Self::Increased,
}
}
}
impl From<ResTryDecreaseKey> for ResTryDecreaseKeyOrPush {
fn from(value: ResTryDecreaseKey) -> Self {
match value {
ResTryDecreaseKey::Decreased => Self::Decreased,
ResTryDecreaseKey::Unchanged => Self::Unchanged,
}
}
}