public PeerId[] NearestPeers(DhtId id, int count) { var cpl = DhtId.CommonPrefixLength(id, _local); lock (_tabLock) { if (cpl >= Buckets.Length) { cpl = Buckets.Length - 1; } var bucket = Buckets[cpl]; var peers = Util.CopyPeersFromList(id, bucket.Peers); if (peers.Count() < count) { if (cpl > 0) { var plist = Buckets[cpl - 1].Peers; peers = Util.CopyPeersFromList(id, plist); } if (cpl < Buckets.Length - 1) { var plist = Buckets[cpl + 1].Peers; peers = Util.CopyPeersFromList(id, plist); } } return(peers.OrderBy(p => p.Distance, new Util.DistanceComparer()) .Take(count) .Select(p => p.P).ToArray()); } }
public Bucket Split(int cpl, DhtId target) { _rwlock.EnterWriteLock(); try { var output = new List <PeerId>(); var newBuck = new Bucket(output); foreach (var e in _list) { var peerId = DhtId.ConvertPeerId(e); var peerCpl = DhtId.CommonPrefixLength(peerId, target); if (peerCpl > cpl) { output.Add(e); } } _list.RemoveAll(output.Contains); return(newBuck); } finally { _rwlock.ExitWriteLock(); } }
public void Remove(PeerId p) { lock (_tabLock) { var peerId = DhtId.ConvertPeerId(p); var cpl = DhtId.CommonPrefixLength(peerId, _local); var bucketId = cpl; if (bucketId >= Buckets.Length) { bucketId = Buckets.Length - 1; } var bucket = Buckets[bucketId]; bucket.Remove(p); } }
public void Update(PeerId p) { var peerId = DhtId.ConvertPeerId(p); var cpl = DhtId.CommonPrefixLength(peerId, _local); lock (_tabLock) { var bucketId = cpl; if (bucketId >= Buckets.Length) { bucketId = Buckets.Length - 1; } var bucket = Buckets[bucketId]; if (bucket.Has(p)) { bucket.MoveToFront(p); return; } if (_metrics.LatencyEWMA(p) > _maxLatency) { return; } bucket.PushFront(p); if (bucket.Length > _bucketSize) { if (bucketId == Buckets.Length - 1) { NextBucket(); } else { bucket.PopBack(); } } } }