package sandbox
import (
"fmt"
"sync"
"github.com/openeuler/Conch/pkg/ulog"
)
const (
MinCID = 3
MaxCID = uint32(4294967294)
)
type CIDAllocator struct {
mu sync.RWMutex
nextCID uint32
cidBySandbox map[string]uint32
}
func NewCIDAllocator() *CIDAllocator {
return &CIDAllocator{
nextCID: MinCID,
cidBySandbox: make(map[string]uint32),
}
}
func (a *CIDAllocator) AllocateCID(sandboxID string) (uint32, error) {
a.mu.Lock()
defer a.mu.Unlock()
if existingCID, ok := a.cidBySandbox[sandboxID]; ok {
return existingCID, nil
}
if a.nextCID > MaxCID {
return 0, fmt.Errorf("CID allocation failed: reached maximum CID limit (%d); current active sandboxes: %d",
MaxCID, len(a.cidBySandbox))
}
cid := a.nextCID
a.cidBySandbox[sandboxID] = cid
a.nextCID++
ulog.Info("allocated CID", ulog.F("sandbox_id", sandboxID), ulog.F("cid", cid))
return cid, nil
}
func (a *CIDAllocator) ReleaseCID(sandboxID string) error {
a.mu.Lock()
defer a.mu.Unlock()
delete(a.cidBySandbox, sandboxID)
return nil
}
func (a *CIDAllocator) GetCID(sandboxID string) (uint32, bool) {
a.mu.RLock()
defer a.mu.RUnlock()
cid, ok := a.cidBySandbox[sandboxID]
return cid, ok
}
func (a *CIDAllocator) GetActiveCount() int {
a.mu.RLock()
defer a.mu.RUnlock()
return len(a.cidBySandbox)
}
func (a *CIDAllocator) ListActiveSandboxes() []string {
a.mu.RLock()
defer a.mu.RUnlock()
sandboxIDs := make([]string, 0, len(a.cidBySandbox))
for sandboxID := range a.cidBySandbox {
sandboxIDs = append(sandboxIDs, sandboxID)
}
return sandboxIDs
}