use crate::TrieKey;
use alloc::boxed::Box;
use core::ptr::NonNull;
pub(crate) struct Node<K: TrieKey, V> {
pub(crate) val: Option<Box<(K, V)>>,
pub(crate) masklen: u32,
pub(crate) left: Link<K, V>,
pub(crate) right: Link<K, V>,
pub(crate) parent: Link<K, V>,
pub(crate) is_right_child: bool,
}
impl<K: TrieKey, V> Node<K, V> {
pub(crate) fn new_leaf(
val: Option<Box<(K, V)>>,
masklen: u32,
parent: Link<K, V>,
is_right_child: bool,
) -> Self {
Self { val, masklen, left: Link::null(), right: Link::null(), parent, is_right_child }
}
pub(crate) fn unlink_branch(&mut self, child: Link<K, V>, root: &mut Link<K, V>) {
let c = child.get_mut().unwrap();
c.parent = self.parent;
c.is_right_child = self.is_right_child;
if let Some(p) = self.parent.get_mut() {
if self.is_right_child {
p.right = child;
} else {
p.left = child;
}
} else {
assert!(self.is_right_child);
*root = child;
}
}
}
pub(crate) struct Link<K: TrieKey, V> {
inner: Option<NonNull<Node<K, V>>>,
}
impl<K: TrieKey, V> PartialEq<Link<K, V>> for Link<K, V> {
fn eq(&self, other: &Link<K, V>) -> bool {
self.inner.eq(&other.inner)
}
}
impl<K: TrieKey, V> Eq for Link<K, V> {}
impl<K: TrieKey, V> core::fmt::Debug for Link<K, V> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
write!(f, "Link({:#018x})", self.inner.map(|p| p.as_ptr() as usize).unwrap_or(0))
}
}
impl<K: TrieKey, V> Clone for Link<K, V> {
fn clone(&self) -> Self {
*self
}
}
impl<K: TrieKey, V> Copy for Link<K, V> {}
impl<K: TrieKey, V> Link<K, V> {
pub(crate) fn new(v: Box<Node<K, V>>) -> Self {
Self { inner: Some(Box::leak(v).into()) }
}
pub(crate) fn null() -> Self {
Self { inner: None }
}
pub(crate) fn is_null(self) -> bool {
self.inner.is_none()
}
pub(crate) fn get<'a>(self) -> Option<&'a Node<K, V>> {
self.inner.map(|p| unsafe { &*p.as_ptr() })
}
pub(crate) fn get_mut<'a>(self) -> Option<&'a mut Node<K, V>> {
self.inner.map(|p| unsafe { &mut *p.as_ptr() })
}
pub(crate) fn free(self) {
if let Some(p) = self.inner {
let _ = unsafe { Box::from_raw(p.as_ptr()) };
}
}
pub(crate) fn next(self, end: Self) -> Self {
if let Some(n) = self.get() {
if !n.left.is_null() {
n.left
} else if !n.right.is_null() {
n.right
} else {
if self == end {
return Self::null();
}
let mut curr = n;
let mut parent = n.parent;
loop {
if parent == end {
if curr.is_right_child {
return Self::null();
}
let p = parent.get().expect("root node is a right child");
return p.right;
} else {
let p = parent.get().expect("reached end before root");
if !curr.is_right_child && !p.right.is_null() {
return p.right;
}
curr = p;
parent = p.parent;
}
}
}
} else {
Self::null()
}
}
pub(crate) fn next_val(self, end: Self) -> Self {
let mut curr = self.next(end);
while let Some(n) = curr.get() {
if n.val.is_some() {
return curr;
} else {
curr = curr.next(end);
}
}
Self::null()
}
}