@@ -290,37 +290,71 @@ impl<BorrowType: marker::BorrowType, K, V>
290
290
}
291
291
}
292
292
293
- macro_rules! def_next_kv_uncheched_dealloc {
294
- { unsafe fn $name: ident : $adjacent_kv: ident } => {
295
- /// Given a leaf edge handle into an owned tree, returns a handle to the next KV,
296
- /// while deallocating any node left behind yet leaving the corresponding edge
297
- /// in its parent node dangling.
298
- ///
299
- /// # Safety
300
- /// - The leaf edge must not be the last one in the direction travelled.
301
- /// - The node carrying the next KV returned must not have been deallocated by a
302
- /// previous call on any handle obtained for this tree.
303
- unsafe fn $name <K , V >(
304
- leaf_edge: Handle <NodeRef <marker:: Dying , K , V , marker:: Leaf >, marker:: Edge >,
305
- ) -> Handle <NodeRef <marker:: Dying , K , V , marker:: LeafOrInternal >, marker:: KV > {
306
- let mut edge = leaf_edge. forget_node_type( ) ;
307
- loop {
308
- edge = match edge. $adjacent_kv( ) {
309
- Ok ( internal_kv) => return internal_kv,
310
- Err ( last_edge) => {
311
- unsafe {
312
- let parent_edge = last_edge. into_node( ) . deallocate_and_ascend( ) ;
313
- unwrap_unchecked( parent_edge) . forget_node_type( )
314
- }
315
- }
293
+ impl < K , V > Handle < NodeRef < marker:: Dying , K , V , marker:: Leaf > , marker:: Edge > {
294
+ /// Given a leaf edge handle into a dying tree, returns the next leaf edge
295
+ /// on the right side, and the key-value pair in between, which is either
296
+ /// in the same leaf node, in an ancestor node, or non-existent.
297
+ ///
298
+ /// This method also deallocates any node(s) it reaches the end of. This
299
+ /// implies that if no more key-value pair exists, the entire remainder of
300
+ /// the tree will have been deallocated and there is nothing left to return.
301
+ ///
302
+ /// # Safety
303
+ /// The next KV must not have been previously returned by counterpart `deallocating_next_back`.
304
+ unsafe fn deallocating_next ( self ) -> Option < ( Self , ( K , V ) ) > {
305
+ let mut edge = self . forget_node_type ( ) ;
306
+ loop {
307
+ edge = match edge. right_kv ( ) {
308
+ Ok ( kv) => {
309
+ let k = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 0 ) } ;
310
+ let v = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 1 ) } ;
311
+ return Some ( ( kv. next_leaf_edge ( ) , ( k, v) ) ) ;
316
312
}
313
+ Err ( last_edge) => match unsafe { last_edge. into_node ( ) . deallocate_and_ascend ( ) } {
314
+ Some ( parent_edge) => parent_edge. forget_node_type ( ) ,
315
+ None => return None ,
316
+ } ,
317
317
}
318
318
}
319
- } ;
320
- }
319
+ }
321
320
322
- def_next_kv_uncheched_dealloc ! { unsafe fn next_kv_unchecked_dealloc: right_kv}
323
- def_next_kv_uncheched_dealloc ! { unsafe fn next_back_kv_unchecked_dealloc: left_kv}
321
+ /// Given a leaf edge handle into a dying tree, returns the next leaf edge
322
+ /// on the left side, and the key-value pair in between, which is either
323
+ /// in the same leaf node, in an ancestor node, or non-existent.
324
+ ///
325
+ /// This method also deallocates any node(s) it reaches the end of. This
326
+ /// implies that if no more key-value pair exists, the entire remainder of
327
+ /// the tree will have been deallocated and there is nothing left to return.
328
+ ///
329
+ /// # Safety
330
+ /// The next KV must not have been previously returned by counterpart `deallocating_next`.
331
+ unsafe fn deallocating_next_back ( self ) -> Option < ( Self , ( K , V ) ) > {
332
+ let mut edge = self . forget_node_type ( ) ;
333
+ loop {
334
+ edge = match edge. left_kv ( ) {
335
+ Ok ( kv) => {
336
+ let k = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 0 ) } ;
337
+ let v = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 1 ) } ;
338
+ return Some ( ( kv. next_back_leaf_edge ( ) , ( k, v) ) ) ;
339
+ }
340
+ Err ( last_edge) => match unsafe { last_edge. into_node ( ) . deallocate_and_ascend ( ) } {
341
+ Some ( parent_edge) => parent_edge. forget_node_type ( ) ,
342
+ None => return None ,
343
+ } ,
344
+ }
345
+ }
346
+ }
347
+
348
+ /// Deallocates a pile of nodes from the leaf up to the root.
349
+ /// This is useful when `deallocating_next` and `deallocating_next_back`
350
+ /// have been nibbling at both sides of the same tree.
351
+ pub fn deallocating_end ( self ) {
352
+ let mut edge = self . forget_node_type ( ) ;
353
+ while let Some ( parent_edge) = unsafe { edge. into_node ( ) . deallocate_and_ascend ( ) } {
354
+ edge = parent_edge. forget_node_type ( ) ;
355
+ }
356
+ }
357
+ }
324
358
325
359
impl < ' a , K , V > Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > {
326
360
/// Moves the leaf edge handle to the next leaf edge and returns references to the
@@ -396,11 +430,8 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
396
430
/// call this method again subject to its safety conditions, or call counterpart
397
431
/// `next_back_unchecked` subject to its safety conditions.
398
432
pub unsafe fn next_unchecked ( & mut self ) -> ( K , V ) {
399
- super :: mem:: replace ( self , |leaf_edge| {
400
- let kv = unsafe { next_kv_unchecked_dealloc ( leaf_edge) } ;
401
- let k = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 0 ) } ;
402
- let v = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 1 ) } ;
403
- ( kv. next_leaf_edge ( ) , ( k, v) )
433
+ super :: mem:: replace ( self , |leaf_edge| unsafe {
434
+ unwrap_unchecked ( leaf_edge. deallocating_next ( ) )
404
435
} )
405
436
}
406
437
@@ -417,11 +448,8 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
417
448
/// call this method again subject to its safety conditions, or call counterpart
418
449
/// `next_unchecked` subject to its safety conditions.
419
450
pub unsafe fn next_back_unchecked ( & mut self ) -> ( K , V ) {
420
- super :: mem:: replace ( self , |leaf_edge| {
421
- let kv = unsafe { next_back_kv_unchecked_dealloc ( leaf_edge) } ;
422
- let k = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 0 ) } ;
423
- let v = unsafe { ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 1 ) } ;
424
- ( kv. next_back_leaf_edge ( ) , ( k, v) )
451
+ super :: mem:: replace ( self , |leaf_edge| unsafe {
452
+ unwrap_unchecked ( leaf_edge. deallocating_next_back ( ) )
425
453
} )
426
454
}
427
455
}
0 commit comments