use crate::{ordering::Ordering, Position, hole::Hole, storage::Storage};
pub(crate) fn sift_up<S: Storage + ?Sized>(
data: &mut S,
pos: Position,
ord: &impl Ordering<S::Key>,
) -> Position {
let mut hole = Hole::new(data, pos);
while hole.move_up(ord) {}
hole.into_pos()
}
pub(crate) fn sift_down<S: Storage + ?Sized>(
data: &mut S,
pos: Position,
ord: &impl Ordering<S::Key>,
) -> Position {
let mut hole = Hole::new(data, pos);
while let Some(child) = hole.upper_child_whole(ord) {
if unsafe { !hole.move_down(child, ord) } {
return hole.into_pos();
}
}
if let Some(child) = hole.upper_child_partial(ord) {
unsafe {
hole.move_down(child, ord);
}
}
hole.into_pos()
}
pub(crate) fn sift_down_to_bottom<S: Storage + ?Sized>(
data: &mut S,
pos: Position,
ord: &impl Ordering<S::Key>,
) -> Position {
let mut hole = Hole::new(data, pos);
while let Some(child) = hole.upper_child_whole(ord) {
unsafe {
hole.move_to(child);
}
}
if let Some(child) = hole.upper_child_partial(ord) {
unsafe {
hole.move_to(child);
}
}
hole.into_pos()
}
pub(crate) fn fixup_sift<S: Storage + ?Sized>(
data: &mut S,
pos: Position,
ord: &impl Ordering<S::Key>,
) -> Position {
let new_pos = sift_up(data, pos, ord);
if new_pos != pos {
return new_pos;
}
sift_down(data, pos, ord)
}