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());
            }
        }
Beispiel #2
0
        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();
                    }
                }
            }
        }