|
12 | 12 | // edges: if height > 0 {
|
13 | 13 | // [Box<Node<K, V, height - 1>>; 2 * B]
|
14 | 14 | // } else { () },
|
15 |
| -// parent: *const Node<K, V, height + 1>, |
| 15 | +// parent: Option<NonNull<Node<K, V, height + 1>>>, |
16 | 16 | // parent_idx: u16,
|
17 | 17 | // len: u16,
|
18 | 18 | // }
|
@@ -50,9 +50,8 @@ const EDGE_IDX_RIGHT_OF_CENTER: usize = B;
|
50 | 50 | /// The underlying representation of leaf nodes.
|
51 | 51 | #[repr(C)]
|
52 | 52 | struct LeafNode<K, V> {
|
53 |
| - /// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`. |
54 |
| - /// This either points to an actual node or is null. |
55 |
| - parent: *const InternalNode<K, V>, |
| 53 | + /// We want to be covariant in `K` and `V`. |
| 54 | + parent: Option<NonNull<InternalNode<K, V>>>, |
56 | 55 |
|
57 | 56 | /// This node's index into the parent node's `edges` array.
|
58 | 57 | /// `*node.parent.edges[node.parent_idx]` should be the same thing as `node`.
|
@@ -80,7 +79,7 @@ impl<K, V> LeafNode<K, V> {
|
80 | 79 | // be both slightly faster and easier to track in Valgrind.
|
81 | 80 | keys: MaybeUninit::uninit_array(),
|
82 | 81 | vals: MaybeUninit::uninit_array(),
|
83 |
| - parent: ptr::null(), |
| 82 | + parent: None, |
84 | 83 | parent_idx: MaybeUninit::uninit(),
|
85 | 84 | len: 0,
|
86 | 85 | }
|
@@ -224,7 +223,7 @@ impl<K, V> Root<K, V> {
|
224 | 223 | )
|
225 | 224 | };
|
226 | 225 | self.height -= 1;
|
227 |
| - self.node_as_mut().as_leaf_mut().parent = ptr::null(); |
| 226 | + self.node_as_mut().as_leaf_mut().parent = None; |
228 | 227 |
|
229 | 228 | unsafe {
|
230 | 229 | 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> {
|
309 | 308 | pub fn len(&self) -> usize {
|
310 | 309 | // Crucially, we only access the `len` field here. If BorrowType is marker::ValMut,
|
311 | 310 | // there might be outstanding mutable references to values that we must not invalidate.
|
312 |
| - unsafe { (*self.as_leaf_ptr()).len as usize } |
| 311 | + unsafe { usize::from((*self.as_leaf_ptr()).len) } |
313 | 312 | }
|
314 | 313 |
|
315 | 314 | /// Returns the height of this node in the whole tree. Zero height denotes the
|
@@ -365,16 +364,19 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
|
365 | 364 | ) -> Result<Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::Edge>, Self> {
|
366 | 365 | // We need to use raw pointers to nodes because, if BorrowType is marker::ValMut,
|
367 | 366 | // there might be outstanding mutable references to values that we must not invalidate.
|
368 |
| - let parent_as_leaf = unsafe { (*self.as_leaf_ptr()).parent as *const LeafNode<K, V> }; |
369 |
| - if let Some(non_zero) = NonNull::new(parent_as_leaf as *mut _) { |
370 |
| - Ok(Handle { |
371 |
| - node: NodeRef { height: self.height + 1, node: non_zero, _marker: PhantomData }, |
372 |
| - idx: unsafe { usize::from(*(*self.as_leaf_ptr()).parent_idx.as_ptr()) }, |
| 367 | + let leaf_ptr = self.as_leaf_ptr(); |
| 368 | + unsafe { (*leaf_ptr).parent } |
| 369 | + .as_ref() |
| 370 | + .map(|parent| Handle { |
| 371 | + node: NodeRef { |
| 372 | + height: self.height + 1, |
| 373 | + node: parent.cast(), |
| 374 | + _marker: PhantomData, |
| 375 | + }, |
| 376 | + idx: unsafe { usize::from((*leaf_ptr).parent_idx.assume_init()) }, |
373 | 377 | _marker: PhantomData,
|
374 | 378 | })
|
375 |
| - } else { |
376 |
| - Err(self) |
377 |
| - } |
| 379 | + .ok_or(self) |
378 | 380 | }
|
379 | 381 |
|
380 | 382 | pub fn first_edge(self) -> Handle<Self, marker::Edge> {
|
@@ -572,7 +574,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
|
572 | 574 | /// Adds a key/value pair to the end of the node.
|
573 | 575 | pub fn push(&mut self, key: K, val: V) {
|
574 | 576 | let len = &mut self.as_leaf_mut().len;
|
575 |
| - let idx = *len as usize; |
| 577 | + let idx = usize::from(*len); |
576 | 578 | assert!(idx < CAPACITY);
|
577 | 579 | *len += 1;
|
578 | 580 | unsafe {
|
@@ -617,7 +619,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
|
617 | 619 | assert!(edge.height == self.height - 1);
|
618 | 620 |
|
619 | 621 | let len = &mut self.as_leaf_mut().len;
|
620 |
| - let idx = *len as usize; |
| 622 | + let idx = usize::from(*len); |
621 | 623 | assert!(idx < CAPACITY);
|
622 | 624 | *len += 1;
|
623 | 625 | unsafe {
|
@@ -672,7 +674,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
|
672 | 674 | let edge =
|
673 | 675 | ptr::read(internal.as_internal().edges.get_unchecked(idx + 1).as_ptr());
|
674 | 676 | let mut new_root = Root { node: edge, height: internal.height - 1 };
|
675 |
| - new_root.node_as_mut().as_leaf_mut().parent = ptr::null(); |
| 677 | + new_root.node_as_mut().as_leaf_mut().parent = None; |
676 | 678 | Some(new_root)
|
677 | 679 | }
|
678 | 680 | };
|
@@ -704,7 +706,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
|
704 | 706 | );
|
705 | 707 |
|
706 | 708 | let mut new_root = Root { node: edge, height: internal.height - 1 };
|
707 |
| - new_root.node_as_mut().as_leaf_mut().parent = ptr::null(); |
| 709 | + new_root.node_as_mut().as_leaf_mut().parent = None; |
708 | 710 |
|
709 | 711 | for i in 0..old_len {
|
710 | 712 | Handle::new_edge(internal.reborrow_mut(), i).correct_parent_link();
|
@@ -956,7 +958,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
|
956 | 958 | /// when the ordering of edges has been changed, such as in the various `insert` methods.
|
957 | 959 | fn correct_parent_link(mut self) {
|
958 | 960 | let idx = self.idx as u16;
|
959 |
| - let ptr = self.node.as_internal_mut() as *mut _; |
| 961 | + let ptr = NonNull::new(self.node.as_internal_mut()); |
960 | 962 | let mut child = self.descend();
|
961 | 963 | child.as_leaf_mut().parent = ptr;
|
962 | 964 | child.as_leaf_mut().parent_idx.write(idx);
|
|
0 commit comments