add CBT bitmap implementation

Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
This commit is contained in:
Lyndon-Li
2026-04-21 09:50:53 +00:00
parent a1fd85c791
commit 26b125769e
6 changed files with 77 additions and 64 deletions
+6 -46
View File
@@ -20,50 +20,10 @@ import (
"math/bits"
"github.com/RoaringBitmap/roaring"
"github.com/vmware-tanzu/velero/pkg/uploader/cbt/types"
)
// Bitmap defines the methods to store and iterate the CBT bitmap
type Bitmap interface {
// Set sets bits within the provided range
Set(uint64, uint64)
// SetFull sets all bits to the bitmap
SetFull()
// Snapshot returns snapshot of the bitmap
Snapshot() string
// ChangeID returns the changeID of the bitmap
ChangeID() string
// VolumeID return ID of the volume from which the snapshot is taken
VolumeID() string
// Iterator returns the iterator for the CBT Bitmap
Iterator() Iterator
}
// Iterator defines the methods to iterate the CBT bitmap and query the associated information
type Iterator interface {
// ChangeID returns the changeID of the bitmap
ChangeID() string
// Snapshot returns snapshot of the bitmap
Snapshot() string
// VolumeID return ID of the volume from which the snapshot is taken
VolumeID() string
// BlockSize returns the granularity of the bitmap
BlockSize() uint
// Count returns the toal number of count in the bitmap
Count() uint64
// Next returns the offset of the next set block and whether it comes to the end of the iteration
Next() (uint64, bool)
}
const (
InvalidOffset64 = ^uint64(0)
)
@@ -83,7 +43,7 @@ type bitmapIterator struct {
iterator roaring.IntPeekable
}
func NewBitmap(blockSize uint, length uint64, snapshot string, changeID string, volumeID string) Bitmap {
func NewBitmap(blockSize uint, length uint64, snapshot string, changeID string, volumeID string) types.Bitmap {
return &bitmapImpl{
bitmap: roaring.New(),
blockSize: blockSize,
@@ -105,14 +65,14 @@ func (c *bitmapImpl) Set(offset, length uint64) {
}
start := offset >> c.blockSizeLog
end := uint64((offset + length + uint64(c.blockSize) - 1) >> c.blockSizeLog)
end := (offset + length + uint64(c.blockSize) - 1) >> c.blockSizeLog
c.bitmap.AddRange(start, end)
}
func (c *bitmapImpl) SetFull() {
start := uint64(0)
end := uint64((c.length + uint64(c.blockSize) - 1) >> c.blockSizeLog)
end := (c.length + uint64(c.blockSize) - 1) >> c.blockSizeLog
c.bitmap.AddRange(start, end)
}
@@ -129,7 +89,7 @@ func (c *bitmapImpl) VolumeID() string {
return c.volumeID
}
func (c *bitmapImpl) Iterator() Iterator {
func (c *bitmapImpl) Iterator() types.Iterator {
if c.bitmap == nil {
return nil
}
+2 -1
View File
@@ -22,10 +22,11 @@ import (
"github.com/pkg/errors"
"github.com/vmware-tanzu/velero/pkg/cbtservice"
"github.com/vmware-tanzu/velero/pkg/uploader/cbt/types"
)
// SetBitmapOrFull translates the allocated/changed blocks from CBT service to the given bitmap or set the bitmap to full when error happens
func SetBitmapOrFull(ctx context.Context, service cbtservice.Service, bitmap Bitmap) (err error) {
func SetBitmapOrFull(ctx context.Context, service cbtservice.Service, bitmap types.Bitmap) (err error) {
defer func() {
if err != nil {
bitmap.SetFull()
+3 -10
View File
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cbt_test
package cbt
import (
"context"
@@ -27,8 +27,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/cbtservice"
cbtservicemocks "github.com/vmware-tanzu/velero/pkg/cbtservice/mocks"
"github.com/vmware-tanzu/velero/pkg/uploader/cbt"
cbtmocks "github.com/vmware-tanzu/velero/pkg/uploader/cbt/mocks"
cbtmocks "github.com/vmware-tanzu/velero/pkg/uploader/cbt/types/mocks"
)
func TestSetBitmapOrFull(t *testing.T) {
@@ -126,13 +125,7 @@ func TestSetBitmapOrFull(t *testing.T) {
svc = svcMock
}
// Use type assertion to bypass gopls false positive on mock type
var bmp cbt.Bitmap
if bmpMock != nil {
bmp = interface{}(bmpMock).(cbt.Bitmap)
}
err := cbt.SetBitmapOrFull(context.Background(), svc, bmp)
err := SetBitmapOrFull(context.Background(), svc, bmpMock)
if tt.expectedErrStr != "" {
require.Error(t, err)
@@ -6,7 +6,7 @@ package mocks
import (
mock "github.com/stretchr/testify/mock"
"github.com/vmware-tanzu/velero/pkg/uploader/cbt"
"github.com/vmware-tanzu/velero/pkg/uploader/cbt/types"
)
// NewBitmap creates a new instance of Bitmap. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
@@ -81,19 +81,19 @@ func (_c *Bitmap_ChangeID_Call) RunAndReturn(run func() string) *Bitmap_ChangeID
}
// Iterator provides a mock function for the type Bitmap
func (_mock *Bitmap) Iterator() cbt.Iterator {
func (_mock *Bitmap) Iterator() types.Iterator {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for Iterator")
}
var r0 cbt.Iterator
if returnFunc, ok := ret.Get(0).(func() cbt.Iterator); ok {
var r0 types.Iterator
if returnFunc, ok := ret.Get(0).(func() types.Iterator); ok {
r0 = returnFunc()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(cbt.Iterator)
r0 = ret.Get(0).(types.Iterator)
}
}
return r0
@@ -116,12 +116,12 @@ func (_c *Bitmap_Iterator_Call) Run(run func()) *Bitmap_Iterator_Call {
return _c
}
func (_c *Bitmap_Iterator_Call) Return(iterator cbt.Iterator) *Bitmap_Iterator_Call {
func (_c *Bitmap_Iterator_Call) Return(iterator types.Iterator) *Bitmap_Iterator_Call {
_c.Call.Return(iterator)
return _c
}
func (_c *Bitmap_Iterator_Call) RunAndReturn(run func() cbt.Iterator) *Bitmap_Iterator_Call {
func (_c *Bitmap_Iterator_Call) RunAndReturn(run func() types.Iterator) *Bitmap_Iterator_Call {
_c.Call.Return(run)
return _c
}
+59
View File
@@ -0,0 +1,59 @@
/*
Copyright The Velero Contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package types
// Bitmap defines the methods to store and iterate the CBT bitmap
type Bitmap interface {
// Set sets bits within the provided range
Set(uint64, uint64)
// SetFull sets all bits to the bitmap
SetFull()
// Snapshot returns snapshot of the bitmap
Snapshot() string
// ChangeID returns the changeID of the bitmap
ChangeID() string
// VolumeID return ID of the volume from which the snapshot is taken
VolumeID() string
// Iterator returns the iterator for the CBT Bitmap
Iterator() Iterator
}
// Iterator defines the methods to iterate the CBT bitmap and query the associated information
type Iterator interface {
// ChangeID returns the changeID of the bitmap
ChangeID() string
// Snapshot returns snapshot of the bitmap
Snapshot() string
// VolumeID return ID of the volume from which the snapshot is taken
VolumeID() string
// BlockSize returns the granularity of the bitmap
BlockSize() uint
// Count returns the toal number of count in the bitmap
Count() uint64
// Next returns the offset of the next set block and whether it comes to the end of the iteration
Next() (uint64, bool)
}