@@ -1124,21 +1124,20 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>
1124
1124
/// by taking care of leaf data.
1125
1125
fn split_leaf_data ( & mut self , new_node : & mut LeafNode < K , V > ) -> ( K , V ) {
1126
1126
debug_assert ! ( self . idx < self . node. len( ) ) ;
1127
- let new_len = self . node . len ( ) - self . idx - 1 ;
1127
+ let old_len = self . node . len ( ) ;
1128
+ let new_len = old_len - self . idx - 1 ;
1128
1129
new_node. len = new_len as u16 ;
1129
1130
unsafe {
1130
1131
let k = self . node . key_area_mut ( self . idx ) . assume_init_read ( ) ;
1131
1132
let v = self . node . val_area_mut ( self . idx ) . assume_init_read ( ) ;
1132
1133
1133
- ptr:: copy_nonoverlapping (
1134
- self . node . key_area_mut ( self . idx + 1 ..) . as_ptr ( ) ,
1135
- new_node. keys . as_mut_ptr ( ) ,
1136
- new_len,
1134
+ move_to_slice (
1135
+ self . node . key_area_mut ( self . idx + 1 ..old_len) ,
1136
+ & mut new_node. keys [ ..new_len] ,
1137
1137
) ;
1138
- ptr:: copy_nonoverlapping (
1139
- self . node . val_area_mut ( self . idx + 1 ..) . as_ptr ( ) ,
1140
- new_node. vals . as_mut_ptr ( ) ,
1141
- new_len,
1138
+ move_to_slice (
1139
+ self . node . val_area_mut ( self . idx + 1 ..old_len) ,
1140
+ & mut new_node. vals [ ..new_len] ,
1142
1141
) ;
1143
1142
1144
1143
* self . node . len_mut ( ) = self . idx as u16 ;
@@ -1190,20 +1189,20 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
1190
1189
/// - All the edges and key-value pairs to the right of this handle are put into
1191
1190
/// a newly allocated node.
1192
1191
pub fn split ( mut self ) -> SplitResult < ' a , K , V , marker:: Internal > {
1192
+ let old_len = self . node . len ( ) ;
1193
1193
unsafe {
1194
1194
let mut new_node = Box :: new ( InternalNode :: new ( ) ) ;
1195
1195
let kv = self . split_leaf_data ( & mut new_node. data ) ;
1196
1196
let new_len = usize:: from ( new_node. data . len ) ;
1197
- ptr:: copy_nonoverlapping (
1198
- self . node . edge_area_mut ( self . idx + 1 ..) . as_ptr ( ) ,
1199
- new_node. edges . as_mut_ptr ( ) ,
1200
- new_len + 1 ,
1197
+ move_to_slice (
1198
+ self . node . edge_area_mut ( self . idx + 1 ..old_len + 1 ) ,
1199
+ & mut new_node. edges [ ..new_len + 1 ] ,
1201
1200
) ;
1202
1201
1203
1202
let height = self . node . height ;
1204
1203
let mut right = NodeRef :: from_new_internal ( new_node, height) ;
1205
1204
1206
- right. borrow_mut ( ) . correct_childrens_parent_links ( 0 ..= new_len) ;
1205
+ right. borrow_mut ( ) . correct_childrens_parent_links ( 0 ..new_len + 1 ) ;
1207
1206
1208
1207
SplitResult { left : self . node , kv, right }
1209
1208
}
@@ -1323,18 +1322,16 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
1323
1322
1324
1323
let parent_key = slice_remove ( parent_node. key_area_mut ( ..old_parent_len) , parent_idx) ;
1325
1324
left_node. key_area_mut ( old_left_len) . write ( parent_key) ;
1326
- ptr:: copy_nonoverlapping (
1327
- right_node. key_area_mut ( ..) . as_ptr ( ) ,
1328
- left_node. key_area_mut ( old_left_len + 1 ..) . as_mut_ptr ( ) ,
1329
- right_len,
1325
+ move_to_slice (
1326
+ right_node. key_area_mut ( ..right_len) ,
1327
+ left_node. key_area_mut ( old_left_len + 1 ..new_left_len) ,
1330
1328
) ;
1331
1329
1332
1330
let parent_val = slice_remove ( parent_node. val_area_mut ( ..old_parent_len) , parent_idx) ;
1333
1331
left_node. val_area_mut ( old_left_len) . write ( parent_val) ;
1334
- ptr:: copy_nonoverlapping (
1335
- right_node. val_area_mut ( ..) . as_ptr ( ) ,
1336
- left_node. val_area_mut ( old_left_len + 1 ..) . as_mut_ptr ( ) ,
1337
- right_len,
1332
+ move_to_slice (
1333
+ right_node. val_area_mut ( ..right_len) ,
1334
+ left_node. val_area_mut ( old_left_len + 1 ..new_left_len) ,
1338
1335
) ;
1339
1336
1340
1337
slice_remove ( & mut parent_node. edge_area_mut ( ..old_parent_len + 1 ) , parent_idx + 1 ) ;
@@ -1346,10 +1343,9 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
1346
1343
// of the node of this edge, thus above zero, so they are internal.
1347
1344
let mut left_node = left_node. reborrow_mut ( ) . cast_to_internal_unchecked ( ) ;
1348
1345
let mut right_node = right_node. cast_to_internal_unchecked ( ) ;
1349
- ptr:: copy_nonoverlapping (
1350
- right_node. edge_area_mut ( ..) . as_ptr ( ) ,
1351
- left_node. edge_area_mut ( old_left_len + 1 ..) . as_mut_ptr ( ) ,
1352
- right_len + 1 ,
1346
+ move_to_slice (
1347
+ right_node. edge_area_mut ( ..right_len + 1 ) ,
1348
+ left_node. edge_area_mut ( old_left_len + 1 ..new_left_len + 1 ) ,
1353
1349
) ;
1354
1350
1355
1351
left_node. correct_childrens_parent_links ( old_left_len + 1 ..new_left_len + 1 ) ;
@@ -1741,5 +1737,15 @@ unsafe fn slice_remove<T>(slice: &mut [MaybeUninit<T>], idx: usize) -> T {
1741
1737
}
1742
1738
}
1743
1739
1740
+ /// Moves all values from a slice of initialized elements to a slice
1741
+ /// of uninitialized elements, leaving behind `src` as all uninitialized.
1742
+ /// Works like `dst.copy_from_slice(src)` but does not require `T` to be `Copy`.
1743
+ fn move_to_slice < T > ( src : & mut [ MaybeUninit < T > ] , dst : & mut [ MaybeUninit < T > ] ) {
1744
+ assert ! ( src. len( ) == dst. len( ) ) ;
1745
+ unsafe {
1746
+ ptr:: copy_nonoverlapping ( src. as_ptr ( ) , dst. as_mut_ptr ( ) , src. len ( ) ) ;
1747
+ }
1748
+ }
1749
+
1744
1750
#[ cfg( test) ]
1745
1751
mod tests;
0 commit comments