private List <SDDC> DetermineToDoRanges(long fileSize, List <SDDC> alreadyDoneRanges) { var result = new List <SDDC>(); var initialRange = new SDDC(0, fileSize); result.Add(initialRange); if (alreadyDoneRanges != null && alreadyDoneRanges.Count > 0) { foreach (var range in alreadyDoneRanges) { var newResult = new List <SDDC>(result); foreach (var resultRange in result) { if (this.SDDataContainerHelper.RangesCollide(range, resultRange)) { newResult.Remove(resultRange); var difference = this.SDDataContainerHelper.RangeDifference(resultRange, range); newResult.AddRange(difference); } } result = newResult; } } return(result); }
public List <SDDC> RangeDifference(SDDC fullRange, SDDC range) { var result = new List <SDDC>(); // no intersection if (!RangesCollide(fullRange, range)) { result.Add(fullRange); return(result); } // fullRange is part of range --> difference is empty if (fullRange.Start >= range.Start && fullRange.End <= range.End) { return(result); } if (fullRange.Start < range.Start) { result.Add(new SDDC(fullRange.Start, range.Start - fullRange.Start)); } if (fullRange.End > range.End) { result.Add(new SDDC(range.End + 1, fullRange.End - range.End)); } return(result); }
private void StartDownload(SDDC range) { var download = this.downloadBuilder.Build(this.url, this.bufferSize, range.Start, range.Length); download.DataReceived += downloadDataReceived; download.DownloadCancelled += downloadCancelled; download.DownloadCompleted += downloadCompleted; download.Start(); lock (this.monitor) { this.downloads.Add(download, range); } }
private void downloadDataReceived(SDDataReceivedEventArgs args) { var offset = args.Offset; var count = args.Count; var data = args.Data; lock (this.monitor) { var justDownloadedRange = new SDDC(offset, count); var todoRange = this.ToDoRanges.Single(r => SDDataContainerHelper.RangesCollide(r, justDownloadedRange)); this.ToDoRanges.Remove(todoRange); var differences = SDDataContainerHelper.RangeDifference(todoRange, justDownloadedRange); this.ToDoRanges.AddRange(differences); var alreadyDoneRange = this.AlreadyDownloadedRanges.FirstOrDefault(r => r.End + 1 == justDownloadedRange.Start); if (alreadyDoneRange == null) { alreadyDoneRange = justDownloadedRange; this.AlreadyDownloadedRanges.Add(alreadyDoneRange); } else { alreadyDoneRange.Length += justDownloadedRange.Length; } var neighborRange = this.AlreadyDownloadedRanges.FirstOrDefault(r => r.Start == alreadyDoneRange.End + 1); if (neighborRange != null) { this.AlreadyDownloadedRanges.Remove(alreadyDoneRange); this.AlreadyDownloadedRanges.Remove(neighborRange); var combinedRange = new SDDC(alreadyDoneRange.Start, alreadyDoneRange.Length + neighborRange.Length); this.AlreadyDownloadedRanges.Add(combinedRange); } } this.OnDataReceived(new SDDataReceivedEventArgs(this, data, offset, count)); }
private void StartDownloadOfNextRange() { SDDC nextRange = null; lock (this.monitor) { nextRange = this.ToDoRanges.FirstOrDefault(r => !this.downloads.Values.Any(r2 => SDDataContainerHelper.RangesCollide(r, r2))); } if (nextRange != null) { StartDownload(nextRange); } if (!this.downloads.Any()) { lock (this.monitor) { this.state = SDState.Finished; } this.OnDownloadCompleted(new SDEventArgs(this)); } }
public bool RangesCollide(SDDC range1, SDDC range2) { return(range1.Start <= range2.End && range2.Start <= range1.End); }