public void CancelSegment(int index, Source src) { if (index < 0 || index >= _totalSegmentsCount) { throw new InvalidOperationException(); } lock (_syncRoot) { if (!_activeSegments[index]) { return; } _activeSegmentsCount--; _activeSegments[index] = false; ActiveSources.Remove(src); } OnSegmentCancelled(new SegmentEventArgs { SegmentInfo = new SegmentInfo { Index = index }, DownloadItem = this, Source = src }); }
public void FinishSegment(int index, Source src) { if (index < 0 || index >= _totalSegmentsCount) { throw new InvalidOperationException(); } bool downloadFinished; lock (_syncRoot) { if (!_activeSegments[index] || _downloadedSegments[index]) { return; } _activeSegmentsCount--; _activeSegments[index] = false; _doneSegmentsCount++; _downloadedSegments[index] = true; downloadFinished = _doneSegmentsCount == _totalSegmentsCount; ActiveSources.Remove(src); HighPrioritySegments.Remove(index); } OnSegmentFinished(new SegmentEventArgs { SegmentInfo = new SegmentInfo { Index = index }, DownloadItem = this, Source = src }); if (downloadFinished) { OnDownloadFinished(); } }
public bool TakeFreeSegment(Source src, out SegmentInfo segment) { segment.Index = -1; segment.Length = 0; segment.Position = 0; segment.StartPosition = -1; if (Priority == DownloadPriority.Pause) { Logger.Warn("Attemt to take segment on paused download item"); return(false); } if (StorageContainer == null) { Logger.Error("Unable to take the segment, no storage container is set"); return(false); } if (StorageContainer.FreeSegments <= 0) { return(false); } bool result = false; lock (_syncRoot) { if (TotalSegmentsCount == _activeSegmentsCount + _doneSegmentsCount) { return(false); } for (var i = 0; i < _highPrioritySegments.Count; i++) { var segIndex = _highPrioritySegments[i]; if (!_downloadedSegments[segIndex] && !_activeSegments[segIndex]) { segment.Index = segIndex; break; } } if (segment.Index == -1) { if (_highPrioritySegments.Count > 0) { // first try to download after the last high priority segment for (var i = _highPrioritySegments[_highPrioritySegments.Count - 1]; i < _totalSegmentsCount; i++) { if (!_downloadedSegments[i] && !_activeSegments[i]) { segment.Index = i; break; } } } if (segment.Index == -1) { for (var i = 0; i < _totalSegmentsCount; i++) { if (!_downloadedSegments[i] && !_activeSegments[i]) { segment.Index = i; break; } } } } if (segment.Index != -1) { segment.StartPosition = (long)segment.Index * _segmentLength; segment.Length = segment.Index == _totalSegmentsCount - 1 ? (int)(_magnet.Size % _segmentLength) : _segmentLength; _activeSegmentsCount++; _activeSegments[segment.Index] = true; _segmentSources[segment.Index] = src; ActiveSources.Add(src); result = true; } } if (result) { OnSegmentTaken(new SegmentEventArgs { SegmentInfo = segment, Source = src, DownloadItem = this }); } return(result); }