public void AddRequests(IReadOnlyList <IPeerWithMessaging> peers, BitField bitfield) { if (!RefreshAfterSeeking) { return; } RefreshAfterSeeking = true; var allPeers = peers .OrderBy(t => - t.DownloadSpeed) .ToArray(); // It's only worth cancelling requests for peers which support cancellation. This is part of // of the fast peer extensions. For peers which do not support cancellation all we can do is // close the connection or allow the existing request queue to drain naturally. var start = HighPriorityPieceIndex; var end = Math.Min(bitfield.Length - 1, start + HighPriorityCount - 1); if (bitfield.FirstFalse(start, end) != -1) { foreach (var peer in allPeers.Where(p => p.CanCancelRequests)) { if (HighPriorityPieceIndex > 0) { peer.EnqueueCancellations(Picker.CancelRequests(peer, 0, HighPriorityPieceIndex - 1)); } if (HighPriorityPieceIndex + HighPriorityCount < bitfield.Length) { peer.EnqueueCancellations(Picker.CancelRequests(peer, HighPriorityPieceIndex + HighPriorityCount, bitfield.Length - 1)); } } } var fastestPeers = allPeers .Where(t => t.DownloadSpeed > 50 * 1024) .ToArray(); // Queue up 12 pieces for each of our fastest peers. At a download // speed of 50kB/sec this should be 3 seconds of transfer for each peer. // We queue from peers which support cancellation first as their queue // is likely to be empty. foreach (var supportsFastPeer in new[] { true, false }) { for (int i = 0; i < 4; i++) { foreach (var peer in fastestPeers.Where(p => p.SupportsFastPeer == supportsFastPeer)) { AddRequests(peer, peers, bitfield, 0, bitfield.Length - 1, 2, 6); } } } // Then fill up the request queues for all peers foreach (var peer in peers) { AddRequests(peer, peers, bitfield); } }
public IList <BlockInfo> CancelRequests(IPeer peer, int startIndex, int endIndex) => Picker.CancelRequests(peer, startIndex, endIndex);