@@ -74,20 +74,20 @@ pub enum Node<B, L> {
74
74
/// When executing against a `SnapshotBuilder`, it's a reference to a `NodeHash`,
75
75
/// which can in turn be used to retrieve the `Node`.
76
76
#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord ) ]
77
- pub enum NodeRef < V > {
78
- ModBranch ( Box < Branch < Self > > ) ,
77
+ pub enum NodeRef < ' s , V > {
78
+ ModBranch ( Box < Branch < ' s , Self > > ) ,
79
79
ModLeaf ( Box < Leaf < V > > ) ,
80
80
Stored ( stored:: Idx ) ,
81
81
}
82
82
83
- impl < V > NodeRef < V > {
83
+ impl < V > NodeRef < ' _ , V > {
84
84
#[ inline( always) ]
85
85
pub fn temp_null_stored ( ) -> Self {
86
86
NodeRef :: Stored ( u32:: MAX )
87
87
}
88
88
}
89
89
90
- impl < V > fmt:: Debug for NodeRef < V > {
90
+ impl < V > fmt:: Debug for NodeRef < ' _ , V > {
91
91
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
92
92
match self {
93
93
Self :: ModBranch ( b) => f. debug_tuple ( "ModBranch" ) . field ( b) . finish ( ) ,
@@ -97,7 +97,7 @@ impl<V> fmt::Debug for NodeRef<V> {
97
97
}
98
98
}
99
99
100
- impl < V > From < Box < Branch < NodeRef < V > > > > for NodeRef < V > {
100
+ impl < ' s , V > From < Box < Branch < ' s , NodeRef < ' s , V > > > > for NodeRef < ' s , V > {
101
101
#[ inline]
102
102
fn from ( branch : Box < Branch < NodeRef < V > > > ) -> Self {
103
103
NodeRef :: ModBranch ( branch)
@@ -263,7 +263,7 @@ mod tests {
263
263
}
264
264
}
265
265
266
- pub struct Prefix {
266
+ pub struct PrefixBufferRef {
267
267
/// This value will be 0 if the branch occurs in the first word of the hash key.
268
268
/// The value is the prior word if the branches parent's word index no more than 1 less.
269
269
/// If the parent's word index is more than 1 word prior,
@@ -272,7 +272,7 @@ pub struct Prefix {
272
272
prior_word_or_prefix_idx : u32 ,
273
273
}
274
274
275
- impl Prefix {
275
+ impl PrefixBufferRef {
276
276
pub fn get_prefix < ' s , ' txn : ' s > (
277
277
& ' s self ,
278
278
prefixies : & ' txn PrefixesBuffer ,
@@ -296,7 +296,7 @@ impl Prefix {
296
296
}
297
297
}
298
298
299
- #[ derive( Clone , PartialEq , Eq , PartialOrd , Ord ) ]
299
+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
300
300
pub struct PrefixesBuffer {
301
301
buffer : Vec < u32 > ,
302
302
}
@@ -318,21 +318,32 @@ impl PrefixesBuffer {
318
318
}
319
319
}
320
320
321
+ #[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
322
+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
323
+ pub enum PrefixCow < ' a > {
324
+ StartOfKey ,
325
+ PriorWord ( u32 ) ,
326
+ Segment ( & ' a [ u32 ] ) ,
327
+ SegmentOwned ( Box < [ u32 ] > ) ,
328
+ }
329
+
330
+ /// A branch node in the trie.
331
+ /// `NR` is the type of the node references.
332
+ /// `PR` is the type of reference to the prefix.
321
333
#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
322
334
#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord ) ]
323
- pub struct Branch < NR > {
335
+ pub struct Branch < ' s , NR > {
324
336
pub left : NR ,
325
337
pub right : NR ,
326
338
pub mask : BranchMask ,
327
- pub prefix : Prefix ,
339
+ pub prefix : PrefixCow < ' s > ,
328
340
}
329
341
330
- impl < NR > fmt:: Debug for Branch < NR > {
342
+ impl < NR > fmt:: Debug for Branch < ' _ , NR > {
331
343
#[ inline]
332
344
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
333
345
f. debug_struct ( "Branch" )
334
346
. field ( "mask" , & self . mask )
335
- . field ( "prior_word" , & self . prior_word )
336
347
. field ( "prefix" , & self . prefix )
337
348
. finish ( )
338
349
}
@@ -359,7 +370,7 @@ pub enum KeyPositionAdjacent {
359
370
PrefixVec ( usize ) ,
360
371
}
361
372
362
- impl < NR > Branch < NR > {
373
+ impl < NR > Branch < NR , PrefixCow < ' a > > {
363
374
/// Returns the position of the key relative to the branch.
364
375
#[ inline( always) ]
365
376
pub fn key_position ( & self , key_hash : & KeyHash ) -> KeyPosition {
@@ -424,19 +435,7 @@ impl<NR> Branch<NR> {
424
435
}
425
436
}
426
437
427
- impl < V > Branch < NodeRef < V > > {
428
- pub ( crate ) fn from_stored ( branch : & Branch < stored:: Idx > ) -> Branch < NodeRef < V > > {
429
- Branch {
430
- left : NodeRef :: Stored ( branch. left ) ,
431
- right : NodeRef :: Stored ( branch. right ) ,
432
- mask : branch. mask ,
433
- prior_word : branch. prior_word ,
434
- // TODO remove the clone
435
- // Maybe use a AsRef<[u32]> instead of Box<[u32]>
436
- prefix : branch. prefix . clone ( ) ,
437
- }
438
- }
439
-
438
+ impl < V , PR > Branch < NodeRef < V > , PR > {
440
439
/// A wrapper around `new_at_branch_ret` which returns nothing.
441
440
/// This exists to aid compiler inlining.
442
441
///
@@ -591,17 +590,19 @@ impl<V> Branch<NodeRef<V>> {
591
590
592
591
debug_assert ! ( new_leaf. key_hash. 0 [ ..word_idx] == old_leaf. as_ref( ) . key_hash. 0 [ ..word_idx] ) ;
593
592
594
- let prior_word_idx = word_idx. saturating_sub ( 1 ) ;
595
- let prefix = new_leaf. key_hash . 0 [ prefix_start_idx..prior_word_idx] . into ( ) ;
596
- let prior_word = if word_idx == 0 {
597
- 0
598
- } else {
593
+ let prefix = if word_idx == 0 {
594
+ PrefixCow :: StartOfKey
595
+ } else if prefix_start_idx == word_idx {
596
+ let prior_word_idx = word_idx - 1 ;
599
597
debug_assert_eq ! (
600
598
new_leaf. key_hash. 0 [ prior_word_idx] ,
601
599
old_leaf. as_ref( ) . key_hash. 0 [ prior_word_idx]
602
600
) ;
603
-
604
- new_leaf. key_hash . 0 [ prior_word_idx]
601
+ PrefixCow :: PriorWord ( new_leaf. key_hash . 0 [ prior_word_idx] )
602
+ } else if prefix_start_idx == word_idx - 1 {
603
+ PrefixCow :: PriorWord ( new_leaf. key_hash . 0 [ word_idx - 1 ] )
604
+ } else {
605
+ PrefixCow :: Segment ( & new_leaf. key_hash . 0 [ prefix_start_idx..word_idx] )
605
606
} ;
606
607
607
608
let mask = BranchMask :: new ( word_idx as u32 , a, b) ;
@@ -628,7 +629,6 @@ impl<V> Branch<NodeRef<V>> {
628
629
left,
629
630
right,
630
631
mask,
631
- prior_word,
632
632
prefix,
633
633
} ) ,
634
634
// TODO use an enum
0 commit comments