diff --git a/src/lib.rs b/src/lib.rs index 690e9a8..d7f74c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,12 @@ #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr( feature = "nightly", - feature(strict_provenance_atomic_ptr, box_vec_non_null, maybe_uninit_slice) + feature( + strict_provenance_atomic_ptr, + box_vec_non_null, + maybe_uninit_slice, + debug_closure_helpers + ) )] #![cfg_attr(feature = "transposed-option", feature(try_trait_v2))] diff --git a/src/tree.rs b/src/tree.rs index 0bc9770..703bbeb 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -24,18 +24,29 @@ use core::{ mod marker { use core::marker::PhantomData; + #[derive(Debug)] pub struct LeafOrInternal; + #[derive(Debug)] pub struct Leaf; + #[derive(Debug)] pub struct Internal; + #[derive(Debug)] pub struct Edge; + #[derive(Debug)] pub struct Value; + #[derive(Debug)] pub struct Owned; + #[derive(Debug)] pub struct Mut<'a>(PhantomData<&'a mut ()>); + #[derive(Debug)] pub struct ValMut<'a>(PhantomData<&'a mut ()>); + #[derive(Debug)] pub struct Immut<'a>(PhantomData<&'a ()>); + #[derive(Debug)] pub struct Dying; + #[derive(Debug)] pub struct DormantMut; pub trait BorrowType { @@ -55,13 +66,15 @@ mod marker { const CAPACITY: usize = 16; +#[derive(Debug)] struct LeafNode { parent: Option>>, parent_idx: MaybeUninit, - value: Option>, + value: Option, leaf: bool, } +#[derive(Debug)] struct InternalNode { data: LeafNode, next: Option>>, @@ -72,11 +85,13 @@ struct InternalNode { type BoxedNode = NonNull>; +#[derive(Debug)] struct NodeRef { node: NonNull>, _marker: PhantomData<(BorrowType, Type)>, } +#[derive(Debug)] struct Handle { node: Node, idx: usize, @@ -140,6 +155,7 @@ impl InternalNode { unsafe fn init(this: *mut Self) { unsafe { LeafNode::init(&raw mut (*this).data); + (&raw mut (*this).data.leaf).write(false); (&raw mut (*this).next).write(None); (&raw mut (*this).len).write(0); // keys and edges may be left uninitialized @@ -150,6 +166,7 @@ impl InternalNode { let mut uninit: Box>> = unsafe { core::mem::transmute(leaf) }; unsafe { core::ptr::swap(&raw mut (*this).data, uninit.as_mut_ptr()); + (&raw mut (*this).data.leaf).write(false); (&raw mut (*this).next).write(None); (&raw mut (*this).len).write(1); } @@ -183,11 +200,15 @@ impl NodeRef { } impl NodeRef { - fn new_internal(child: Root) -> Self { + fn new_internal_with_child(child: Root) -> Self { let mut node = InternalNode::new(); node.edges[0].write(child.node); - // SAFETY: `height` isn't zero + unsafe { NodeRef::from_new_internal(node) } + } + + fn new_internal() -> Self { + let node = InternalNode::new(); unsafe { NodeRef::from_new_internal(node) } } @@ -199,7 +220,6 @@ impl NodeRef { node, _marker: PhantomData, }; - this.borrow_mut().correct_all_childrens_parent_links(); this } } @@ -295,41 +315,34 @@ impl } } -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<'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(); +impl<'a, K, V, NodeType, HandleType> Handle, K, V, NodeType>, 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 + /// dangerous. + /// + /// For details, see `NodeRef::reborrow_mut`. + pub(super) unsafe fn reborrow_mut( + &mut 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: unsafe { self.node.reborrow_mut() }, + idx: self.idx, + _marker: PhantomData, } } - 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 handle which can be reawakened later. + /// + /// See `DormantMutRef` for more details. + pub(super) fn dormant( + &self, + ) -> Handle, HandleType> { + Handle { + node: self.node.dormant(), + idx: self.idx, + _marker: PhantomData, + } } } @@ -341,6 +354,11 @@ impl NodeRef { // SAFETY: the static node type is `Internal`. this.node.as_ptr() as *mut InternalNode } + + fn as_internal_non_null(this: &Self) -> NonNull> { + // SAFETY: the static node type is `Internal`. + unsafe { NonNull::new_unchecked(Self::as_internal_ptr(this)) } + } } impl<'a, K, V> NodeRef, K, V, marker::Internal> { @@ -349,6 +367,19 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { let ptr = Self::as_internal_ptr(self); unsafe { &mut *ptr } } + + pub(super) fn len_mut(&mut self) -> &mut u16 { + // SAFETY: we have exclusive access to the entire node. + unsafe { &mut (*Self::as_internal_ptr(self)).len } + } + + pub(super) fn next_mut(&mut self) -> Option, K, V, marker::Internal>> { + let internal = self.as_internal_mut(); + internal.next.map(|next| NodeRef { + node: next.cast(), + _marker: PhantomData, + }) + } } impl NodeRef { @@ -422,6 +453,46 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { } } +impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { + /// Borrows exclusive access to an element of the key storage area. + /// + /// # Safety + /// `index` is in bounds of 0..CAPACITY + unsafe fn key_area_mut(&mut self, index: I) -> &mut Output + where + I: core::slice::SliceIndex<[MaybeUninit], Output = Output>, + { + // SAFETY: the caller will not be able to call further methods on self + // until the key slice reference is dropped, as we have unique access + // for the lifetime of the borrow. + unsafe { + self.as_internal_mut() + .keys + .as_mut_slice() + .get_unchecked_mut(index) + } + } + + /// Borrows exclusive access to an element or slice of the node's value storage area. + /// + /// # Safety + /// `index` is in bounds of 0..CAPACITY + unsafe fn edge_area_mut(&mut self, index: I) -> &mut Output + where + I: core::slice::SliceIndex<[MaybeUninit>], Output = Output>, + { + // SAFETY: the caller will not be able to call further methods on self + // until the value slice reference is dropped, as we have unique access + // for the lifetime of the borrow. + unsafe { + self.as_internal_mut() + .edges + .as_mut_slice() + .get_unchecked_mut(index) + } + } +} + impl NodeRef { /// Revert to the unique borrow initially captured. /// @@ -492,13 +563,6 @@ impl NodeRef { } 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) } @@ -514,6 +578,24 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { .assume_init_ref() } } + + pub(super) fn edges(&self) -> &[BoxedNode] { + let internal = self.into_internal(); + unsafe { + internal + .edges + .get_unchecked(..usize::from(internal.len + 1)) + .assume_init_ref() + } + } + + pub(super) fn next(&self) -> Option, K, V, marker::Internal>> { + let internal = self.into_internal(); + internal.next.map(|next| NodeRef { + node: next.cast(), + _marker: PhantomData, + }) + } } impl @@ -545,11 +627,35 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeTyp /// 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() }; + let v = leaf.value.as_ref().unwrap(); v } } +impl Handle, marker::Edge> { + pub(super) fn forget_node_type( + self, + ) -> Handle, marker::Edge> { + unsafe { Handle::new_edge(self.node.forget_type(), self.idx) } + } +} + +impl Handle, marker::Edge> { + pub(super) fn forget_node_type( + self, + ) -> Handle, marker::Edge> { + unsafe { Handle::new_edge(self.node.forget_type(), self.idx) } + } +} + +impl Handle, marker::Value> { + pub(super) fn forget_node_type( + self, + ) -> Handle, marker::Value> { + unsafe { Handle::new_value(self.node.forget_type()) } + } +} + pub(super) enum ForceResult { Leaf(Leaf), Internal(Internal), @@ -629,6 +735,50 @@ impl NodeRef { } } +impl<'a, K, V> NodeRef, K, V, marker::Leaf> { + /// node must have parent/ be a leaf node. + pub(super) unsafe fn make_internal_node( + self, + ) -> NodeRef, K, V, marker::Internal> { + let leaf = self.node; + + let mut parent = self.ascend().ok().unwrap(); + let internal = Box::into_non_null(InternalNode::new_with_leaf(unsafe { + Box::from_non_null(leaf) + })) + .cast(); + + parent.node.as_internal_mut().edges[parent.idx].write(internal); + + NodeRef { + node: internal, + _marker: PhantomData, + } + } +} + +impl<'a, K, V, Type> Handle, K, V, marker::Leaf>, Type> { + /// node must have parent/ be a leaf node. + pub(super) unsafe fn make_internal_node( + self, + ) -> Handle, K, V, marker::Internal>, Type> { + Handle { + node: unsafe { self.node.make_internal_node() }, + idx: self.idx, + _marker: PhantomData, + } + } +} + +impl Handle, marker::Edge> { + /// Converts this edge handle into a value handle. + pub(super) fn into_value( + self, + ) -> Handle, marker::Value> { + unsafe { Handle::new_value(self.node) } + } +} + 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( @@ -653,22 +803,89 @@ impl<'a, K: 'a, V: 'a, Type> Handle, K, V, Type>, marker /// Inserts a key-value pair into pub(super) unsafe fn insert_recursing( mut self, - mut key: Q, + mut key_seq: Q, val: V, - ) -> Handle, K, V, marker::Leaf>, marker::Value> + ) -> Handle, K, V, marker::LeafOrInternal>, marker::Value> where Q: Iterator, K: Ord, { + let Some(key) = key_seq.next() else { + // key has run out: insert value here. + self.node.as_leaf_mut().value = Some(val); + // TODO: handle occupied values. + return unsafe { Handle::new_value(self.node.as_leaf_or_internal()) }; + }; + let idx = self.idx; - match unsafe { self.force() } { + let mut internal = match self.force() { ForceResult::Leaf(leaf) => { // need to turn the leaf into an internal node. - } - ForceResult::Internal(internal) => todo!(), - } - todo!() + // SAFETY: root is allocated as an internal node. + // the only node that doesn't have a parent is the root node, + // all parent nodes are internal nodes. + let internal = unsafe { leaf.make_internal_node() }; + + internal + } + ForceResult::Internal(mut internal) => { + if idx >= CAPACITY { + // create a sibling node + let mut sibling = NodeRef::new_internal(); + let mut sibling = sibling.borrow_mut(); + // let sibling = Box::into_non_null(InternalNode::new()); + // set parent link + unsafe { + core::ptr::copy_nonoverlapping( + &raw mut internal.node.as_leaf_mut().parent, + &raw mut sibling.as_leaf_mut().parent, + 1, + ); + core::ptr::copy_nonoverlapping( + &raw mut internal.node.as_leaf_mut().parent_idx, + &raw mut sibling.as_leaf_mut().parent_idx, + 1, + ); + } + + internal.node.as_internal_mut().next = + Some(NodeRef::as_internal_non_null(&sibling)); + + unsafe { Handle::new_edge(sibling.dormant(), 0).awaken() } + } else { + internal + } + } + }; + + let last = unsafe { + let mut child = NodeRef::new_leaf(); + + // set parent link + child.borrow_mut().as_leaf_mut().parent = + Some(NodeRef::as_internal_non_null(&internal.node)); + child + .borrow_mut() + .as_leaf_mut() + .parent_idx + .write(internal.idx as u16); + + let new_len = internal.node.len() + 1; + + slice_insert(internal.node.key_area_mut(..new_len), internal.idx, key); + slice_insert( + internal.node.edge_area_mut(..new_len), + internal.idx, + child.node, + ); + *internal.node.len_mut() = new_len as u16; + + let child = Handle::new_edge(child.borrow_mut(), 0); + child.insert_recursing(key_seq, val).dormant() + }; + + unsafe { last.awaken() } } } @@ -697,7 +914,7 @@ mod search { } impl NodeRef { - fn search_tree( + pub(super) fn search_tree( mut self, mut key: Q, ) -> SearchResult @@ -774,24 +991,51 @@ mod search { { match key.cmp(k.borrow()) { Ordering::Greater => {} - Ordering::Equal => return IndexResult::Edge(start_index + offset), - Ordering::Less => return IndexResult::Insert(start_index + offset), + Ordering::Equal => { + std::eprintln!("found key at index {}", start_index + offset); + return IndexResult::Edge(start_index + offset); + } + Ordering::Less => { + std::eprintln!("insert key at index {}", start_index + offset); + return IndexResult::Insert(start_index + offset); + } } } + std::eprintln!("insert key at index {}", keys.len()); IndexResult::Insert(keys.len()) } } #[cfg(test)] mod tests { + use super::super::Tree; use super::*; - fn build_test_node() { - let mut root = NodeRef::::new_leaf(); + #[test] + fn asdf() { + let mut tree = Tree::new(); + let entry = tree.entry("+".chars()); + std::dbg!(&entry); + entry.or_insert("Plus"); - let root_mut = root.borrow_mut(); - // root_mut.as_leaf_mut(). + let entry = tree.entry("++".chars()); + std::dbg!(&entry); + entry.or_insert("PlusPlus"); + + let entry = tree.entry("+=".chars()); + std::dbg!(&entry); + entry.or_insert("PlusEqual"); + + std::dbg!(tree.entry("++".chars())); + + std::eprintln!("tree: {:?}", &tree); + + assert_eq!( + tree.entry("++".chars()).or_insert("asdf").get(), + &"PlusPlus" + ); + assert_eq!(tree.entry("+".chars()).or_insert("asdf").get(), &"Plus"); } } } @@ -809,6 +1053,41 @@ mod entry { Occupied(OccupiedEntry<'a, K, V>), } + use core::fmt::Debug; + + impl Debug for Entry<'_, Q, K, V> + where + Q: Iterator, + { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Entry::Vacant(vacant) => write!(f, "Vacant({:?})", vacant), + Entry::Occupied(occupied) => write!(f, "Occupied({:?})", occupied), + } + } + } + + impl Debug for VacantEntry<'_, Q, K, V> + where + Q: Iterator, + { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("VacantEntry") + .field("key", &self.key) + .field("handle", &self.handle) + .finish() + } + } + + impl Debug for OccupiedEntry<'_, K, V> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("OccupiedEntry") + .field("value", &self.get()) + .field("handle", &self.handle) + .finish() + } + } + pub struct VacantEntry<'a, Q, K, V> where Q: Iterator, @@ -827,9 +1106,21 @@ mod entry { 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, K, V> OccupiedEntry<'a, K, V> { + pub fn get(&self) -> &V { + unsafe { self.handle.reborrow().into_value() } + } + } + + impl<'a, Q, K: Ord, V> Entry<'a, Q, K, V> + where + Q: Iterator, + { + pub fn or_insert(self, value: V) -> OccupiedEntry<'a, K, V> { + match self { + Entry::Vacant(vacant) => vacant.insert_entry(value), + Entry::Occupied(occupied) => occupied, + } } } @@ -837,16 +1128,25 @@ mod entry { where Q: Iterator, { - pub fn insert(self, value: V) -> OccupiedEntry<'a, K, V> { + pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V> { let handle = match self.handle { // no root node yet None => { - unimplemented!() + let tree = unsafe { self.dormant_map.reborrow() }; + let root = tree.root.insert(NodeRef::new_internal()); + + unsafe { + Handle::new_edge(root.borrow_mut(), 0).insert_recursing(self.key, value) + } } - Some(handle) => {} + Some(handle) => unsafe { handle.insert_recursing(self.key, value) }, }; - todo!() + OccupiedEntry { + handle, + dormant_map: self.dormant_map, + _marker: PhantomData, + } } } } @@ -925,13 +1225,71 @@ mod borrow { } } -type Root = NodeRef; +type Root = NodeRef; struct Tree { root: Option>, _marker: PhantomData>, } +impl<'a, K: core::fmt::Debug + 'a, V: core::fmt::Debug + 'a> core::fmt::Debug for &'a Tree { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut map = f.debug_map(); + + fn format_node_ref<'a, K: 'a, V: 'a>( + f: &mut core::fmt::Formatter<'_>, + node: &NodeRef, K, V, marker::LeafOrInternal>, + ) -> core::fmt::Result + where + K: core::fmt::Debug, + V: core::fmt::Debug, + { + match node.force() { + ForceResult::Leaf(leaf) => f + .debug_struct("Leaf") + .field("value", &leaf.into_leaf().value) + .finish(), + ForceResult::Internal(internal) => f + .debug_struct("Internal") + .field("value", &internal.into_leaf().value) + .field_with("edges", |f| { + let mut list = f.debug_list(); + for (key, edge) in internal.keys().iter().zip(internal.edges()) { + list.entry_with(|f| { + f.debug_set() + .entry(key) + .entry_with(|f| { + format_node_ref( + f, + &NodeRef { + node: *edge, + _marker: PhantomData, + }, + ) + }) + .finish() + }); + } + list.finish() + }) + .finish(), + } + } + + match self.root { + Some(ref root) => { + map.key(&"root").value_with(|f| { + let internal = root.reborrow(); + format_node_ref(f, &internal.as_leaf_or_internal()) + }); + + map.finish() + } + None => map.finish(), + } + } +} + impl Tree { pub fn new() -> Self { Self { @@ -941,6 +1299,141 @@ impl Tree { } } +#[derive(Debug)] +pub struct OnceAndIter +where + I: Iterator, +{ + once: Option, + iter: I, +} + +impl Iterator for OnceAndIter +where + I: Iterator, +{ + type Item = T; + + fn next(&mut self) -> Option { + if let Some(once) = self.once.take() { + Some(once) + } else { + self.iter.next() + } + } +} + +impl From for OnceAndIter +where + I: Iterator, +{ + fn from(iter: I) -> Self { + Self { once: None, iter } + } +} + +impl OnceAndIter +where + I: Iterator, +{ + pub fn once(once: T, iter: I) -> Self { + Self { + once: Some(once), + iter, + } + } +} + +impl Tree +where + K: Ord, +{ + // pub fn closest_entry( + // &mut self, + // mut key_seq: Q, + // ) -> Option, K, V>> + // where + // Q: Iterator, + // { + // use borrow::DormantMutRef; + // use entry::Entry; + + // let (tree, dormant) = DormantMutRef::new(self); + + // match tree.root { + // None => None, + // Some(ref mut root) => match root.borrow_mut().forget_type().search_tree(&mut key_seq) { + // search::SearchResult::Found(handle) => { + // Some(Entry::Occupied(entry::OccupiedEntry { + // handle, + // dormant_map: dormant, + // _marker: PhantomData, + // })) + // } + // search::SearchResult::GoDown(handle) => match key_seq.next() { + // None => Some(Entry::Occupied(entry::OccupiedEntry { + // handle: handle.forget_node_type().into_value(), + // dormant_map: dormant, + // _marker: PhantomData, + // })), + // Some(key) => Some(Entry::Vacant(entry::VacantEntry { + // key: OnceAndIter::once(key, key_seq), + // handle: Some(handle.forget_node_type()), + // dormant_map: dormant, + // _marker: PhantomData, + // })), + // }, + // search::SearchResult::Insert(key, handle) => { + // Some(Entry::Vacant(entry::VacantEntry { + // key: OnceAndIter::once(key, key_seq), + // handle: Some(handle), + // dormant_map: dormant, + // _marker: PhantomData, + // })) + // } + // }, + // } + // } + + pub fn entry(&'_ mut self, mut key_seq: Q) -> entry::Entry<'_, OnceAndIter, K, V> + where + Q: Iterator, + { + use borrow::DormantMutRef; + use entry::{Entry::*, OccupiedEntry, VacantEntry}; + + let (tree, dormant) = DormantMutRef::new(self); + + match tree.root { + None => Vacant(VacantEntry { + key: key_seq.into(), + handle: None, + dormant_map: dormant, + _marker: PhantomData, + }), + Some(ref mut root) => match root.borrow_mut().forget_type().search_tree(&mut key_seq) { + search::SearchResult::Found(handle) => Occupied(OccupiedEntry { + handle, + dormant_map: dormant, + _marker: PhantomData, + }), + search::SearchResult::GoDown(handle) => Vacant(VacantEntry { + key: key_seq.into(), + handle: Some(handle.forget_node_type()), + dormant_map: dormant, + _marker: PhantomData, + }), + search::SearchResult::Insert(key, handle) => Vacant(VacantEntry { + key: OnceAndIter::once(key, key_seq), + handle: Some(handle), + dormant_map: dormant, + _marker: PhantomData, + }), + }, + } + } +} + unsafe fn slice_insert(slice: &mut [MaybeUninit], idx: usize, value: T) { unsafe { let len = slice.len();