|
@@ -1,11 +1,5 @@
|
|
|
-use core::panic;
|
|
|
-use parking_lot::lock_api::RawMutex as _;
|
|
|
-use parking_lot::{RawMutex, RwLock};
|
|
|
-use slab::Slab;
|
|
|
-use std::cell::UnsafeCell;
|
|
|
use std::collections::VecDeque;
|
|
|
use std::marker::PhantomData;
|
|
|
-use std::sync::Arc;
|
|
|
|
|
|
#[derive(Hash, PartialEq, Eq, Clone, Copy, Debug, PartialOrd, Ord)]
|
|
|
pub struct NodeId(pub usize);
|
|
@@ -93,17 +87,7 @@ pub trait TreeView<T>: Sized {
|
|
|
|
|
|
fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>>;
|
|
|
|
|
|
- fn parent_child_mut(&mut self, id: NodeId) -> Option<(&mut T, Self::IteratorMut<'_>)> {
|
|
|
- let mut_ptr: *mut Self = self;
|
|
|
- unsafe {
|
|
|
- // Safety: No node has itself as a child.
|
|
|
- (*mut_ptr).get_mut(id).and_then(|parent| {
|
|
|
- (*mut_ptr)
|
|
|
- .children_mut(id)
|
|
|
- .map(|children| (parent, children))
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
+ fn parent_child_mut(&mut self, id: NodeId) -> Option<(&mut T, Self::IteratorMut<'_>)>;
|
|
|
|
|
|
fn children_ids(&self, id: NodeId) -> Option<&[NodeId]>;
|
|
|
|
|
@@ -111,28 +95,12 @@ pub trait TreeView<T>: Sized {
|
|
|
|
|
|
fn parent_mut(&mut self, id: NodeId) -> Option<&mut T>;
|
|
|
|
|
|
- fn node_parent_mut(&mut self, id: NodeId) -> Option<(&mut T, Option<&mut T>)> {
|
|
|
- let mut_ptr: *mut Self = self;
|
|
|
- unsafe {
|
|
|
- // Safety: No node has itself as a parent.
|
|
|
- (*mut_ptr)
|
|
|
- .get_mut(id)
|
|
|
- .map(|node| (node, (*mut_ptr).parent_mut(id)))
|
|
|
- }
|
|
|
- }
|
|
|
+ fn node_parent_mut(&mut self, id: NodeId) -> Option<(&mut T, Option<&mut T>)>;
|
|
|
|
|
|
fn parent_id(&self, id: NodeId) -> Option<NodeId>;
|
|
|
|
|
|
fn height(&self, id: NodeId) -> Option<u16>;
|
|
|
|
|
|
- fn map<T2, F: Fn(&T) -> &T2, FMut: Fn(&mut T) -> &mut T2>(
|
|
|
- &mut self,
|
|
|
- map: F,
|
|
|
- map_mut: FMut,
|
|
|
- ) -> TreeMap<T, T2, Self, F, FMut> {
|
|
|
- TreeMap::new(self, map, map_mut)
|
|
|
- }
|
|
|
-
|
|
|
fn size(&self) -> usize;
|
|
|
|
|
|
fn traverse_depth_first(&self, mut f: impl FnMut(&T)) {
|
|
@@ -208,58 +176,39 @@ pub trait TreeLike<T>: TreeView<T> {
|
|
|
fn insert_after(&mut self, id: NodeId, new: NodeId);
|
|
|
}
|
|
|
|
|
|
-pub struct ChildNodeIterator<'a, T, Tr: TreeView<T>> {
|
|
|
- tree: &'a Tr,
|
|
|
- children_ids: &'a [NodeId],
|
|
|
+pub struct ChildNodeIterator<'a, T> {
|
|
|
+ nodes: &'a Slab<Node<T>>,
|
|
|
+ children_ids: Vec<NodeId>,
|
|
|
index: usize,
|
|
|
node_type: PhantomData<T>,
|
|
|
}
|
|
|
|
|
|
-impl<'a, T: 'a, Tr: TreeView<T>> Iterator for ChildNodeIterator<'a, T, Tr> {
|
|
|
+impl<'a, T: 'a> Iterator for ChildNodeIterator<'a, T> {
|
|
|
type Item = &'a T;
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
self.children_ids.get(self.index).map(|id| {
|
|
|
self.index += 1;
|
|
|
- self.tree.get_unchecked(*id)
|
|
|
+ &self.nodes.get(id.0).unwrap().value
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub struct ChildNodeIteratorMut<'a, T, Tr: TreeView<T> + 'a> {
|
|
|
- tree: *mut Tr,
|
|
|
- children_ids: &'a [NodeId],
|
|
|
- index: usize,
|
|
|
- node_type: PhantomData<T>,
|
|
|
-}
|
|
|
-
|
|
|
-unsafe impl<'a, T, Tr: TreeView<T> + 'a> Sync for ChildNodeIteratorMut<'a, T, Tr> {}
|
|
|
-
|
|
|
-impl<'a, T, Tr: TreeView<T>> ChildNodeIteratorMut<'a, T, Tr> {
|
|
|
- fn tree_mut(&mut self) -> &'a mut Tr {
|
|
|
- unsafe { &mut *self.tree }
|
|
|
- }
|
|
|
+pub struct ChildNodeIteratorMut<'a, T> {
|
|
|
+ nodes: Vec<&'a mut Node<T>>,
|
|
|
}
|
|
|
|
|
|
-impl<'a, T: 'a, Tr: TreeView<T>> Iterator for ChildNodeIteratorMut<'a, T, Tr> {
|
|
|
+impl<'a, T: 'a> Iterator for ChildNodeIteratorMut<'a, T> {
|
|
|
type Item = &'a mut T;
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
- let owned = self.children_ids.get(self.index).copied();
|
|
|
- match owned {
|
|
|
- Some(id) => {
|
|
|
- self.index += 1;
|
|
|
-
|
|
|
- Some(self.tree_mut().get_mut_unchecked(id))
|
|
|
- }
|
|
|
- None => None,
|
|
|
- }
|
|
|
+ self.nodes.pop().map(|node| &mut node.value)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
impl<T> TreeView<T> for Tree<T> {
|
|
|
- type Iterator<'a> = ChildNodeIterator<'a, T, Tree<T>> where T: 'a;
|
|
|
- type IteratorMut<'a> = ChildNodeIteratorMut<'a, T, Tree<T>> where T: 'a;
|
|
|
+ type Iterator<'a> = ChildNodeIterator<'a, T> where T: 'a;
|
|
|
+ type IteratorMut<'a> = ChildNodeIteratorMut<'a, T> where T: 'a;
|
|
|
|
|
|
fn root(&self) -> NodeId {
|
|
|
self.root
|
|
@@ -275,24 +224,26 @@ impl<T> TreeView<T> for Tree<T> {
|
|
|
|
|
|
fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>> {
|
|
|
self.children_ids(id).map(|children_ids| ChildNodeIterator {
|
|
|
- tree: self,
|
|
|
- children_ids,
|
|
|
+ nodes: &self.nodes,
|
|
|
+ children_ids: children_ids.to_vec(),
|
|
|
index: 0,
|
|
|
node_type: PhantomData,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>> {
|
|
|
- let raw_ptr = self as *mut Self;
|
|
|
- unsafe {
|
|
|
- // Safety: No node will appear as a child twice
|
|
|
- self.children_ids(id)
|
|
|
- .map(|children_ids| ChildNodeIteratorMut {
|
|
|
- tree: &mut *raw_ptr,
|
|
|
- children_ids,
|
|
|
- index: 0,
|
|
|
- node_type: PhantomData,
|
|
|
- })
|
|
|
+ // Safety: No node has itself as a parent.
|
|
|
+ if let Some(children_ids) = self.children_ids(id) {
|
|
|
+ let children_ids = children_ids.to_vec();
|
|
|
+ Some(ChildNodeIteratorMut {
|
|
|
+ nodes: unsafe {
|
|
|
+ self.nodes
|
|
|
+ .get_many_mut_unchecked(children_ids.into_iter().rev().map(|id| id.0))
|
|
|
+ .unwrap()
|
|
|
+ },
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ None
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -340,6 +291,39 @@ impl<T> TreeView<T> for Tree<T> {
|
|
|
fn size(&self) -> usize {
|
|
|
self.nodes.len()
|
|
|
}
|
|
|
+
|
|
|
+ fn node_parent_mut(&mut self, id: NodeId) -> Option<(&mut T, Option<&mut T>)> {
|
|
|
+ if let Some(parent_id) = self.parent_id(id) {
|
|
|
+ self.nodes
|
|
|
+ .get2_mut(id.0, parent_id.0)
|
|
|
+ .map(|(node, parent)| (&mut node.value, Some(&mut parent.value)))
|
|
|
+ } else {
|
|
|
+ self.nodes.get_mut(id.0).map(|node| (&mut node.value, None))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn parent_child_mut(&mut self, id: NodeId) -> Option<(&mut T, Self::IteratorMut<'_>)> {
|
|
|
+ // Safety: No node will appear as a child twice
|
|
|
+ if let Some(children_ids) = self.children_ids(id) {
|
|
|
+ debug_assert!(!children_ids.iter().any(|child_id| *child_id == id));
|
|
|
+ let mut borrowed = unsafe {
|
|
|
+ let as_vec = children_ids.to_vec();
|
|
|
+ self.nodes
|
|
|
+ .get_many_mut_unchecked(
|
|
|
+ as_vec
|
|
|
+ .into_iter()
|
|
|
+ .rev()
|
|
|
+ .map(|id| id.0)
|
|
|
+ .chain(std::iter::once(id.0)),
|
|
|
+ )
|
|
|
+ .unwrap()
|
|
|
+ };
|
|
|
+ let node = &mut borrowed.pop().unwrap().value;
|
|
|
+ Some((node, ChildNodeIteratorMut { nodes: borrowed }))
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl<T> TreeLike<T> for Tree<T> {
|
|
@@ -435,248 +419,6 @@ impl<T> TreeLike<T> for Tree<T> {
|
|
|
self.set_height(new, height);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-pub struct TreeMap<'a, T1, T2, Tr, F, FMut>
|
|
|
-where
|
|
|
- Tr: TreeView<T1>,
|
|
|
- F: Fn(&T1) -> &T2,
|
|
|
- FMut: Fn(&mut T1) -> &mut T2,
|
|
|
-{
|
|
|
- tree: &'a mut Tr,
|
|
|
- map: F,
|
|
|
- map_mut: FMut,
|
|
|
- in_node_type: PhantomData<T1>,
|
|
|
- out_node_type: PhantomData<T2>,
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a, T1, T2, Tr, F, FMut> TreeMap<'a, T1, T2, Tr, F, FMut>
|
|
|
-where
|
|
|
- Tr: TreeView<T1>,
|
|
|
- F: Fn(&T1) -> &T2,
|
|
|
- FMut: Fn(&mut T1) -> &mut T2,
|
|
|
-{
|
|
|
- pub fn new(tree: &'a mut Tr, map: F, map_mut: FMut) -> Self {
|
|
|
- TreeMap {
|
|
|
- tree,
|
|
|
- map,
|
|
|
- map_mut,
|
|
|
- in_node_type: PhantomData,
|
|
|
- out_node_type: PhantomData,
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a, T1, T2, Tr, F, FMut> TreeView<T2> for TreeMap<'a, T1, T2, Tr, F, FMut>
|
|
|
-where
|
|
|
- Tr: TreeView<T1>,
|
|
|
- F: Fn(&T1) -> &T2,
|
|
|
- FMut: Fn(&mut T1) -> &mut T2,
|
|
|
-{
|
|
|
- type Iterator<'b> = ChildNodeIterator<'b, T2, TreeMap<'a, T1, T2, Tr, F, FMut>>
|
|
|
- where
|
|
|
- T2: 'b,
|
|
|
- Self:'b;
|
|
|
- type IteratorMut<'b> = ChildNodeIteratorMut<'b, T2, TreeMap<'a, T1, T2, Tr, F, FMut>>
|
|
|
- where
|
|
|
- T2: 'b,
|
|
|
- Self:'b;
|
|
|
-
|
|
|
- fn root(&self) -> NodeId {
|
|
|
- self.tree.root()
|
|
|
- }
|
|
|
-
|
|
|
- fn get(&self, id: NodeId) -> Option<&T2> {
|
|
|
- self.tree.get(id).map(|node| (self.map)(node))
|
|
|
- }
|
|
|
-
|
|
|
- fn get_mut(&mut self, id: NodeId) -> Option<&mut T2> {
|
|
|
- self.tree.get_mut(id).map(|node| (self.map_mut)(node))
|
|
|
- }
|
|
|
-
|
|
|
- fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>> {
|
|
|
- self.children_ids(id).map(|children_ids| ChildNodeIterator {
|
|
|
- tree: self,
|
|
|
- children_ids,
|
|
|
- index: 0,
|
|
|
- node_type: PhantomData,
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>> {
|
|
|
- let raw_ptr = self as *mut Self;
|
|
|
- unsafe {
|
|
|
- // Safety: No node can be a child twice.
|
|
|
- self.children_ids(id)
|
|
|
- .map(|children_ids| ChildNodeIteratorMut {
|
|
|
- tree: &mut *raw_ptr,
|
|
|
- children_ids,
|
|
|
- index: 0,
|
|
|
- node_type: PhantomData,
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- fn children_ids(&self, id: NodeId) -> Option<&[NodeId]> {
|
|
|
- self.tree.children_ids(id)
|
|
|
- }
|
|
|
-
|
|
|
- fn parent(&self, id: NodeId) -> Option<&T2> {
|
|
|
- self.tree.parent(id).map(|node| (self.map)(node))
|
|
|
- }
|
|
|
-
|
|
|
- fn parent_mut(&mut self, id: NodeId) -> Option<&mut T2> {
|
|
|
- self.tree.parent_mut(id).map(|node| (self.map_mut)(node))
|
|
|
- }
|
|
|
-
|
|
|
- fn parent_id(&self, id: NodeId) -> Option<NodeId> {
|
|
|
- self.tree.parent_id(id)
|
|
|
- }
|
|
|
-
|
|
|
- fn height(&self, id: NodeId) -> Option<u16> {
|
|
|
- self.tree.height(id)
|
|
|
- }
|
|
|
-
|
|
|
- fn get_unchecked(&self, id: NodeId) -> &T2 {
|
|
|
- (self.map)(self.tree.get_unchecked(id))
|
|
|
- }
|
|
|
-
|
|
|
- fn get_mut_unchecked(&mut self, id: NodeId) -> &mut T2 {
|
|
|
- (self.map_mut)(self.tree.get_mut_unchecked(id))
|
|
|
- }
|
|
|
-
|
|
|
- fn size(&self) -> usize {
|
|
|
- self.tree.size()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/// A view into a tree that can be shared between multiple threads. Nodes are locked invividually.
|
|
|
-pub struct SharedView<'a, T, Tr: TreeView<T>> {
|
|
|
- tree: Arc<UnsafeCell<&'a mut Tr>>,
|
|
|
- node_locks: Arc<RwLock<Vec<RawMutex>>>,
|
|
|
- node_type: PhantomData<T>,
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a, T, Tr: TreeView<T>> SharedView<'a, T, Tr> {
|
|
|
- /// Checks if a node is currently locked. Returns None if the node does not exist.
|
|
|
- pub fn check_lock(&self, id: NodeId) -> Option<bool> {
|
|
|
- let locks = self.node_locks.read();
|
|
|
- locks.get(id.0).map(|lock| lock.is_locked())
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-unsafe impl<'a, T, Tr: TreeView<T>> Send for SharedView<'a, T, Tr> {}
|
|
|
-unsafe impl<'a, T, Tr: TreeView<T>> Sync for SharedView<'a, T, Tr> {}
|
|
|
-impl<'a, T, Tr: TreeView<T>> Clone for SharedView<'a, T, Tr> {
|
|
|
- fn clone(&self) -> Self {
|
|
|
- Self {
|
|
|
- tree: self.tree.clone(),
|
|
|
- node_locks: self.node_locks.clone(),
|
|
|
- node_type: PhantomData,
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a, T, Tr: TreeView<T>> SharedView<'a, T, Tr> {
|
|
|
- pub fn new(tree: &'a mut Tr) -> Self {
|
|
|
- let tree = Arc::new(UnsafeCell::new(tree));
|
|
|
- let mut node_locks = Vec::new();
|
|
|
- for _ in 0..unsafe { (*tree.get()).size() } {
|
|
|
- node_locks.push(RawMutex::INIT);
|
|
|
- }
|
|
|
- Self {
|
|
|
- tree,
|
|
|
- node_locks: Arc::new(RwLock::new(node_locks)),
|
|
|
- node_type: PhantomData,
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- fn lock_node(&self, node: NodeId) {
|
|
|
- let read = self.node_locks.read();
|
|
|
- let lock = read.get(node.0);
|
|
|
- match lock {
|
|
|
- Some(lock) => lock.lock(),
|
|
|
- None => {
|
|
|
- drop(read);
|
|
|
- let mut write = self.node_locks.write();
|
|
|
- write.resize_with(node.0 + 1, || RawMutex::INIT);
|
|
|
- unsafe { write.get_unchecked(node.0).lock() }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- fn unlock_node(&self, node: NodeId) {
|
|
|
- let read = self.node_locks.read();
|
|
|
- let lock = read.get(node.0);
|
|
|
- match lock {
|
|
|
- Some(lock) => unsafe { lock.unlock() },
|
|
|
- None => {
|
|
|
- panic!("unlocking node that was not locked")
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- fn with_node<R>(&self, node_id: NodeId, f: impl FnOnce(&'a mut Tr) -> R) -> R {
|
|
|
- self.lock_node(node_id);
|
|
|
- let tree = unsafe { &mut *self.tree.get() };
|
|
|
- let r = f(tree);
|
|
|
- self.unlock_node(node_id);
|
|
|
- r
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a, T, Tr: TreeView<T>> TreeView<T> for SharedView<'a, T, Tr> {
|
|
|
- type Iterator<'b> = Tr::Iterator<'b> where T: 'b, Self: 'b;
|
|
|
-
|
|
|
- type IteratorMut<'b>=Tr::IteratorMut<'b>
|
|
|
- where
|
|
|
- T: 'b,
|
|
|
- Self: 'b;
|
|
|
-
|
|
|
- fn root(&self) -> NodeId {
|
|
|
- unsafe { (*self.tree.get()).root() }
|
|
|
- }
|
|
|
-
|
|
|
- fn get(&self, id: NodeId) -> Option<&T> {
|
|
|
- self.with_node(id, |t| t.get(id))
|
|
|
- }
|
|
|
-
|
|
|
- fn get_mut(&mut self, id: NodeId) -> Option<&mut T> {
|
|
|
- self.with_node(id, |t| t.get_mut(id))
|
|
|
- }
|
|
|
-
|
|
|
- fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>> {
|
|
|
- self.with_node(id, |t| t.children(id))
|
|
|
- }
|
|
|
-
|
|
|
- fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>> {
|
|
|
- self.with_node(id, |t| t.children_mut(id))
|
|
|
- }
|
|
|
-
|
|
|
- fn children_ids(&self, id: NodeId) -> Option<&[NodeId]> {
|
|
|
- self.with_node(id, |t| t.children_ids(id))
|
|
|
- }
|
|
|
-
|
|
|
- fn parent(&self, id: NodeId) -> Option<&T> {
|
|
|
- self.with_node(id, |t| t.get(id))
|
|
|
- }
|
|
|
-
|
|
|
- fn parent_mut(&mut self, id: NodeId) -> Option<&mut T> {
|
|
|
- self.with_node(id, |t| t.parent_mut(id))
|
|
|
- }
|
|
|
-
|
|
|
- fn parent_id(&self, id: NodeId) -> Option<NodeId> {
|
|
|
- self.with_node(id, |t| t.parent_id(id))
|
|
|
- }
|
|
|
-
|
|
|
- fn height(&self, id: NodeId) -> Option<u16> {
|
|
|
- unsafe { (*self.tree.get()).height(id) }
|
|
|
- }
|
|
|
-
|
|
|
- fn size(&self) -> usize {
|
|
|
- unsafe { (*self.tree.get()).size() }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
#[test]
|
|
|
fn creation() {
|
|
|
let mut tree = Tree::new(1);
|
|
@@ -785,59 +527,6 @@ fn deletion() {
|
|
|
assert_eq!(tree.children_ids(parent).unwrap(), &[]);
|
|
|
}
|
|
|
|
|
|
-#[test]
|
|
|
-fn shared_view() {
|
|
|
- use std::thread;
|
|
|
- let mut tree = Tree::new(1);
|
|
|
- let parent = tree.root();
|
|
|
- let child = tree.create_node(0);
|
|
|
- tree.add_child(parent, child);
|
|
|
-
|
|
|
- let shared = SharedView::new(&mut tree);
|
|
|
-
|
|
|
- thread::scope(|s| {
|
|
|
- let (mut shared1, mut shared2, mut shared3) =
|
|
|
- (shared.clone(), shared.clone(), shared.clone());
|
|
|
- s.spawn(move || {
|
|
|
- assert_eq!(*shared1.get_mut(parent).unwrap(), 1);
|
|
|
- assert_eq!(*shared1.get_mut(child).unwrap(), 0);
|
|
|
- });
|
|
|
- s.spawn(move || {
|
|
|
- assert_eq!(*shared2.get_mut(child).unwrap(), 0);
|
|
|
- assert_eq!(*shared2.get_mut(parent).unwrap(), 1);
|
|
|
- });
|
|
|
- s.spawn(move || {
|
|
|
- assert_eq!(*shared3.get_mut(parent).unwrap(), 1);
|
|
|
- assert_eq!(*shared3.get_mut(child).unwrap(), 0);
|
|
|
- });
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-#[test]
|
|
|
-fn map() {
|
|
|
- #[derive(Debug, PartialEq)]
|
|
|
- struct Value {
|
|
|
- value: i32,
|
|
|
- }
|
|
|
- impl Value {
|
|
|
- fn new(value: i32) -> Self {
|
|
|
- Self { value }
|
|
|
- }
|
|
|
- }
|
|
|
- let mut tree = Tree::new(Value::new(1));
|
|
|
- let parent = tree.root();
|
|
|
- let child = tree.create_node(Value::new(0));
|
|
|
- tree.add_child(parent, child);
|
|
|
-
|
|
|
- let mut mapped = tree.map(|x| &x.value, |x| &mut x.value);
|
|
|
-
|
|
|
- *mapped.get_mut(child).unwrap() = 1;
|
|
|
- *mapped.get_mut(parent).unwrap() = 2;
|
|
|
-
|
|
|
- assert_eq!(*tree.get(parent).unwrap(), Value::new(2));
|
|
|
- assert_eq!(*tree.get(child).unwrap(), Value::new(1));
|
|
|
-}
|
|
|
-
|
|
|
#[test]
|
|
|
fn traverse_depth_first() {
|
|
|
let mut tree = Tree::new(0);
|
|
@@ -857,3 +546,124 @@ fn traverse_depth_first() {
|
|
|
node_count += 1;
|
|
|
});
|
|
|
}
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn get_node_children_mut() {
|
|
|
+ let mut tree = Tree::new(0);
|
|
|
+ let parent = tree.root();
|
|
|
+ let child1 = tree.create_node(1);
|
|
|
+ tree.add_child(parent, child1);
|
|
|
+ let child2 = tree.create_node(2);
|
|
|
+ tree.add_child(parent, child2);
|
|
|
+ let child3 = tree.create_node(3);
|
|
|
+ tree.add_child(parent, child3);
|
|
|
+
|
|
|
+ let (parent, children) = tree.parent_child_mut(parent).unwrap();
|
|
|
+ for (i, child) in children.enumerate() {
|
|
|
+ assert_eq!(*child, i + 1);
|
|
|
+ }
|
|
|
+ println!("Parent: {:#?}", parent);
|
|
|
+}
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn get_many_mut_unchecked() {
|
|
|
+ let mut slab = Slab::new();
|
|
|
+ let parent = slab.insert(0);
|
|
|
+ let child = slab.insert(1);
|
|
|
+ let grandchild = slab.insert(2);
|
|
|
+
|
|
|
+ let all =
|
|
|
+ unsafe { slab.get_many_mut_unchecked([parent, child, grandchild].into_iter()) }.unwrap();
|
|
|
+ println!("All: {:#?}", all);
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Debug)]
|
|
|
+struct Slab<T> {
|
|
|
+ data: Vec<Option<T>>,
|
|
|
+ free: VecDeque<usize>,
|
|
|
+}
|
|
|
+
|
|
|
+impl<T> Default for Slab<T> {
|
|
|
+ fn default() -> Self {
|
|
|
+ Self::new()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<T> Slab<T> {
|
|
|
+ fn new() -> Self {
|
|
|
+ Self {
|
|
|
+ data: Vec::new(),
|
|
|
+ free: VecDeque::new(),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn get(&self, id: usize) -> Option<&T> {
|
|
|
+ self.data.get(id).and_then(|x| x.as_ref())
|
|
|
+ }
|
|
|
+
|
|
|
+ unsafe fn get_unchecked(&self, id: usize) -> &T {
|
|
|
+ self.data.get_unchecked(id).as_ref().unwrap()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn get_mut(&mut self, id: usize) -> Option<&mut T> {
|
|
|
+ self.data.get_mut(id).and_then(|x| x.as_mut())
|
|
|
+ }
|
|
|
+
|
|
|
+ unsafe fn get_unchecked_mut(&mut self, id: usize) -> &mut T {
|
|
|
+ self.data.get_unchecked_mut(id).as_mut().unwrap()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn get2_mut(&mut self, id1: usize, id2: usize) -> Option<(&mut T, &mut T)> {
|
|
|
+ assert!(id1 != id2);
|
|
|
+ let ptr = self.data.as_mut_ptr();
|
|
|
+ let first = unsafe { &mut *ptr.add(id1) };
|
|
|
+ let second = unsafe { &mut *ptr.add(id2) };
|
|
|
+ if let (Some(first), Some(second)) = (first, second) {
|
|
|
+ Some((first, second))
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ unsafe fn get_many_mut_unchecked(
|
|
|
+ &mut self,
|
|
|
+ ids: impl Iterator<Item = usize>,
|
|
|
+ ) -> Option<Vec<&mut T>> {
|
|
|
+ let ptr = self.data.as_mut_ptr();
|
|
|
+ let mut result = Vec::new();
|
|
|
+ for id in ids {
|
|
|
+ let item = unsafe { &mut *ptr.add(id) };
|
|
|
+ if let Some(item) = item {
|
|
|
+ result.push(item);
|
|
|
+ } else {
|
|
|
+ return None;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Some(result)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn insert(&mut self, value: T) -> usize {
|
|
|
+ if let Some(id) = self.free.pop_front() {
|
|
|
+ self.data[id] = Some(value);
|
|
|
+ id
|
|
|
+ } else {
|
|
|
+ self.data.push(Some(value));
|
|
|
+ self.data.len() - 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn try_remove(&mut self, id: usize) -> Option<T> {
|
|
|
+ self.data.get_mut(id).and_then(|x| {
|
|
|
+ self.free.push_back(id);
|
|
|
+ x.take()
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ fn remove(&mut self, id: usize) -> T {
|
|
|
+ self.try_remove(id).unwrap()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn len(&self) -> usize {
|
|
|
+ self.data.len() - self.free.len()
|
|
|
+ }
|
|
|
+}
|