[#245] blobovnicza: Fix initializing dimensional buckets

In previous implementation Blobovnicza could incorrectly initialize
dimensional buckets: if SmallSizeLimit = 2 ^ X + Y && Y < 2 ^ X, then
largest dimensional bucket was [2 ^ (X - 1) : 2 ^ X]. This was caused by an
incorrect condition for stopping the iterator along the dimensional
boundaries.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2020-12-14 12:25:05 +03:00 committed by Alex Vanin
parent 6814140a19
commit 91bea44a1a
2 changed files with 8 additions and 4 deletions

View file

@ -26,7 +26,9 @@ func (b *Blobovnicza) iterateBucketKeys(f func(uint64, uint64, []byte) (bool, er
} }
func (b *Blobovnicza) iterateBounds(f func(uint64, uint64) (bool, error)) error { func (b *Blobovnicza) iterateBounds(f func(uint64, uint64) (bool, error)) error {
for upper := firstBucketBound; upper <= max(b.objSizeLimit, firstBucketBound); upper *= 2 { objLimitBound := upperPowerOfTwo(b.objSizeLimit)
for upper := firstBucketBound; upper <= max(objLimitBound, firstBucketBound); upper *= 2 {
var lower uint64 var lower uint64
if upper == firstBucketBound { if upper == firstBucketBound {

View file

@ -31,12 +31,14 @@ func bucketKeyFromBounds(upperBound uint64) []byte {
} }
func bucketForSize(sz uint64) []byte { func bucketForSize(sz uint64) []byte {
var upperBound uint64 return bucketKeyFromBounds(upperPowerOfTwo(sz))
}
for upperBound = firstBucketBound; upperBound < sz; upperBound *= 2 { func upperPowerOfTwo(v uint64) (upperBound uint64) {
for upperBound = firstBucketBound; upperBound < v; upperBound *= 2 {
} }
return bucketKeyFromBounds(upperBound) return
} }
func (b *Blobovnicza) incSize(sz uint64) { func (b *Blobovnicza) incSize(sz uint64) {