Skip to content

Commit efdb859

Browse files
committed
Auto merge of #80873 - ssomers:btree_cleanup_slices_4, r=Mark-Simulacrum
BTreeMap: tougher checks on code using raw into_kv_pointers r? `@Mark-Simulacrum`
2 parents 635ccfe + c1dfb4a commit efdb859

File tree

1 file changed

+88
-81
lines changed
  • library/alloc/src/collections/btree

1 file changed

+88
-81
lines changed

Diff for: library/alloc/src/collections/btree/node.rs

+88-81
Original file line numberDiff line numberDiff line change
@@ -712,13 +712,6 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
712712
(key, val, edge)
713713
}
714714
}
715-
716-
fn into_kv_pointers_mut(mut self) -> (*mut K, *mut V) {
717-
let leaf = self.as_leaf_mut();
718-
let keys = MaybeUninit::slice_as_mut_ptr(&mut leaf.keys);
719-
let vals = MaybeUninit::slice_as_mut_ptr(&mut leaf.vals);
720-
(keys, vals)
721-
}
722715
}
723716

724717
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
@@ -1428,36 +1421,42 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
14281421

14291422
// Move leaf data.
14301423
{
1431-
let left_kv = left_node.reborrow_mut().into_kv_pointers_mut();
1432-
let right_kv = right_node.reborrow_mut().into_kv_pointers_mut();
1433-
let parent_kv = {
1434-
let kv = self.parent.kv_mut();
1435-
(kv.0 as *mut K, kv.1 as *mut V)
1436-
};
1437-
14381424
// Make room for stolen elements in the right child.
1439-
ptr::copy(right_kv.0, right_kv.0.add(count), old_right_len);
1440-
ptr::copy(right_kv.1, right_kv.1.add(count), old_right_len);
1425+
slice_shr(right_node.key_area_mut(..new_right_len), count);
1426+
slice_shr(right_node.val_area_mut(..new_right_len), count);
14411427

14421428
// Move elements from the left child to the right one.
1443-
move_kv(left_kv, new_left_len + 1, right_kv, 0, count - 1);
1444-
1445-
// Move parent's key-value pair to the right child.
1446-
move_kv(parent_kv, 0, right_kv, count - 1, 1);
1429+
move_to_slice(
1430+
left_node.key_area_mut(new_left_len + 1..old_left_len),
1431+
right_node.key_area_mut(..count - 1),
1432+
);
1433+
move_to_slice(
1434+
left_node.val_area_mut(new_left_len + 1..old_left_len),
1435+
right_node.val_area_mut(..count - 1),
1436+
);
14471437

14481438
// Move the left-most stolen pair to the parent.
1449-
move_kv(left_kv, new_left_len, parent_kv, 0, 1);
1439+
let k = left_node.key_area_mut(new_left_len).assume_init_read();
1440+
let v = left_node.val_area_mut(new_left_len).assume_init_read();
1441+
let (k, v) = self.parent.replace_kv(k, v);
1442+
1443+
// Move parent's key-value pair to the right child.
1444+
right_node.key_area_mut(count - 1).write(k);
1445+
right_node.val_area_mut(count - 1).write(v);
14501446
}
14511447

14521448
match (left_node.reborrow_mut().force(), right_node.reborrow_mut().force()) {
1453-
(ForceResult::Internal(left), ForceResult::Internal(mut right)) => {
1449+
(ForceResult::Internal(mut left), ForceResult::Internal(mut right)) => {
14541450
// Make room for stolen edges.
1455-
let right_edges = right.edge_area_mut(..).as_mut_ptr();
1456-
ptr::copy(right_edges, right_edges.add(count), old_right_len + 1);
1457-
right.correct_childrens_parent_links(count..new_right_len + 1);
1451+
slice_shr(right.edge_area_mut(..new_right_len + 1), count);
14581452

14591453
// Steal edges.
1460-
move_edges(left, new_left_len + 1, right, 0, count);
1454+
move_to_slice(
1455+
left.edge_area_mut(new_left_len + 1..old_left_len + 1),
1456+
right.edge_area_mut(..count),
1457+
);
1458+
1459+
right.correct_childrens_parent_links(0..new_right_len + 1);
14611460
}
14621461
(ForceResult::Leaf(_), ForceResult::Leaf(_)) => {}
14631462
_ => unreachable!(),
@@ -1485,36 +1484,43 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
14851484

14861485
// Move leaf data.
14871486
{
1488-
let left_kv = left_node.reborrow_mut().into_kv_pointers_mut();
1489-
let right_kv = right_node.reborrow_mut().into_kv_pointers_mut();
1490-
let parent_kv = {
1491-
let kv = self.parent.kv_mut();
1492-
(kv.0 as *mut K, kv.1 as *mut V)
1493-
};
1487+
// Move the right-most stolen pair to the parent.
1488+
let k = right_node.key_area_mut(count - 1).assume_init_read();
1489+
let v = right_node.val_area_mut(count - 1).assume_init_read();
1490+
let (k, v) = self.parent.replace_kv(k, v);
14941491

14951492
// Move parent's key-value pair to the left child.
1496-
move_kv(parent_kv, 0, left_kv, old_left_len, 1);
1493+
left_node.key_area_mut(old_left_len).write(k);
1494+
left_node.val_area_mut(old_left_len).write(v);
14971495

14981496
// Move elements from the right child to the left one.
1499-
move_kv(right_kv, 0, left_kv, old_left_len + 1, count - 1);
1500-
1501-
// Move the right-most stolen pair to the parent.
1502-
move_kv(right_kv, count - 1, parent_kv, 0, 1);
1497+
move_to_slice(
1498+
right_node.key_area_mut(..count - 1),
1499+
left_node.key_area_mut(old_left_len + 1..new_left_len),
1500+
);
1501+
move_to_slice(
1502+
right_node.val_area_mut(..count - 1),
1503+
left_node.val_area_mut(old_left_len + 1..new_left_len),
1504+
);
15031505

15041506
// Fill gap where stolen elements used to be.
1505-
ptr::copy(right_kv.0.add(count), right_kv.0, new_right_len);
1506-
ptr::copy(right_kv.1.add(count), right_kv.1, new_right_len);
1507+
slice_shl(right_node.key_area_mut(..old_right_len), count);
1508+
slice_shl(right_node.val_area_mut(..old_right_len), count);
15071509
}
15081510

15091511
match (left_node.reborrow_mut().force(), right_node.reborrow_mut().force()) {
1510-
(ForceResult::Internal(left), ForceResult::Internal(mut right)) => {
1512+
(ForceResult::Internal(mut left), ForceResult::Internal(mut right)) => {
15111513
// Steal edges.
1512-
move_edges(right.reborrow_mut(), 0, left, old_left_len + 1, count);
1514+
move_to_slice(
1515+
right.edge_area_mut(..count),
1516+
left.edge_area_mut(old_left_len + 1..new_left_len + 1),
1517+
);
15131518

15141519
// Fill gap where stolen edges used to be.
1515-
let right_edges = right.edge_area_mut(..).as_mut_ptr();
1516-
ptr::copy(right_edges.add(count), right_edges, new_right_len + 1);
1517-
right.correct_childrens_parent_links(0..=new_right_len);
1520+
slice_shl(right.edge_area_mut(..old_right_len + 1), count);
1521+
1522+
left.correct_childrens_parent_links(old_left_len + 1..new_left_len + 1);
1523+
right.correct_childrens_parent_links(0..new_right_len + 1);
15181524
}
15191525
(ForceResult::Leaf(_), ForceResult::Leaf(_)) => {}
15201526
_ => unreachable!(),
@@ -1523,35 +1529,6 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
15231529
}
15241530
}
15251531

1526-
unsafe fn move_kv<K, V>(
1527-
source: (*mut K, *mut V),
1528-
source_offset: usize,
1529-
dest: (*mut K, *mut V),
1530-
dest_offset: usize,
1531-
count: usize,
1532-
) {
1533-
unsafe {
1534-
ptr::copy_nonoverlapping(source.0.add(source_offset), dest.0.add(dest_offset), count);
1535-
ptr::copy_nonoverlapping(source.1.add(source_offset), dest.1.add(dest_offset), count);
1536-
}
1537-
}
1538-
1539-
// Source and destination must have the same height.
1540-
unsafe fn move_edges<'a, K: 'a, V: 'a>(
1541-
mut source: NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
1542-
source_offset: usize,
1543-
mut dest: NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
1544-
dest_offset: usize,
1545-
count: usize,
1546-
) {
1547-
unsafe {
1548-
let source_ptr = source.edge_area_mut(..).as_ptr();
1549-
let dest_ptr = dest.edge_area_mut(dest_offset..).as_mut_ptr();
1550-
ptr::copy_nonoverlapping(source_ptr.add(source_offset), dest_ptr, count);
1551-
dest.correct_childrens_parent_links(dest_offset..dest_offset + count);
1552-
}
1553-
}
1554-
15551532
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Leaf> {
15561533
/// Removes any static information asserting that this node is a `Leaf` node.
15571534
pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
@@ -1629,25 +1606,33 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, ma
16291606
unsafe {
16301607
let new_left_len = self.idx;
16311608
let mut left_node = self.reborrow_mut().into_node();
1609+
let old_left_len = left_node.len();
16321610

1633-
let new_right_len = left_node.len() - new_left_len;
1611+
let new_right_len = old_left_len - new_left_len;
16341612
let mut right_node = right.reborrow_mut();
16351613

16361614
assert!(right_node.len() == 0);
16371615
assert!(left_node.height == right_node.height);
16381616

16391617
if new_right_len > 0 {
1640-
let left_kv = left_node.reborrow_mut().into_kv_pointers_mut();
1641-
let right_kv = right_node.reborrow_mut().into_kv_pointers_mut();
1642-
1643-
move_kv(left_kv, new_left_len, right_kv, 0, new_right_len);
1644-
16451618
*left_node.len_mut() = new_left_len as u16;
16461619
*right_node.len_mut() = new_right_len as u16;
16471620

1621+
move_to_slice(
1622+
left_node.key_area_mut(new_left_len..old_left_len),
1623+
right_node.key_area_mut(..new_right_len),
1624+
);
1625+
move_to_slice(
1626+
left_node.val_area_mut(new_left_len..old_left_len),
1627+
right_node.val_area_mut(..new_right_len),
1628+
);
16481629
match (left_node.force(), right_node.force()) {
1649-
(ForceResult::Internal(left), ForceResult::Internal(right)) => {
1650-
move_edges(left, new_left_len + 1, right, 1, new_right_len);
1630+
(ForceResult::Internal(mut left), ForceResult::Internal(mut right)) => {
1631+
move_to_slice(
1632+
left.edge_area_mut(new_left_len + 1..old_left_len + 1),
1633+
right.edge_area_mut(1..new_right_len + 1),
1634+
);
1635+
right.correct_childrens_parent_links(1..new_right_len + 1);
16511636
}
16521637
(ForceResult::Leaf(_), ForceResult::Leaf(_)) => {}
16531638
_ => unreachable!(),
@@ -1737,6 +1722,28 @@ unsafe fn slice_remove<T>(slice: &mut [MaybeUninit<T>], idx: usize) -> T {
17371722
}
17381723
}
17391724

1725+
/// Shifts the elements in a slice `distance` positions to the left.
1726+
///
1727+
/// # Safety
1728+
/// The slice has at least `distance` elements.
1729+
unsafe fn slice_shl<T>(slice: &mut [MaybeUninit<T>], distance: usize) {
1730+
unsafe {
1731+
let slice_ptr = slice.as_mut_ptr();
1732+
ptr::copy(slice_ptr.add(distance), slice_ptr, slice.len() - distance);
1733+
}
1734+
}
1735+
1736+
/// Shifts the elements in a slice `distance` positions to the right.
1737+
///
1738+
/// # Safety
1739+
/// The slice has at least `distance` elements.
1740+
unsafe fn slice_shr<T>(slice: &mut [MaybeUninit<T>], distance: usize) {
1741+
unsafe {
1742+
let slice_ptr = slice.as_mut_ptr();
1743+
ptr::copy(slice_ptr, slice_ptr.add(distance), slice.len() - distance);
1744+
}
1745+
}
1746+
17401747
/// Moves all values from a slice of initialized elements to a slice
17411748
/// of uninitialized elements, leaving behind `src` as all uninitialized.
17421749
/// Works like `dst.copy_from_slice(src)` but does not require `T` to be `Copy`.

0 commit comments

Comments
 (0)