diff --git a/pkg/local_object_storage/blobovnicza/sizes.go b/pkg/local_object_storage/blobovnicza/sizes.go index 5b89760c..82454fa2 100644 --- a/pkg/local_object_storage/blobovnicza/sizes.go +++ b/pkg/local_object_storage/blobovnicza/sizes.go @@ -3,6 +3,7 @@ package blobovnicza import ( "encoding/binary" "fmt" + "math/bits" "strconv" ) @@ -31,11 +32,11 @@ func bucketForSize(sz uint64) []byte { return bucketKeyFromBounds(upperPowerOfTwo(sz)) } -func upperPowerOfTwo(v uint64) (upperBound uint64) { - for upperBound = firstBucketBound; upperBound < v; upperBound *= 2 { +func upperPowerOfTwo(v uint64) uint64 { + if v <= firstBucketBound { + return firstBucketBound } - - return + return 1 << bits.Len64(v-1) } func (b *Blobovnicza) incSize(sz uint64) { diff --git a/pkg/local_object_storage/blobovnicza/sizes_test.go b/pkg/local_object_storage/blobovnicza/sizes_test.go index c218dc63..2bf451f1 100644 --- a/pkg/local_object_storage/blobovnicza/sizes_test.go +++ b/pkg/local_object_storage/blobovnicza/sizes_test.go @@ -1,6 +1,7 @@ package blobovnicza import ( + "fmt" "testing" "github.com/stretchr/testify/require" @@ -36,3 +37,13 @@ func TestSizes(t *testing.T) { require.Equal(t, bucketKeyFromBounds(item.upperBound), bucketForSize(item.sz)) } } + +func BenchmarkUpperBound(b *testing.B) { + for _, size := range []uint64{1, 1023, 65 * 1024, 40 * 1024 * 1024} { + b.Run(fmt.Sprintf("size=%d", size), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = upperPowerOfTwo(size) + } + }) + } +}