normalizeWeights calculates the normalized weights for each endpoint in the given endpoints map. It returns a slice of endpointWithState structs, where each struct contains the picker for an endpoint and its corresponding weight. The function also returns the minimum weight among all endpoints. The
(endpoints *resolver.EndpointMap[*endpointState])
| 137 | // |
| 138 | // Must be called with a non-empty endpoints map. |
| 139 | func normalizeWeights(endpoints *resolver.EndpointMap[*endpointState]) ([]endpointInfo, float64) { |
| 140 | var weightSum uint32 |
| 141 | // Since attributes are explicitly ignored in the EndpointMap key, we need |
| 142 | // to iterate over the values to get the weights. |
| 143 | endpointVals := endpoints.Values() |
| 144 | for _, epState := range endpointVals { |
| 145 | weightSum += epState.weight |
| 146 | } |
| 147 | ret := make([]endpointInfo, 0, endpoints.Len()) |
| 148 | min := 1.0 |
| 149 | for _, epState := range endpointVals { |
| 150 | // (*endpointState).weight is set to 1 if the weight attribute is not |
| 151 | // found on the endpoint. And since this function is guaranteed to be |
| 152 | // called with a non-empty endpoints map, weightSum is guaranteed to be |
| 153 | // non-zero. So, we need not worry about divide by zero error here. |
| 154 | nw := float64(epState.weight) / float64(weightSum) |
| 155 | ret = append(ret, endpointInfo{ |
| 156 | hashKey: epState.hashKey, |
| 157 | scaledWeight: nw, |
| 158 | originalWeight: epState.weight, |
| 159 | }) |
| 160 | min = math.Min(min, nw) |
| 161 | } |
| 162 | // Sort the endpoints to return consistent results. |
| 163 | // |
| 164 | // Note: this might not be necessary, but this makes sure the ring is |
| 165 | // consistent as long as the endpoints are the same, for example, in cases |
| 166 | // where an endpoint is added and then removed, the RPCs will still pick the |
| 167 | // same old endpoint. |
| 168 | sort.Slice(ret, func(i, j int) bool { |
| 169 | return ret[i].hashKey < ret[j].hashKey |
| 170 | }) |
| 171 | return ret, min |
| 172 | } |
| 173 | |
| 174 | // pick does a binary search. It returns the item with smallest index i that |
| 175 | // r.items[i].hash >= h. |