diff --git a/go.mod b/go.mod index 17f3221fb..717fcf57c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/longhorn/longhorn-instance-manager go 1.22.2 require ( - github.com/RoaringBitmap/roaring v1.9.4 github.com/google/uuid v1.6.0 github.com/longhorn/backupstore v0.0.0-20240823072635-7afd6aa10d3e github.com/longhorn/go-common-libs v0.0.0-20240821134112-907f57efd48f @@ -27,6 +26,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0 // indirect + github.com/RoaringBitmap/roaring v1.9.4 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.12.0 // indirect diff --git a/pkg/process/process_manager.go b/pkg/process/process_manager.go index 8e7b2c73a..e91d708d1 100644 --- a/pkg/process/process_manager.go +++ b/pkg/process/process_manager.go @@ -19,6 +19,7 @@ import ( "google.golang.org/protobuf/types/known/emptypb" "k8s.io/mount-utils" + lhBitmap "github.com/longhorn/go-common-libs/bitmap" lhKubernetes "github.com/longhorn/go-common-libs/kubernetes" lhLonghorn "github.com/longhorn/go-common-libs/longhorn" @@ -52,7 +53,7 @@ type Manager struct { processes map[string]*Process processUpdateCh chan *Process - availablePorts *util.Bitmap + availablePorts *lhBitmap.Bitmap logsDir string @@ -65,6 +66,11 @@ func NewManager(ctx context.Context, portRange string, logsDir string) (*Manager if err != nil { return nil, err } + bitmap, err := lhBitmap.NewBitmap(start, end) + if err != nil { + return nil, err + } + pm := &Manager{ ctx: ctx, portRangeMin: start, @@ -76,7 +82,7 @@ func NewManager(ctx context.Context, portRange string, logsDir string) (*Manager lock: &sync.RWMutex{}, processes: map[string]*Process{}, processUpdateCh: make(chan *Process), - availablePorts: util.NewBitmap(start, end), + availablePorts: bitmap, logsDir: logsDir, diff --git a/pkg/util/bitmap.go b/pkg/util/bitmap.go deleted file mode 100644 index 1d8fc8ef2..000000000 --- a/pkg/util/bitmap.go +++ /dev/null @@ -1,86 +0,0 @@ -package util - -import ( - "fmt" - "sync" - - "github.com/RoaringBitmap/roaring" -) - -type Bitmap struct { - base int32 - size int32 - data *roaring.Bitmap - lock *sync.Mutex -} - -// NewBitmap allocate a bitmap range from [start, end], notice the end is included -func NewBitmap(start, end int32) *Bitmap { - size := end - start + 1 - data := roaring.New() - if size > 0 { - data.AddRange(0, uint64(size)) - } - return &Bitmap{ - base: start, - size: size, - data: data, - lock: &sync.Mutex{}, - } -} - -func (b *Bitmap) AllocateRange(count int32) (int32, int32, error) { - b.lock.Lock() - defer b.lock.Unlock() - - if count <= 0 { - return 0, 0, fmt.Errorf("invalid request for non-positive counts: %v", count) - } - i := b.data.Iterator() - bStart := int32(0) - for bStart <= b.size { - last := int32(-1) - remains := count - for i.HasNext() && remains > 0 { - // first element - if last < 0 { - last = int32(i.Next()) - bStart = last - remains-- - continue - } - next := int32(i.Next()) - // failed to find the available range - if next-last > 1 { - break - } - last = next - remains-- - } - if remains == 0 { - break - } - if !i.HasNext() { - return 0, 0, fmt.Errorf("cannot find an empty port range") - } - } - bEnd := bStart + count - 1 - b.data.RemoveRange(uint64(bStart), uint64(bEnd)+1) - return b.base + bStart, b.base + bEnd, nil -} - -func (b *Bitmap) ReleaseRange(start, end int32) error { - b.lock.Lock() - defer b.lock.Unlock() - - if start == end && end == 0 { - return nil - } - bStart := start - b.base - bEnd := end - b.base - if bStart < 0 || bEnd >= b.size { - return fmt.Errorf("exceed range: %v-%v (%v-%v)", start, end, bStart, bEnd) - } - b.data.AddRange(uint64(bStart), uint64(bEnd)+1) - return nil -} diff --git a/pkg/util/bitmap_test.go b/pkg/util/bitmap_test.go deleted file mode 100644 index 6e05b3239..000000000 --- a/pkg/util/bitmap_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package util - -import ( - "testing" - - . "gopkg.in/check.v1" -) - -func Test(t *testing.T) { TestingT(t) } - -type TestSuite struct{} - -var _ = Suite(&TestSuite{}) - -func (s *TestSuite) TestBitmap(c *C) { - bm := NewBitmap(100, 200) - - start, end, err := bm.AllocateRange(100) - c.Assert(err, IsNil) - c.Assert(start, Equals, int32(100)) - c.Assert(end, Equals, int32(199)) - - start, end, err = bm.AllocateRange(1) - c.Assert(err, IsNil) - c.Assert(start, Equals, int32(200)) - c.Assert(end, Equals, int32(200)) - - _, _, err = bm.AllocateRange(1) - c.Assert(err, NotNil) - - err = bm.ReleaseRange(100, 100) - c.Assert(err, IsNil) - - start, end, err = bm.AllocateRange(1) - c.Assert(err, IsNil) - c.Assert(start, Equals, int32(100)) - c.Assert(end, Equals, int32(100)) - - err = bm.ReleaseRange(105, 120) - c.Assert(err, IsNil) - - start, end, err = bm.AllocateRange(15) - c.Assert(err, IsNil) - c.Assert(start, Equals, int32(105)) - c.Assert(end, Equals, int32(119)) - - _, _, err = bm.AllocateRange(2) - c.Assert(err, NotNil) - - start, end, err = bm.AllocateRange(1) - c.Assert(err, IsNil) - c.Assert(start, Equals, int32(120)) - c.Assert(end, Equals, int32(120)) -}