Skip to content

Commit

Permalink
2008-05-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Browse files Browse the repository at this point in the history
	In piece selection functions, Pass std::deque<...> by reference 
rather
	than returning it.
	* src/BitfieldMan.cc
	* src/BitfieldMan.h
	* src/DefaultBtRequestFactory.cc
	* src/DefaultPieceStorage.cc
	* src/Piece.cc
	* src/Piece.h
	* test/BitfieldManTest.cc
  • Loading branch information
tatsuhiro-t committed May 11, 2008
1 parent a702d60 commit bf5a8c3
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 45 deletions.
12 changes: 12 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
2008-05-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

In piece selection functions, Pass std::deque<...> by reference rather
than returning it.
* src/BitfieldMan.cc
* src/BitfieldMan.h
* src/DefaultBtRequestFactory.cc
* src/DefaultPieceStorage.cc
* src/Piece.cc
* src/Piece.h
* test/BitfieldManTest.cc

2008-05-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Implemented rarest piece first piece selection strategy.
Expand Down
33 changes: 20 additions & 13 deletions src/BitfieldMan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -388,53 +388,60 @@ bool BitfieldMan::getSparseMissingUnusedIndex(size_t& index) const {
}

template<typename Array>
std::deque<size_t>
BitfieldMan::getAllMissingIndexes(const Array& bitfield, size_t bitfieldLength) const
bool BitfieldMan::getAllMissingIndexes(std::deque<size_t>& indexes,
const Array& bitfield,
size_t bitfieldLength) const
{
std::deque<size_t> missingIndexes;
for(size_t i = 0; i < bitfieldLength; ++i) {
size_t base = i*8;
for(size_t bi = 0; bi < 8 && base+bi < blocks; ++bi) {
unsigned char mask = 128 >> bi;
if(bitfield[i] & mask) {
missingIndexes.push_back(base+bi);
indexes.push_back(base+bi);
}
}
}
return missingIndexes;
return !indexes.empty();
}

std::deque<size_t> BitfieldMan::getAllMissingIndexes() const {
bool BitfieldMan::getAllMissingIndexes(std::deque<size_t>& indexes) const
{
array_fun<unsigned char> bf = array_negate(bitfield);
if(filterEnabled) {
bf = array_and(bf, filterBitfield);
}
return getAllMissingIndexes(bf, bitfieldLength);
return getAllMissingIndexes(indexes, bf, bitfieldLength);
}

std::deque<size_t> BitfieldMan::getAllMissingIndexes(const unsigned char* peerBitfield, size_t peerBitfieldLength) const {
bool BitfieldMan::getAllMissingIndexes(std::deque<size_t>& indexes,
const unsigned char* peerBitfield,
size_t peerBitfieldLength) const
{
if(bitfieldLength != peerBitfieldLength) {
return std::deque<size_t>();
return false;
}
array_fun<unsigned char> bf = array_and(array_negate(bitfield),
peerBitfield);
if(filterEnabled) {
bf = array_and(bf, filterBitfield);
}
return getAllMissingIndexes(bf, bitfieldLength);
return getAllMissingIndexes(indexes, bf, bitfieldLength);
}

std::deque<size_t> BitfieldMan::getAllMissingUnusedIndexes(const unsigned char* peerBitfield, size_t peerBitfieldLength) const {
bool BitfieldMan::getAllMissingUnusedIndexes(std::deque<size_t>& indexes,
const unsigned char* peerBitfield,
size_t peerBitfieldLength) const
{
if(bitfieldLength != peerBitfieldLength) {
return std::deque<size_t>();
return false;
}
array_fun<unsigned char> bf = array_and(array_and(array_negate(bitfield),
array_negate(useBitfield)),
peerBitfield);
if(filterEnabled) {
bf = array_and(bf, filterBitfield);
}
return getAllMissingIndexes(bf, bitfieldLength);
return getAllMissingIndexes(indexes, bf, bitfieldLength);
}

size_t BitfieldMan::countMissingBlock() const {
Expand Down
14 changes: 9 additions & 5 deletions src/BitfieldMan.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ class BitfieldMan {
bool getFirstMissingIndex(size_t& index, const Array& bitfield, size_t bitfieldLength) const;

template<typename Array>
std::deque<size_t> getAllMissingIndexes(const Array& bitfield, size_t bitfieldLength) const;
bool getAllMissingIndexes(std::deque<size_t>& indexes,
const Array& bitfield,
size_t bitfieldLength) const;

bool isBitSetInternal(const unsigned char* bitfield, size_t index) const;
bool setBitInternal(unsigned char* bitfield, size_t index, bool on);
Expand Down Expand Up @@ -137,16 +139,18 @@ class BitfieldMan {
/**
* affected by filter
*/
std::deque<size_t> getAllMissingIndexes() const;
bool getAllMissingIndexes(std::deque<size_t>&indexes) const;
/**
* affected by filter
*/
std::deque<size_t> getAllMissingIndexes(const unsigned char* bitfield, size_t len) const;
bool getAllMissingIndexes(std::deque<size_t>& indexes,
const unsigned char* bitfield, size_t len) const;
/**
* affected by filter
*/
std::deque<size_t> getAllMissingUnusedIndexes(const unsigned char* bitfield,
size_t len) const;
bool getAllMissingUnusedIndexes(std::deque<size_t>& indexes,
const unsigned char* bitfield,
size_t len) const;
/**
* affected by filter
*/
Expand Down
3 changes: 2 additions & 1 deletion src/DefaultBtRequestFactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ BtMessages DefaultBtRequestFactory::createRequestMessagesOnEndGame(size_t max)
for(Pieces::iterator itr = pieces.begin();
itr != pieces.end() && requests.size() < max; itr++) {
PieceHandle& piece = *itr;
std::deque<size_t> missingBlockIndexes = piece->getAllMissingBlockIndexes();
std::deque<size_t> missingBlockIndexes;
piece->getAllMissingBlockIndexes(missingBlockIndexes);
random_shuffle(missingBlockIndexes.begin(), missingBlockIndexes.end());
for(std::deque<size_t>::const_iterator bitr = missingBlockIndexes.begin();
bitr != missingBlockIndexes.end() && requests.size() < max; bitr++) {
Expand Down
33 changes: 18 additions & 15 deletions src/DefaultPieceStorage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,23 +142,26 @@ class FindRarestPiece

bool DefaultPieceStorage::getMissingPieceIndex(size_t& index, const PeerHandle& peer)
{
std::deque<size_t> indexes;
bool r;
if(isEndGame()) {
return bitfieldMan->getMissingIndex(index, peer->getBitfield(),
peer->getBitfieldLength());
r = bitfieldMan->getAllMissingIndexes(indexes, peer->getBitfield(),
peer->getBitfieldLength());
} else {
std::deque<size_t> indexes =
bitfieldMan->getAllMissingUnusedIndexes(peer->getBitfield(),
peer->getBitfieldLength());
if(indexes.empty()) {
return false;
} else {
std::sort(indexes.begin(), indexes.end());
std::deque<SharedHandle<PieceStat> >::const_iterator i =
std::find_if(_sortedPieceStats.begin(), _sortedPieceStats.end(),
FindRarestPiece(indexes));
index = (*i)->getIndex();
return true;
}
r = bitfieldMan->getAllMissingUnusedIndexes(indexes,
peer->getBitfield(),
peer->getBitfieldLength());
}
if(r) {
// We assume indexes is sorted using comparator less.
//std::sort(indexes.begin(), indexes.end());
std::deque<SharedHandle<PieceStat> >::const_iterator i =
std::find_if(_sortedPieceStats.begin(), _sortedPieceStats.end(),
FindRarestPiece(indexes));
index = (*i)->getIndex();
return true;
} else {
return false;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Piece.cc
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ bool Piece::getFirstMissingBlockIndexWithoutLock(size_t& index) const
return bitfield->getFirstMissingIndex(index);
}

std::deque<size_t> Piece::getAllMissingBlockIndexes() const {
return bitfield->getAllMissingIndexes();
bool Piece::getAllMissingBlockIndexes(std::deque<size_t>& indexes) const {
return bitfield->getAllMissingIndexes(indexes);
}

std::string Piece::toString() const {
Expand Down
2 changes: 1 addition & 1 deletion src/Piece.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class Piece {
bool getMissingUnusedBlockIndex(size_t& index) const;
bool getMissingBlockIndex(size_t& index) const;
bool getFirstMissingBlockIndexWithoutLock(size_t& index) const;
std::deque<size_t> getAllMissingBlockIndexes() const;
bool getAllMissingBlockIndexes(std::deque<size_t>& indexes) const;
void completeBlock(size_t blockIndex);
void cancelBlock(size_t blockIndex);

Expand Down
63 changes: 55 additions & 8 deletions test/BitfieldManTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class BitfieldManTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testSetBitRange);
CPPUNIT_TEST(testGetAllMissingIndexes);
CPPUNIT_TEST(testGetAllMissingIndexes_noarg);
CPPUNIT_TEST(testGetAllMissingUnusedIndexes);
CPPUNIT_TEST(testGetMissingUnusedIndex);
CPPUNIT_TEST(testGetMissingIndex_noarg);
CPPUNIT_TEST(testGetMissingUnusedIndex_noarg);
Expand Down Expand Up @@ -48,7 +49,8 @@ class BitfieldManTest:public CppUnit::TestFixture {
void testGetMissingUnusedIndex_noarg();
void testGetAllMissingIndexes();
void testGetAllMissingIndexes_noarg();

void testGetAllMissingUnusedIndexes();

void testIsAllBitSet();
void testFilter();
void testGetSparceMissingUnusedIndex();
Expand Down Expand Up @@ -594,12 +596,20 @@ void BitfieldManTest::testGetAllMissingIndexes_noarg()
uint64_t totalLength = 1024*1024;
BitfieldMan bf(blockLength, totalLength);

CPPUNIT_ASSERT_EQUAL((size_t)64, bf.getAllMissingIndexes().size());
{
std::deque<size_t> indexes;
CPPUNIT_ASSERT(bf.getAllMissingIndexes(indexes));
CPPUNIT_ASSERT_EQUAL((size_t)64, indexes.size());
}
for(size_t i = 0; i < 63; ++i) {
bf.setBit(i);
}
CPPUNIT_ASSERT_EQUAL((size_t)1, bf.getAllMissingIndexes().size());
CPPUNIT_ASSERT_EQUAL((size_t)63, bf.getAllMissingIndexes().front());
{
std::deque<size_t> indexes;
CPPUNIT_ASSERT(bf.getAllMissingIndexes(indexes));
CPPUNIT_ASSERT_EQUAL((size_t)1, indexes.size());
CPPUNIT_ASSERT_EQUAL((size_t)63, indexes.front());
}
}

void BitfieldManTest::testGetAllMissingIndexes()
Expand All @@ -610,16 +620,53 @@ void BitfieldManTest::testGetAllMissingIndexes()
BitfieldMan peerBf(blockLength, totalLength);
peerBf.setAllBit();

CPPUNIT_ASSERT_EQUAL((size_t)64, bf.getAllMissingIndexes(peerBf.getBitfield(),
peerBf.getBitfieldLength()).size());
{
std::deque<size_t> indexes;
CPPUNIT_ASSERT(bf.getAllMissingIndexes(indexes,
peerBf.getBitfield(),
peerBf.getBitfieldLength()));
CPPUNIT_ASSERT_EQUAL((size_t)64, indexes.size());
}
for(size_t i = 0; i < 62; ++i) {
bf.setBit(i);
}
peerBf.unsetBit(62);
{
std::deque<size_t> indexes;
CPPUNIT_ASSERT(bf.getAllMissingIndexes(indexes,
peerBf.getBitfield(),
peerBf.getBitfieldLength()));

CPPUNIT_ASSERT_EQUAL((size_t)1, indexes.size());
CPPUNIT_ASSERT_EQUAL((size_t)63, indexes.front());
}
}

void BitfieldManTest::testGetAllMissingUnusedIndexes()
{
size_t blockLength = 16*1024;
uint64_t totalLength = 1024*1024;
BitfieldMan bf(blockLength, totalLength);
BitfieldMan peerBf(blockLength, totalLength);
peerBf.setAllBit();

{
std::deque<size_t> indexes = bf.getAllMissingIndexes(peerBf.getBitfield(),
peerBf.getBitfieldLength());
std::deque<size_t> indexes;
CPPUNIT_ASSERT(bf.getAllMissingUnusedIndexes(indexes,
peerBf.getBitfield(),
peerBf.getBitfieldLength()));
CPPUNIT_ASSERT_EQUAL((size_t)64, indexes.size());
}
for(size_t i = 0; i < 61; ++i) {
bf.setBit(i);
}
bf.setUseBit(61);
peerBf.unsetBit(62);
{
std::deque<size_t> indexes;
CPPUNIT_ASSERT(bf.getAllMissingUnusedIndexes(indexes,
peerBf.getBitfield(),
peerBf.getBitfieldLength()));

CPPUNIT_ASSERT_EQUAL((size_t)1, indexes.size());
CPPUNIT_ASSERT_EQUAL((size_t)63, indexes.front());
Expand Down

0 comments on commit bf5a8c3

Please sign in to comment.