1818
1919package resolver
2020
21+ import (
22+ "encoding/base64"
23+ "sort"
24+ "strings"
25+ )
26+
2127type addressMapEntry struct {
2228 addr Address
2329 value any
@@ -137,66 +143,61 @@ func (a *AddressMap) Values() []any {
137143 return ret
138144}
139145
140- type endpointNode struct {
141- addrs map [string ]struct {}
142- }
143-
144- // Equal returns whether the unordered set of addrs are the same between the
145- // endpoint nodes.
146- func (en * endpointNode ) Equal (en2 * endpointNode ) bool {
147- if len (en .addrs ) != len (en2 .addrs ) {
148- return false
149- }
150- for addr := range en .addrs {
151- if _ , ok := en2 .addrs [addr ]; ! ok {
152- return false
153- }
154- }
155- return true
156- }
157-
158- func toEndpointNode (endpoint Endpoint ) endpointNode {
159- en := make (map [string ]struct {})
160- for _ , addr := range endpoint .Addresses {
161- en [addr .Addr ] = struct {}{}
162- }
163- return endpointNode {
164- addrs : en ,
165- }
166- }
146+ type endpointMapKey string
167147
168148// EndpointMap is a map of endpoints to arbitrary values keyed on only the
169149// unordered set of address strings within an endpoint. This map is not thread
170150// safe, thus it is unsafe to access concurrently. Must be created via
171151// NewEndpointMap; do not construct directly.
172152type EndpointMap struct {
173- endpoints map [* endpointNode ]any
153+ endpoints map [endpointMapKey ]endpointData
154+ }
155+
156+ type endpointData struct {
157+ // decodedKey stores the original key to avoid decoding when iterating on
158+ // EndpointMap keys.
159+ decodedKey Endpoint
160+ value any
174161}
175162
176163// NewEndpointMap creates a new EndpointMap.
177164func NewEndpointMap () * EndpointMap {
178165 return & EndpointMap {
179- endpoints : make (map [* endpointNode ]any ),
166+ endpoints : make (map [endpointMapKey ]endpointData ),
167+ }
168+ }
169+
170+ // encodeEndpoint returns a string that uniquely identifies the unordered set of
171+ // addresses within an endpoint.
172+ func encodeEndpoint (e Endpoint ) endpointMapKey {
173+ addrs := make ([]string , 0 , len (e .Addresses ))
174+ // base64 encoding the address strings restricts the characters present
175+ // within the strings. This allows us to use a delimiter without the need of
176+ // escape characters.
177+ for _ , addr := range e .Addresses {
178+ addrs = append (addrs , base64 .StdEncoding .EncodeToString ([]byte (addr .Addr )))
180179 }
180+ sort .Strings (addrs )
181+ // " " should not appear in base64 encoded strings.
182+ return endpointMapKey (strings .Join (addrs , " " ))
181183}
182184
183185// Get returns the value for the address in the map, if present.
184186func (em * EndpointMap ) Get (e Endpoint ) (value any , ok bool ) {
185- en := toEndpointNode (e )
186- if endpoint := em . find ( en ); endpoint != nil {
187- return em . endpoints [ endpoint ] , true
187+ val , found := em . endpoints [ encodeEndpoint (e )]
188+ if found {
189+ return val . value , true
188190 }
189191 return nil , false
190192}
191193
192194// Set updates or adds the value to the address in the map.
193195func (em * EndpointMap ) Set (e Endpoint , value any ) {
194- en := toEndpointNode (e )
195- if endpoint := em .find ( en ); endpoint != nil {
196- em . endpoints [ endpoint ] = value
197- return
196+ en := encodeEndpoint (e )
197+ em .endpoints [ en ] = endpointData {
198+ decodedKey : Endpoint { Addresses : e . Addresses },
199+ value : value ,
198200 }
199- em .endpoints [& en ] = value
200201}
201202
202203// Len returns the number of entries in the map.
@@ -211,12 +212,8 @@ func (em *EndpointMap) Len() int {
211212// used for EndpointMap accesses.
212213func (em * EndpointMap ) Keys () []Endpoint {
213214 ret := make ([]Endpoint , 0 , len (em .endpoints ))
214- for en := range em .endpoints {
215- var endpoint Endpoint
216- for addr := range en .addrs {
217- endpoint .Addresses = append (endpoint .Addresses , Address {Addr : addr })
218- }
219- ret = append (ret , endpoint )
215+ for _ , en := range em .endpoints {
216+ ret = append (ret , en .decodedKey )
220217 }
221218 return ret
222219}
@@ -225,27 +222,13 @@ func (em *EndpointMap) Keys() []Endpoint {
225222func (em * EndpointMap ) Values () []any {
226223 ret := make ([]any , 0 , len (em .endpoints ))
227224 for _ , val := range em .endpoints {
228- ret = append (ret , val )
225+ ret = append (ret , val . value )
229226 }
230227 return ret
231228}
232229
233- // find returns a pointer to the endpoint node in em if the endpoint node is
234- // already present. If not found, nil is returned. The comparisons are done on
235- // the unordered set of addresses within an endpoint.
236- func (em EndpointMap ) find (e endpointNode ) * endpointNode {
237- for endpoint := range em .endpoints {
238- if e .Equal (endpoint ) {
239- return endpoint
240- }
241- }
242- return nil
243- }
244-
245230// Delete removes the specified endpoint from the map.
246231func (em * EndpointMap ) Delete (e Endpoint ) {
247- en := toEndpointNode (e )
248- if entry := em .find (en ); entry != nil {
249- delete (em .endpoints , entry )
250- }
232+ en := encodeEndpoint (e )
233+ delete (em .endpoints , en )
251234}
0 commit comments