/// <summary>
        /// Adds assigned download to <see cref="assignedDownloadsByHash"/> and helper structures <see cref="assignedDownloadsSorted"/> and <see cref="assignedHeadersByPeerId"/>.
        /// </summary>
        /// <remarks>Have to be locked by <see cref="assignedLock"/>.</remarks>
        /// <param name="assignment">The assignment.</param>
        private void AddAssignedDownloadLocked(AssignedDownload assignment)
        {
            this.assignedDownloadsByHash.Add(assignment.Header.HashBlock, assignment);

            // Add to assignedHeadersByPeerId.
            if (!this.assignedHeadersByPeerId.TryGetValue(assignment.PeerId, out List <ChainedHeader> headersForIds))
            {
                headersForIds = new List <ChainedHeader>();
                this.assignedHeadersByPeerId.Add(assignment.PeerId, headersForIds);
            }

            headersForIds.Add(assignment.Header);

            // Add to assignedDownloadsSorted.
            LinkedListNode <AssignedDownload> lastDownload = this.assignedDownloadsSorted.Last;

            if ((lastDownload == null) || (lastDownload.Value.Header.Height <= assignment.Header.Height))
            {
                assignment.LinkedListNode = this.assignedDownloadsSorted.AddLast(assignment);
            }
            else
            {
                LinkedListNode <AssignedDownload> current = lastDownload;

                while ((current.Previous != null) && (current.Previous.Value.Header.Height > assignment.Header.Height))
                {
                    current = current.Previous;
                }

                assignment.LinkedListNode = this.assignedDownloadsSorted.AddBefore(current, assignment);
            }
        }
Exemple #2
0
        /// <summary>Finds all blocks assigned to a given peer, removes assignments from <see cref="assignedDownloadsByHash"/> and returns removed assignments.</summary>
        /// <remarks>Have to be locked by <see cref="assignedLock"/>.</remarks>
        private Dictionary <int, List <ChainedHeader> > ReleaseAssignmentsLocked(int peerId)
        {
            var headersByJobId = new Dictionary <int, List <ChainedHeader> >();

            if (this.assignedHeadersByPeerId.TryGetValue(peerId, out List <ChainedHeader> headers))
            {
                var assignmentsToRemove = new List <AssignedDownload>(headers.Count);

                foreach (ChainedHeader header in headers)
                {
                    AssignedDownload assignment = this.assignedDownloadsByHash[header.HashBlock];

                    if (!headersByJobId.TryGetValue(assignment.JobId, out List <ChainedHeader> jobHeaders))
                    {
                        jobHeaders = new List <ChainedHeader>();
                        headersByJobId.Add(assignment.JobId, jobHeaders);
                    }

                    jobHeaders.Add(assignment.Header);

                    assignmentsToRemove.Add(assignment);

                    this.logger.LogTrace("Header '{0}' for job ID {1} was released from peer ID {2}.", header, assignment.JobId, peerId);
                }

                foreach (AssignedDownload assignment in assignmentsToRemove)
                {
                    this.RemoveAssignedDownloadLocked(assignment);
                }
            }

            return(headersByJobId);
        }
        /// <summary>
        /// Removes assigned download from <see cref="assignedDownloadsByHash"/> and helper structures <see cref="assignedDownloadsSorted"/> and <see cref="assignedHeadersByPeerId"/>.
        /// </summary>
        /// <remarks>Have to be locked by <see cref="assignedLock"/>.</remarks>
        /// <param name="assignment">Assignment that should be removed.</param>
        private void RemoveAssignedDownloadLocked(AssignedDownload assignment)
        {
            this.assignedDownloadsByHash.Remove(assignment.Header.HashBlock);

            List <ChainedHeader> headersForId = this.assignedHeadersByPeerId[assignment.PeerId];

            headersForId.Remove(assignment.Header);
            if (headersForId.Count == 0)
            {
                this.assignedHeadersByPeerId.Remove(assignment.PeerId);
            }

            this.assignedDownloadsSorted.Remove(assignment.LinkedListNode);
        }
Exemple #4
0
        /// <summary>
        /// Removes assigned download from <see cref="assignedDownloadsByHash"/> and helper structures <see cref="assignedDownloadsSorted"/> and <see cref="assignedHeadersByPeerId"/>.
        /// </summary>
        /// <remarks>Have to be locked by <see cref="assignedLock"/>.</remarks>
        /// <param name="assignment">Assignment that should be removed.</param>
        private void RemoveAssignedDownloadLocked(AssignedDownload assignment)
        {
            this.logger.LogTrace("({0}:'{1}')", nameof(assignment), assignment);

            this.assignedDownloadsByHash.Remove(assignment.Header.HashBlock);

            List <ChainedHeader> headersForId = this.assignedHeadersByPeerId[assignment.PeerId];

            headersForId.Remove(assignment.Header);
            if (headersForId.Count == 0)
            {
                this.assignedHeadersByPeerId.Remove(assignment.PeerId);
            }

            this.assignedDownloadsSorted.Remove(assignment.LinkedListNode);

            this.logger.LogTrace("(-)");
        }