IList <BlockInfo> PriorityPick(IPeer peer, BitField available, IReadOnlyList <IPeer> otherPeers, int count, int startIndex, int endIndex)
        {
            BlockInfo?        request;
            IList <BlockInfo> bundle;

            if (HighPriorityPieceIndex >= startIndex && HighPriorityPieceIndex <= endIndex)
            {
                var start = HighPriorityPieceIndex;
                var end   = Math.Min(endIndex, HighPriorityPieceIndex + HighPriorityCount - 1);

                for (int prioritised = start; prioritised <= start + 1 && prioritised <= end; prioritised++)
                {
                    if (available[prioritised])
                    {
                        if ((bundle = HighPriorityPicker.PickPiece(peer, available, otherPeers, count, prioritised, prioritised)) != null)
                        {
                            return(bundle);
                        }
                        if ((request = HighPriorityPicker.ContinueAnyExistingRequest(peer, prioritised, prioritised, 3)) != null)
                        {
                            return new[] { request.Value }
                        }
                        ;
                    }
                }

                if ((bundle = HighPriorityPicker.PickPiece(peer, available, otherPeers, count, start, end)) != null)
                {
                    return(bundle);
                }
            }

            if (endIndex < HighPriorityPieceIndex)
            {
                return(null);
            }

            var lowPriorityEndIndex = Math.Min(HighPriorityPieceIndex + LowPriorityCount, endIndex);

            if ((bundle = LowPriorityPicker.PickPiece(peer, available, otherPeers, count, HighPriorityPieceIndex, lowPriorityEndIndex)) != null)
            {
                return(bundle);
            }

            // If we're downloading from the 'not important at all' section, queue up at most 2.
            if (peer.AmRequestingPiecesCount > 2)
            {
                return(null);
            }

            return(LowPriorityPicker.PickPiece(peer, available, otherPeers, count, HighPriorityPieceIndex, endIndex));
        }
        public void Initialise(ITorrentData torrentData, IReadOnlyList <BitField> ignoringBitfields)
        {
            TorrentData = torrentData;

            var standardPicker = new StandardPicker();

            HighPriorityPicker = IgnoringPicker.Wrap(new PriorityPicker(standardPicker), ignoringBitfields);

            LowPriorityPicker = new RandomisedPicker(standardPicker);
            LowPriorityPicker = new RarestFirstPicker(LowPriorityPicker);
            LowPriorityPicker = new PriorityPicker(LowPriorityPicker);
            LowPriorityPicker = IgnoringPicker.Wrap(LowPriorityPicker, ignoringBitfields);

            LowPriorityPicker.Initialise(torrentData);
            HighPriorityPicker.Initialise(torrentData);
        }
Пример #3
0
        int PriorityPick(IPeer peer, BitField available, IReadOnlyList <IPeer> otherPeers, int startIndex, int endIndex, Span <BlockInfo> requests)
        {
            BlockInfo?request;
            int       requestCount;

            if (HighPriorityPieceIndex >= startIndex && HighPriorityPieceIndex <= endIndex)
            {
                var start = HighPriorityPieceIndex;
                var end   = Math.Min(endIndex, HighPriorityPieceIndex + HighPriorityCount - 1);

                for (int prioritised = start; prioritised <= start + 1 && prioritised <= end; prioritised++)
                {
                    if (available[prioritised])
                    {
                        if ((requestCount = HighPriorityPicker.PickPiece(peer, available, otherPeers, prioritised, prioritised, requests)) > 0)
                        {
                            return(requestCount);
                        }
                        if ((request = HighPriorityPicker.ContinueAnyExistingRequest(peer, prioritised, prioritised, 3)) != null)
                        {
                            requests[0] = request.Value;
                            return(1);
                        }
                    }
                }

                if ((requestCount = HighPriorityPicker.PickPiece(peer, available, otherPeers, start, end, requests)) > 0)
                {
                    return(requestCount);
                }
            }

            var lowPriorityEndIndex = Math.Min(HighPriorityPieceIndex + LowPriorityCount, endIndex);

            if ((requestCount = LowPriorityPicker.PickPiece(peer, available, otherPeers, HighPriorityPieceIndex, lowPriorityEndIndex, requests)) > 0)
            {
                return(requestCount);
            }

            // If we're downloading from the 'not important at all' section, queue up at most 2.
            if (peer.AmRequestingPiecesCount < 2)
            {
                return(LowPriorityPicker.PickPiece(peer, available, otherPeers, startIndex, endIndex, requests));
            }

            return(0);
        }
        public void Initialise(ITorrentManagerInfo torrentData, IReadOnlyList <ReadOnlyBitField> ignoringBitfields)
        {
            TorrentData       = torrentData.TorrentInfo !;
            IgnoringBitfields = ignoringBitfields;
            Temp = new BitField(TorrentData.PieceCount());

            var standardPicker = new StandardPicker();

            HighPriorityPicker = IgnoringPicker.Wrap(new PriorityPicker(standardPicker), ignoringBitfields);

            LowPriorityPicker = new RandomisedPicker(standardPicker);
            LowPriorityPicker = new RarestFirstPicker(LowPriorityPicker);
            LowPriorityPicker = new PriorityPicker(LowPriorityPicker);
            LowPriorityPicker = IgnoringPicker.Wrap(LowPriorityPicker, ignoringBitfields);

            LowPriorityPicker.Initialise(torrentData);
            HighPriorityPicker.Initialise(torrentData);
        }