@@ -116,6 +116,18 @@ impl BucketIndex {
116116 self . 0
117117 }
118118
119+ /// Returns the minimum inclusive and maximum inclusive [`Distance`]
120+ /// included in the bucket for this index.
121+ fn range ( & self ) -> ( Distance , Distance ) {
122+ let min = Distance ( U256 :: pow ( U256 :: from ( 2 ) , U256 :: from ( self . 0 ) ) ) ;
123+ if self . 0 == u8:: MAX . into ( ) {
124+ ( min, Distance ( U256 :: MAX ) )
125+ } else {
126+ let max = Distance ( U256 :: pow ( U256 :: from ( 2 ) , U256 :: from ( self . 0 + 1 ) ) - 1 ) ;
127+ ( min, max)
128+ }
129+ }
130+
119131 /// Generates a random distance that falls into the bucket for this index.
120132 fn rand_distance ( & self , rng : & mut impl rand:: Rng ) -> Distance {
121133 let mut bytes = [ 0u8 ; 32 ] ;
@@ -447,6 +459,12 @@ where
447459 TKey : Clone + AsRef < KeyBytes > ,
448460 TVal : Clone
449461{
462+ /// Returns the minimum inclusive and maximum inclusive [`Distance`] for
463+ /// this bucket.
464+ pub fn range ( & self ) -> ( Distance , Distance ) {
465+ self . index . range ( )
466+ }
467+
450468 /// Checks whether the bucket is empty.
451469 pub fn is_empty ( & self ) -> bool {
452470 self . num_entries ( ) == 0
@@ -525,6 +543,47 @@ mod tests {
525543 }
526544 }
527545
546+ #[ test]
547+ fn buckets_are_non_overlapping_and_exhaustive ( ) {
548+ let local_key = Key :: from ( PeerId :: random ( ) ) ;
549+ let timeout = Duration :: from_secs ( 0 ) ;
550+ let mut table = KBucketsTable :: < KeyBytes , ( ) > :: new ( local_key. into ( ) , timeout) ;
551+
552+ let mut prev_max = U256 :: from ( 0 ) ;
553+
554+ for bucket in table. iter ( ) {
555+ let ( min, max) = bucket. range ( ) ;
556+ assert_eq ! ( Distance ( prev_max + U256 :: from( 1 ) ) , min) ;
557+ prev_max = max. 0 ;
558+ }
559+
560+ assert_eq ! ( U256 :: MAX , prev_max) ;
561+ }
562+
563+ #[ test]
564+ fn bucket_contains_range ( ) {
565+ fn prop ( ix : u8 ) {
566+ let index = BucketIndex ( ix as usize ) ;
567+ let mut bucket = KBucket :: < Key < PeerId > , ( ) > :: new ( Duration :: from_secs ( 0 ) ) ;
568+ let bucket_ref = KBucketRef {
569+ index,
570+ bucket : & mut bucket,
571+ } ;
572+
573+ let ( min, max) = bucket_ref. range ( ) ;
574+
575+ assert ! ( min <= max) ;
576+
577+ assert ! ( bucket_ref. contains( & min) ) ;
578+ assert ! ( bucket_ref. contains( & max) ) ;
579+
580+ assert ! ( !bucket_ref. contains( & Distance ( min. 0 - 1 ) ) ) ;
581+ assert ! ( !bucket_ref. contains( & Distance ( max. 0 + 1 ) ) ) ;
582+ }
583+
584+ quickcheck ( prop as fn ( _) ) ;
585+ }
586+
528587 #[ test]
529588 fn rand_distance ( ) {
530589 fn prop ( ix : u8 ) -> bool {
0 commit comments