Skip to content

Commit f68e089

Browse files
committedSep 19, 2020
Auto merge of #76929 - ssomers:btree_cleanup_2, r=Mark-Simulacrum
BTreeMap: wrap node's raw parent pointer in NonNull Now that the other `*const` (root) is gone, seemed like a small step forward. r? `@Mark-Simulacrum`
2 parents 59fb88d + 0661b0a commit f68e089

File tree

1 file changed

+22
-20
lines changed
  • library/alloc/src/collections/btree

1 file changed

+22
-20
lines changed
 

‎library/alloc/src/collections/btree/node.rs

+22-20
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// edges: if height > 0 {
1313
// [Box<Node<K, V, height - 1>>; 2 * B]
1414
// } else { () },
15-
// parent: *const Node<K, V, height + 1>,
15+
// parent: Option<NonNull<Node<K, V, height + 1>>>,
1616
// parent_idx: u16,
1717
// len: u16,
1818
// }
@@ -50,9 +50,8 @@ const EDGE_IDX_RIGHT_OF_CENTER: usize = B;
5050
/// The underlying representation of leaf nodes.
5151
#[repr(C)]
5252
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>>>,
5655

5756
/// This node's index into the parent node's `edges` array.
5857
/// `*node.parent.edges[node.parent_idx]` should be the same thing as `node`.
@@ -80,7 +79,7 @@ impl<K, V> LeafNode<K, V> {
8079
// be both slightly faster and easier to track in Valgrind.
8180
keys: MaybeUninit::uninit_array(),
8281
vals: MaybeUninit::uninit_array(),
83-
parent: ptr::null(),
82+
parent: None,
8483
parent_idx: MaybeUninit::uninit(),
8584
len: 0,
8685
}
@@ -224,7 +223,7 @@ impl<K, V> Root<K, V> {
224223
)
225224
};
226225
self.height -= 1;
227-
self.node_as_mut().as_leaf_mut().parent = ptr::null();
226+
self.node_as_mut().as_leaf_mut().parent = None;
228227

229228
unsafe {
230229
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> {
309308
pub fn len(&self) -> usize {
310309
// Crucially, we only access the `len` field here. If BorrowType is marker::ValMut,
311310
// 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) }
313312
}
314313

315314
/// 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> {
365364
) -> Result<Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::Edge>, Self> {
366365
// We need to use raw pointers to nodes because, if BorrowType is marker::ValMut,
367366
// 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()) },
373377
_marker: PhantomData,
374378
})
375-
} else {
376-
Err(self)
377-
}
379+
.ok_or(self)
378380
}
379381

380382
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> {
572574
/// Adds a key/value pair to the end of the node.
573575
pub fn push(&mut self, key: K, val: V) {
574576
let len = &mut self.as_leaf_mut().len;
575-
let idx = *len as usize;
577+
let idx = usize::from(*len);
576578
assert!(idx < CAPACITY);
577579
*len += 1;
578580
unsafe {
@@ -617,7 +619,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
617619
assert!(edge.height == self.height - 1);
618620

619621
let len = &mut self.as_leaf_mut().len;
620-
let idx = *len as usize;
622+
let idx = usize::from(*len);
621623
assert!(idx < CAPACITY);
622624
*len += 1;
623625
unsafe {
@@ -672,7 +674,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
672674
let edge =
673675
ptr::read(internal.as_internal().edges.get_unchecked(idx + 1).as_ptr());
674676
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;
676678
Some(new_root)
677679
}
678680
};
@@ -704,7 +706,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
704706
);
705707

706708
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;
708710

709711
for i in 0..old_len {
710712
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::
956958
/// when the ordering of edges has been changed, such as in the various `insert` methods.
957959
fn correct_parent_link(mut self) {
958960
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());
960962
let mut child = self.descend();
961963
child.as_leaf_mut().parent = ptr;
962964
child.as_leaf_mut().parent_idx.write(idx);

0 commit comments

Comments
 (0)
Please sign in to comment.