diff --git a/src/tree.rs b/src/tree.rs index 771de03..d65a443 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -206,6 +206,31 @@ impl Handle, mar } } +impl NodeRef { + pub(super) fn deallocate_and_ascend( + self, + ) -> Option, marker::Edge>> { + let node = self.node; + let parent = self.ascend().ok(); + + unsafe { + match (*node.as_ptr()).capacity as usize { + 0 => {} + capacity => { + let keys = (*node.as_ptr()).keys; + let edges = (*node.as_ptr()).edges; + + _ = Box::from_non_null(NonNull::slice_from_raw_parts(keys, capacity)); + _ = Box::from_non_null(NonNull::slice_from_raw_parts(edges, capacity)); + } + } + _ = Box::from_non_null(node); + } + + parent + } +} + impl<'a, K, V, HandleType> Handle, K, V>, HandleType> { /// Temporarily takes out another mutable handle on the same location. Beware, as /// this method is very dangerous, doubly so since it might not immediately appear @@ -518,6 +543,22 @@ impl<'a, K: 'a, V: 'a> Handle, K, V>, marker::Value> { } } +impl NodeRef { + /// Borrows exclusive access to the leaf portion of a dying leaf or internal node. + fn as_leaf_dying(&mut self) -> &mut LeafNode { + let ptr = Self::as_leaf_ptr(self); + // SAFETY: we have exclusive access to the entire node. + unsafe { &mut *ptr } + } +} + +impl NodeRef { + pub(super) unsafe fn into_value(mut self) -> Option { + let leaf = self.as_leaf_dying(); + leaf.value.take() + } +} + impl<'a, K: 'a, V: 'a> Handle, K, V>, marker::Value> { pub(super) unsafe fn value_mut(&mut self) -> &mut V { let leaf = self.node.as_leaf_mut(); @@ -684,7 +725,7 @@ impl<'a, K: 'a, V: 'a> Handle, K, V>, marker::Edge> { // search: mod search { - use super::{ForceResult, Handle, NodeRef, marker}; + use super::{marker, ForceResult, Handle, NodeRef}; use core::borrow::Borrow; use core::cmp::Ordering; @@ -831,7 +872,7 @@ enum HandleOrTree<'a, BorrowType, K, V, HandleType> { mod entry { use core::marker::PhantomData; - use super::{Handle, NodeRef, marker}; + use super::{marker, Handle, NodeRef}; pub enum Entry<'a, Q: 'a, K: 'a, V: 'a> where @@ -948,12 +989,11 @@ mod entry { mod subtree { use core::marker::PhantomData; - use crate::tree::{HandleOrTree, search}; + use crate::tree::{search, HandleOrTree}; use super::{ - NodeRef, OnceAndIter, entry::{Entry, OccupiedEntry, VacantEntry}, - marker, + marker, NodeRef, OnceAndIter, }; // BorrowType may be one of `Immut`, `Mut`.