/// <summary> /// </summary> public void PruneTimeoutDownloads() { lock (ActiveBlockDownloads) { for (int i = 0; i < ActiveBlockDownloads.Count; i++) { ManifestPendingDownloadBlock Download = ActiveBlockDownloads[i]; ulong Elapsed = TimeUtils.Ticks - Download.TimeStarted; if (Elapsed > BlockDownloadTimeout) { if (!Download.Recieved) { ActiveBlockDownloadSize -= Download.Size; Download.Recieved = true; ActiveBlockDownloads[i] = Download; Logger.Log(LogLevel.Warning, LogCategory.Manifest, "Pruned active download as it timed out: manifest={0} block={1}", Download.ManifestId.ToString(), Download.BlockIndex); } ActiveBlockDownloads.RemoveAt(i); i--; } } } }
/// <summary> /// </summary> public void RemoveActiveBlockDownload(Guid ManifestId, int BlockIndex, bool WasSuccess) { lock (ActiveBlockDownloads) { for (int i = 0; i < ActiveBlockDownloads.Count; i++) { ManifestPendingDownloadBlock Download = ActiveBlockDownloads[i]; if (Download.BlockIndex == BlockIndex && Download.ManifestId == ManifestId) { if (!Download.Recieved) { if (WasSuccess) { UpdateLatency(Download); } ActiveBlockDownloadSize -= Download.Size; Download.Recieved = true; ActiveBlockDownloads[i] = Download; } //Console.WriteLine("Removing (for block {0} in manifest {1}) of size {2} total queued {3}.", Download.ManifestId, Download.BlockIndex, Download.Size, ActiveBlockDownloadSize); ActiveBlockDownloads.RemoveAt(i); break; } } } }
/// <summary> /// </summary> /// <param name="Block"></param> private void UpdateLatency(ManifestPendingDownloadBlock Download) { ulong Elapsed = TimeUtils.Ticks - Download.TimeStarted; //Console.WriteLine("Recieved block {0} in {1} ms", Download.BlockIndex, Elapsed); BlockRecieveLatency.Add(Elapsed); AverageBlockSize.Add(Download.Size); }
/// <summary> /// </summary> /// <param name="Block"></param> public void AddActiveBlockDownload(ManifestPendingDownloadBlock Block) { lock (ActiveBlockDownloads) { ActiveBlockDownloadSize += Block.Size; ActiveBlockDownloads.Add(Block); } }
/// <summary> /// </summary> /// <returns></returns> public bool HasBlock(ManifestPendingDownloadBlock Block) { foreach (ManifestBlockListState ManifestState in BlockState.States) { if (ManifestState.Id == Block.ManifestId) { return(ManifestState.BlockState.Get(Block.BlockIndex)); } } return(false); }
/// <summary> /// </summary> /// <param name=""></param> /// <returns></returns> public bool IsDownloadingBlock(ManifestPendingDownloadBlock Block) { lock (ActiveBlockDownloads) { foreach (ManifestPendingDownloadBlock Download in ActiveBlockDownloads) { if (Download.BlockIndex == Block.BlockIndex && Download.ManifestId == Block.ManifestId) { return(true); } } } return(false); }
/// <summary> /// </summary> /// <param name="ManifestId"></param> /// <param name="BlockIndex"></param> /// <returns></returns> public bool HasActiveBlockDownload(Guid ManifestId, int BlockIndex) { lock (ActiveBlockDownloads) { for (int i = 0; i < ActiveBlockDownloads.Count; i++) { ManifestPendingDownloadBlock Download = ActiveBlockDownloads[i]; if (Download.BlockIndex == BlockIndex && Download.ManifestId == ManifestId) { return(true); } } } return(false); }
/// <summary> /// </summary> /// <param name="ManifestId"></param> /// <param name="BlockIndex"></param> public void MarkActiveBlockDownloadAsRecieved(Guid ManifestId, int BlockIndex) { lock (ActiveBlockDownloads) { for (int i = 0; i < ActiveBlockDownloads.Count; i++) { ManifestPendingDownloadBlock Download = ActiveBlockDownloads[i]; if (Download.BlockIndex == BlockIndex && Download.ManifestId == ManifestId) { if (!Download.Recieved) { UpdateLatency(Download); ActiveBlockDownloadSize -= Download.Size; Download.Recieved = true; ActiveBlockDownloads[i] = Download; } break; } } } }
/// <summary> /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnPaint(object sender, PaintEventArgs e) { e.Graphics.FillRectangle(SystemBrushes.Window, 0, 0, Size.Width - 1, Size.Height - 1); ControlPaint.DrawBorder(e.Graphics, new Rectangle(0, 0, Size.Width, Size.Height), SystemColors.ControlLight, ButtonBorderStyle.Solid); // e.Graphics.DrawRectangle(SystemPens.ControlLight, 0, 0, Size.Width - 1, Size.Height - 1); if (State == null) { return; } ManifestDownloadState Downloader = Program.ManifestDownloadManager.GetDownload(State.ActiveManifestId); if (Downloader == null) { return; } if (Downloader.Manifest == null) { return; } int OuterPadding = 5; int CellSize = 7; int CellPadding = 3; int CellOveralSize = CellSize + CellPadding; int Rows = (int)Math.Floor((Size.Height - CellPadding * 2 - OuterPadding * 2) / (float)CellOveralSize); int Columns = (int)Math.Floor((Size.Width - CellPadding * 2 - OuterPadding * 2 - LegendWidth) / (float)CellOveralSize); int MaxCells = Rows * Columns; int CellCount = (int)Downloader.Manifest.BlockCount; int CellDivision = 1; while (CellCount > MaxCells) { CellDivision++; CellCount = ((int)Downloader.Manifest.BlockCount + (CellDivision - 1)) / CellDivision; } // Calculate states. Array.Resize(ref CellStates, CellCount); for (int Cell = 0; Cell < CellCount; Cell++) { CellStates[Cell] = CellState.NotDownloaded; int StartBlock = Cell * CellDivision; int EndBlock = StartBlock + (CellDivision - 1); // Has already been downloaded? for (int Block = StartBlock; Block <= EndBlock; Block++) { if (Downloader.BlockStates.Get(Block)) { CellStates[Cell] = CellState.Downloaded; } } } // Is in download queue. for (int i = 0; i < Program.ManifestDownloadManager.DownloadQueue.Count; i++) { ManifestPendingDownloadBlock Item = Program.ManifestDownloadManager.DownloadQueue[i]; if (Item.ManifestId == State.ActiveManifestId) { int CellIndex = Item.BlockIndex / CellDivision; if (CellIndex < CellStates.Length) { CellStates[CellIndex] = CellState.Downloading; } } } // Grab most recent downloads. lock (Program.ManifestDownloadManager.RecentBlockChanges) { for (int i = 0; i < Program.ManifestDownloadManager.RecentBlockChanges.Count; i++) { ManifestRecentBlockChange Item = Program.ManifestDownloadManager.RecentBlockChanges[i]; if (Item.ManifestId == State.ActiveManifestId) { int CellIndex = Item.BlockIndex / CellDivision; if (CellIndex < CellStates.Length) { if (Item.Type == ManifestBlockChangeType.Upload) { CellStates[CellIndex] = CellState.Uploading; } else if (Item.Type == ManifestBlockChangeType.Validate) { CellStates[CellIndex] = CellState.Validating; } } } } } for (int Cell = 0; Cell < CellCount; Cell++) { int RowIndex = Cell / Columns; int ColumnIndex = Cell % Columns; int CellX = ColumnIndex * CellOveralSize + CellPadding + OuterPadding; int CellY = RowIndex * CellOveralSize + CellPadding + OuterPadding; CellState State = CellStates[Cell]; Brush FillBrush = CellStateBrushes[(int)State]; e.Graphics.FillRectangle(FillBrush, CellX, CellY, CellSize, CellSize); e.Graphics.DrawRectangle(SystemPens.ActiveBorder, CellX, CellY, CellSize, CellSize); } // Draw the legend. int LegendX = Size.Width - LegendWidth - OuterPadding; int LegendY = OuterPadding + 5; //e.Graphics.DrawString("Legend", SystemFonts.DefaultFont, Brushes.Black, LegendX, LegendY); //LegendY += 20; for (int i = 0; i < (int)CellState.Max; i++) { Brush FillBrush = CellStateBrushes[i]; e.Graphics.FillRectangle(FillBrush, LegendX, LegendY, CellSize, CellSize); e.Graphics.DrawRectangle(SystemPens.ActiveBorder, LegendX, LegendY, CellSize, CellSize); e.Graphics.DrawString(CellStateNames[i], SystemFonts.DefaultFont, Brushes.Black, LegendX + CellSize + CellPadding, LegendY - 3); LegendY += 16; } }
/// <summary> /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnPaint(object sender, PaintEventArgs e) { if (!Active) { return; } if (UseOuterBorder) { e.Graphics.FillRectangle(SystemBrushes.Window, 0, 0, Size.Width - 1, Size.Height - 1); ControlPaint.DrawBorder(e.Graphics, new Rectangle(0, 0, Size.Width, Size.Height), SystemColors.ControlLight, ButtonBorderStyle.Solid); } long BlockCount = 0; SparseStateArray StateArray = null; if (State != null) { ManifestDownloadState Downloader = Program.ManifestDownloadManager.GetDownload(State.ActiveManifestId); if (Downloader == null) { return; } if (Downloader.Manifest == null) { return; } BlockCount = Downloader.Manifest.BlockCount; StateArray = Downloader.BlockStates; } else if (ManifestBlockState != null) { StateArray = ManifestBlockState.BlockState; BlockCount = StateArray.Size; } if (StateArray == null) { return; } int OuterPadding = UseOuterBorder ? 8 : 0; int BarX = OuterPadding; int BarY = OuterPadding; int BarWidth = Size.Width - (OuterPadding * 2); int BarHeight = Size.Height - (OuterPadding * 2); int MaxCells = BarWidth / 4; int CellCount = (int)BlockCount; int CellDivision = 1; while (CellCount > MaxCells) { CellDivision++; CellCount = ((int)BlockCount + (CellDivision - 1)) / CellDivision; } // Calculate states. Array.Resize(ref CellStates, CellCount); for (int Cell = 0; Cell < CellCount; Cell++) { CellStates[Cell] = CellState.NotDownloaded; } if (StateArray.Ranges != null) { foreach (SparseStateArray.Range Range in StateArray.Ranges) { if (Range.State) { for (int i = Range.Start; i <= Range.End; i++) { CellStates[i / CellDivision] = CellState.Downloaded; } } } } if (ApplyLocalStates) { // Is in download queue. for (int i = 0; i < Program.ManifestDownloadManager.DownloadQueue.Count; i++) { ManifestPendingDownloadBlock Item = Program.ManifestDownloadManager.DownloadQueue[i]; if (Item.ManifestId == State.ActiveManifestId) { int CellIndex = Item.BlockIndex / CellDivision; if (CellIndex < CellStates.Length) { CellStates[CellIndex] = CellState.Downloading; } } } // Grab most recent downloads. lock (Program.ManifestDownloadManager.RecentBlockChanges) { for (int i = 0; i < Program.ManifestDownloadManager.RecentBlockChanges.Count; i++) { ManifestRecentBlockChange Item = Program.ManifestDownloadManager.RecentBlockChanges[i]; if (Item.ManifestId == State.ActiveManifestId) { int CellIndex = Item.BlockIndex / CellDivision; if (CellIndex < CellStates.Length) { if (Item.Type == ManifestBlockChangeType.Upload) { CellStates[CellIndex] = CellState.Uploading; } else if (Item.Type == ManifestBlockChangeType.Validate) { CellStates[CellIndex] = CellState.Validating; } } } } } } float Spacing = BarWidth / (float)CellCount; for (int Cell = 0; Cell < CellCount; Cell++) { float CellX = BarX + (Cell * Spacing); float CellY = BarY; CellState State = CellStates[Cell]; Brush FillBrush = CellStateBrushes[(int)State]; e.Graphics.FillRectangle(FillBrush, CellX, CellY, Spacing, BarHeight); } ControlPaint.DrawBorder(e.Graphics, new Rectangle(BarX, BarY, BarWidth, BarHeight), SystemColors.ActiveBorder, ButtonBorderStyle.Solid); }