@@ -40,7 +40,15 @@ proc new*(
4040 selfId: selfId, localNodeId: localNodeId.get (selfId), buckets: @ [], config: config
4141 )
4242
43+ func bucketCount (maxBuckets: int ): int =
44+ # # Buckets past the key length can never be reached, and at least one bucket
45+ # # is always needed.
46+ clamp (maxBuckets, 1 , IdLength * 8 )
47+
4348proc bucketIndex * (rtable: RoutingTable , key: Key ): int =
49+ # # Bucket index is the shared prefix length with `selfId`. Tables with fewer
50+ # # buckets than the key length don't rescale it: the last bucket absorbs every
51+ # # peer sharing at least that long a prefix.
4452 let
4553 selfHash =
4654 if rtable.config.selfIdPreHashed:
@@ -50,10 +58,7 @@ proc bucketIndex*(rtable: RoutingTable, key: Key): int =
5058 keyHash = key.hashFor (rtable.config.hasher)
5159 lz = xorDistance (selfHash, keyHash).leadingZeros
5260
53- if rtable.config.maxBuckets <= 1 :
54- return 0
55-
56- return min (((lz * rtable.config.maxBuckets) div 256 ), rtable.config.maxBuckets - 1 )
61+ min (lz, bucketCount (rtable.config.maxBuckets) - 1 )
5762
5863proc peerIndexInBucket (bucket: Bucket , nodeId: Key ): Opt [int ] =
5964 for i, p in bucket.peers:
@@ -209,9 +214,7 @@ proc randomKeyInBucket*(
209214 selfId: Key , bucketIndex: int , rng: Rng , maxBuckets: int = DefaultMaxBuckets
210215): Key =
211216 let
212- index = clamp (bucketIndex, 0 , (maxBuckets - 1 ))
213- buckets = max (1 , maxBuckets)
214- leadingZeros = index * 256 div buckets
217+ leadingZeros = clamp (bucketIndex, 0 , bucketCount (maxBuckets) - 1 )
215218 (byteIdx, rem) = divmod (leadingZeros, 8 )
216219 boundBitIdx = 7 - rem
217220
0 commit comments