227 lines
5.7 KiB
Go
227 lines
5.7 KiB
Go
package region
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"sync"
|
|
)
|
|
|
|
// NewRegionMapRange creates a new region map range for a zone
|
|
func NewRegionMapRange(zoneName string) *RegionMapRange {
|
|
return &RegionMapRange{
|
|
name: zoneName,
|
|
versionMap: make(map[*VersionRange]RegionMap),
|
|
}
|
|
}
|
|
|
|
// AddVersionRange adds a version-specific region map
|
|
func (rmr *RegionMapRange) AddVersionRange(minVersion, maxVersion int32, regionMap RegionMap) error {
|
|
rmr.mutex.Lock()
|
|
defer rmr.mutex.Unlock()
|
|
|
|
if regionMap == nil {
|
|
return fmt.Errorf("region map cannot be nil")
|
|
}
|
|
|
|
versionRange := &VersionRange{
|
|
MinVersion: minVersion,
|
|
MaxVersion: maxVersion,
|
|
}
|
|
|
|
rmr.versionMap[versionRange] = regionMap
|
|
|
|
log.Printf("[Region] Added version range [%d-%d] for zone '%s'",
|
|
minVersion, maxVersion, rmr.name)
|
|
|
|
return nil
|
|
}
|
|
|
|
// FindVersionRange finds a region map that supports the given version range
|
|
func (rmr *RegionMapRange) FindVersionRange(minVersion, maxVersion int32) (RegionMap, bool) {
|
|
rmr.mutex.RLock()
|
|
defer rmr.mutex.RUnlock()
|
|
|
|
for versionRange, regionMap := range rmr.versionMap {
|
|
// If min and max version are both in range
|
|
if versionRange.MinVersion <= minVersion && maxVersion <= versionRange.MaxVersion {
|
|
return regionMap, true
|
|
}
|
|
// If the min version is in range, but max range is 0 (unlimited)
|
|
if versionRange.MinVersion <= minVersion && versionRange.MaxVersion == 0 {
|
|
return regionMap, true
|
|
}
|
|
// If min version is 0 and max_version has a cap
|
|
if versionRange.MinVersion == 0 && maxVersion <= versionRange.MaxVersion {
|
|
return regionMap, true
|
|
}
|
|
}
|
|
|
|
return nil, false
|
|
}
|
|
|
|
// FindRegionByVersion finds a region map for a specific client version
|
|
func (rmr *RegionMapRange) FindRegionByVersion(version int32) RegionMap {
|
|
rmr.mutex.RLock()
|
|
defer rmr.mutex.RUnlock()
|
|
|
|
var fallbackMap RegionMap
|
|
|
|
for versionRange, regionMap := range rmr.versionMap {
|
|
// If min and max version are both 0, this is a fallback map
|
|
if versionRange.MinVersion == 0 && versionRange.MaxVersion == 0 {
|
|
fallbackMap = regionMap
|
|
continue
|
|
}
|
|
|
|
// Check if version is in range
|
|
if version >= versionRange.MinVersion {
|
|
// If MaxVersion is 0, it means unlimited
|
|
if versionRange.MaxVersion == 0 || version <= versionRange.MaxVersion {
|
|
return regionMap
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return fallback map if no specific version match
|
|
return fallbackMap
|
|
}
|
|
|
|
// GetAllVersionRanges returns all version ranges and their associated region maps
|
|
func (rmr *RegionMapRange) GetAllVersionRanges() map[*VersionRange]RegionMap {
|
|
rmr.mutex.RLock()
|
|
defer rmr.mutex.RUnlock()
|
|
|
|
// Return a copy to prevent external modification
|
|
result := make(map[*VersionRange]RegionMap)
|
|
for vr, rm := range rmr.versionMap {
|
|
result[vr] = rm
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// GetLoadedMapCount returns the number of loaded region maps
|
|
func (rmr *RegionMapRange) GetLoadedMapCount() int {
|
|
rmr.mutex.RLock()
|
|
defer rmr.mutex.RUnlock()
|
|
|
|
return len(rmr.versionMap)
|
|
}
|
|
|
|
// RemoveVersionRange removes a version range by its min/max versions
|
|
func (rmr *RegionMapRange) RemoveVersionRange(minVersion, maxVersion int32) bool {
|
|
rmr.mutex.Lock()
|
|
defer rmr.mutex.Unlock()
|
|
|
|
for versionRange := range rmr.versionMap {
|
|
if versionRange.MinVersion == minVersion && versionRange.MaxVersion == maxVersion {
|
|
delete(rmr.versionMap, versionRange)
|
|
log.Printf("[Region] Removed version range [%d-%d] for zone '%s'",
|
|
minVersion, maxVersion, rmr.name)
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// Clear removes all version ranges and region maps
|
|
func (rmr *RegionMapRange) Clear() {
|
|
rmr.mutex.Lock()
|
|
defer rmr.mutex.Unlock()
|
|
|
|
// Clear the map
|
|
for vr := range rmr.versionMap {
|
|
delete(rmr.versionMap, vr)
|
|
}
|
|
|
|
log.Printf("[Region] Cleared all version ranges for zone '%s'", rmr.name)
|
|
}
|
|
|
|
// GetName returns the zone name for this region map range
|
|
func (rmr *RegionMapRange) GetName() string {
|
|
return rmr.name
|
|
}
|
|
|
|
// GetMinVersion returns the minimum version supported by any region map
|
|
func (rmr *RegionMapRange) GetMinVersion() int32 {
|
|
rmr.mutex.RLock()
|
|
defer rmr.mutex.RUnlock()
|
|
|
|
if len(rmr.versionMap) == 0 {
|
|
return 0
|
|
}
|
|
|
|
minVersion := int32(999999) // Start with a high value
|
|
|
|
for versionRange := range rmr.versionMap {
|
|
if versionRange.MinVersion > 0 && versionRange.MinVersion < minVersion {
|
|
minVersion = versionRange.MinVersion
|
|
}
|
|
}
|
|
|
|
if minVersion == 999999 {
|
|
return 0 // No valid minimum found
|
|
}
|
|
|
|
return minVersion
|
|
}
|
|
|
|
// GetMaxVersion returns the maximum version supported by any region map
|
|
func (rmr *RegionMapRange) GetMaxVersion() int32 {
|
|
rmr.mutex.RLock()
|
|
defer rmr.mutex.RUnlock()
|
|
|
|
if len(rmr.versionMap) == 0 {
|
|
return 0
|
|
}
|
|
|
|
maxVersion := int32(0)
|
|
|
|
for versionRange := range rmr.versionMap {
|
|
if versionRange.MaxVersion > maxVersion {
|
|
maxVersion = versionRange.MaxVersion
|
|
}
|
|
}
|
|
|
|
return maxVersion
|
|
}
|
|
|
|
// NewVersionRange creates a new version range
|
|
func NewVersionRange(minVersion, maxVersion int32) *VersionRange {
|
|
return &VersionRange{
|
|
MinVersion: minVersion,
|
|
MaxVersion: maxVersion,
|
|
}
|
|
}
|
|
|
|
// GetMinVersion returns the minimum version for this range
|
|
func (vr *VersionRange) GetMinVersion() int32 {
|
|
return vr.MinVersion
|
|
}
|
|
|
|
// GetMaxVersion returns the maximum version for this range
|
|
func (vr *VersionRange) GetMaxVersion() int32 {
|
|
return vr.MaxVersion
|
|
}
|
|
|
|
// ContainsVersion checks if a version is within this range
|
|
func (vr *VersionRange) ContainsVersion(version int32) bool {
|
|
if vr.MinVersion > 0 && version < vr.MinVersion {
|
|
return false
|
|
}
|
|
|
|
if vr.MaxVersion > 0 && version > vr.MaxVersion {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// String returns a string representation of the version range
|
|
func (vr *VersionRange) String() string {
|
|
if vr.MaxVersion == 0 {
|
|
return fmt.Sprintf("[%d+]", vr.MinVersion)
|
|
}
|
|
return fmt.Sprintf("[%d-%d]", vr.MinVersion, vr.MaxVersion)
|
|
} |