eq2go/internal/zone/region/region_map_range.go
2025-08-06 14:39:39 -05:00

226 lines
5.7 KiB
Go

package region
import (
"fmt"
"log"
)
// 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)
}