示例#1
0
        public KadValue FindValue(KadId valueId)
        {
            if (Owner.Storage.Contains(valueId))
            {
                var storageVal = Owner.Storage.Get(valueId);
                if (Owner.IsValueExpired(storageVal))
                {
                    Owner.Storage.Remove(valueId);
                }
                else
                {
                    return(storageVal);
                }
            }

            SortedSet <KadContactNode>       shortList;
            Tuple <KadContactNode, KadValue> value = LookupValue(valueId, out shortList);

            if (value != null)
            {
                if (shortList.Min.Id != value.Item1.Id)
                {
                    Owner.StoreValue(shortList.Min, value.Item2);
                }

                Owner.Storage.Put(value.Item2);
            }

            return(value.Item2);
        }
示例#2
0
        private Tuple <KadContactNode, KadValue> LookupValue(KadId valueId, out SortedSet <KadContactNode> retSortList)
        {
            var closestNodes = Owner.BucketList.GetClosestNodes(valueId, MaxConcurrentThreads);
            SortedSet <KadContactNode> shortList = new SortedSet <KadContactNode>(closestNodes, new KadId.KadIdToBaseComparator(valueId));

            retSortList = shortList;
            if (shortList.Count == 0)
            {
                return(null);
            }

            SortedSet <KadId> queriedNodes   = new SortedSet <KadId>(new KadId.KadIdToIdComparator());
            KadId             closestId      = shortList.Min.Id;
            SemaphoreSlim     tasksSemaphore = new SemaphoreSlim(MaxConcurrentThreads);
            KadContactNode    returnedNode   = null;
            KadValue          value          = null;
            //Should do fine for small alpha
            List <Task> tasks = new List <Task>();

            while (queriedNodes.Count < ReplicationCount)
            {
                var shortListSnapshot = shortList.Where((n) => !queriedNodes.Contains(n.Id)).ToList();
                foreach (var node in shortListSnapshot)
                {
                    tasks.Add(Task.Run(() => {
                        var response = Owner.FindValue(node, valueId);
                        if (response != null)
                        {
                            if (response.Type == MessageType.FindNode)
                            {
                                foreach (var contact in response.Contacts)
                                {
                                    shortList.Add(contact);
                                }
                            }
                            else if (response.Type == MessageType.FindValue)
                            {
                                value        = new KadValue(valueId, DateTime.Now, response.Payload);
                                returnedNode = node;
                            }
                        }
                        tasksSemaphore.Release();
                    }));
                    queriedNodes.Add(node.Id);
                    tasksSemaphore.Wait();
                }

                Task.WaitAll(tasks.ToArray());
                tasks.Clear();

                if ((shortList.Min.Id ^ closestId) >= closestId)
                {
                    break;
                }

                closestId = shortList.Min.Id;
            }

            return(value != null ? new Tuple <KadContactNode, KadValue>(returnedNode, value) : null);
        }
示例#3
0
        /// <summary>
        /// Retrives value from other node
        /// </summary>
        /// <param name="node">Node to query</param>
        /// <param name="valId">Value id</param>
        /// <returns>Value if queried node has value, otherwise closest nodes to id</returns>
        public NodeMessage FindValue(KadContactNode node, KadId valId)
        {
            NodeMessage findValMsg = new NodeMessage.Builder()
                                     .SetType(MessageType.FindValue)
                                     .SetOriginator(Id)
                                     .SetIsRequest(true)
                                     .SetPayload(valId.Value)
                                     .Build();

            findValMsg.AddCallback(UpdateLastSeen);

            return(_server.SendMessageSync(node.EndPoint, findValMsg, TimeoutInMSec).Response);
        }
示例#4
0
        private IEnumerable <KadContactNode> LookupNode(KadId nodeId)
        {
            var closestNodes = Owner.BucketList.GetClosestNodes(nodeId, MaxConcurrentThreads);
            SortedSet <KadContactNode> shortList = new SortedSet <KadContactNode>(closestNodes, new KadId.KadIdToBaseComparator(nodeId));

            if (shortList.Count == 0)
            {
                return(shortList);
            }

            SortedSet <KadId> queriedNodes = new SortedSet <KadId>(new KadId.KadIdToIdComparator());
            KadId             closestId    = shortList.Min.Id;

            SemaphoreSlim tasksSemaphore = new SemaphoreSlim(MaxConcurrentThreads);

            List <Task> tasks = new List <Task>();

            while (queriedNodes.Count < ReplicationCount)
            {
                var shortListSnapshot = shortList.Where((n) => !queriedNodes.Contains(n.Id)).ToList();
                foreach (var node in shortListSnapshot)
                {
                    tasks.Add(Task.Run(() => {
                        var contacts = Owner.FindNode(node, nodeId);
                        foreach (var contact in contacts)
                        {
                            shortList.Add(contact);
                        }

                        tasksSemaphore.Release();
                    }));

                    tasksSemaphore.Wait();
                }

                Task.WaitAll(tasks.ToArray());
                tasks.Clear();

                if ((shortList.Min.Id ^ closestId) >= closestId)
                {
                    break;
                }

                closestId = shortList.Min.Id;
            }

            return(shortList.Take(ReplicationCount).ToList());
        }
示例#5
0
        public void RefreshBucket(KadId id)
        {
            var closestNodes = LookupNode(id);

            foreach (var contactNode in closestNodes)
            {
                switch (Owner.BucketList.Put(contactNode))
                {
                case Buckets.BucketList.BucketPutResult.BucketIsFull:
                    TryReplaceLeastSeenContactFromBucket(contactNode);
                    break;

                case Buckets.BucketList.BucketPutResult.Updated:
                case Buckets.BucketList.BucketPutResult.Success:
                    //Nothing to do here.
                    break;
                }
            }
        }
示例#6
0
        /// <summary>
        /// Find contact's closest nodes to id
        /// </summary>
        /// <param name="node">Node to query</param>
        /// <param name="id">Id to compare</param>
        /// <returns>Closest nodes to id</returns>
        public IEnumerable <KadContactNode> FindNode(KadContactNode node, KadId id)
        {
            NodeMessage msg = new NodeMessage.Builder()
                              .SetType(MessageType.FindNode)
                              .SetOriginator(Id)
                              .SetIsRequest(true)
                              .SetPayload(id.Value)
                              .Build();

            NodeMessage response = _server.SendMessageSync(node.EndPoint, msg, TimeoutInMSec).Response;

            msg.AddCallback(UpdateLastSeen);
            if (response != null)
            {
                return(new List <KadContactNode>(response.Contacts));
            }

            return(new List <KadContactNode>());
        }
示例#7
0
        public void RefreshUnaccessedBuckets()
        {
            SortedSet <Buckets.Bucket> sortedBuckets = new SortedSet <Buckets.Bucket>(Owner.BucketList.Buckets, new Buckets.Bucket.ByLastUpdatedComparer());

            foreach (var bucket in sortedBuckets)
            {
                if ((DateTime.UtcNow - bucket.LastUpdated).TotalSeconds > BucketsRefreshInSecs)
                {
                    byte[] intBytes = BitConverter.GetBytes(bucket.Id);
                    byte[] idBytes  = new byte[ReplicationCount];
                    Buffer.BlockCopy(intBytes, 0, idBytes, 0, intBytes.Length);
                    KadId bucketId = new KadId(idBytes);
                    RefreshBucket(bucketId);
                }
                else
                {
                    break;
                }
            }
        }
示例#8
0
 public KadContactNode(KadId id, IPEndPoint endPoint)
 {
     Id       = id;
     EndPoint = endPoint;
 }
示例#9
0
        /// <summary>
        /// Pings other node
        /// </summary>
        /// <param name="id">Node id to ping</param>
        /// <returns></returns>
        public NodeMessage Ping(KadId id)
        {
            var bucket = BucketList.GetBucket(id);

            return(Ping(bucket.GetNode(id)));
        }
示例#10
0
 public KadNode(IPEndPoint ipEndpoint, KadId id)
 {
     Id = id;
     InitNode(ipEndpoint);
 }
示例#11
0
 public KadNode(IPEndPoint ipEndpoint)
 {
     Id = KadId.GenerateRandom();
     InitNode(ipEndpoint);
 }
示例#12
0
        /// <summary>
        /// Processes request from other node. Used by NodeServer class
        /// </summary>
        /// <param name="msg">Request to process</param>
        /// <param name="origAddress">Request originator adress</param>
        public void ProcessRequest(NodeMessage msg, IPEndPoint origAddress)
        {
            switch (msg.Type)
            {
            case MessageType.Ping: {     //TODO: handle cases when bucket is full, etc
                NodeMessage respMsg = new NodeMessage.Builder()
                                      .SetType(MessageType.Ping)
                                      .SetOriginator(Id)
                                      .SetSeq(msg.Seq)
                                      .SetIsRequest(false)
                                      .Build();

                _server.SendMessage(origAddress, respMsg);
                break;
            }


            case MessageType.FindNode: {
                var         closestNodes = BucketList.GetClosestNodes(new KadId(msg.Payload), 20);
                NodeMessage respMsg      = new NodeMessage.Builder()
                                           .SetType(MessageType.FindNode)
                                           .SetSeq(msg.Seq)
                                           .SetOriginator(Id)
                                           .SetContacts(closestNodes)
                                           .Build();

                _server.SendMessage(origAddress, respMsg);
                break;
            }

            case MessageType.FindValue: {
                KadId valueId = new KadId(msg.Payload);

                NodeMessage.Builder msgBuilder = new NodeMessage.Builder()
                                                 .SetType(MessageType.FindValue)
                                                 .SetSeq(msg.Seq)
                                                 .SetOriginator(Id);

                if (Storage.Contains(valueId))
                {
                    msgBuilder.SetKadValueAsPayload(Storage.Get(valueId));
                }
                else
                {
                    var closestNodes = BucketList.GetClosestNodes(valueId, 20);
                    msgBuilder.SetContacts(closestNodes)
                    .SetType(MessageType.FindNode);
                }

                _server.SendMessage(origAddress, msgBuilder.Build());
                break;
            }

            case MessageType.CanStoreValue: {
                NodeMessage respMsg = new NodeMessage.Builder()
                                      .SetType(MessageType.CanStoreValue)
                                      .SetSeq(msg.Seq)
                                      .SetOriginator(Id)
                                      .SetIsRequest(false)
                                      .SetFlagAsPayload(!Storage.IsFull())
                                      .Build();

                _server.SendMessage(origAddress, respMsg);
                break;
            }

            case MessageType.StoreValue: {
                NodeMessage.Builder msgBuilder = new NodeMessage.Builder()
                                                 .SetSeq(msg.Seq)
                                                 .SetOriginator(Id)
                                                 .SetIsRequest(false)
                                                 .SetType(MessageType.CanStoreValue);

                if (Storage.IsFull())
                {
                    msgBuilder.SetFlagAsPayload(false);
                }
                else
                {
                    msgBuilder.SetFlagAsPayload(true);
                    Storage.Put(msg.Value);
                }

                _server.SendMessage(origAddress, msgBuilder.Build());
                break;
            }
            }

            UpdateLastSeen(msg);
        }
示例#13
0
        /// <summary>
        /// Retrives value from other node
        /// </summary>
        /// <param name="node">Node to query</param>
        /// <param name="valId">Value id</param>
        /// <returns>Value if queried node has value, otherwise closest nodes to id</returns>
        public NodeMessage FindValue(KadId id, KadId valId)
        {
            var bucket = BucketList.GetBucket(id);

            return(FindValue(bucket.GetNode(id), valId));
        }
示例#14
0
        /// <summary>
        /// Store value in contact
        /// </summary>
        /// <param name="node">Contact node</param>
        /// <param name="value">Value to store</param>
        /// <returns>true, if node stored value</returns>
        public bool StoreValue(KadId id, KadValue value)
        {
            var bucket = BucketList.GetBucket(id);

            return(StoreValue(bucket.GetNode(id), value));
        }
示例#15
0
        /// <summary>
        /// Find contact's closest nodes to id
        /// </summary>
        /// <param name="node">Node to query</param>
        /// <param name="id">Id to compare</param>
        /// <returns>Closest nodes to id</returns>
        public IEnumerable <KadContactNode> FindNode(KadId id, KadId idToFind)
        {
            var bucket = BucketList.GetBucket(id);

            return(FindNode(bucket.GetNode(id), idToFind));
        }
示例#16
0
 public KadIdToBaseComparator(KadId baseId)
 {
     _base = baseId;
 }