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) }