package geo import "math" // Candidate is one region a guess may pick. Code is in the record // vocabulary ("" is the deployment's home); the caller has already // filtered to eligible, policy-allowed candidates. type Candidate struct { Code string Home bool AWSRegion string } // NearestWith returns the candidate nearest p, measured to each // candidate's AWS region through pointOf. // // - A candidate whose region has no point is left out. // - If the HOME is among cands and has no point, ok is false: picking // among the rest could choose a far region over an unmeasured near // home, and the home is where today's behaviour lives (spec ยง6.3). // - Distances are compared in whole kilometres. A tie goes to the home, // then to the lexically smallest code, so every console answers alike. func NearestWith(p Point, cands []Candidate, pointOf func(string) (Point, bool)) (code string, ok bool) { best := -1 bestKm := math.MaxInt for i, c := range cands { cp, has := pointOf(c.AWSRegion) if !has { if c.Home { return "", false } continue } km := int(math.Round(DistanceKm(p, cp))) switch { case best < 0, km < bestKm: case km == bestKm && better(c, cands[best]): default: continue } best, bestKm = i, km } if best < 0 { return "", false } return cands[best].Code, true } // better breaks an exact tie: the home first, then the smaller code. func better(a, b Candidate) bool { if a.Home != b.Home { return a.Home } return a.Code < b.Code }