/// <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); } }
/// <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); }
/// <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("(-)"); }