diff --git a/ChangeLog b/ChangeLog index 186b8bf4..df477adf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2008-06-17 Tatsuhiro Tsujikawa + + Filled up pieces based on the number of missing blocks, rather than + simplay the number of piece * block length. + * src/BtRequestFactory.h + * src/DefaultBtInteractive.cc + * src/DefaultBtInteractive.h + * src/DefaultBtRequestFactory.cc + * src/DefaultBtRequestFactory.h + * src/Piece.cc + * src/Piece.h + * test/BitfieldManTest.cc + * test/DefaultBtRequestFactoryTest.cc + * test/MockBtRequestFactory.h + 2008-06-17 Tatsuhiro Tsujikawa Made _epEvents a member variable. diff --git a/src/BtRequestFactory.h b/src/BtRequestFactory.h index bba4cfc2..ae31966d 100644 --- a/src/BtRequestFactory.h +++ b/src/BtRequestFactory.h @@ -56,6 +56,8 @@ public: virtual size_t countTargetPiece() = 0; + virtual size_t countMissingBlock() = 0; + virtual void removeCompletedPiece() = 0; virtual void doChokedAction() = 0; diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc index a1b45c47..9d24e475 100644 --- a/src/DefaultBtInteractive.cc +++ b/src/DefaultBtInteractive.cc @@ -288,26 +288,32 @@ void DefaultBtInteractive::decideInterest() { } } -void DefaultBtInteractive::fillPiece(size_t maxPieceNum) { +void DefaultBtInteractive::fillPiece(size_t maxMissingBlock) { if(pieceStorage->hasMissingPiece(peer)) { + + size_t numMissingBlock = btRequestFactory->countMissingBlock(); + if(peer->peerChoking()) { if(peer->isFastExtensionEnabled()) { - while(btRequestFactory->countTargetPiece() < maxPieceNum) { + + while(numMissingBlock < maxMissingBlock) { PieceHandle piece = pieceStorage->getMissingFastPiece(peer); if(piece.isNull()) { break; } else { btRequestFactory->addTargetPiece(piece); + numMissingBlock += piece->countMissingBlock(); } } } } else { - while(btRequestFactory->countTargetPiece() < maxPieceNum) { + while(numMissingBlock < maxMissingBlock) { PieceHandle piece = pieceStorage->getMissingPiece(peer); if(piece.isNull()) { break; } else { btRequestFactory->addTargetPiece(piece); + numMissingBlock += piece->countMissingBlock(); } } } @@ -323,14 +329,7 @@ void DefaultBtInteractive::addRequests() { } else { MAX_PENDING_REQUEST = 6; } - size_t pieceNum; - if(pieceStorage->isEndGame()) { - pieceNum = 1; - } else { - size_t blocks = DIV_FLOOR(btContext->getPieceLength(), Piece::BLOCK_LENGTH); - pieceNum = DIV_FLOOR(MAX_PENDING_REQUEST, blocks); - } - fillPiece(pieceNum); + fillPiece(MAX_PENDING_REQUEST); size_t reqNumToCreate = MAX_PENDING_REQUEST <= dispatcher->countOutstandingRequest() ? diff --git a/src/DefaultBtInteractive.h b/src/DefaultBtInteractive.h index 0e8a1425..f7f47a33 100644 --- a/src/DefaultBtInteractive.h +++ b/src/DefaultBtInteractive.h @@ -122,7 +122,7 @@ private: void checkHave(); void sendKeepAlive(); void decideInterest(); - void fillPiece(size_t maxPieceNum); + void fillPiece(size_t maxMissingBlock); void addRequests(); void detectMessageFlooding(); void checkActiveInteraction(); diff --git a/src/DefaultBtRequestFactory.cc b/src/DefaultBtRequestFactory.cc index 3f52642a..616367b4 100644 --- a/src/DefaultBtRequestFactory.cc +++ b/src/DefaultBtRequestFactory.cc @@ -186,6 +186,30 @@ void DefaultBtRequestFactory::createRequestMessagesOnEndGame } } +class CountMissingBlock +{ +private: + size_t _numMissingBlock; +public: + CountMissingBlock():_numMissingBlock(0) {} + + size_t getNumMissingBlock() + { + return _numMissingBlock; + } + + void operator()(const SharedHandle& piece) + { + _numMissingBlock += piece->countMissingBlock(); + } +}; + +size_t DefaultBtRequestFactory::countMissingBlock() +{ + return std::for_each(pieces.begin(), pieces.end(), + CountMissingBlock()).getNumMissingBlock(); +} + std::deque >& DefaultBtRequestFactory::getTargetPieces() { return pieces; diff --git a/src/DefaultBtRequestFactory.h b/src/DefaultBtRequestFactory.h index 49252180..84cf701f 100644 --- a/src/DefaultBtRequestFactory.h +++ b/src/DefaultBtRequestFactory.h @@ -72,6 +72,8 @@ public: return pieces.size(); } + virtual size_t countMissingBlock(); + virtual void removeCompletedPiece(); virtual void doChokedAction(); diff --git a/src/Piece.cc b/src/Piece.cc index 4745a08d..b06a8eb9 100644 --- a/src/Piece.cc +++ b/src/Piece.cc @@ -162,6 +162,11 @@ size_t Piece::countCompleteBlock() const return bitfield->countBlock()-bitfield->countMissingBlock(); } +size_t Piece::countMissingBlock() const +{ + return bitfield->countMissingBlock(); +} + bool Piece::hasBlock(size_t blockIndex) const { return bitfield->isBitSet(blockIndex); diff --git a/src/Piece.h b/src/Piece.h index dcd9429c..d0940320 100644 --- a/src/Piece.h +++ b/src/Piece.h @@ -95,6 +95,8 @@ public: size_t countCompleteBlock() const; + size_t countMissingBlock() const; + bool hasBlock(size_t blockIndex) const; /** diff --git a/test/BitfieldManTest.cc b/test/BitfieldManTest.cc index 2ab8e936..75f3ca22 100644 --- a/test/BitfieldManTest.cc +++ b/test/BitfieldManTest.cc @@ -26,6 +26,7 @@ class BitfieldManTest:public CppUnit::TestFixture { CPPUNIT_TEST(testGetMissingIndex_noarg); CPPUNIT_TEST(testGetMissingUnusedIndex_noarg); CPPUNIT_TEST(testCountFilteredBlock); + CPPUNIT_TEST(testCountMissingBlock); CPPUNIT_TEST_SUITE_END(); private: SharedHandle fixedNumberRandomizer; @@ -59,6 +60,7 @@ public: void testGetMissingUnusedLength(); void testSetBitRange(); void testCountFilteredBlock(); + void testCountMissingBlock(); }; @@ -741,4 +743,14 @@ void BitfieldManTest::testCountFilteredBlock() CPPUNIT_ASSERT_EQUAL((size_t)0, bt.countFilteredBlock()); } +void BitfieldManTest::testCountMissingBlock() +{ + BitfieldMan bt(1024, 1024*10); + CPPUNIT_ASSERT_EQUAL((size_t)10, bt.countMissingBlock()); + bt.setBit(1); + CPPUNIT_ASSERT_EQUAL((size_t)9, bt.countMissingBlock()); + bt.setAllBit(); + CPPUNIT_ASSERT_EQUAL((size_t)0, bt.countMissingBlock()); +} + } // namespace aria2 diff --git a/test/DefaultBtRequestFactoryTest.cc b/test/DefaultBtRequestFactoryTest.cc index 3fae76c1..299b6f7d 100644 --- a/test/DefaultBtRequestFactoryTest.cc +++ b/test/DefaultBtRequestFactoryTest.cc @@ -123,9 +123,18 @@ public: CPPUNIT_TEST_SUITE_REGISTRATION(DefaultBtRequestFactoryTest); void DefaultBtRequestFactoryTest::testAddTargetPiece() { - SharedHandle piece(new Piece(0, 16*1024)); - btRequestFactory->addTargetPiece(piece); - CPPUNIT_ASSERT_EQUAL((size_t)1, btRequestFactory->countTargetPiece()); + { + SharedHandle piece(new Piece(0, 16*1024*10)); + btRequestFactory->addTargetPiece(piece); + CPPUNIT_ASSERT_EQUAL((size_t)1, btRequestFactory->countTargetPiece()); + } + { + SharedHandle piece(new Piece(1, 16*1024*9)); + piece->completeBlock(0); + btRequestFactory->addTargetPiece(piece); + CPPUNIT_ASSERT_EQUAL((size_t)2, btRequestFactory->countTargetPiece()); + } + CPPUNIT_ASSERT_EQUAL((size_t)18, btRequestFactory->countMissingBlock()); } void DefaultBtRequestFactoryTest::testRemoveCompletedPiece() { diff --git a/test/MockBtRequestFactory.h b/test/MockBtRequestFactory.h index 5a9fa7ee..fa0d2721 100644 --- a/test/MockBtRequestFactory.h +++ b/test/MockBtRequestFactory.h @@ -17,6 +17,8 @@ public: virtual size_t countTargetPiece() { return 0; } + virtual size_t countMissingBlock() { return 0; } + virtual void removeCompletedPiece() {} virtual void doChokedAction() {}