コード例 #1
0
        public void NoneHashed_NothingDownloaded()
        {
            var unhashedPieces = new MutableBitField(10).SetAll(true);
            var downloaded     = new MutableBitField(10).SetAll(false);

            Assert.DoesNotThrow(() => new FastResume(InfoHash, downloaded, unhashedPieces), "#1");
        }
コード例 #2
0
        public void NoneHashed_AllDownloaded()
        {
            var unhashedPieces = new MutableBitField(10).SetAll(true);
            var downloaded     = new MutableBitField(10).SetAll(true);

            Assert.Throws <ArgumentException> (() => new FastResume(InfoHash, downloaded, unhashedPieces), "#1");
        }
コード例 #3
0
        public override IList <BlockInfo> PickPiece(IPeer peer, BitField available, IReadOnlyList <IPeer> otherPeers, int count, int startIndex, int endIndex)
        {
            if (available.AllFalse)
            {
                return(null);
            }

            if (count > 1)
            {
                return(base.PickPiece(peer, available, otherPeers, count, startIndex, endIndex));
            }

            GenerateRarestFirst(available, otherPeers);

            while (rarest.Count > 0)
            {
                MutableBitField   current = rarest.Pop();
                IList <BlockInfo> bundle  = base.PickPiece(peer, current, otherPeers, count, startIndex, endIndex);
                spares.Push(current);

                if (bundle != null)
                {
                    return(bundle);
                }
            }

            return(null);
        }
コード例 #4
0
 internal PeerId(Peer peer, IPeerConnection connection, MutableBitField bitfield)
     : this(peer)
 {
     Connection      = connection ?? throw new ArgumentNullException(nameof(connection));
     Peer            = peer ?? throw new ArgumentNullException(nameof(peer));
     MutableBitField = bitfield;
 }
コード例 #5
0
        public void Setup()
        {
            int pieceLength = 16 * Constants.BlockSize;
            int pieces      = 40;
            int size        = pieces * pieceLength;

            bitfield    = new MutableBitField(pieces);
            torrentData = new TestTorrentData {
                Files       = TorrentFileInfo.Create(pieceLength, ("Test", size, "Full/Path/Test")),
                PieceLength = pieceLength,
                Size        = size
            };

            checker = new PiecePickerFilterChecker();
            picker  = new RarestFirstPicker(checker);
            picker.Initialise(torrentData);

            peer = PeerId.CreateNull(pieces);
            peer.BitField.SetAll(true);

            peers = new List <PeerId> ();
            for (int i = 0; i < 5; i++)
            {
                peers.Add(PeerId.CreateNull(pieces));
            }
        }
コード例 #6
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 MutableBitField(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 pick in checker.Picks)
            {
                Assert.IsTrue(new MutableBitField(available).Not().And(pick.available).AllFalse, "#1");
            }

            // Ensure at least one of the pieces in our bitfield *was* offered.
            foreach (var pick in checker.Picks)
            {
                Assert.IsFalse(new MutableBitField(available).And(pick.available).AllFalse, "#2");
            }
        }
コード例 #7
0
        public void LargeBitfield()
        {
            var bf = new MutableBitField(1000);

            bf.SetAll(true);
            Assert.AreEqual(1000, bf.TrueCount);
        }
コード例 #8
0
        public async Task ReadZeroFromDisk()
        {
            PieceWriter.FilesThatExist.AddRange(new[] {
                Manager.Files [0],
                Manager.Files [2],
            });

            PieceWriter.DoNotReadFrom.AddRange(new[] {
                Manager.Files[0],
                Manager.Files[3],
            });

            var bf = new MutableBitField(Manager.PieceCount()).SetAll(true);

            Manager.LoadFastResume(new FastResume(Manager.InfoHash, bf, Manager.UnhashedPieces.SetAll(false)));

            Assert.IsTrue(Manager.Bitfield.AllTrue, "#1");
            foreach (var file in Manager.Files)
            {
                Assert.IsTrue(file.BitField.AllTrue, "#2." + file.Path);
            }

            var mode = new HashingMode(Manager, DiskManager, ConnectionManager, Settings);

            Manager.Mode = mode;
            await mode.WaitForHashingToComplete();

            Assert.IsTrue(Manager.Bitfield.AllFalse, "#3");
            foreach (var file in Manager.Files)
            {
                Assert.IsTrue(file.BitField.AllFalse, "#4." + file.Path);
            }
        }
コード例 #9
0
 public override void Decode(ReadOnlySpan <byte> buffer)
 {
     if (CanDecode && !(MutableBitField is null))
     {
         MutableBitField.From(buffer);
     }
 }
コード例 #10
0
        public void FirstTrue_2()
        {
            var b = new MutableBitField(1025);

            b[1024] = true;
            Assert.AreEqual(1024, b.FirstTrue(0, b.Length - 1));
        }
コード例 #11
0
 public PickedPieces(int pieceCount)
 {
     alreadyRequestedBitField = new MutableBitField(pieceCount);
     duplicates        = new Dictionary <int, List <Piece> > ();
     mostRecentRequest = new Dictionary <IPeer, Piece> ();
     requests          = new Dictionary <int, Piece> ();
 }
コード例 #12
0
        protected override void HandleExtendedHandshakeMessage(PeerId id, ExtendedHandshakeMessage message)
        {
            base.HandleExtendedHandshakeMessage(id, message);

            if (id.ExtensionSupports.Supports(LTMetadata.Support.Name))
            {
                var metadataSize = message.MetadataSize.GetValueOrDefault(0);
                if (Stream == null && metadataSize > 0)
                {
                    Stream = new MemoryStream(new byte[metadataSize], 0, metadataSize, true, true);
                    int size = metadataSize % LTMetadata.BlockSize;
                    if (size > 0)
                    {
                        size = 1;
                    }
                    size    += metadataSize / LTMetadata.BlockSize;
                    bitField = new MutableBitField(size);
                }

                // We only create the Stream if the remote peer has sent the metadata size key in their handshake.
                // There's no guarantee the remote peer has the metadata yet, so even though they support metadata
                // mode they might not be able to share the data.
                if (Stream != null)
                {
                    RequestNextNeededPiece(id);
                }
            }
        }
コード例 #13
0
ファイル: Program.cs プロジェクト: gweffect/monotorrent
        public void PickAndValidate_600Concurrent()
        {
            Picker.Initialise(new TorrentData());

            var       bf = new MutableBitField(Requester.BitField);
            BlockInfo?requested;

            while ((requested = Picker.PickPiece(Requester, bf)).HasValue)
            {
                Requested.Enqueue(requested.Value);
                if (Requested.Count > 600)
                {
                    var popped = Requested.Dequeue();
                    if (Picker.ValidatePiece(Requester, popped, out bool done, out _))
                    {
                        if (done)
                        {
                            bf[popped.PieceIndex] = false;
                        }
                    }
                }
            }

            while (Requested.Count > 0)
            {
                Picker.ValidatePiece(Requester, Requested.Dequeue(), out bool _, out _);
            }
        }
コード例 #14
0
        public override int PickPiece(IPeer peer, BitField available, IReadOnlyList <IPeer> otherPeers, int startIndex, int endIndex, Span <BlockInfo> requests)
        {
            if (available.AllFalse)
            {
                return(0);
            }

            if (requests.Length > 1)
            {
                return(base.PickPiece(peer, available, otherPeers, startIndex, endIndex, requests));
            }

            GenerateRarestFirst(available, otherPeers);

            while (rarest.Count > 0)
            {
                MutableBitField current   = rarest.Pop();
                int             requested = base.PickPiece(peer, current, otherPeers, startIndex, endIndex, requests);
                spares.Push(current);

                if (requested > 0)
                {
                    return(requested);
                }
            }

            return(0);
        }
コード例 #15
0
 public void SetUp()
 {
     // The bool[] must be kept in sync with the byte[] constructor. They represent exactly the same thing.
     initalValues      = new[] { true, false, true, false, true, false, true, true, true, false, false, true };
     secondValues      = new[] { true, true, false, false, true, false, true, false, true, false, false, true };
     initialByteValues = new byte[] { 171, 144 };
     bf = new MutableBitField(initalValues);
 }
コード例 #16
0
 public InitialSeedUnchoker(TorrentManager manager)
     : base(manager)
 {
     advertisedPieces = new List <SeededPiece> ();
     bitfield         = new MutableBitField(manager.Bitfield.Length);
     peers            = new List <ChokeData> ();
     temp             = new MutableBitField(bitfield.Length);
 }
コード例 #17
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 MutableBitField(initialByteValues, initalValues.Length);
             Assert.Fail("The bitfield was corrupt but decoded correctly: Loop {0}", i);
         } catch (MessageException) { initialByteValues[1] -= i; }
     }
 }
コード例 #18
0
        public void Equals_False()
        {
            var bf    = new MutableBitField(10).SetAll(true);
            var other = new MutableBitField(bf).Set(5, false);

            Assert.IsFalse(bf.Equals(other));
            Assert.IsFalse(bf.Equals(null));
            Assert.IsFalse(bf.Equals(new BitField(5)));

            bf.Set(6, false);
            Assert.AreEqual(bf.TrueCount, other.TrueCount);
            Assert.IsFalse(bf.Equals(other));
        }
コード例 #19
0
        public void TwoPieceRange()
        {
            var onePiece = new MutableBitField(seeder.BitField.Length).Set(0, true);

            picker.PickPiece(seeder, onePiece, new List <PeerId> (), 1, 12, 14);

            Assert.AreEqual(2, checker.Picks.Count, "#1");
            Assert.AreEqual(13, checker.Picks[0].startIndex, "#2");
            Assert.AreEqual(14, checker.Picks[0].endIndex, "#3");

            Assert.AreEqual(12, checker.Picks[1].startIndex, "#4");
            Assert.AreEqual(13, checker.Picks[1].endIndex, "#5");
        }
コード例 #20
0
        public override void Initialise(ITorrentData torrentData)
        {
            base.Initialise(torrentData);

            allPrioritisedPieces = new MutableBitField(torrentData.PieceCount());
            temp = new MutableBitField(torrentData.PieceCount());

            files.Clear();
            for (int i = 0; i < torrentData.Files.Count; i++)
            {
                files.Add(new Files(torrentData.Files[i]));
            }
            BuildSelectors();
        }
コード例 #21
0
        public void Setup()
        {
            singleFile     = CreateSingleFile();
            singleBitfield = new MutableBitField(singleFile.PieceCount()).SetAll(true);
            singlePeer     = PeerId.CreateNull(singleBitfield.Length);

            multiFile     = CreateMultiFile();
            multiBitfield = new MutableBitField(multiFile.PieceCount()).SetAll(true);
            multiPeer     = PeerId.CreateNull(multiBitfield.Length);

            checker = new PiecePickerFilterChecker();
            picker  = new PriorityPicker(checker);
            peers   = new List <PeerId> ();
        }
コード例 #22
0
ファイル: PieceManager.cs プロジェクト: xuesongTX/monotorrent
        internal void Initialise()
        {
            if (Manager.HasMetadata)
            {
                Initialised            = true;
                PendingHashCheckPieces = new MutableBitField(Manager.Bitfield.Length);

                var ignorableBitfieds = new[] {
                    Manager.Bitfield,
                    PendingHashCheckPieces,
                    Manager.UnhashedPieces,
                };
                Requester.Initialise(Manager, ignorableBitfieds);
            }
        }
コード例 #23
0
        public void Initialise(ITorrentData torrentData, IReadOnlyList <BitField> ignoringBitfields)
        {
            IgnorableBitfields = ignoringBitfields;
            TorrentData        = torrentData;

            Temp = new MutableBitField(TorrentData.PieceCount());

            IPiecePicker picker = new StandardPicker();

            picker = new RandomisedPicker(picker);
            picker = new RarestFirstPicker(picker);
            Picker = new PriorityPicker(picker);

            Picker.Initialise(torrentData);
        }
コード例 #24
0
        public void MultiFile_EveryPriority()
        {
            picker.Initialise(multiFile);

            multiFile.Files[0].Priority = Priority.Normal;
            multiFile.Files[1].Priority = Priority.DoNotDownload;
            multiFile.Files[2].Priority = Priority.Highest;
            multiFile.Files[3].Priority = Priority.High;
            multiFile.Files[4].Priority = Priority.Lowest;
            multiFile.Files[5].Priority = Priority.Low;
            multiFile.Files[6].Priority = Priority.DoNotDownload; // 12 byte file
            multiFile.Files[7].Priority = Priority.High;          // 12 byte file

            Span <BlockInfo> buffer = stackalloc BlockInfo[1];

            picker.PickPiece(multiPeer, multiBitfield, peers, 0, multiBitfield.Length - 1, buffer);
            Assert.AreEqual(5, checker.Picks.Count, "#1");

            // Make sure every downloadable file is available
            var bf = new MutableBitField(multiBitfield.Length);

            foreach (var file in multiFile.Files.Where(t => t.Priority != Priority.DoNotDownload))
            {
                Assert.IsTrue(picker.IsInteresting(multiPeer, bf.SetAll(false).Set(file.StartPieceIndex, true)), "#2");
                Assert.IsTrue(picker.IsInteresting(multiPeer, bf.SetAll(false).Set(file.EndPieceIndex, true)), "#3");
            }

            // Make sure the not downloadable file is not available and
            // that everything was selected in priority order.
            Assert.IsFalse(picker.IsInteresting(multiPeer, bf.SetAll(false).Set(multiFile.Files[1].StartPieceIndex + 1, true)), "#4");
            Assert.IsFalse(picker.IsInteresting(multiPeer, bf.SetAll(false).Set(multiFile.Files[1].EndPieceIndex - 1, true)), "#5");

            bf = new MutableBitField(multiBitfield.Length).SetTrue(multiFile.Files[2].GetSelector());
            Assert.AreEqual(bf, checker.Picks[0].available, "#6");

            bf = new MutableBitField(multiBitfield.Length).SetTrue(multiFile.Files[3].GetSelector())
                 .SetTrue(multiFile.Files[7].GetSelector());
            Assert.AreEqual(bf, checker.Picks[1].available, "#7");

            bf = new MutableBitField(multiBitfield.Length).SetTrue(multiFile.Files[0].GetSelector());
            Assert.AreEqual(bf, checker.Picks[2].available, "#8");

            bf = new MutableBitField(multiBitfield.Length).SetTrue(multiFile.Files[5].GetSelector());
            Assert.AreEqual(bf, checker.Picks[3].available, "#9");

            bf = new MutableBitField(multiBitfield.Length).SetTrue(multiFile.Files[4].GetSelector());
            Assert.AreEqual(bf, checker.Picks[4].available, "#10");
        }
コード例 #25
0
        public void LoadEncoded()
        {
            var unhashedPieces = new MutableBitField(10).SetAll(false);
            var downloaded     = new MutableBitField(10).SetAll(true);
            var fastResume     = new FastResume(InfoHash, downloaded, unhashedPieces);
            var stream         = new MemoryStream();

            fastResume.Encode(stream);
            Assert.IsTrue(stream.Length > 0, "#1");

            stream.Seek(0, SeekOrigin.Begin);
            Assert.IsTrue(FastResume.TryLoad(stream, out var newFastResume), "#2");
            Assert.IsNotNull(newFastResume, "#3");
            Assert.IsTrue(newFastResume.UnhashedPieces.AllFalse, "#4");
            Assert.IsTrue(newFastResume.Bitfield.AllTrue, "#5");
        }
コード例 #26
0
        public async Task FastResume_NoneExist ()
        {
            var bf = new MutableBitField (Manager.PieceCount ()).SetAll (true);
            Manager.LoadFastResume (new FastResume (Manager.InfoHash, bf, Manager.UnhashedPieces.SetAll (false)));

            Assert.IsTrue (Manager.Bitfield.AllTrue, "#1");
            foreach (var file in Manager.Files)
                Assert.IsTrue (file.BitField.AllTrue, "#2." + file.Path);

            var startingMode = new StartingMode (Manager, DiskManager, ConnectionManager, Settings);
            Manager.Mode = startingMode;
            await startingMode.WaitForStartingToComplete ();

            Assert.IsTrue (Manager.Bitfield.AllFalse, "#3");
            foreach (var file in Manager.Files)
                Assert.IsTrue (file.BitField.AllFalse, "#4." + file.Path);
        }
コード例 #27
0
        public void DupeRequests_CanRequestInTriplicate()
        {
            var seeders = new IPeer[] {
                PeerId.CreateNull(bitfield.Length, true, false, true),
                PeerId.CreateNull(bitfield.Length, true, false, true),
                PeerId.CreateNull(bitfield.Length, true, false, true),
            };

            var queue       = new Queue <IPeer> (seeders);
            var requests    = seeders.ToDictionary(t => t, t => new List <BlockInfo> ());
            var singlePiece = new MutableBitField(seeders[0].BitField).SetAll(false).Set(3, true);

            // Request an entire piece using 1 peer first to ensure we have collisions when
            // issuing duplicates. In the end all peers should have the same set though.
            while (true)
            {
                var req = picker.PickPiece(seeders[0], singlePiece)
                          ?? picker.ContinueAnyExistingRequest(seeders[0], 0, bitfield.Length - 1, 3);
                if (req.HasValue)
                {
                    requests[seeders[0]].Add(req.Value);
                }
                else
                {
                    break;
                }
            }
            Assert.AreEqual(torrentData.BlocksPerPiece, requests[seeders[0]].Count);

            while (queue.Count > 0)
            {
                var seeder = queue.Dequeue();
                var req    = picker.PickPiece(seeder, singlePiece)
                             ?? picker.ContinueAnyExistingRequest(seeder, 0, bitfield.Length - 1, 3);

                if (req.HasValue)
                {
                    queue.Enqueue(seeder);
                    requests[seeder].Add(req.Value);
                }
            }

            CollectionAssert.AreEquivalent(requests[seeders[0]], requests[seeders[1]]);
            CollectionAssert.AreEquivalent(requests[seeders[1]], requests[seeders[2]]);
            Assert.AreEqual(torrentData.BlocksPerPiece, requests.Values.First().Count);
        }
コード例 #28
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 = 1; i < a.Length * 8; i++)
            {
                var first  = new MutableBitField(a, i);
                var second = new MutableBitField(b, i);

                first.And(second);
            }
        }
コード例 #29
0
        public void From()
        {
            MutableBitField b = new MutableBitField(31);

            b.SetAll(true);
            Assert.AreEqual(31, b.TrueCount, "#1");
            Assert.IsTrue(b.AllTrue, "#1b");

            b = new MutableBitField(32);
            b.SetAll(true);
            Assert.AreEqual(32, b.TrueCount, "#2");
            Assert.IsTrue(b.AllTrue, "#2b");

            b = new MutableBitField(33);
            b.SetAll(true);
            Assert.AreEqual(33, b.TrueCount, "#3");
            Assert.IsTrue(b.AllTrue, "#3b");
        }
コード例 #30
0
        public void Initialise(ITorrentData torrentData, IReadOnlyList <BitField> ignoringBitfields)
        {
            TorrentData       = torrentData;
            IgnoringBitfields = ignoringBitfields;
            Temp = new MutableBitField(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);
        }