]> git.lizzy.rs Git - rust.git/blobdiff - library/alloc/src/collections/btree/node.rs
Rollup merge of #76926 - ssomers:btree_cleanup_1, r=Mark-Simulacrum
[rust.git] / library / alloc / src / collections / btree / node.rs
index 6c343b17264404fb80a94cdbab26085adfe98794..f52d07c9b8c94bd4e538c87233bcc24190ff0d3c 100644 (file)
@@ -12,7 +12,7 @@
 //     edges: if height > 0 {
 //         [Box<Node<K, V, height - 1>>; 2 * B]
 //     } else { () },
-//     parent: *const Node<K, V, height + 1>,
+//     parent: Option<NonNull<Node<K, V, height + 1>>>,
 //     parent_idx: u16,
 //     len: u16,
 // }
@@ -50,9 +50,8 @@
 /// The underlying representation of leaf nodes.
 #[repr(C)]
 struct LeafNode<K, V> {
-    /// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`.
-    /// This either points to an actual node or is null.
-    parent: *const InternalNode<K, V>,
+    /// We want to be covariant in `K` and `V`.
+    parent: Option<NonNull<InternalNode<K, V>>>,
 
     /// This node's index into the parent node's `edges` array.
     /// `*node.parent.edges[node.parent_idx]` should be the same thing as `node`.
@@ -80,7 +79,7 @@ unsafe fn new() -> Self {
             // be both slightly faster and easier to track in Valgrind.
             keys: MaybeUninit::uninit_array(),
             vals: MaybeUninit::uninit_array(),
-            parent: ptr::null(),
+            parent: None,
             parent_idx: MaybeUninit::uninit(),
             len: 0,
         }
@@ -224,7 +223,7 @@ pub fn pop_internal_level(&mut self) {
             )
         };
         self.height -= 1;
-        self.node_as_mut().as_leaf_mut().parent = ptr::null();
+        self.node_as_mut().as_leaf_mut().parent = None;
 
         unsafe {
             Global.dealloc(NonNull::from(top).cast(), Layout::new::<InternalNode<K, V>>());
@@ -309,7 +308,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
     pub 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 { (*self.as_leaf_ptr()).len as usize }
+        unsafe { usize::from((*self.as_leaf_ptr()).len) }
     }
 
     /// Returns the height of this node in the whole tree. Zero height denotes the
@@ -365,16 +364,19 @@ pub fn ascend(
     ) -> Result<Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::Edge>, Self> {
         // 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 parent_as_leaf = unsafe { (*self.as_leaf_ptr()).parent as *const LeafNode<K, V> };
-        if let Some(non_zero) = NonNull::new(parent_as_leaf as *mut _) {
-            Ok(Handle {
-                node: NodeRef { height: self.height + 1, node: non_zero, _marker: PhantomData },
-                idx: unsafe { usize::from(*(*self.as_leaf_ptr()).parent_idx.as_ptr()) },
+        let leaf_ptr = self.as_leaf_ptr();
+        unsafe { (*leaf_ptr).parent }
+            .as_ref()
+            .map(|parent| Handle {
+                node: NodeRef {
+                    height: self.height + 1,
+                    node: parent.cast(),
+                    _marker: PhantomData,
+                },
+                idx: unsafe { usize::from((*leaf_ptr).parent_idx.assume_init()) },
                 _marker: PhantomData,
             })
-        } else {
-            Err(self)
-        }
+            .ok_or(self)
     }
 
     pub fn first_edge(self) -> Handle<Self, marker::Edge> {
@@ -465,6 +467,22 @@ fn as_leaf_mut(&mut self) -> &'a mut LeafNode<K, V> {
         unsafe { &mut (*self.node.as_ptr()) }
     }
 
+    /// Borrows a mutable reference to one of the keys stored in the node.
+    ///
+    /// # Safety
+    /// The node has more than `idx` initialized elements.
+    pub unsafe fn key_mut_at(&mut self, idx: usize) -> &mut K {
+        unsafe { self.reborrow_mut().into_key_mut_at(idx) }
+    }
+
+    /// Borrows a mutable reference to one of the values stored in the node.
+    ///
+    /// # Safety
+    /// The node has more than `idx` initialized elements.
+    pub unsafe fn val_mut_at(&mut self, idx: usize) -> &mut V {
+        unsafe { self.reborrow_mut().into_val_mut_at(idx) }
+    }
+
     fn keys_mut(&mut self) -> &mut [K] {
         // 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
@@ -555,15 +573,14 @@ unsafe fn into_key_val_mut_at(self, idx: usize) -> (&'a K, &'a mut V) {
 impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
     /// Adds a key/value pair to the end of the node.
     pub fn push(&mut self, key: K, val: V) {
-        assert!(self.len() < CAPACITY);
-
-        let idx = self.len();
-
+        let len = &mut self.as_leaf_mut().len;
+        let idx = usize::from(*len);
+        assert!(idx < CAPACITY);
+        *len += 1;
         unsafe {
-            ptr::write(self.keys_mut().get_unchecked_mut(idx), key);
-            ptr::write(self.vals_mut().get_unchecked_mut(idx), val);
+            ptr::write(self.key_mut_at(idx), key);
+            ptr::write(self.val_mut_at(idx), val);
         }
-        self.as_leaf_mut().len += 1;
     }
 
     /// Adds a key/value pair to the beginning of the node.
@@ -600,17 +617,15 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
     /// the end of the node.
     pub fn push(&mut self, key: K, val: V, edge: Root<K, V>) {
         assert!(edge.height == self.height - 1);
-        assert!(self.len() < CAPACITY);
-
-        let idx = self.len();
 
+        let len = &mut self.as_leaf_mut().len;
+        let idx = usize::from(*len);
+        assert!(idx < CAPACITY);
+        *len += 1;
         unsafe {
-            ptr::write(self.keys_mut().get_unchecked_mut(idx), key);
-            ptr::write(self.vals_mut().get_unchecked_mut(idx), val);
+            ptr::write(self.key_mut_at(idx), key);
+            ptr::write(self.val_mut_at(idx), val);
             self.as_internal_mut().edges.get_unchecked_mut(idx + 1).write(edge.node);
-
-            self.as_leaf_mut().len += 1;
-
             Handle::new_edge(self.reborrow_mut(), idx + 1).correct_parent_link();
         }
     }
@@ -659,7 +674,7 @@ pub fn pop(&mut self) -> (K, V, Option<Root<K, V>>) {
                     let edge =
                         ptr::read(internal.as_internal().edges.get_unchecked(idx + 1).as_ptr());
                     let mut new_root = Root { node: edge, height: internal.height - 1 };
-                    new_root.node_as_mut().as_leaf_mut().parent = ptr::null();
+                    new_root.node_as_mut().as_leaf_mut().parent = None;
                     Some(new_root)
                 }
             };
@@ -691,7 +706,7 @@ pub fn pop_front(&mut self) -> (K, V, Option<Root<K, V>>) {
                     );
 
                     let mut new_root = Root { node: edge, height: internal.height - 1 };
-                    new_root.node_as_mut().as_leaf_mut().parent = ptr::null();
+                    new_root.node_as_mut().as_leaf_mut().parent = None;
 
                     for i in 0..old_len {
                         Handle::new_edge(internal.reborrow_mut(), i).correct_parent_link();
@@ -903,7 +918,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
     /// The returned pointer points to the inserted value.
     fn insert_fit(&mut self, key: K, val: V) -> *mut V {
         self.leafy_insert_fit(key, val);
-        unsafe { self.node.vals_mut().get_unchecked_mut(self.idx) }
+        unsafe { self.node.val_mut_at(self.idx) }
     }
 }
 
@@ -914,14 +929,14 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
     /// The returned pointer points to the inserted value.
     fn insert(mut self, key: K, val: V) -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) {
         if self.node.len() < CAPACITY {
-            let ptr = self.insert_fit(key, val);
+            let val_ptr = self.insert_fit(key, val);
             let kv = unsafe { Handle::new_kv(self.node, self.idx) };
-            (InsertResult::Fit(kv), ptr)
+            (InsertResult::Fit(kv), val_ptr)
         } else {
             let (middle_kv_idx, insertion) = splitpoint(self.idx);
             let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) };
             let (mut left, k, v, mut right) = middle.split();
-            let ptr = match insertion {
+            let val_ptr = match insertion {
                 InsertionPlace::Left(insert_idx) => unsafe {
                     Handle::new_edge(left.reborrow_mut(), insert_idx).insert_fit(key, val)
                 },
@@ -933,7 +948,7 @@ fn insert(mut self, key: K, val: V) -> (InsertResult<'a, K, V, marker::Leaf>, *m
                     .insert_fit(key, val)
                 },
             };
-            (InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right }), ptr)
+            (InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right }), val_ptr)
         }
     }
 }
@@ -943,7 +958,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
     /// when the ordering of edges has been changed, such as in the various `insert` methods.
     fn correct_parent_link(mut self) {
         let idx = self.idx as u16;
-        let ptr = self.node.as_internal_mut() as *mut _;
+        let ptr = NonNull::new(self.node.as_internal_mut());
         let mut child = self.descend();
         child.as_leaf_mut().parent = ptr;
         child.as_leaf_mut().parent_idx.write(idx);