From 26b125769e65ef036cd0d85d3acd4f6ecea0d370 Mon Sep 17 00:00:00 2001 From: Lyndon-Li Date: Tue, 21 Apr 2026 17:46:29 +0800 Subject: [PATCH] add CBT bitmap implementation Signed-off-by: Lyndon-Li --- pkg/uploader/cbt/bitmap.go | 52 ++-------------- pkg/uploader/cbt/set.go | 3 +- pkg/uploader/cbt/set_test.go | 13 +--- pkg/uploader/cbt/{ => types}/mocks/Bitmap.go | 14 ++--- .../cbt/{ => types}/mocks/Iterator.go | 0 pkg/uploader/cbt/types/types.go | 59 +++++++++++++++++++ 6 files changed, 77 insertions(+), 64 deletions(-) rename pkg/uploader/cbt/{ => types}/mocks/Bitmap.go (94%) rename pkg/uploader/cbt/{ => types}/mocks/Iterator.go (100%) create mode 100644 pkg/uploader/cbt/types/types.go diff --git a/pkg/uploader/cbt/bitmap.go b/pkg/uploader/cbt/bitmap.go index 6defaf8b0..f26cb22b7 100644 --- a/pkg/uploader/cbt/bitmap.go +++ b/pkg/uploader/cbt/bitmap.go @@ -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 } diff --git a/pkg/uploader/cbt/set.go b/pkg/uploader/cbt/set.go index 93383076f..5919419e6 100644 --- a/pkg/uploader/cbt/set.go +++ b/pkg/uploader/cbt/set.go @@ -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() diff --git a/pkg/uploader/cbt/set_test.go b/pkg/uploader/cbt/set_test.go index c4a055cba..3bfbde1d4 100644 --- a/pkg/uploader/cbt/set_test.go +++ b/pkg/uploader/cbt/set_test.go @@ -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) diff --git a/pkg/uploader/cbt/mocks/Bitmap.go b/pkg/uploader/cbt/types/mocks/Bitmap.go similarity index 94% rename from pkg/uploader/cbt/mocks/Bitmap.go rename to pkg/uploader/cbt/types/mocks/Bitmap.go index 289c88215..faa4ee242 100644 --- a/pkg/uploader/cbt/mocks/Bitmap.go +++ b/pkg/uploader/cbt/types/mocks/Bitmap.go @@ -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 } diff --git a/pkg/uploader/cbt/mocks/Iterator.go b/pkg/uploader/cbt/types/mocks/Iterator.go similarity index 100% rename from pkg/uploader/cbt/mocks/Iterator.go rename to pkg/uploader/cbt/types/mocks/Iterator.go diff --git a/pkg/uploader/cbt/types/types.go b/pkg/uploader/cbt/types/types.go new file mode 100644 index 000000000..f512d7a8a --- /dev/null +++ b/pkg/uploader/cbt/types/types.go @@ -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) +}