Exemple #1
0
        public void OnlyAvailablePiecesAllowed()
        {
            // The bitfield representing the overall torrent shouldn't be used by the
            // rarest first picker, so set it all to true to make sure it has no impact.
            bitfield.SetAll(true);

            // Pretend the peer has 4 pieces we can choose.
            var available = new BitField(bitfield.Length)
                            .Set(1, true)
                            .Set(2, true)
                            .Set(4, true)
                            .Set(8, true);

            // Every other peer has all pieces except for piece '2'.
            for (int i = 0; i < 5; i++)
            {
                peers[i].BitField.SetAll(true).Set(i, false);
            }

            // Ensure that pieces which were not in the 'available' bitfield were not offered
            // as suggestions.
            foreach (var bf in checker.PickPieceBitfield)
            {
                Assert.IsTrue(available.Clone().Not().And(bf).AllFalse, "#1");
            }

            // Ensure at least one of the pieces in our bitfield *was* offered.
            foreach (var bf in checker.PickPieceBitfield)
            {
                Assert.IsFalse(available.Clone().And(bf).AllFalse, "#2");
            }
        }
        public void StandardPicker_PickStandardPiece()
        {
            peers[0].IsChoking = false;
            peers[0].BitField.SetAll(true);

            bitfield[1] = true;
            var message = picker.PickPiece(peers[0], bitfield.Clone().Not(), peers, 1, 0, 10);

            Assert.AreEqual(0, message[0].PieceIndex);

            peers[1].IsChoking = false;
            peers[1].BitField.SetAll(true);
            peers[1].Peer.HashedPiece(false);
            message = picker.PickPiece(peers[1], bitfield.Clone().Not(), peers, 1, 0, 10);
            Assert.AreEqual(2, message[0].PieceIndex);
        }
Exemple #3
0
        public RarestFirstRqStrategy(int piecesCount, BitField piecesHave = null)
        {
            _piecesCount  = piecesCount;
            _requested    = piecesHave == null ? new BitField(_piecesCount) : piecesHave;
            _randomPieces = new Stack <int>(InitialRandomPiecesCount);

            int falseCount        = piecesCount - _requested.TrueCount;
            int randomPiecesCount = falseCount < InitialRandomPiecesCount ? falseCount : InitialRandomPiecesCount;

            //Random pieces before rarest first algorithm
            if (randomPiecesCount > 0)
            {
                int[]    falseIndicies = new int[falseCount];
                BitField requestedCopy = _requested.Clone();
                for (int i = 0; i < falseCount; i++)
                {
                    int falseIdx = requestedCopy.FirstFalse();
                    falseIndicies[i]        = falseIdx;
                    requestedCopy[falseIdx] = true;
                }

                FisherYatesShuffle(falseIndicies, falseCount);
                for (int i = 0; i < randomPiecesCount; i++)
                {
                    _randomPieces.Push(falseIndicies[i]);
                }
            }
        }
        void BuildSelectors()
        {
            files.Sort();
            prioritised.Clear();

            // If it's a single file (or they're all the same priority) then we
            // won't need prioritised bitfields or a bitfield to check the
            // interested status. Set the IsInteresting bitfield to false so
            // it's always in a predictable state and bail out.
            //
            // If all files are set to DoNotDownload we'll bail out early here.
            if (files.Count == 1 || files.TrueForAll(AllSamePriority))
            {
                allPrioritisedPieces.SetAll(false);
                return;
            }

            // At least one file is not set to DoNotDownload
            temp.SetAll(false);
            temp.SetTrue((files[0].File.StartPieceIndex, files[0].File.EndPieceIndex));
            allPrioritisedPieces.From(temp);
            for (int i = 1; i < files.Count && files[i].Priority != Priority.DoNotDownload; i++)
            {
                allPrioritisedPieces.SetTrue((files[i].File.StartPieceIndex, files[i].File.EndPieceIndex));

                if (files[i].Priority == files[i - 1].Priority)
                {
                    temp.SetTrue((files[i].File.StartPieceIndex, files[i].File.EndPieceIndex));
                }
                else if (!temp.AllFalse)
                {
                    prioritised.Add(temp.Clone());
                    temp.SetAll(false);
                    temp.SetTrue((files[i].File.StartPieceIndex, files[i].File.EndPieceIndex));
                }
            }

            if (!temp.AllFalse)
            {
                prioritised.Add(temp.Clone());
            }
        }
Exemple #5
0
        internal FastResume(InfoHash infoHash, BitField bitfield, BitField unhashedPieces)
        {
            Infohash       = infoHash ?? throw new ArgumentNullException(nameof(infoHash));
            Bitfield       = bitfield?.Clone() ?? throw new ArgumentNullException(nameof(bitfield));
            UnhashedPieces = unhashedPieces?.Clone() ?? throw new ArgumentNullException(nameof(UnhashedPieces));

            for (int i = 0; i < Bitfield.Length; i++)
            {
                if (bitfield[i] && unhashedPieces[i])
                {
                    throw new ArgumentException($"The bitfield is set to true at index {i} but that piece is marked as unhashed.");
                }
            }
        }
Exemple #6
0
        void GenerateRarestFirst(BitField peerBitfield, IReadOnlyList <IPeer> otherPeers)
        {
            // Move anything in the rarest buffer into the spares
            while (rarest.Count > 0)
            {
                spares.Push(rarest.Pop());
            }

            BitField current = spares.Count > 0 ? spares.Pop().From(peerBitfield) : peerBitfield.Clone();

            // 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 = spares.Count > 0 ? spares.Pop().From(current) : current.Clone();

                // 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);
            }
        }
Exemple #7
0
        public void Clone()
        {
            var clone = _bf.Clone();

            Assert.AreEqual(_bf, clone);
        }
        public void Clone()
        {
            BitField clone = bf.Clone();

            Assert.AreEqual(bf, clone);
        }
        public void Test()
        {
            var bitField = new BitField(0, false);

            Assert.AreEqual(bitField.Length, 0);
            Assert.AreEqual(bitField[1], false);

            int size = Rand.Default.Range(1, 256);

            bitField = new BitField(size, false);
            BitArray bitArray = new BitArray(size, false);

            check(bitField, bitArray);

            size = Rand.Default.Range(1, 256);
            bool[] boolData = new bool[size];
            for (int i = 0; i < boolData.Length; i++)
            {
                boolData[i] = Rand.Default.Range(0, 2) > 0;
            }
            bitField = new BitField(boolData);
            bitArray = new BitArray(boolData);
            check(bitField, bitArray);

            size = Rand.Default.Range(1, 64);
            byte[] byteData = new byte[size];
            for (int i = 0; i < byteData.Length; i++)
            {
                byteData[i] = Rand.Default.RandByte();
            }
            bitField = new BitField(byteData);
            bitArray = new BitArray(byteData);
            check(bitField, bitArray);

            size = Rand.Default.Range(1, 32);
            int[] intData = new int[size];
            for (int i = 0; i < intData.Length; i++)
            {
                intData[i] = Rand.Default.RandInt();
            }
            bitField = new BitField(intData);
            bitArray = new BitArray(intData);
            check(bitField, bitArray);

            size    = Rand.Default.Range(1, 32);
            intData = new int[size];
            for (int i = 0; i < intData.Length; i++)
            {
                intData[i] = Rand.Default.RandInt();
            }
            bitArray = new BitArray(intData);
            bitField = new BitField(bitArray);
            check(bitField, bitArray);

            size    = Rand.Default.Range(1, 32);
            intData = new int[size];
            for (int i = 0; i < intData.Length; i++)
            {
                intData[i] = Rand.Default.RandInt();
            }
            bitField = new BitField(intData);
            bitField = new BitField(bitField);
            bitArray = new BitArray(intData);
            check(bitField, bitArray);

            for (int i = 0; i < bitField.Length; i++)
            {
                bool value = Rand.Default.Range(0, 2) > 0;
                bitField.Set(i, value);
                bitArray.Set(i, value);
            }
            check(bitField, bitArray);

            Assert.IsTrue(bitField.Any());

            bitField.SetAll(false);
            Assert.IsFalse(bitField.Any());

            bitField.SetAll(true);
            bitArray.SetAll(true);
            check(bitField, bitArray);

            size    = Rand.Default.Range(1, 32);
            intData = new int[size];
            for (int i = 0; i < intData.Length; i++)
            {
                intData[i] = Rand.Default.RandInt();
            }
            bitField = new BitField(intData);
            bitArray = new BitArray(intData);
            check(bitField, bitArray);

            bitField = bitField.Not();
            bitArray = bitArray.Not();
            check(bitField, bitArray);

            size    = Rand.Default.Range(1, 32);
            intData = new int[size];
            for (int i = 0; i < intData.Length; i++)
            {
                intData[i] = Rand.Default.RandInt();
            }
            bitField = new BitField(intData);
            bitArray = new BitArray(intData);
            check(bitField, bitArray);

            intData = new int[size];
            for (int i = 0; i < intData.Length; i++)
            {
                intData[i] = Rand.Default.RandInt();
            }
            var bitFieldTwo = new BitField(intData);
            var bitArrayTwo = new BitArray(intData);

            check(bitFieldTwo, bitArrayTwo);

            bitField = bitField.Or(bitFieldTwo);
            bitArray = bitArray.Or(bitArrayTwo);
            check(bitField, bitArray);

            intData = new int[size];
            for (int i = 0; i < intData.Length; i++)
            {
                intData[i] = Rand.Default.RandInt();
            }
            bitFieldTwo = new BitField(intData);
            bitArrayTwo = new BitArray(intData);
            check(bitFieldTwo, bitArrayTwo);

            bitField = bitField.Xor(bitFieldTwo);
            bitArray = bitArray.Xor(bitArrayTwo);
            check(bitField, bitArray);

            intData = new int[size];
            for (int i = 0; i < intData.Length; i++)
            {
                intData[i] = Rand.Default.RandInt();
            }
            bitFieldTwo = new BitField(intData);
            bitArrayTwo = new BitArray(intData);
            check(bitFieldTwo, bitArrayTwo);

            bitField = bitField.And(bitFieldTwo);
            bitArray = bitArray.And(bitArrayTwo);
            check(bitField, bitArray);

            bitFieldTwo = bitField.Clone() as BitField;
            Assert.IsNotNull(bitFieldTwo);
            check(bitFieldTwo, bitArray);

            size     = Rand.Default.Range(1, 256);
            boolData = new bool[size];
            for (int i = 0; i < boolData.Length; i++)
            {
                boolData[i] = Rand.Default.Range(0, 2) > 0;
            }

            bitField = new BitField(boolData);
            var boolDataTwo = new bool[size];

            bitField.CopyTo(boolDataTwo, 0);
            for (int i = 0; i < boolData.Length; i++)
            {
                Assert.AreEqual(boolData[i], boolDataTwo[i]);
            }

            size     = Rand.Default.Range(1, 64);
            byteData = new byte[size];
            for (int i = 0; i < byteData.Length; i++)
            {
                byteData[i] = Rand.Default.RandByte();
            }

            bitField = new BitField(byteData);
            var byteDataTwo = new byte[size];

            bitField.CopyTo(byteDataTwo, 0);
            for (int i = 0; i < byteData.Length; i++)
            {
                Assert.AreEqual(byteData[i], byteDataTwo[i]);
            }

            size    = Rand.Default.Range(1, 32);
            intData = new int[size];
            for (int i = 0; i < intData.Length; i++)
            {
                intData[i] = Rand.Default.RandInt();
            }

            bitField = new BitField(intData);
            var intDataTwo = new int[size];

            bitField.CopyTo(intDataTwo, 0);
            for (int i = 0; i < intData.Length; i++)
            {
                Assert.AreEqual(intData[i], intDataTwo[i]);
            }
        }