@@ -1282,25 +1282,25 @@ impl<'a, K, V> BalancingContext<'a, K, V> {
1282
1282
self . right_child
1283
1283
}
1284
1284
1285
- /// Returns `true` if it is valid to call `.merge()` in the balancing context,
1286
- /// i.e., whether there is enough room in a node to hold the combination of
1287
- /// both adjacent child nodes, along with the key-value pair in the parent.
1285
+ /// Returns whether merging is possible, i.e., whether there is enough room
1286
+ /// in a node to combine the central KV with both adjacent child nodes.
1288
1287
pub fn can_merge ( & self ) -> bool {
1289
1288
self . left_child . len ( ) + 1 + self . right_child . len ( ) <= CAPACITY
1290
1289
}
1291
1290
}
1292
1291
1293
1292
impl < ' a , K : ' a , V : ' a > BalancingContext < ' a , K , V > {
1294
- /// Merges the parent's key-value pair and both adjacent child nodes into
1295
- /// the left node and returns an edge handle in that expanded left node.
1296
- /// If `track_edge_idx` is given some value, the returned edge corresponds
1297
- /// to where the edge in that child node ended up,
1298
- ///
1299
- /// Panics unless we `.can_merge()`.
1300
- pub fn merge (
1293
+ /// Performs a merge and lets a closure decide what to return.
1294
+ fn do_merge <
1295
+ F : FnOnce (
1296
+ NodeRef < marker:: Mut < ' a > , K , V , marker:: Internal > ,
1297
+ NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > ,
1298
+ ) -> R ,
1299
+ R ,
1300
+ > (
1301
1301
self ,
1302
- track_edge_idx : Option < LeftOrRight < usize > > ,
1303
- ) -> Handle < NodeRef < marker :: Mut < ' a > , K , V , marker :: LeafOrInternal > , marker :: Edge > {
1302
+ result : F ,
1303
+ ) -> R {
1304
1304
let Handle { node : mut parent_node, idx : parent_idx, _marker } = self . parent ;
1305
1305
let old_parent_len = parent_node. len ( ) ;
1306
1306
let mut left_node = self . left_child ;
@@ -1310,11 +1310,6 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
1310
1310
let new_left_len = old_left_len + 1 + right_len;
1311
1311
1312
1312
assert ! ( new_left_len <= CAPACITY ) ;
1313
- assert ! ( match track_edge_idx {
1314
- None => true ,
1315
- Some ( LeftOrRight :: Left ( idx) ) => idx <= old_left_len,
1316
- Some ( LeftOrRight :: Right ( idx) ) => idx <= right_len,
1317
- } ) ;
1318
1313
1319
1314
unsafe {
1320
1315
* left_node. len_mut ( ) = new_left_len as u16 ;
@@ -1353,14 +1348,47 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
1353
1348
} else {
1354
1349
Global . deallocate ( right_node. node . cast ( ) , Layout :: new :: < LeafNode < K , V > > ( ) ) ;
1355
1350
}
1356
-
1357
- let new_idx = match track_edge_idx {
1358
- None => 0 ,
1359
- Some ( LeftOrRight :: Left ( idx) ) => idx,
1360
- Some ( LeftOrRight :: Right ( idx) ) => old_left_len + 1 + idx,
1361
- } ;
1362
- Handle :: new_edge ( left_node, new_idx)
1363
1351
}
1352
+ result ( parent_node, left_node)
1353
+ }
1354
+
1355
+ /// Merges the parent's key-value pair and both adjacent child nodes into
1356
+ /// the left child node and returns the shrunk parent node.
1357
+ ///
1358
+ /// Panics unless we `.can_merge()`.
1359
+ pub fn merge_tracking_parent ( self ) -> NodeRef < marker:: Mut < ' a > , K , V , marker:: Internal > {
1360
+ self . do_merge ( |parent, _child| parent)
1361
+ }
1362
+
1363
+ /// Merges the parent's key-value pair and both adjacent child nodes into
1364
+ /// the left child node and returns that child node.
1365
+ ///
1366
+ /// Panics unless we `.can_merge()`.
1367
+ pub fn merge_tracking_child ( self ) -> NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > {
1368
+ self . do_merge ( |_parent, child| child)
1369
+ }
1370
+
1371
+ /// Merges the parent's key-value pair and both adjacent child nodes into
1372
+ /// the left child node and returns the edge handle in that child node
1373
+ /// where the tracked child edge ended up,
1374
+ ///
1375
+ /// Panics unless we `.can_merge()`.
1376
+ pub fn merge_tracking_child_edge (
1377
+ self ,
1378
+ track_edge_idx : LeftOrRight < usize > ,
1379
+ ) -> Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: Edge > {
1380
+ let old_left_len = self . left_child . len ( ) ;
1381
+ let right_len = self . right_child . len ( ) ;
1382
+ assert ! ( match track_edge_idx {
1383
+ LeftOrRight :: Left ( idx) => idx <= old_left_len,
1384
+ LeftOrRight :: Right ( idx) => idx <= right_len,
1385
+ } ) ;
1386
+ let child = self . merge_tracking_child ( ) ;
1387
+ let new_idx = match track_edge_idx {
1388
+ LeftOrRight :: Left ( idx) => idx,
1389
+ LeftOrRight :: Right ( idx) => old_left_len + 1 + idx,
1390
+ } ;
1391
+ unsafe { Handle :: new_edge ( child, new_idx) }
1364
1392
}
1365
1393
1366
1394
/// Removes a key-value pair from the left child and places it in the key-value storage
0 commit comments