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); }
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()); } }
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."); } } }
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); } }
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]); } }