예제 #1
0
        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());
            }
        }
예제 #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();
            }
        }
예제 #3
0
 public RoutingTable(int bucketSize, DhtId localId, TimeSpan latency, IMetrics metrics)
 {
     Buckets     = new[] { new Bucket() };
     _bucketSize = bucketSize;
     _local      = localId;
     _maxLatency = latency;
     _metrics    = metrics;
     _tabLock    = new object();
 }
예제 #4
0
        public PeerId NearestPeer(DhtId id)
        {
            var peers = NearestPeers(id, 1);

            if (peers.Length > 0)
            {
                return(peers[0]);
            }

            return(null);
        }
예제 #5
0
        public PeerId Find(PeerId id)
        {
            var srch = NearestPeers(DhtId.ConvertPeerId(id), 1);

            if (srch.Length == 0 || srch[0] != id)
            {
                return(null);
            }

            return(srch[0]);
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        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();
                    }
                }
            }
        }
예제 #8
0
 public static IEnumerable <PeerId> SortClosestPeers(IEnumerable <PeerId> peers, DhtId target)
 {
     return(CopyPeersFromList(target, peers)
            .OrderBy(p => p.Distance, new DistanceComparer())
            .Select(p => p.P));
 }
예제 #9
0
 public static IEnumerable <PeerDistance> CopyPeersFromList(DhtId target, IEnumerable <PeerId> peers)
 {
     return(from peer in peers let pid = DhtId.ConvertPeerId(peer) select new PeerDistance {
         P = peer, Distance = ((byte[])target).XOR(pid)
     });
 }