/// <summary> /// Returns an enumeration of all nodes in ascending order of distance from the given identifier /// </summary> /// <param name="identifier">The identifier.</param> /// <returns></returns> public IEnumerable <Contact> ClosestNodes(Identifier512 identifier) { int mid = Identifier512.CommonPrefixLength(identifier, LocalIdentifier); if (mid != 512) { foreach (var contact in buckets[mid].OrderWithComparer(new ContactComparer(identifier))) { yield return(contact); } } //loop through buckets, moving up and down from mid concatenating the two buckets either side of mid and returning them in order of distance List <Contact> contacts = new List <Contact>(); bool moreLow = true; bool moreHigh = true; for (int i = 1; moreHigh || moreLow; i++) { int indexHigh = mid + i; int indexLow = mid - i; contacts.Clear(); if (indexHigh >= buckets.Length) { moreHigh = false; } else { contacts.AddRange(buckets[indexHigh]); } if (indexLow < 0) { moreLow = false; } else { contacts.AddRange(buckets[indexLow]); } foreach (var contact in contacts.OrderWithComparer(new ContactComparer(identifier))) { yield return(contact); } } }
/// <summary> /// Moves the specified contact to the top of the most recently used queue /// </summary> /// <param name="source">The source.</param> internal void Update(Contact source) { if (Configuration.UpdateRoutingTable) { if (source == null) { return; } if (source.Identifier == LocalIdentifier) { return; } if (source.NetworkId != NetworkId) { throw new ArgumentException("Network Id of contact and ContactCollection must be the same"); } buckets[Identifier512.CommonPrefixLength(source.Identifier, LocalIdentifier)].Update(source); } }