use std::mem::swap;
use std::slice::{Iter, IterMut};
use super::arena::*;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct NodeId(ArenaIndex);
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Node<T, const N: usize> {
data: T,
parent: Option<NodeId>,
children: [Option<NodeId>; N],
}
impl<T, const N: usize> Node<T, N> {
pub fn new(data: T, parent: Option<NodeId>, children: [Option<NodeId>; N]) -> Self {
Node { data, parent, children }
}
pub fn parent(&self) -> Option<NodeId> {
self.parent
}
pub fn child(&self, index: usize) -> Option<NodeId> {
self.children[index]
}
fn child_mut(&mut self, index: usize) -> &mut Option<NodeId> {
&mut self.children[index]
}
pub fn children(&self) -> &[Option<NodeId>; N] {
&self.children
}
#[allow(dead_code)]
fn children_mut(&mut self) -> &mut [Option<NodeId>; N] {
&mut self.children
}
pub fn iter_children(&self) -> Iter<'_, Option<NodeId>> {
self.children.iter()
}
#[allow(dead_code)]
fn iter_children_mut(&mut self) -> IterMut<'_, Option<NodeId>> {
self.children.iter_mut()
}
pub fn data(&self) -> &T {
&self.data
}
pub fn data_mut(&mut self) -> &mut T {
&mut self.data
}
}
impl<T: Default, const N: usize> Default for Node<T, N> {
fn default() -> Self {
Node {
data: Default::default(),
parent: None,
children: [ None; N]
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TreeError{
ChildAlreadyExists,
ParentDoesntExist,
RootAlreadyExists,
NodeDoesntExist,
}
pub struct Tree<T, const N: usize> {
arena: Arena<Node<T, N>>,
root: Option<NodeId>,
}
impl<T, const N: usize> Tree<T, N> {
pub fn new() -> Self {
Tree{
arena: Arena::new(),
root: None,
}
}
pub fn with_capacity(capacity: usize) -> Self {
Tree{
arena: Arena::with_capacity(capacity),
root: None,
}
}
pub fn root(&self) -> Option<NodeId> {
self.root
}
#[allow(dead_code)]
pub fn root_mut(&mut self) -> &mut Option<NodeId> {
&mut self.root
}
pub fn set_root(&mut self, data: T) -> Result<NodeId, TreeError> {
if self.root.is_some() { return Err(TreeError::RootAlreadyExists); }
let node = Node::new(data, None, [None; N]);
let node_id = NodeId(self.arena.alloc(node));
self.root = Some(node_id);
Ok(node_id)
}
pub fn add(&mut self, parent_id: NodeId, index: usize, data: T) -> Result<NodeId, TreeError> {
assert!(index < N, "Index out of bounds");
let parent = self.arena.get(parent_id.0).ok_or(TreeError::ParentDoesntExist)?;
if parent.child(index).is_some() { return Err(TreeError::ChildAlreadyExists); }
let node = Node::new(data, Some(parent_id), [None; N]);
let node_id = NodeId(self.arena.alloc(node));
let parent = self.arena.get_mut(parent_id.0).unwrap();
let child = parent.child_mut(index);
*child = Some(node_id);
Ok(node_id)
}
pub fn clear(&mut self) {
self.arena.clear();
self.root = None;
}
pub fn get(&self, index: NodeId) -> Result<&Node<T, N>, TreeError> {
self.arena.get(index.0).ok_or(TreeError::NodeDoesntExist)
}
pub fn get_mut(&mut self, index: NodeId) -> Result<&mut Node<T, N>, TreeError> {
self.arena.get_mut(index.0).ok_or(TreeError::NodeDoesntExist)
}
pub fn data(&self, node: NodeId) -> Result<&T, TreeError> {
self.arena.get(node.0).map(|node| node.data()).ok_or(TreeError::NodeDoesntExist)
}
#[allow(dead_code)]
pub fn data_mut(&mut self, node: NodeId) -> Result<&mut T, TreeError> {
self.arena.get_mut(node.0).map(|node| node.data_mut()).ok_or(TreeError::NodeDoesntExist)
}
#[allow(dead_code)]
pub fn parent(&self, node: NodeId) -> Result<Option<NodeId>, TreeError> {
self.arena.get(node.0).map(|node| node.parent()).ok_or(TreeError::NodeDoesntExist)
}
#[allow(dead_code)]
pub fn children(&self, node: NodeId) -> Result<&[Option<NodeId>; N], TreeError> {
self.arena.get(node.0).map(|node| node.children()).ok_or(TreeError::NodeDoesntExist)
}
#[allow(dead_code)]
pub fn iter_children(&self, node: NodeId) -> Result<Iter<'_, Option<NodeId>>, TreeError> {
self.arena.get(node.0).map(|node| node.iter_children()).ok_or(TreeError::NodeDoesntExist)
}
pub fn child(&self, node: NodeId, i: usize) -> Result<Option<NodeId>, TreeError> {
self.arena.get(node.0).map(|node| node.child(i)).ok_or(TreeError::NodeDoesntExist)
}
pub fn move_root_to(&mut self, node: NodeId) -> Result<(), TreeError> {
self.get_mut(node)?.parent = None;
self.root = Some(node);
Ok(())
}
#[allow(dead_code)]
pub fn capacity(&self) -> usize {
self.arena.capacity()
}
pub fn allocated_nodes(&self) -> usize {
self.arena.len()
}
}
impl<T: Copy, const N: usize> Tree<T, N> {
pub fn compact(&mut self) {
let mut tree = Self::with_capacity(self.arena.capacity());
if let Some(root) = self.root{
let new_root = tree.set_root(self.get(root).unwrap().data).unwrap();
let mut stack = Vec::<(NodeId, NodeId, usize)>::with_capacity(64);
stack.push((root, new_root, 0));
while let Some((current_id, new_current_id, i)) = stack.last_mut() {
if *i >= N{
stack.pop();
}
else if let Some(node) = self.child(*current_id, *i).unwrap() {
let child_id = node;
let new_child_id = tree.add(*new_current_id, *i, *self.data(child_id).unwrap()).unwrap();
*i += 1;
stack.push((child_id, new_child_id, 0));
}
else{
*i += 1;
}
}
}
swap(self, &mut tree);
}
}
impl<T, const N: usize> std::ops::Index<NodeId> for Tree<T, N> {
type Output = Node<T, N>;
fn index(&self, index: NodeId) -> &Self::Output {
&self.arena[index.0]
}
}
impl<T, const N: usize> std::ops::IndexMut<NodeId> for Tree<T, N> {
fn index_mut(&mut self, index: NodeId) -> &mut Self::Output {
&mut self.arena[index.0]
}
}
#[cfg(test)]
mod tests {
use super::*;
fn setup_tree() -> Tree<i32, 2> {
Tree::new()
}
#[test]
fn test_set_root() {
let mut tree = setup_tree();
let root_id = tree.set_root(100).expect("Should set root");
assert_eq!(tree.root(), Some(root_id));
assert_eq!(tree.data(root_id).unwrap(), &100);
}
#[test]
fn test_set_root_twice_fails() {
let mut tree = setup_tree();
tree.set_root(1).unwrap();
let err = tree.set_root(2).unwrap_err();
assert_eq!(err, TreeError::RootAlreadyExists);
}
#[test]
fn test_add_child() {
let mut tree = setup_tree();
let root = tree.set_root(0).unwrap();
let child = tree.add(root, 0, 10).expect("Should add child");
assert_eq!(tree.data(child).unwrap(), &10);
assert_eq!(tree.parent(child).unwrap(), Some(root));
assert_eq!(tree.children(root).unwrap()[0], Some(child));
}
#[should_panic(expected = "Index out of bounds")]
#[test]
fn test_add_child_out_of_range() {
let mut tree = setup_tree(); let root = tree.set_root(0).unwrap();
let err = tree.add(root, 2, 10).unwrap_err();
}
#[test]
fn test_add_child_already_exists() {
let mut tree = setup_tree();
let root = tree.set_root(0).unwrap();
tree.add(root, 0, 10).unwrap();
let err = tree.add(root, 0, 20).unwrap_err();
assert_eq!(err, TreeError::ChildAlreadyExists);
}
#[test]
fn test_add_to_non_existent_parent() {
let mut tree = setup_tree();
let fake_id = NodeId(ArenaIndex::from_usize(1));
let err = tree.add(fake_id, 0, 10).unwrap_err();
assert_eq!(err, TreeError::ParentDoesntExist);
}
#[test]
fn test_data_mut() {
let mut tree = setup_tree();
let root = tree.set_root(10).unwrap();
*tree.data_mut(root).unwrap() = 20;
assert_eq!(tree.data(root).unwrap(), &20);
}
#[test]
fn test_clear() {
let mut tree = setup_tree();
tree.set_root(10).unwrap();
tree.clear();
assert!(tree.root().is_none());
let fake_id = NodeId(ArenaIndex::from_usize(1));
assert_eq!(tree.get(fake_id).unwrap_err(), TreeError::NodeDoesntExist);
}
#[test]
fn test_iter_children() {
let mut tree = setup_tree();
let root = tree.set_root(0).unwrap();
tree.add(root, 0, 1).unwrap();
let children: Vec<_> = tree.iter_children(root).unwrap().collect();
assert_eq!(children.len(), 2);
assert!(children[0].is_some());
assert!(children[1].is_none());
}
#[test]
fn test_index_traits() {
let mut tree = setup_tree();
let root = tree.set_root(10).unwrap();
assert_eq!(tree[root].data(), &10);
tree[root].data_mut();
}
#[test]
fn test_capacity_and_allocated_nodes() {
let mut tree = Tree::<i32, 2>::with_capacity(10);
assert!(tree.capacity() >= 10);
assert_eq!(tree.allocated_nodes(), 0);
let root = tree.set_root(42).unwrap();
assert_eq!(tree.allocated_nodes(), 1);
tree.add(root, 0, 10).unwrap();
assert_eq!(tree.allocated_nodes(), 2);
}
#[test]
fn test_child_favorable_and_unfavorable() {
let mut tree = Tree::<i32, 2>::new();
let root = tree.set_root(1).unwrap();
let child_0 = tree.add(root, 0, 2).unwrap();
assert_eq!(tree.child(root, 0), Ok(Some(child_0)));
assert_eq!(tree.child(root, 1), Ok(None));
let old_root = root;
tree.clear();
assert_eq!(tree.child(old_root, 0), Err(TreeError::NodeDoesntExist));
}
#[test]
#[should_panic]
fn test_child_out_of_bounds_panics() {
let mut tree = Tree::<i32, 2>::new();
let root = tree.set_root(1).unwrap();
let _ = tree.child(root, 2);
}
#[test]
fn test_move_root_to() {
let mut tree = Tree::<i32, 2>::new();
let root = tree.set_root(1).unwrap();
let child = tree.add(root, 0, 2).unwrap();
assert!(tree.move_root_to(child).is_ok());
assert_eq!(tree.root(), Some(child));
assert_eq!(tree.parent(child), Ok(None));
tree.clear();
assert_eq!(tree.move_root_to(child), Err(TreeError::NodeDoesntExist));
}
#[test]
fn test_compact_empty_or_single_node() {
let mut tree = Tree::<i32, 2>::new();
tree.compact();
assert_eq!(tree.allocated_nodes(), 0);
tree.set_root(42).unwrap();
tree.compact();
assert_eq!(tree.allocated_nodes(), 1);
let root = tree.root().unwrap();
assert_eq!(*tree.data(root).unwrap(), 42);
}
#[test]
fn test_compact_complex_scenario() {
let mut tree = Tree::<i32, 2>::new();
let root = tree.set_root(0).unwrap();
let a = tree.add(root, 0, 10).unwrap();
let _b = tree.add(root, 1, 20).unwrap();
let _c = tree.add(a, 0, 30).unwrap();
let _d = tree.add(a, 1, 40).unwrap();
assert_eq!(tree.allocated_nodes(), 5);
tree.move_root_to(a).unwrap();
assert_eq!(tree.allocated_nodes(), 5);
tree.compact();
assert_eq!(tree.allocated_nodes(), 3);
let new_root = tree.root().unwrap();
assert_eq!(*tree.data(new_root).unwrap(), 10);
let new_c = tree.child(new_root, 0).unwrap().unwrap();
assert_eq!(*tree.data(new_c).unwrap(), 30);
let new_d = tree.child(new_root, 1).unwrap().unwrap();
assert_eq!(*tree.data(new_d).unwrap(), 40);
}
}