GetNeighborsEx returns the N closest distinct nodes to the name input in the circle.
(name string, n int, roles proto.ServerRoles)
| 302 | |
| 303 | // GetNeighborsEx returns the N closest distinct nodes to the name input in the circle. |
| 304 | func (c *Consistent) GetNeighborsEx(name string, n int, roles proto.ServerRoles) ([]proto.Node, error) { |
| 305 | c.RLock() |
| 306 | defer c.RUnlock() |
| 307 | c.cacheLock.RLock() |
| 308 | defer c.cacheLock.RUnlock() |
| 309 | |
| 310 | if len(c.circle) == 0 { |
| 311 | return nil, ErrEmptyCircle |
| 312 | } |
| 313 | |
| 314 | count := len(c.sortedHashes) / c.NumberOfReplicas |
| 315 | if count < n { |
| 316 | n = count |
| 317 | } |
| 318 | |
| 319 | var ( |
| 320 | key = hashKey(name) |
| 321 | i = c.search(key) |
| 322 | start = i |
| 323 | res = make([]proto.Node, 0, n) |
| 324 | elem = *c.circle[c.sortedHashes[i]] |
| 325 | ) |
| 326 | var noFilter = roles == nil || len(roles) == 0 |
| 327 | |
| 328 | if noFilter || roles.Contains(elem.Role) { |
| 329 | res = append(res, elem) |
| 330 | } |
| 331 | |
| 332 | if noFilter && len(res) == n { |
| 333 | return res, nil |
| 334 | } |
| 335 | |
| 336 | for i = start + 1; i != start; i++ { |
| 337 | if i >= len(c.sortedHashes) { |
| 338 | i = 0 |
| 339 | } |
| 340 | elem = *c.circle[c.sortedHashes[i]] |
| 341 | if noFilter || roles.Contains(elem.Role) { |
| 342 | if !sliceContainsMember(res, elem) { |
| 343 | res = append(res, elem) |
| 344 | } |
| 345 | } |
| 346 | if len(res) == n { |
| 347 | break |
| 348 | } |
| 349 | } |
| 350 | |
| 351 | return res, nil |
| 352 | } |
| 353 | |
| 354 | // GetNeighbors returns the N closest distinct nodes to the name input in the circle. |
| 355 | func (c *Consistent) GetNeighbors(name string, n int) ([]proto.Node, error) { |