diff --git a/src/lib.rs b/src/lib.rs index e8dd57f..690e9a8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr( feature = "nightly", - feature(strict_provenance_atomic_ptr, box_vec_non_null) + feature(strict_provenance_atomic_ptr, box_vec_non_null, maybe_uninit_slice) )] #![cfg_attr(feature = "transposed-option", feature(try_trait_v2))] diff --git a/src/tree.rs b/src/tree.rs index 49e24c9..0bc9770 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -14,6 +14,8 @@ use alloc::boxed::Box; use core::{ + borrow::Borrow, + cmp::Ordering, marker::PhantomData, mem::{ManuallyDrop, MaybeUninit}, ptr::NonNull, @@ -27,12 +29,12 @@ mod marker { pub struct Internal; pub struct Edge; - pub struct KV; + pub struct Value; pub struct Owned; pub struct Mut<'a>(PhantomData<&'a mut ()>); pub struct ValMut<'a>(PhantomData<&'a mut ()>); - pub struct Immutable<'a>(PhantomData<&'a ()>); + pub struct Immut<'a>(PhantomData<&'a ()>); pub struct Dying; pub struct DormantMut; @@ -46,7 +48,7 @@ mod marker { impl<'a> BorrowType for Mut<'a> {} impl<'a> BorrowType for ValMut<'a> {} - impl<'a> BorrowType for Immutable<'a> {} + impl<'a> BorrowType for Immut<'a> {} impl BorrowType for Dying {} impl BorrowType for DormantMut {} } @@ -56,7 +58,7 @@ const CAPACITY: usize = 16; struct LeafNode { parent: Option>>, parent_idx: MaybeUninit, - value: ManuallyDrop, + value: Option>, leaf: bool, } @@ -70,8 +72,7 @@ struct InternalNode { type BoxedNode = NonNull>; -struct NodeRef { - height: usize, +struct NodeRef { node: NonNull>, _marker: PhantomData<(BorrowType, Type)>, } @@ -82,23 +83,47 @@ struct Handle { _marker: PhantomData, } -impl Handle, marker::Edge> { - unsafe fn new_edge(node: NodeRef, idx: usize) -> Self { - assert!(idx < node.len()); - Handle { +impl<'a, K: 'a, V: 'a, Type> Copy for NodeRef, K, V, Type> {} +impl<'a, K: 'a, V: 'a, Type> Clone for NodeRef, K, V, Type> { + fn clone(&self) -> Self { + *self + } +} + +unsafe impl Sync for NodeRef {} + +unsafe impl Send for NodeRef, K, V, Type> {} +unsafe impl Send for NodeRef, K, V, Type> {} +unsafe impl Send for NodeRef, K, V, Type> {} +unsafe impl Send for NodeRef {} +unsafe impl Send for NodeRef {} + +impl Handle, marker::Edge> { + unsafe fn new_edge(node: NodeRef, idx: usize) -> Self { + Self { node, idx, _marker: PhantomData, } } } +impl Handle, marker::Value> { + unsafe fn new_value(node: NodeRef) -> Self { + Self { + node, + idx: 0, + _marker: PhantomData, + } + } +} impl LeafNode { unsafe fn init(this: *mut Self) { unsafe { (&raw mut (*this).parent).write(None); - (&raw mut (*this).len).write(0); - // parent_idx and keys/values may be left uninitialized + (&raw mut (*this).leaf).write(true); + (&raw mut (*this).value).write(None); + // parent_idx may be left uninitialized } } @@ -116,9 +141,28 @@ impl InternalNode { unsafe { LeafNode::init(&raw mut (*this).data); (&raw mut (*this).next).write(None); - (&raw mut (*this).edges).write([None; CAPACITY + 1]); + (&raw mut (*this).len).write(0); + // keys and edges may be left uninitialized } } + + fn init_with_leaf(this: *mut Self, leaf: Box>) { + let mut uninit: Box>> = unsafe { core::mem::transmute(leaf) }; + unsafe { + core::ptr::swap(&raw mut (*this).data, uninit.as_mut_ptr()); + (&raw mut (*this).next).write(None); + (&raw mut (*this).len).write(1); + } + } + + fn new_with_leaf(leaf: Box>) -> Box { + let mut this = Box::::new_uninit(); + unsafe { + Self::init_with_leaf(this.as_mut_ptr(), leaf); + this.assume_init() + } + } + fn new() -> Box { let mut this = Box::::new_uninit(); unsafe { @@ -128,33 +172,30 @@ impl InternalNode { } } -impl NodeRef { +impl NodeRef { fn new_leaf() -> Self { let node = LeafNode::new(); NodeRef { - height: 0, node: Box::into_non_null(node), _marker: PhantomData, } } } -impl NodeRef { +impl NodeRef { fn new_internal(child: Root) -> Self { let mut node = InternalNode::new(); - node.edges[0] = Some(child.node); + node.edges[0].write(child.node); // SAFETY: `height` isn't zero - unsafe { NodeRef::from_new_internal(node, child.height + 1) } + unsafe { NodeRef::from_new_internal(node) } } /// # Safety /// `height` must not be zero. - unsafe fn from_new_internal(internal: Box>, height: usize) -> Self { - debug_assert!(height > 0); + unsafe fn from_new_internal(internal: Box>) -> Self { let node = NonNull::from(Box::leak(internal)).cast(); let mut this = NodeRef { - height, node, _marker: PhantomData, }; @@ -163,54 +204,136 @@ impl NodeRef { } } -// here follows std::BTree stuff - -impl NodeRef { - /// Mutably borrows the owned root node. Unlike `reborrow_mut`, this is safe - /// because the return value cannot be used to destroy the root, and there - /// cannot be other references to the tree. - pub(super) fn borrow_mut(&mut self) -> NodeRef, Type> { - NodeRef { - height: self.height, - node: self.node, +impl NodeRef { + /// Unpack a node reference that was packed as `NodeRef::parent`. + fn from_internal(node: NonNull>) -> Self { + let node = NodeRef { + node: node.cast(), _marker: PhantomData, + }; + + debug_assert!(!node.is_leaf()); + + node + } +} + +impl NodeRef { + /// Finds the parent of the current node. Returns `Ok(handle)` if the current + /// node actually has a parent, where `handle` points to the edge of the parent + /// that points to the current node. Returns `Err(self)` if the current node has + /// no parent, giving back the original `NodeRef`. + /// + /// The method name assumes you picture trees with the root node on top. + /// + /// `edge.descend().ascend().unwrap()` and `node.ascend().unwrap().descend()` should + /// both, upon success, do nothing. + pub(super) fn ascend( + self, + ) -> Result, marker::Edge>, Self> { + const { + assert!(BorrowType::TRAVERSAL_PERMIT); } + + // We need to use raw pointers to nodes because, if BorrowType is marker::ValMut, + // there might be outstanding mutable references to values that we must not invalidate. + let leaf_ptr: *const _ = Self::as_leaf_ptr(&self); + unsafe { (*leaf_ptr).parent } + .as_ref() + .map(|parent| Handle { + node: NodeRef::from_internal(*parent), + idx: unsafe { usize::from((*leaf_ptr).parent_idx.assume_init()) }, + _marker: PhantomData, + }) + .ok_or(self) + } +} + +impl NodeRef { + pub(super) fn first_edge(self) -> Handle { + unsafe { Handle::new_edge(self, 0) } } - /// Irreversibly transitions to a reference that permits traversal and offers - /// destructive methods and little else. - pub(super) fn into_dying(self) -> NodeRef { + pub(super) fn last_edge(self) -> Handle { + let len = self.len(); + unsafe { Handle::new_edge(self, len) } + } +} + +impl + Handle, marker::Edge> +{ + /// Finds the node pointed to by this edge. + /// + /// The method name assumes you picture trees with the root node on top. + /// + /// `edge.descend().ascend().unwrap()` and `node.ascend().unwrap().descend()` should + /// both, upon success, do nothing. + pub(super) fn descend(self) -> NodeRef { + const { + assert!(BorrowType::TRAVERSAL_PERMIT); + } + + // We need to use raw pointers to nodes because, if BorrowType is + // marker::ValMut, there might be outstanding mutable references to + // values that we must not invalidate. There's no worry accessing the + // height field because that value is copied. Beware that, once the + // node pointer is dereferenced, we access the edges array with a + // reference (Rust issue #73987) and invalidate any other references + // to or inside the array, should any be around. + let parent_ptr = NodeRef::as_internal_ptr(&self.node); + let node = unsafe { + (*parent_ptr) + .edges + .get_unchecked(self.idx) + .assume_init_read() + }; NodeRef { - height: self.height, - node: self.node, + node, _marker: PhantomData, } } } -impl NodeRef { - fn len(&self) -> usize { - unsafe { (*self.node.as_ptr()).len as usize } - } - - fn height(&self) -> usize { - self.height - } - - fn reborrow(&self) -> NodeRef, Type> { - NodeRef { - height: self.height, - node: self.node, - _marker: PhantomData, - } - } - - fn as_leaf_ptr(this: &Self) -> *mut LeafNode { - this.node.as_ptr() +impl<'a, K, V> Handle, K, V, marker::Internal>, marker::Edge> { + /// Fixes the parent pointer and index in the child node that this edge + /// links to. This is useful when the ordering of edges has been changed, + fn correct_parent_link(self) { + // Create backpointer without invalidating other references to the node. + let ptr = unsafe { NonNull::new_unchecked(NodeRef::as_internal_ptr(&self.node)) }; + let idx = self.idx; + let mut child = self.descend(); + child.set_parent_link(ptr, idx); } } -impl NodeRef { +impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { + /// Sets the node's link to its parent edge, + /// without invalidating other references to the node. + fn set_parent_link(&mut self, parent: NonNull>, parent_idx: usize) { + let leaf = Self::as_leaf_ptr(self); + unsafe { (*leaf).parent = Some(parent) }; + unsafe { (*leaf).parent_idx.write(parent_idx as u16) }; + } +} + +impl<'a, K, V> NodeRef, K, V, marker::Internal> { + /// # Safety + /// Every item returned by `range` is a valid edge index for the node. + unsafe fn correct_childrens_parent_links>(&mut self, range: R) { + for i in range { + debug_assert!(i <= self.len()); + unsafe { Handle::new_edge(self.reborrow_mut(), i) }.correct_parent_link(); + } + } + + fn correct_all_childrens_parent_links(&mut self) { + let len = self.len(); + unsafe { self.correct_childrens_parent_links(0..=len) }; + } +} + +impl NodeRef { /// Exposes the data of an internal node. /// /// Returns a raw ptr to avoid invalidating other references to this node. @@ -220,7 +343,7 @@ impl NodeRef { } } -impl<'a, K, V> NodeRef, marker::Internal> { +impl<'a, K, V> NodeRef, K, V, marker::Internal> { /// Borrows exclusive access to the data of an internal node. fn as_internal_mut(&mut self) -> &mut InternalNode { let ptr = Self::as_internal_ptr(self); @@ -228,175 +351,581 @@ impl<'a, K, V> NodeRef, marker::Internal> { } } -impl<'a, K: 'a, V: 'a> NodeRef, marker::LeafOrInternal> { - fn set_parent_link(&mut self, parent: NonNull>, parent_idx: usize) { - unsafe { - let leaf_ptr = Self::as_leaf_ptr(self); - (*leaf_ptr).parent = Some(parent); - (*leaf_ptr).parent_idx.write(parent_idx as u16); - } - } -} - -impl<'a, K: 'a, V: 'a, Type> NodeRef, Type> { - unsafe fn key_area_mut(&mut self, index: I) -> &mut Output - where - I: core::slice::SliceIndex<[MaybeUninit], Output = Output>, - Output: ?Sized, - { - unsafe { - self.as_leaf_mut() - .keys - .as_mut_slice() - .get_unchecked_mut(index) - } - } - unsafe fn val_area_mut(&mut self, index: I) -> &mut Output - where - I: core::slice::SliceIndex<[MaybeUninit], Output = Output>, - Output: ?Sized, - { - unsafe { - self.as_leaf_mut() - .values - .as_mut_slice() - .get_unchecked_mut(index) - } - } -} - -impl<'a, K: 'a, V: 'a> NodeRef, marker::Internal> { - unsafe fn edge_area_mut(&mut self, index: I) -> &mut Output - where - I: core::slice::SliceIndex<[MaybeUninit>], Output = Output>, - Output: ?Sized, - { - unsafe { - self.as_internal_mut() - .edges - .as_mut_slice() - .get_unchecked_mut(index) - } - } -} - -impl<'a, K: 'a, V: 'a, Type> NodeRef, Type> { - /// Borrows exclusive access to the length of the node. - pub(super) fn len_mut(&mut self) -> &mut u16 { - &mut self.as_leaf_mut().len - } -} - -impl<'a, K, V, Type> NodeRef, Type> { - unsafe fn reborrow_mut(&mut self) -> NodeRef, Type> { +impl NodeRef { + /// Mutably borrows the owned root node. Unlike `reborrow_mut`, this is safe + /// because the return value cannot be used to destroy the root, and there + /// cannot be other references to the tree. + pub(super) fn borrow_mut(&mut self) -> NodeRef, K, V, Type> { NodeRef { - height: self.height, node: self.node, _marker: PhantomData, } } + /// Slightly mutably borrows the owned root node. + pub(super) fn borrow_valmut(&mut self) -> NodeRef, K, V, Type> { + NodeRef { + node: self.node, + _marker: PhantomData, + } + } + + /// Irreversibly transitions to a reference that permits traversal and offers + /// destructive methods and little else. + pub(super) fn into_dying(self) -> NodeRef { + NodeRef { + node: self.node, + _marker: PhantomData, + } + } +} + +impl<'a, K, V, Type> NodeRef, K, V, Type> { + /// Temporarily takes out another mutable reference to the same node. Beware, as + /// this method is very dangerous, doubly so since it might not immediately appear + /// dangerous. + /// + /// Because mutable pointers can roam anywhere around the tree, the returned + /// pointer can easily be used to make the original pointer dangling, out of + /// bounds, or invalid under stacked borrow rules. + // FIXME(@gereeter) consider adding yet another type parameter to `NodeRef` + // that restricts the use of navigation methods on reborrowed pointers, + // preventing this unsafety. + unsafe fn reborrow_mut(&mut self) -> NodeRef, K, V, Type> { + NodeRef { + node: self.node, + _marker: PhantomData, + } + } + + /// Borrows exclusive access to the leaf portion of a leaf or internal node. fn as_leaf_mut(&mut self) -> &mut LeafNode { - unsafe { &mut *Self::as_leaf_ptr(self) } + let ptr = Self::as_leaf_ptr(self); + // SAFETY: we have exclusive access to the entire node. + unsafe { &mut *ptr } } + /// Offers exclusive access to the leaf portion of a leaf or internal node. fn into_leaf_mut(mut self) -> &'a mut LeafNode { - // SAFETY: `self` is a mutable reference to a `NodeRef` with a mutable borrow type. - unsafe { &mut *Self::as_leaf_ptr(&mut self) } - } -} - -impl<'a, K, V> NodeRef, marker::Internal> { - unsafe fn correct_childrens_parent_links(&mut self, range: R) - where - R: Iterator, - { - for i in range { - assert!(i < self.len()); - unsafe { - Handle::new_edge(self.reborrow_mut(), i).correct_parent_link(); - } - } + let ptr = Self::as_leaf_ptr(&mut self); + // SAFETY: we have exclusive access to the entire node. + unsafe { &mut *ptr } } - fn correct_all_childrens_parent_links(&mut self) { - let len = self.len(); - unsafe { - self.correct_childrens_parent_links(0..=len); + /// Returns a dormant copy of this node with its lifetime erased which can + /// be reawakened later. + pub(super) fn dormant(&self) -> NodeRef { + NodeRef { + node: self.node, + _marker: PhantomData, } } } -impl<'a, K, V> Handle, marker::Internal>, marker::Edge> { - fn correct_parent_link(self) { - let ptr = unsafe { NonNull::new_unchecked(NodeRef::as_internal_ptr(&self.node)) }; - let idx = self.idx; - let mut child = self.descend(); - child.set_parent_link(ptr, idx); +impl NodeRef { + /// Revert to the unique borrow initially captured. + /// + /// # Safety + /// + /// The reborrow must have ended, i.e., the reference returned by `new` and + /// all pointers and references derived from it, must not be used anymore. + pub(super) unsafe fn awaken<'a>(self) -> NodeRef, K, V, Type> { + NodeRef { + node: self.node, + _marker: PhantomData, + } } } -impl<'a, K, V, NodeType, HandleType> Handle, NodeType>, HandleType> { - unsafe fn reborrow_mut( - &mut self, - ) -> Handle, NodeType>, HandleType> { +impl Handle, HandleType> { + /// Revert to the unique borrow initially captured. + /// + /// # Safety + /// + /// The reborrow must have ended, i.e., the reference returned by `new` and + /// all pointers and references derived from it, must not be used anymore. + pub(super) unsafe fn awaken<'a>( + self, + ) -> Handle, K, V, NodeType>, HandleType> { Handle { - node: unsafe { self.node.reborrow_mut() }, + node: unsafe { self.node.awaken() }, idx: self.idx, _marker: PhantomData, } } } -impl Handle, marker::Edge> { - fn descend(self) -> NodeRef { - let parent_ptr = NodeRef::as_internal_ptr(&self.node); - let node = unsafe { - (*parent_ptr) - .edges - .get_unchecked(self.idx) - .assume_init_read() - }; +impl NodeRef { + /// Finds the length of the node. This is the number of keys or values. + /// The number of edges is `len() + 1`. + /// Note that, despite being safe, calling this function can have the side effect + /// of invalidating mutable references that unsafe code has created. + pub(super) fn len(&self) -> usize { + // Crucially, we only access the `len` field here. If BorrowType is marker::ValMut, + // there might be outstanding mutable references to values that we must not invalidate. + unsafe { usize::from((*Self::as_internal_ptr(self)).len) } + } +} + +impl NodeRef { + pub(super) fn is_leaf(&self) -> bool { + unsafe { (*Self::as_leaf_ptr(self)).leaf } + } + + /// Temporarily takes out another, immutable reference to the same node. + pub(super) fn reborrow(&self) -> NodeRef, K, V, Type> { NodeRef { - height: self.node.height - 1, - node, + node: self.node, + _marker: PhantomData, + } + } + + /// Exposes the leaf portion of any leaf or internal node. + /// + /// Returns a raw ptr to avoid invalidating other references to this node. + fn as_leaf_ptr(this: &Self) -> *mut LeafNode { + // The node must be valid for at least the LeafNode portion. + // This is not a reference in the NodeRef type because we don't know if + // it should be unique or shared. + this.node.as_ptr() + } +} + +impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { + /// Exposes the leaf portion of any leaf or internal node in an immutable tree. + fn into_leaf(self) -> &'a LeafNode { + let ptr = Self::as_leaf_ptr(&self); + // SAFETY: there can be no mutable references into this tree borrowed as `Immut`. + unsafe { &*ptr } + } + + fn into_internal(self) -> &'a InternalNode { + // SAFETY: the static node type is `Internal`. + unsafe { &*Self::as_internal_ptr(&self) } + } + + /// Borrows a view into the keys stored in the node. + pub(super) fn keys(&self) -> &[K] { + let internal = self.into_internal(); + unsafe { + internal + .keys + .get_unchecked(..usize::from(internal.len)) + .assume_init_ref() + } + } +} + +impl + Handle, HandleType> +{ + /// Temporarily takes out another immutable handle on the same location. + pub(super) fn reborrow( + &self, + ) -> Handle, K, V, NodeType>, HandleType> { + // We can't use Handle::new_kv or Handle::new_edge because we don't know our type + Handle { + node: self.node.reborrow(), + idx: self.idx, _marker: PhantomData, } } } -impl<'a, K: 'a, V: 'a> Handle, marker::Internal>, marker::Edge> { - fn insert_fit(&mut self, key: K, val: V, edge: Root) { - debug_assert!(self.node.len() < CAPACITY); - debug_assert!(edge.height == self.node.height - 1); - let new_len = self.node.len() + 1; - - unsafe { - slice_insert(self.node.key_area_mut(..new_len), self.idx, key); - slice_insert(self.node.val_area_mut(..new_len), self.idx, val); - slice_insert( - self.node.edge_area_mut(..new_len + 1), - self.idx + 1, - edge.node, - ); - *self.node.len_mut() = new_len as u16; - - self.node - .correct_childrens_parent_links(self.idx + 1..new_len + 1); - } +impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { + /// Exposes the leaf portion of any leaf or internal node in an immutable tree. + fn into_leaf(self) -> &'a LeafNode { + let ptr = Self::as_leaf_ptr(&self); + // SAFETY: there can be no mutable references into this tree borrowed as `Immut`. + unsafe { &*ptr } } +} - fn insert(mut self, key: K, val: V, edge: Root) { - if self.node.len() < CAPACITY { - self.insert_fit(key, val, edge); - } else { +impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType>, marker::Value> { + /// SAFETY: the caller must ensure that `idx < node.len()` + pub(super) unsafe fn into_value(self) -> &'a V { + let leaf = self.node.into_leaf(); + let v = unsafe { leaf.value.as_ref().unwrap().assume_init_ref() }; + v + } +} + +pub(super) enum ForceResult { + Leaf(Leaf), + Internal(Internal), +} + +impl + Handle, HandleType> +{ + fn force( + self, + ) -> ForceResult< + Handle, HandleType>, + Handle, HandleType>, + > { + match self.node.force() { + ForceResult::Leaf(leaf) => ForceResult::Leaf(Handle { + node: leaf, + idx: self.idx, + _marker: PhantomData, + }), + ForceResult::Internal(internal) => ForceResult::Internal(Handle { + node: internal, + idx: self.idx, + _marker: PhantomData, + }), } } } -impl<'a, K: 'a, V: 'a> Handle, marker::Leaf>, marker::Edge> {} +impl NodeRef { + fn force( + self, + ) -> ForceResult< + NodeRef, + NodeRef, + > { + if self.is_leaf() { + ForceResult::Leaf(NodeRef { + node: self.node, + _marker: PhantomData, + }) + } else { + ForceResult::Internal(NodeRef { + node: self.node, + _marker: PhantomData, + }) + } + } +} -type Root = NodeRef; +impl NodeRef { + /// Removes any static information asserting that this node is a `Leaf` node. + pub(super) fn forget_type(self) -> NodeRef { + NodeRef { + node: self.node, + _marker: PhantomData, + } + } +} + +impl NodeRef { + /// Removes any static information asserting that this node is an `Internal` node. + pub(super) fn forget_type(self) -> NodeRef { + NodeRef { + node: self.node, + _marker: PhantomData, + } + } +} + +impl NodeRef { + pub(super) fn as_leaf_or_internal(self) -> NodeRef { + NodeRef { + node: self.node, + _marker: PhantomData, + } + } +} + +impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { + /// Unsafely asserts to the compiler the static information that this node is a `Leaf`. + pub(super) unsafe fn cast_to_leaf_unchecked( + self, + ) -> NodeRef, K, V, marker::Leaf> { + NodeRef { + node: self.node, + _marker: PhantomData, + } + } + + /// Unsafely asserts to the compiler the static information that this node is an `Internal`. + unsafe fn cast_to_internal_unchecked(self) -> NodeRef, K, V, marker::Internal> { + NodeRef { + node: self.node, + _marker: PhantomData, + } + } +} + +impl<'a, K: 'a, V: 'a, Type> Handle, K, V, Type>, marker::Edge> { + /// Inserts a key-value pair into + pub(super) unsafe fn insert_recursing( + mut self, + mut key: Q, + val: V, + ) -> Handle, K, V, marker::Leaf>, marker::Value> + where + Q: Iterator, + K: Ord, + { + let idx = self.idx; + match unsafe { self.force() } { + ForceResult::Leaf(leaf) => { + // need to turn the leaf into an internal node. + } + ForceResult::Internal(internal) => todo!(), + } + + todo!() + } +} + +// search: + +mod search { + use super::{ForceResult, Handle, NodeRef, marker}; + use core::borrow::Borrow; + use core::cmp::Ordering; + + pub(super) enum SearchResult { + /// The node which contains the value for the key. + Found(Handle, marker::Value>), + /// The key was found, and the search should continue at the given edge. + GoDown(Handle, marker::Edge>), + /// The key was not found, and should be inserted at the given position. + Insert( + K, + Handle, marker::Edge>, + ), + } + + pub(super) enum IndexResult { + Edge(usize), + Insert(usize), + } + + impl NodeRef { + fn search_tree( + mut self, + mut key: Q, + ) -> SearchResult + where + Q: Iterator, + K: Ord, + { + use SearchResult::*; + loop { + self = match self.search_node(&mut key) { + Found(handle) => { + return Found(handle); + } + GoDown(handle) => handle.descend(), + Insert(key, handle) => return Insert(key, handle), + } + } + } + } + + impl NodeRef { + fn search_node( + self, + mut key: Q, + ) -> SearchResult + where + Q: Iterator, + K: Ord, + { + use SearchResult::*; + + let Some(key) = key.next() else { + // key has run out, a value is either occupying this + // node, or belongs here. + return SearchResult::Found(unsafe { + Handle::new_value(self.as_leaf_or_internal()) + }); + }; + + match self.force() { + // self is a leaf node and doesn't contain any keys: + // a new leaf node should be inserted at this point. + ForceResult::Leaf(leaf) => { + SearchResult::Insert(key, unsafe { Handle::new_edge(leaf.forget_type(), 0) }) + } + ForceResult::Internal(internal) => { + match unsafe { internal.find_key_index(&key, 0) } { + IndexResult::Insert(idx) => Insert(key, unsafe { + Handle::new_edge(internal.forget_type(), idx) + }), + IndexResult::Edge(idx) => { + GoDown(unsafe { Handle::new_edge(internal, idx) }) + } + } + } + } + } + } + + impl NodeRef { + /// # Safety + /// `start_index` must be a valid edge index for the node. + unsafe fn find_key_index(&self, key: &Q, start_index: usize) -> IndexResult + where + Q: Ord, + K: Borrow, + { + let node = self.reborrow(); + let keys = node.keys(); + debug_assert!(start_index <= keys.len()); + for (offset, k) in unsafe { keys.get_unchecked(start_index..) } + .iter() + .enumerate() + { + match key.cmp(k.borrow()) { + Ordering::Greater => {} + Ordering::Equal => return IndexResult::Edge(start_index + offset), + Ordering::Less => return IndexResult::Insert(start_index + offset), + } + } + + IndexResult::Insert(keys.len()) + } + } + + #[cfg(test)] + mod tests { + use super::*; + + fn build_test_node() { + let mut root = NodeRef::::new_leaf(); + + let root_mut = root.borrow_mut(); + // root_mut.as_leaf_mut(). + } + } +} + +mod entry { + use core::marker::PhantomData; + + use super::{Handle, NodeRef, Tree, borrow::DormantMutRef, marker}; + + pub enum Entry<'a, Q: 'a, K: 'a, V: 'a> + where + Q: Iterator, + { + Vacant(VacantEntry<'a, Q, K, V>), + Occupied(OccupiedEntry<'a, K, V>), + } + + pub struct VacantEntry<'a, Q, K, V> + where + Q: Iterator, + { + pub(super) key: Q, + pub(super) handle: + Option, K, V, marker::LeafOrInternal>, marker::Edge>>, + pub(super) dormant_map: DormantMutRef<'a, Tree>, + pub(super) _marker: PhantomData<&'a mut (K, V)>, + } + + pub struct OccupiedEntry<'a, K, V> { + pub(super) handle: + Handle, K, V, marker::LeafOrInternal>, marker::Value>, + pub(super) dormant_map: DormantMutRef<'a, Tree>, + pub(super) _marker: PhantomData<&'a mut (K, V)>, + } + + impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { + pub fn key(&self) -> Option<&K> { + unsafe { self.handle.reborrow().into_kv().0 } + } + } + + impl<'a, Q, K: Ord, V> VacantEntry<'a, Q, K, V> + where + Q: Iterator, + { + pub fn insert(self, value: V) -> OccupiedEntry<'a, K, V> { + let handle = match self.handle { + // no root node yet + None => { + unimplemented!() + } + Some(handle) => {} + }; + + todo!() + } + } +} + +mod borrow { + use core::{marker::PhantomData, ptr::NonNull}; + + /// Models a reborrow of some unique reference, when you know that the reborrow + /// and all its descendants (i.e., all pointers and references derived from it) + /// will not be used any more at some point, after which you want to use the + /// original unique reference again. + /// + /// The borrow checker usually handles this stacking of borrows for you, but + /// some control flows that accomplish this stacking are too complicated for + /// the compiler to follow. A `DormantMutRef` allows you to check borrowing + /// yourself, while still expressing its stacked nature, and encapsulating + /// the raw pointer code needed to do this without undefined behavior. + pub(super) struct DormantMutRef<'a, T> { + ptr: NonNull, + _marker: PhantomData<&'a mut T>, + } + + unsafe impl<'a, T> Sync for DormantMutRef<'a, T> where &'a mut T: Sync {} + unsafe impl<'a, T> Send for DormantMutRef<'a, T> where &'a mut T: Send {} + + impl<'a, T> DormantMutRef<'a, T> { + /// Capture a unique borrow, and immediately reborrow it. For the compiler, + /// the lifetime of the new reference is the same as the lifetime of the + /// original reference, but you promise to use it for a shorter period. + pub(super) fn new(t: &'a mut T) -> (&'a mut T, Self) { + let ptr = NonNull::from(t); + // SAFETY: we hold the borrow throughout 'a via `_marker`, and we expose + // only this reference, so it is unique. + let new_ref = unsafe { &mut *ptr.as_ptr() }; + ( + new_ref, + Self { + ptr, + _marker: PhantomData, + }, + ) + } + + /// Revert to the unique borrow initially captured. + /// + /// # Safety + /// + /// The reborrow must have ended, i.e., the reference returned by `new` and + /// all pointers and references derived from it, must not be used anymore. + pub(super) unsafe fn awaken(self) -> &'a mut T { + // SAFETY: our own safety conditions imply this reference is again unique. + unsafe { &mut *self.ptr.as_ptr() } + } + + /// Borrows a new mutable reference from the unique borrow initially captured. + /// + /// # Safety + /// + /// The reborrow must have ended, i.e., the reference returned by `new` and + /// all pointers and references derived from it, must not be used anymore. + pub(super) unsafe fn reborrow(&mut self) -> &'a mut T { + // SAFETY: our own safety conditions imply this reference is again unique. + unsafe { &mut *self.ptr.as_ptr() } + } + + /// Borrows a new shared reference from the unique borrow initially captured. + /// + /// # Safety + /// + /// The reborrow must have ended, i.e., the reference returned by `new` and + /// all pointers and references derived from it, must not be used anymore. + pub(super) unsafe fn reborrow_shared(&self) -> &'a T { + // SAFETY: our own safety conditions imply this reference is again unique. + unsafe { &*self.ptr.as_ptr() } + } + } +} + +type Root = NodeRef; struct Tree { root: Option>,