コード例 #1
0
 /// <summary>
 /// Raised the <see cref="OnChanged"/> event.
 /// </summary>
 /// <param name="contact"></param>
 /// <param name="operation"></param>
 private void RaiseOnChanged(IContact contact, BucketOperation operation)
 {
     if (OnChanged != null)
     {
         OnChanged(contact, operation);
     }
 }
コード例 #2
0
        /// <summary>
        /// Raised the <see cref="OnChanged"/> event.
        /// </summary>
        /// <param name="contact"></param>
        /// <param name="operation"></param>
        private void RaiseOnChanged(IContact contact, BucketOperation operation)
        {
            if (contact == null)
            {
                throw new ArgumentNullException("contact");
            }

            if (OnChanged != null)
            {
                OnChanged(contact, operation);
            }
        }
コード例 #3
0
        /// <summary>
        /// Adds an <see cref="IContact" /> to the <see cref="Bucket" /> and maintains the sorting.
        /// </summary>
        /// <param name="contact"></param>
        public void Add(IContact contact)
        {
            if (contact == null)
            {
                throw new ArgumentNullException("contact");
            }

            // Prevent a Kademlia from registering himself as a contact
            if (contact.Equals(_owner.Contact))
            {
                return;
            }

            BucketOperation operation             = BucketOperation.Add;
            IContact        firstContact          = null;
            BucketOperation operationFirstContact = BucketOperation.Update;

            try
            {
                // Obtain lock
                _contactsReaderWriterLock.EnterWriteLock();

                // 2 cases:
                //   1. contact is in list
                //   2. contact is not in list
                if (_contacts.Remove(contact))
                {
                    operation = BucketOperation.Update;
                }

                // Check if there is space in the bucket
                // If we just successfully removed the bucket we know it is an update operation,
                // else it will be an add operation
                if (_contacts.Count < Constants.K)
                {
                    // There is space
                    _contacts.Add(contact);
                }
                else
                {
                    // There is not space, try to contact the least recently seen contact (located at the head)
                    firstContact = _contacts.First();

                    bool replyReceived = false;

                    try
                    {
                        using (NodeProxy nodeProxy = new NodeProxy(_owner, firstContact, false))
                        {
                            replyReceived = nodeProxy.Context.Ping();
                        }
                    }
                    catch (Exception) { { } }

                    // Remove the least recently seen contact from head
                    _contacts.Remove(firstContact);

                    if (replyReceived)
                    {
                        // It responded, so move it to the tail of the list, and issue an update event
                        operationFirstContact = BucketOperation.Update;
                        _contacts.Add(firstContact);

                        // This means that we discard the new contact
                        operation = BucketOperation.Discard;
                    }
                    else
                    {
                        // The least recently seen contact did not respond, so issue a remove event
                        // and add the new contact to the tail, as it is the most recently seen
                        operationFirstContact = BucketOperation.Remove;
                        _contacts.Add(contact);

                        // This means that we add the new contact
                        operation = BucketOperation.Add;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
            finally
            {
                // Release lock
                _contactsReaderWriterLock.ExitWriteLock();
            }

            if (firstContact != null)
            {
                RaiseOnChanged(firstContact, operationFirstContact);
            }
            RaiseOnChanged(contact, operation);
        }