@@ -16,22 +16,29 @@ limitations under the License.
1616
1717package cbt
1818
19- import "github.com/vmware-tanzu/velero/pkg/cbtservice"
19+ import (
20+ "math/bits"
21+
22+ "github.com/RoaringBitmap/roaring"
23+ )
2024
2125// Bitmap defines the methods to store and iterate the CBT bitmap
2226type Bitmap interface {
2327 // Set sets bits within the provided range
24- Set (cbtservice. Range )
28+ Set (uint64 , uint64 )
2529
2630 // SetFull sets all bits to the bitmap
2731 SetFull ()
2832
2933 // Snapshot returns snapshot of the bitmap
30- SourceID () string
34+ Snapshot () string
3135
3236 // ChangeID returns the changeID of the bitmap
3337 ChangeID () string
3438
39+ // VolumeID return ID of the volume from which the snapshot is taken
40+ VolumeID () string
41+
3542 // Iterator returns the iterator for the CBT Bitmap
3643 Iterator () Iterator
3744}
@@ -44,12 +51,107 @@ type Iterator interface {
4451 // Snapshot returns snapshot of the bitmap
4552 Snapshot () string
4653
54+ // VolumeID return ID of the volume from which the snapshot is taken
55+ VolumeID () string
56+
4757 // BlockSize returns the granularity of the bitmap
48- BlockSize () int
58+ BlockSize () uint
4959
5060 // Count returns the toal number of count in the bitmap
5161 Count () uint64
5262
5363 // Next returns the offset of the next set block and whether it comes to the end of the iteration
54- Next () (int64 , bool )
64+ Next () (uint64 , bool )
65+ }
66+
67+ const (
68+ InvalidOffset64 = ^ uint64 (0 )
69+ )
70+
71+ type bitmapImpl struct {
72+ bitmap * roaring.Bitmap
73+ blockSize uint
74+ blockSizeLog int
75+ length uint64
76+ snapshot string
77+ changeID string
78+ volumeID string
79+ }
80+
81+ type bitmapIterator struct {
82+ bitmapImpl
83+ iterator roaring.IntPeekable
84+ }
85+
86+ func NewBitmap (blockSize uint , length uint64 , snapshot string , changeID string , volumeID string ) Bitmap {
87+ return & bitmapImpl {
88+ bitmap : roaring .New (),
89+ blockSize : blockSize ,
90+ blockSizeLog : bits .Len (blockSize ) - 1 ,
91+ length : length ,
92+ snapshot : snapshot ,
93+ changeID : changeID ,
94+ volumeID : volumeID ,
95+ }
96+ }
97+
98+ func (c * bitmapImpl ) Set (offset , length uint64 ) {
99+ if offset >= c .length {
100+ return
101+ }
102+
103+ if offset + length > c .length {
104+ length = c .length - offset
105+ }
106+
107+ start := offset >> c .blockSizeLog
108+ end := uint64 ((offset + length + uint64 (c .blockSize ) - 1 ) >> c .blockSizeLog )
109+
110+ c .bitmap .AddRange (start , end )
111+ }
112+
113+ func (c * bitmapImpl ) SetFull () {
114+ start := uint64 (0 )
115+ end := uint64 ((c .length + uint64 (c .blockSize ) - 1 ) >> c .blockSizeLog )
116+
117+ c .bitmap .AddRange (start , end )
118+ }
119+
120+ func (c * bitmapImpl ) Snapshot () string {
121+ return c .snapshot
122+ }
123+
124+ func (c * bitmapImpl ) ChangeID () string {
125+ return c .changeID
126+ }
127+
128+ func (c * bitmapImpl ) VolumeID () string {
129+ return c .volumeID
130+ }
131+
132+ func (c * bitmapImpl ) Iterator () Iterator {
133+ if c .bitmap == nil {
134+ return nil
135+ }
136+
137+ return & bitmapIterator {
138+ bitmapImpl : * c ,
139+ iterator : c .bitmap .Iterator (),
140+ }
141+ }
142+
143+ func (c * bitmapIterator ) Next () (uint64 , bool ) {
144+ if ! c .iterator .HasNext () {
145+ return InvalidOffset64 , false
146+ }
147+
148+ return uint64 (c .iterator .Next ()) << c .blockSizeLog , true
149+ }
150+
151+ func (c * bitmapIterator ) Count () uint64 {
152+ return c .bitmap .GetCardinality ()
153+ }
154+
155+ func (c * bitmapIterator ) BlockSize () uint {
156+ return c .blockSize
55157}
0 commit comments