public override MessageBundle PickPiece(PeerId id, BitField peerBitfield, List<PeerId> otherPeers, int count,
            int startIndex, int endIndex)
        {
            // Only request 2 pieces at a time in endgame mode
            // to prevent a *massive* overshoot
            if (id.IsChoking || id.AmRequestingPiecesCount > 2)
                return null;

            LoadPieces(id, peerBitfield);

            // 1) See if there are any blocks which have not been requested at all. Request the block if the peer has it
            foreach (var p in pieces)
            {
                if (!peerBitfield[p.Index] || p.AllBlocksRequested)
                    continue;

                for (var i = 0; i < p.BlockCount; i++)
                {
                    if (p.Blocks[i].Requested)
                        continue;
                    p.Blocks[i].Requested = true;
                    var request = new Request(id, p.Blocks[i]);
                    requests.Add(request);
                    return new MessageBundle(request.Block.CreateRequest(id));
                }
            }

            // 2) For each block with an existing request, add another request. We do a search from the start
            //    of the list to the end. So when we add a duplicate request, move both requests to the end of the list
            foreach (var p in pieces)
            {
                if (!peerBitfield[p.Index])
                    continue;

                for (var i = 0; i < p.BlockCount; i++)
                {
                    if (p.Blocks[i].Received || AlreadyRequested(p.Blocks[i], id))
                        continue;

                    var c = requests.Count;
                    for (var j = 0; j < requests.Count - 1 && (c-- > 0); j++)
                    {
                        if (requests[j].Block.PieceIndex == p.Index &&
                            requests[j].Block.StartOffset == p.Blocks[i].StartOffset)
                        {
                            var r = requests[j];
                            requests.RemoveAt(j);
                            requests.Add(r);
                            j--;
                        }
                    }
                    p.Blocks[i].Requested = true;
                    var request = new Request(id, p.Blocks[i]);
                    requests.Add(request);
                    return new MessageBundle(request.Block.CreateRequest(id));
                }
            }

            return null;
        }
        private void GenerateRarestFirst(BitField peerBitfield, IEnumerable<PeerId> otherPeers)
        {
            // Move anything in the rarest buffer into the spares
            while (_rarest.Count > 0)
                _spares.Push(_rarest.Pop());

            var current = DequeueSpare();
            current.From(peerBitfield);

            // Store this bitfield as the first iteration of the Rarest First algorithm.
            _rarest.Push(current);

            // Get a cloned copy of the bitfield and begin iterating to find the rarest pieces
            foreach (var t in otherPeers.Where(t => !t.BitField.AllTrue))
            {
                current = DequeueSpare().From(current);

                // currentBitfield = currentBitfield & (!otherBitfield)
                // This calculation finds the pieces this peer has that other peers *do not* have.
                // i.e. the rarest piece.
                current.NAnd(t.BitField);

                // If the bitfield now has no pieces we've completed our task
                if (current.AllFalse)
                {
                    _spares.Push(current);
                    break;
                }

                // Otherwise push the bitfield on the stack and clone it and iterate again.
                _rarest.Push(current);
            }
        }
 public InitialSeedingMode(TorrentManager manager)
     : base(manager)
 {
     unchoker = new InitialSeedUnchoker(manager);
     manager.chokeUnchoker = unchoker;
     zero = new BitField(manager.Bitfield.Length);
 }
예제 #4
0
        public void Setup()
        {
            alreadyGot = new List<Block>();
            bitfield = new BitField(40).SetAll(true);
            picker = new EndGamePicker();
            pieces = new List<Piece>(new Piece[] {
                new Piece(4, rig.Torrent),
                new Piece(6, rig.Torrent),
                new Piece(36, rig.Torrent),
                new Piece(24, rig.Torrent)
            });

            for (int i = 0; i < pieces.Count; i++)
            {
                for (int j = 0; j < pieces[i].BlockCount; j++)
                {
                    if (j % 3 == 0)
                    {
                        pieces[i].Blocks[j].CreateRequest(id);
                        if (j % 2 == 0)
                        {
                            pieces[i].Blocks[j].Received = true;
                        }
                        pieces[i].Blocks[j].Requested = true;
                        alreadyGot.Add(pieces[i].Blocks[j]);
                    }
                }
            }

            picker.Initialise(bitfield, rig.Torrent.Files, pieces);
        }
예제 #5
0
 public override bool IsInteresting(BitField bitfield)
 {
     temp.From(bitfield).NAnd(this.bitfield);
     if (temp.AllFalse)
         return false;
     return base.IsInteresting(temp);
 }
        public EndGamePickerTests()
        {
            rig = TestRig.CreateMultiFile();

            bitfield = new BitField(40).SetAll(true)
                .Set(4, false)
                .Set(6, false)
                .Set(24, false)
                .Set(36, false);
            picker = new EndGamePicker();
            pieces = new List<Piece>(new[]
            {
                new Piece(4, rig.Torrent.PieceLength, rig.Torrent.Size),
                new Piece(6, rig.Torrent.PieceLength, rig.Torrent.Size),
                new Piece(24, rig.Torrent.PieceLength, rig.Torrent.Size),
                new Piece(36, rig.Torrent.PieceLength, rig.Torrent.Size)
            });

            id = new PeerId(new Peer("peerid", new Uri("tcp://weburl.com")), rig.Manager);
            id.IsChoking = false;
            id.BitField.SetAll(false);

            other = new PeerId(new Peer("other", new Uri("tcp://other.com")), rig.Manager);
            other.IsChoking = false;
            other.BitField.SetAll(false);
        }
예제 #7
0
 /// <summary>
 /// Initializes new instance of LinkedInGetMemberOptions
 /// </summary>
 public LinkedInGetMemberOptions()
 {
     BasicProfileOptions = new BitField<LinkedInBasicProfileFields>();
     EmailProfileOptions = new BitField<LinkedInEmailProfileFields>();
     FullProfileOptions = new BitField<LinkedInFullProfileFields>();
     Parameters = new LinkedInGetMemberParameters();
 }
 public override MessageBundle PickPiece(PeerId id, BitField peerBitfield, List<PeerId> otherPeers, int count,
     int startIndex, int endIndex)
 {
     var bundle = ActivePicker.PickPiece(id, peerBitfield, otherPeers, count, startIndex, endIndex);
     if (bundle == null && TryEnableEndgame())
         return ActivePicker.PickPiece(id, peerBitfield, otherPeers, count, startIndex, endIndex);
     return bundle;
 }
예제 #9
0
 public void SetUp()
 {
     // The bool[] must be kept in sync with the byte[] constructor. They represent exactly the same thing.
     initalValues = new bool[] { true, false, true, false, true, false, true, true, true, false, false, true };
     secondValues = new bool[] { true, true, false, false, true, false, true, false, true, false, false, true };
     initialByteValues = new byte[] { 171, 144 };
     bf = new BitField(initalValues);
 }
 public InitialSeedUnchoker(TorrentManager manager)
 {
     advertisedPieces = new List<SeededPiece>();
     bitfield = new BitField(manager.Bitfield.Length);
     this.manager = manager;
     peers = new List<ChokeData>();
     temp = new BitField(bitfield.Length);
 }
 public override void Initialise(BitField bitfield, TorrentFile[] files, IEnumerable<Piece> requests)
 {
     this.bitfield = bitfield;
     endgameSelector = new BitField(bitfield.Length);
     this.files = files;
     inEndgame = false;
     TryEnableEndgame();
     ActivePicker.Initialise(bitfield, files, requests);
 }
예제 #12
0
 public override MessageBundle PickPiece(PeerId id, BitField peerBitfield, List<PeerId> otherPeers, int count, int startIndex, int endIndex)
 {
     // Invert 'bitfield' and AND it with the peers bitfield
     // Any pieces which are 'true' in the bitfield will not be downloaded
     temp.From(peerBitfield).NAnd(bitfield);
     if (temp.AllFalse)
         return null;
     return base.PickPiece(id, temp, otherPeers, count, startIndex, endIndex);
 }
예제 #13
0
        public FastResume(InfoHash infoHash, BitField bitfield)
        {
            if (infoHash == null)
                throw new ArgumentNullException(nameof(infoHash));
            if (bitfield == null)
                throw new ArgumentNullException(nameof(bitfield));

            Infohash = infoHash;
            Bitfield = bitfield;
        }
예제 #14
0
        public FastResume(InfoHash infoHash, BitField bitfield)
        {
            if (infoHash == null)
                throw new ArgumentNullException("infoHash");
            if (bitfield == null)
                throw new ArgumentNullException("bitfield");

            this.infoHash = infoHash;
            this.bitfield = bitfield;
        }
예제 #15
0
 public override void Initialise(BitField bitfield, TorrentFile[] files, IEnumerable<Piece> requests)
 {
     // 'Requests' should contain a list of all the pieces we need to complete
     pieces = new List<Piece>(requests);
     foreach (var piece in pieces)
     {
         for (var i = 0; i < piece.BlockCount; i++)
             if (piece.Blocks[i].RequestedOff != null)
                 this.requests.Add(new Request(piece.Blocks[i].RequestedOff, piece.Blocks[i]));
     }
 }
        public FastResume(InfoHash infoHash, BitField bitfield, IEnumerable<Priority> priorities)
        {
            if (infoHash==null)
                throw new ArgumentNullException("infoHash");
            if(bitfield == null)
                throw new ArgumentNullException("bitfield");

            this.infoHash = infoHash;
            this.bitfield = bitfield;
            this.priorities = priorities.ToArray();
        }
예제 #17
0
        public FastResume(BEncodedDictionary dict)
        {
            CheckContent(dict, VersionKey, 1);
            CheckContent(dict, InfoHashKey);
            CheckContent(dict, BitfieldKey);
            CheckContent(dict, BitfieldLengthKey);

            Infohash = new InfoHash(((BEncodedString) dict[InfoHashKey]).TextBytes);
            Bitfield = new BitField((int) ((BEncodedNumber) dict[BitfieldLengthKey]).Number);
            var data = ((BEncodedString) dict[BitfieldKey]).TextBytes;
            Bitfield.FromArray(data, 0, data.Length);
        }
예제 #18
0
        public override MessageBundle PickPiece(PeerId id, BitField peerBitfield, List<PeerId> otherPeers, int count, int startIndex, int endIndex)
        {
            if (peerBitfield.AllFalse)
                return null;

            if (count > 1)
                return base.PickPiece(id, peerBitfield, otherPeers, count, startIndex, endIndex);

            int midpoint = random.Next(startIndex, endIndex);
            return base.PickPiece(id, peerBitfield, otherPeers, count, midpoint, endIndex) ??
                   base.PickPiece(id, peerBitfield, otherPeers, count, startIndex, midpoint);
        }
예제 #19
0
 /// <summary>
 /// Initializes new instance of LinkedInSearchOptions
 /// </summary>
 public LinkedInSearchOptions()
 {
     Keywords = new List<string>();
     MemberFieldOptions = new LinkedInGetMemberOptions();
     FacetFields = new BitField<LinkedInFacetFields>();
     BucketFields = new BitField<LinkedInBucketFields>();
     FacetLanguageValues = new List<LinkedInFacetLanguage>();
     FacetLocationValues = new List<string>();
     FacetIndustryValues = new List<string>();
     FacetCurrentCompanyValues = new List<string>();
     FacetPastCompanyValues = new List<string>();
     FacetSchoolValues = new List<string>();
 }
예제 #20
0
 public void InvalidBitfieldTest()
 {
     // Set each of the 4 trailing bits to 1 to force a decode error
     for (byte i = 8; i > 0; i /= 2)
     {
         try
         {
             initialByteValues[1] += i;
             bf = new BitField(initialByteValues, initalValues.Length);
             Assert.Fail("The bitfield was corrupt but decoded correctly: Loop {0}", i);
         }
         catch (MessageException) { initialByteValues[1] -= i; }
     }
 }
예제 #21
0
        public void And()
        {
            var bf2 = new BitField(_secondValues);
            _bf.And(bf2);

            Assert.AreEqual(new BitField(_secondValues), bf2, "#1: bf2 should be unmodified");
            for (var i = 0; i < _bf.Length; i++)
                Assert.AreEqual(_initalValues[i] && _secondValues[i], _bf[i], "#2");

            var count = _initalValues
                .Where((x, i) => x && _secondValues[i])
                .Count();

            Assert.AreEqual(count, _bf.TrueCount, "#3");
        }
예제 #22
0
        public void And()
        {
            var bf2 = new BitField(secondValues);
            bf.And(bf2);

            Assert.Equal(new BitField(secondValues), bf2);
            for (var i = 0; i < bf.Length; i++)
                Assert.Equal(initalValues[i] && secondValues[i], bf[i]);

            var count = 0;
            for (var i = 0; i < initalValues.Length; i++)
                if (initalValues[i] && secondValues[i])
                    count++;

            Assert.Equal(count, bf.TrueCount);
        }
예제 #23
0
        public void And2()
        {
            Random r = new Random ();
            byte [] a = new byte [100];
            byte [] b = new byte [100];

            r.NextBytes (a);
            r.NextBytes (b);

            for (int i = 0; i < a.Length * 8; i++) {
                BitField first = new BitField (a, i);
                BitField second = new BitField (b, i);

                first.And (second);
            }
        }
예제 #24
0
        public void And()
        {
            BitField bf2 = new BitField(secondValues);
            bf.And(bf2);

            Assert.AreEqual(new BitField(secondValues), bf2, "#1: bf2 should be unmodified");
            for (int i = 0; i < bf.Length; i++)
                Assert.AreEqual(initalValues[i] && secondValues[i], bf[i], "#2");

            int count = 0;
            for (int i = 0; i < initalValues.Length; i++)
                if (initalValues[i] && secondValues[i])
                    count++;

            Assert.AreEqual(count, bf.TrueCount, "#3");
        }
예제 #25
0
        public void And2()
        {
            var random = new Random ();
            var a = new byte [100];
            var b = new byte [100];

            random.NextBytes (a);
            random.NextBytes (b);

            for (var i = 0; i < a.Length * 8; i++) {
                var first = new BitField (a, i);
                var second = new BitField (b, i);

                first.And(second);
            }
        }
        public FastResume(BEncodedDictionary dict)
        {
            CheckContent(dict, VersionKey, (BEncodedNumber)1);
            CheckContent(dict, InfoHashKey);
            CheckContent(dict, BitfieldKey);
            CheckContent(dict, BitfieldLengthKey);

            infoHash = new InfoHash(((BEncodedString)dict[InfoHashKey]).TextBytes);
            bitfield = new BitField((int)((BEncodedNumber)dict[BitfieldLengthKey]).Number);
            byte[] data = ((BEncodedString)dict[BitfieldKey]).TextBytes;
            bitfield.FromArray(data, 0, data.Length);

            if (dict.ContainsKey(PrioritiesKey))
            {
                var list = (BEncodedList)dict[PrioritiesKey];
                priorities = list.Select(v => (Priority)((BEncodedNumber)v).Number).ToArray();
            }
        }
예제 #27
0
        public override MessageBundle PickPiece(PeerId id, BitField peerBitfield, List<PeerId> otherPeers, int count, int startIndex, int endIndex)
        {
            if (peerBitfield.AllFalse)
                return null;

            if (count > 1)
                return base.PickPiece(id, peerBitfield, otherPeers, count, startIndex, endIndex);
            
            GenerateRarestFirst(peerBitfield, otherPeers);

            while (rarest.Count > 0)
            {
                BitField current = rarest.Pop();
                MessageBundle bundle = base.PickPiece(id, current, otherPeers, count, startIndex, endIndex);
                spares.Push(current);

                if (bundle != null)
                    return bundle;
            }

            return null;
        }
예제 #28
0
        public override MessageBundle PickPiece(PeerId id, BitField peerBitfield, List<PeerId> otherPeers, int count, int startIndex, int endIndex)
        {
            PickPieceId.Add(id);
            BitField clone = new BitField(peerBitfield.Length);
            clone.Or(peerBitfield);
            PickPieceBitfield.Add(clone);
            PickPiecePeers.Add(otherPeers);
            PickPieceStartIndex.Add(startIndex);
            PickPieceEndIndex.Add(endIndex);
            PickPieceCount.Add(count);

            for (int i = startIndex; i < endIndex; i++)
            {
                if (PickedPieces.Contains(i))
                    continue;
                PickedPieces.Add(i);
                if (ReturnNoPiece)
                    return null;
                else
                    return new MessageBundle();
            }
            return null;
        }
예제 #29
0
        void GenerateRarestFirst(BitField peerBitfield, List<PeerId> otherPeers)
        {
            // Move anything in the rarest buffer into the spares
            while (rarest.Count > 0)
                spares.Push(rarest.Pop());

            BitField current = DequeueSpare();
            current.From(peerBitfield);

            // Store this bitfield as the first iteration of the Rarest First algorithm.
            rarest.Push(current);

            // Get a cloned copy of the bitfield and begin iterating to find the rarest pieces
            for (int i = 0; i < otherPeers.Count; i++)
            {
                if (otherPeers[i].BitField.AllTrue)
                    continue;

                current = DequeueSpare().From(current);

                // currentBitfield = currentBitfield & (!otherBitfield)
                // This calculation finds the pieces this peer has that other peers *do not* have.
                // i.e. the rarest piece.
                current.NAnd(otherPeers[i].BitField);

                // If the bitfield now has no pieces we've completed our task
                if (current.AllFalse)
                {
                    spares.Push(current);
                    break;
                }

                // Otherwise push the bitfield on the stack and clone it and iterate again.
                rarest.Push(current);
            }
        }
        public override MessageBundle PickPiece(PeerId id, BitField peerBitfield, List<PeerId> otherPeers, int count,
            int startIndex, int endIndex)
        {
            MessageBundle bundle;
            int start, end;

            if (HighPrioritySetStart >= startIndex && HighPrioritySetStart <= endIndex)
            {
                start = HighPrioritySetStart;
                end = Math.Min(endIndex, HighPrioritySetStart + HighPrioritySetSize - 1);
                if ((bundle = base.PickPiece(id, peerBitfield, otherPeers, count, start, end)) != null)
                    return bundle;
            }

            if (MediumPrioritySetStart >= startIndex && MediumPrioritySetStart <= endIndex)
            {
                start = MediumPrioritySetStart;
                end = Math.Min(endIndex, MediumPrioritySetStart + MediumPrioritySetSize - 1);
                if ((bundle = base.PickPiece(id, peerBitfield, otherPeers, count, start, end)) != null)
                    return bundle;
            }

            return base.PickPiece(id, peerBitfield, otherPeers, count, startIndex, endIndex);
        }
예제 #31
0
 internal void RefreshPickerWithMetadata(BitField bitfield, ITorrentData data)
 {
     ChangePicker(originalPicker, bitfield);
     Picker.Initialise(bitfield, data, Enumerable.Empty <Piece> ());
 }
예제 #32
0
 public bool IsInteresting(IPeer peer, BitField bitfield)
 {
     return(!bitfield.AllFalse);
 }
예제 #33
0
 /// <summary>
 /// Creates a new BitfieldMessage
 /// </summary>
 /// <param name="length">The length of the bitfield</param>
 public BitfieldMessage(int length)
 {
     BitField = new MutableBitField(length);
 }
예제 #34
0
 public InitialSeedingMode(TorrentManager manager, DiskManager diskManager, ConnectionManager connectionManager, EngineSettings settings)
     : base(manager, diskManager, connectionManager, settings, new InitialSeedUnchoker(manager))
 {
     zero = new MutableBitField(manager.Bitfield.Length);
 }
예제 #35
0
        private bool GetFontOption(BitField field)
        {
            int options = GetInt(OFFSET_FONT_OPTIONS);

            return(field.IsSet(options));
        }
예제 #36
0
 internal PieceManager(TorrentManager manager)
 {
     Manager = manager;
     Picker  = new NullPicker();
     PendingHashCheckPieces = new BitField(1);
 }
예제 #37
0
        public override IList <PieceRequest> PickPiece(PeerId id, BitField peerBitfield, List <PeerId> otherPeers, int count, int startIndex, int endIndex)
        {
            // Only request 2 pieces at a time in endgame mode
            // to prevent a *massive* overshoot
            if (id.IsChoking || id.AmRequestingPiecesCount > 2)
            {
                return(null);
            }

            LoadPieces(id, peerBitfield);

            // 1) See if there are any blocks which have not been requested at all. Request the block if the peer has it
            foreach (Piece p in pieces)
            {
                if (!peerBitfield[p.Index] || p.AllBlocksRequested)
                {
                    continue;
                }

                for (int i = 0; i < p.BlockCount; i++)
                {
                    if (p.Blocks[i].Requested)
                    {
                        continue;
                    }
                    var requestMessage = p.Blocks[i].CreateRequest(id);
                    requests.Add(new Request(id, p.Blocks[i]));
                    return(new [] { requestMessage });
                }
            }

            // 2) For each block with an existing request, add another request. We do a search from the start
            //    of the list to the end. So when we add a duplicate request, move both requests to the end of the list
            foreach (Piece p in pieces)
            {
                if (!peerBitfield[p.Index])
                {
                    continue;
                }

                for (int i = 0; i < p.BlockCount; i++)
                {
                    if (p.Blocks[i].Received || AlreadyRequested(p.Blocks[i], id))
                    {
                        continue;
                    }

                    int c = requests.Count;
                    for (int j = 0; j < requests.Count - 1 && (c-- > 0); j++)
                    {
                        if (requests[j].Block.PieceIndex == p.Index && requests[j].Block.StartOffset == p.Blocks[i].StartOffset)
                        {
                            Request r = requests[j];
                            requests.RemoveAt(j);
                            requests.Add(r);
                            j--;
                        }
                    }
                    var requestMessage = p.Blocks[i].CreateRequest(id);
                    requests.Add(new Request(id, p.Blocks[i]));
                    return(new [] { requestMessage });
                }
            }

            return(null);
        }
예제 #38
0
        public PieceRequest PickPiece(IPieceRequester peer, BitField available, IReadOnlyList <IPieceRequester> otherPeers)
        {
            IList <PieceRequest> bundle = PickPiece(peer, available, otherPeers, 1);

            return(bundle?.Single());
        }
예제 #39
0
 private void SetModified(bool modified, BitField field)
 {
     field_5_options = field.SetBoolean(field_5_options, !modified);
 }
예제 #40
0
 private bool IsModified(BitField field)
 {
     return(!field.IsSet(field_5_options));
 }
예제 #41
0
 public override bool IsInteresting(BitField bitfield)
 {
     IsInterestingBitfield.Add(bitfield);
     return(!bitfield.AllFalse);
 }
예제 #42
0
 internal PieceManager(TorrentManager manager)
 {
     Manager = manager;
     PendingHashCheckPieces = new BitField(1);
     Requester = manager.Engine !.Factories.CreatePieceRequester();
 }
예제 #43
0
 public virtual void Initialise(BitField bitfield, ITorrentData torrentData, IEnumerable <Piece> requests)
 {
     CheckOverriden();
     BasePicker.Initialise(bitfield, torrentData, requests);
 }
        public void AddRequests(IPeerWithMessaging peer, IReadOnlyList <IPeerWithMessaging> allPeers)
        {
            int maxRequests = peer.MaxPendingRequests;

            if (!peer.CanRequestMorePieces)
            {
                return;
            }

            int count = peer.PreferredRequestAmount(TorrentData.PieceLength);

            // This is safe to invoke. 'ContinueExistingRequest' strongly guarantees that a peer will only
            // continue a piece they have initiated. If they're choking then the only piece they can continue
            // will be a fast piece (if one exists!)
            if (!peer.IsChoking || peer.SupportsFastPeer)
            {
                while (peer.AmRequestingPiecesCount < maxRequests)
                {
                    BlockInfo?request = Picker.ContinueExistingRequest(peer, 0, peer.BitField.Length - 1);
                    if (request != null)
                    {
                        peer.EnqueueRequest(request.Value);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            // FIXME: Would it be easier if RequestManager called PickPiece(AllowedFastPieces[0]) or something along those lines?
            if (!peer.IsChoking || (peer.SupportsFastPeer && peer.IsAllowedFastPieces.Count > 0))
            {
                BitField filtered = null;
                while (peer.AmRequestingPiecesCount < maxRequests)
                {
                    filtered ??= ApplyIgnorables(peer.BitField);
                    IList <BlockInfo> request = Picker.PickPiece(peer, filtered, allPeers, count, 0, TorrentData.PieceCount() - 1);
                    if (request != null && request.Count > 0)
                    {
                        peer.EnqueueRequests(request);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (!peer.IsChoking && peer.AmRequestingPiecesCount == 0)
            {
                while (peer.AmRequestingPiecesCount < maxRequests)
                {
                    BlockInfo?request = Picker.ContinueAnyExistingRequest(peer, 0, TorrentData.PieceCount() - 1, 1);
                    // If this peer is a seeder and we are unable to request any new blocks, then we should enter
                    // endgame mode. Every block has been requested at least once at this point.
                    if (request == null && (InEndgameMode || peer.IsSeeder))
                    {
                        request        = Picker.ContinueAnyExistingRequest(peer, 0, TorrentData.PieceCount() - 1, 2);
                        InEndgameMode |= request != null;
                    }

                    if (request != null)
                    {
                        peer.EnqueueRequest(request.Value);
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
예제 #45
0
        public void BitFieldSameContainerTest()
        {
            var test = new BitField <byte>(4, startBitOffset: 0);

            test.Bitmask.ShouldBe <byte>(0b1111_0000);
        }
예제 #46
0
 public virtual bool IsInteresting(BitField bitfield)
 {
     CheckOverriden();
     return(BasePicker.IsInteresting(bitfield));
 }
예제 #47
0
 private void UpdateCubeRowDirections(int cubex, int cubey, int row, BitField rowA, BitField rowB)
 {
     foreach (Cell cell in Cells.CubeRow(cubex, cubey, row))
     {
         // possible values that are exclusive to this row
         if (!cell.HasValue)
         {
             cell.HorizontalDirections = cell.Possibles & !(rowA | rowB);
         }
     }
 }
예제 #48
0
 public override void Initialise(BitField bitfield, TorrentFile[] files, IEnumerable <Piece> requests)
 {
     base.Initialise(bitfield, files, requests);
     this.length = bitfield.Length;
 }
예제 #49
0
 private void UpdateCubeColumnDirections(int cubex, int cubey, int column, BitField columnA, BitField columnB)
 {
     foreach (Cell cell in Cells.CubeColumn(cubex, cubey, column))
     {
         // possible values that are exclusive to this column
         if (!cell.HasValue)
         {
             cell.VerticalDirections = cell.Possibles & !(columnA | columnB);
         }
     }
 }
예제 #50
0
 public ChokeData(PeerId peer)
 {
     LastChoked    = DateTime.Now;
     Peer          = peer;
     CurrentPieces = new BitField(peer.BitField.Length);
 }
예제 #51
0
 public override void Initialise(BitField bitfield, ITorrentData torrentData, IEnumerable <Piece> requests)
 {
 }
예제 #52
0
 public TorrentFileInfo(ITorrentFile torrentFile, string fullPath)
 {
     TorrentFile = torrentFile;
     FullPath    = DownloadCompleteFullPath = DownloadIncompleteFullPath = fullPath;
     BitField    = new BitField(torrentFile.EndPieceIndex - torrentFile.StartPieceIndex + 1);
 }
예제 #53
0
 /// <summary>
 /// Creates a new BitfieldMessage
 /// </summary>
 /// <param name="bitfield">The bitfield to use</param>
 public BitfieldMessage(BitField bitfield)
 {
     BitField = bitfield;
 }
예제 #54
0
 internal PieceManager(TorrentManager manager)
 {
     Manager        = manager;
     Picker         = new NullPicker();
     UnhashedPieces = new BitField(1);
 }
예제 #55
0
 private bool GetOptionFlag(BitField field)
 {
     return(field.IsSet(field_5_options));
 }
예제 #56
0
 public IList <PieceRequest> PickPiece(IPieceRequester peer, BitField available, IReadOnlyList <IPieceRequester> otherPeers, int count)
 {
     return(PickPiece(peer, available, otherPeers, count, 0, available.Length));
 }
예제 #57
0
 private void SetOptionFlag(bool flag, BitField field)
 {
     field_5_options = field.SetBoolean(field_5_options, flag);
 }
예제 #58
0
 internal PieceManager()
 {
     Picker         = new NullPicker();
     UnhashedPieces = new BitField(0);
 }
예제 #59
0
 public virtual IList <PieceRequest> PickPiece(IPieceRequester peer, BitField available, IReadOnlyList <IPieceRequester> otherPeers, int count, int startIndex, int endIndex)
 {
     CheckOverriden();
     return(BasePicker.PickPiece(peer, available, otherPeers, count, startIndex, endIndex));
 }
예제 #60
0
        int CanRequest(BitField bitfield, int pieceStartIndex, int pieceEndIndex, ref int pieceCount)
        {
            // This is the easiest case to consider - special case it
            if (pieceCount == 1)
            {
                while (pieceStartIndex <= pieceEndIndex && (pieceStartIndex = bitfield.FirstTrue(pieceStartIndex, pieceEndIndex)) != -1)
                {
                    var end = bitfield.FirstFalse(pieceStartIndex, pieceEndIndex);

                    // If end is a valid value, it's the first *false* piece. Subtract '1' from it
                    // to give us the last available piece we can request. If it's -1 then we can use
                    // 'pieceEndIndex' as the last available piece to request as all pieces are available.
                    var lastAvailable = end == -1 ? pieceEndIndex : end - 1;
                    for (int i = pieceStartIndex; i <= lastAvailable; i++)
                    {
                        if (!AlreadyRequested(i))
                        {
                            return(i);
                        }
                    }
                    pieceStartIndex = lastAvailable + 1;
                }
                return(-1);
            }

            int largestStart = 0;
            int largestEnd   = 0;

            while (pieceStartIndex <= pieceEndIndex && (pieceStartIndex = bitfield.FirstTrue(pieceStartIndex, pieceEndIndex)) != -1)
            {
                int end = bitfield.FirstFalse(pieceStartIndex, pieceEndIndex);
                if (end == -1)
                {
                    end = Math.Min(pieceStartIndex + pieceCount, bitfield.Length);
                }

                // Do not include 'end' as it's the first *false* piece.
                for (int i = pieceStartIndex; i < end; i++)
                {
                    if (AlreadyRequested(i))
                    {
                        end = i;
                    }
                }

                if ((end - pieceStartIndex) >= pieceCount)
                {
                    return(pieceStartIndex);
                }

                if ((largestEnd - largestStart) < (end - pieceStartIndex))
                {
                    largestStart = pieceStartIndex;
                    largestEnd   = end;
                }

                pieceStartIndex = Math.Max(pieceStartIndex + 1, end);
            }

            pieceCount = largestEnd - largestStart;
            return(pieceCount == 0 ? -1 : largestStart);
        }