From 91bea44a1a5004d9f5311efb84a6fa4cbf8b4eb6 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 14 Dec 2020 12:25:05 +0300 Subject: [PATCH] [#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 --- pkg/local_object_storage/blobovnicza/iterate.go | 4 +++- pkg/local_object_storage/blobovnicza/sizes.go | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/local_object_storage/blobovnicza/iterate.go b/pkg/local_object_storage/blobovnicza/iterate.go index 18da2132c..e62c5bb94 100644 --- a/pkg/local_object_storage/blobovnicza/iterate.go +++ b/pkg/local_object_storage/blobovnicza/iterate.go @@ -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 { - 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 if upper == firstBucketBound { diff --git a/pkg/local_object_storage/blobovnicza/sizes.go b/pkg/local_object_storage/blobovnicza/sizes.go index 1bcee4bde..c304df56a 100644 --- a/pkg/local_object_storage/blobovnicza/sizes.go +++ b/pkg/local_object_storage/blobovnicza/sizes.go @@ -31,12 +31,14 @@ func bucketKeyFromBounds(upperBound 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) {