diff --git a/ChangeLog b/ChangeLog index f92c2900..1d67a380 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2009-05-06 Tatsuhiro Tsujikawa + + Moved piece statistics stuff to new PieceStatMan class. + Refactored PieceSelector interface. + * src/DefaultPieceStorage.cc + * src/DefaultPieceStorage.h + * src/LongestSequencePieceSelector.cc + * src/LongestSequencePieceSelector.h + * src/Makefile.am + * src/PieceSelector.h + * src/PieceStatMan.cc + * src/PieceStatMan.h + * src/RarestPieceSelector.cc + * src/RarestPieceSelector.h + * src/RequestGroup.cc + * test/DefaultPieceStorageTest.cc + * test/InOrderPieceSelector.h + * test/Makefile.am + * test/PieceStatManTest.cc + * test/RarestPieceSelectorTest.cc + 2009-05-06 Tatsuhiro Tsujikawa Added static member _protocolFamily to SocketCore. By default, diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc index 08d48515..696a3613 100644 --- a/src/DefaultPieceStorage.cc +++ b/src/DefaultPieceStorage.cc @@ -58,13 +58,12 @@ #include "StringFormat.h" #include "RarestPieceSelector.h" #include "array_fun.h" +#include "PieceStatMan.h" namespace aria2 { DefaultPieceStorage::DefaultPieceStorage -(const DownloadContextHandle& downloadContext, - const Option* option, - const SharedHandle& pieceSelector): +(const DownloadContextHandle& downloadContext, const Option* option): downloadContext(downloadContext), bitfieldMan(BitfieldManFactory::getFactoryInstance()-> createBitfieldMan(downloadContext->getPieceLength(), @@ -73,13 +72,9 @@ DefaultPieceStorage::DefaultPieceStorage endGamePieceNum(END_GAME_PIECE_NUM), logger(LogFactory::getInstance()), option(option), - _pieceSelector(pieceSelector) -{ - if(_pieceSelector.isNull()) { - _pieceSelector.reset - (new RarestPieceSelector(downloadContext->getNumPieces(), true)); - } -} + _pieceStatMan(new PieceStatMan(downloadContext->getNumPieces(), true)), + _pieceSelector(new RarestPieceSelector(_pieceStatMan)) +{} DefaultPieceStorage::~DefaultPieceStorage() { delete bitfieldMan; @@ -653,26 +648,26 @@ void DefaultPieceStorage::setDiskWriterFactory(const DiskWriterFactoryHandle& di void DefaultPieceStorage::addPieceStats(const unsigned char* bitfield, size_t bitfieldLength) { - _pieceSelector->addPieceStats(bitfield, bitfieldLength); + _pieceStatMan->addPieceStats(bitfield, bitfieldLength); } void DefaultPieceStorage::subtractPieceStats(const unsigned char* bitfield, size_t bitfieldLength) { - _pieceSelector->subtractPieceStats(bitfield, bitfieldLength); + _pieceStatMan->subtractPieceStats(bitfield, bitfieldLength); } void DefaultPieceStorage::updatePieceStats(const unsigned char* newBitfield, size_t newBitfieldLength, const unsigned char* oldBitfield) { - _pieceSelector->updatePieceStats(newBitfield, newBitfieldLength, + _pieceStatMan->updatePieceStats(newBitfield, newBitfieldLength, oldBitfield); } void DefaultPieceStorage::addPieceStats(size_t index) { - _pieceSelector->addPieceStats(index); + _pieceStatMan->addPieceStats(index); } } // namespace aria2 diff --git a/src/DefaultPieceStorage.h b/src/DefaultPieceStorage.h index 66f7eb84..b00348c9 100644 --- a/src/DefaultPieceStorage.h +++ b/src/DefaultPieceStorage.h @@ -45,6 +45,7 @@ class Logger; class Option; class DiskWriterFactory; class FileEntry; +class PieceStatMan; class PieceSelector; #define END_GAME_PIECE_NUM 20 @@ -81,6 +82,8 @@ private: const Option* option; Haves haves; + SharedHandle _pieceStatMan; + SharedHandle _pieceSelector; bool getMissingPieceIndex(size_t& index, @@ -108,9 +111,7 @@ public: // If it is set to false, a piece whose index is smallest has the highest // priority. DefaultPieceStorage(const SharedHandle& downloadContext, - const Option* option, - const SharedHandle& pieceSelector - = SharedHandle()); + const Option* option); virtual ~DefaultPieceStorage(); @@ -223,6 +224,16 @@ public: void addUsedPiece(const SharedHandle& piece); void setDiskWriterFactory(const SharedHandle& diskWriterFactory); + + const SharedHandle& getPieceStatMan() const + { + return _pieceStatMan; + } + + void setPieceSelector(const SharedHandle& pieceSelector) + { + _pieceSelector = pieceSelector; + } }; typedef SharedHandle DefaultPieceStorageHandle; diff --git a/src/LongestSequencePieceSelector.cc b/src/LongestSequencePieceSelector.cc index e1582cca..243175e9 100644 --- a/src/LongestSequencePieceSelector.cc +++ b/src/LongestSequencePieceSelector.cc @@ -85,16 +85,4 @@ bool LongestSequencePieceSelector::select } } -void LongestSequencePieceSelector::addPieceStats -(const unsigned char* bitfield, size_t bitfieldLength) {} - -void LongestSequencePieceSelector::subtractPieceStats -(const unsigned char* bitfield, size_t bitfieldLength) {} - -void LongestSequencePieceSelector::updatePieceStats -(const unsigned char* newBitfield, size_t newBitfieldLength, - const unsigned char* oldBitfield) {} - -void LongestSequencePieceSelector::addPieceStats(size_t index) {} - } // namespace aria2 diff --git a/src/LongestSequencePieceSelector.h b/src/LongestSequencePieceSelector.h index 232b313d..d2284994 100644 --- a/src/LongestSequencePieceSelector.h +++ b/src/LongestSequencePieceSelector.h @@ -47,18 +47,6 @@ public: // returns 15 because { 10, 11, 12, 13, 14, 15 } is the longest sequence. virtual bool select (size_t& index, const unsigned char* bitfield, size_t nbits) const; - - virtual void addPieceStats(size_t index); - - virtual void addPieceStats(const unsigned char* bitfield, - size_t bitfieldLength); - - virtual void subtractPieceStats(const unsigned char* bitfield, - size_t bitfieldLength); - - virtual void updatePieceStats(const unsigned char* newBitfield, - size_t newBitfieldLength, - const unsigned char* oldBitfield); }; } // namespace aria2 diff --git a/src/Makefile.am b/src/Makefile.am index f9e1d774..9945f1a6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -117,6 +117,7 @@ SRCS = Socket.h\ PieceStorage.h\ DefaultPieceStorage.cc DefaultPieceStorage.h\ UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h\ + PieceStatMan.cc PieceStatMan.h\ StatCalc.h\ ConsoleStatCalc.cc ConsoleStatCalc.h\ TransferStat.cc TransferStat.h\ diff --git a/src/Makefile.in b/src/Makefile.in index 04ade8b4..9969bf8f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.10.1 from Makefile.am. +# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -355,8 +355,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ AutoSaveCommand.cc AutoSaveCommand.h PieceStorage.h \ DefaultPieceStorage.cc DefaultPieceStorage.h \ UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h \ - StatCalc.h ConsoleStatCalc.cc ConsoleStatCalc.h \ - TransferStat.cc TransferStat.h Dependency.h \ + PieceStatMan.cc PieceStatMan.h StatCalc.h ConsoleStatCalc.cc \ + ConsoleStatCalc.h TransferStat.cc TransferStat.h Dependency.h \ BtProgressInfoFile.h DefaultBtProgressInfoFile.cc \ DefaultBtProgressInfoFile.h NullProgressInfoFile.h \ FileAllocationIterator.h SingleFileAllocationIterator.cc \ @@ -768,8 +768,9 @@ am__objects_23 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ PStringSegment.$(OBJEXT) PStringBuildVisitor.$(OBJEXT) \ ParameterizedStringParser.$(OBJEXT) TimeBasedCommand.$(OBJEXT) \ AutoSaveCommand.$(OBJEXT) DefaultPieceStorage.$(OBJEXT) \ - UnknownLengthPieceStorage.$(OBJEXT) ConsoleStatCalc.$(OBJEXT) \ - TransferStat.$(OBJEXT) DefaultBtProgressInfoFile.$(OBJEXT) \ + UnknownLengthPieceStorage.$(OBJEXT) PieceStatMan.$(OBJEXT) \ + ConsoleStatCalc.$(OBJEXT) TransferStat.$(OBJEXT) \ + DefaultBtProgressInfoFile.$(OBJEXT) \ SingleFileAllocationIterator.$(OBJEXT) \ ContentTypeRequestGroupCriteria.$(OBJEXT) \ DownloadHandler.$(OBJEXT) DownloadHandlerConstants.$(OBJEXT) \ @@ -1008,6 +1009,7 @@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ aria2c_SOURCES = main.cc\ @@ -1084,8 +1086,8 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \ AutoSaveCommand.cc AutoSaveCommand.h PieceStorage.h \ DefaultPieceStorage.cc DefaultPieceStorage.h \ UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h \ - StatCalc.h ConsoleStatCalc.cc ConsoleStatCalc.h \ - TransferStat.cc TransferStat.h Dependency.h \ + PieceStatMan.cc PieceStatMan.h StatCalc.h ConsoleStatCalc.cc \ + ConsoleStatCalc.h TransferStat.cc TransferStat.h Dependency.h \ BtProgressInfoFile.h DefaultBtProgressInfoFile.cc \ DefaultBtProgressInfoFile.h NullProgressInfoFile.h \ FileAllocationIterator.h SingleFileAllocationIterator.cc \ @@ -1169,8 +1171,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ @@ -1466,6 +1468,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Piece.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceHashCheckIntegrityEntry.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceHashMetalinkParserState.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceStatMan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PiecedSegment.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PiecesMetalinkParserState.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Platform.Po@am__quote@ @@ -1568,7 +1571,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS diff --git a/src/PieceSelector.h b/src/PieceSelector.h index 0b229258..e6e70f5d 100644 --- a/src/PieceSelector.h +++ b/src/PieceSelector.h @@ -37,9 +37,7 @@ #include "common.h" -#include - -#include "SharedHandle.h" +#include namespace aria2 { @@ -49,18 +47,6 @@ public: virtual bool select (size_t& index, const unsigned char* bitfield, size_t nbits) const = 0; - - virtual void addPieceStats(size_t index) = 0; - - virtual void addPieceStats(const unsigned char* bitfield, - size_t bitfieldLength) = 0; - - virtual void subtractPieceStats(const unsigned char* bitfield, - size_t bitfieldLength) = 0; - - virtual void updatePieceStats(const unsigned char* newBitfield, - size_t newBitfieldLength, - const unsigned char* oldBitfield) = 0; }; } // namespace aria2 diff --git a/src/PieceStatMan.cc b/src/PieceStatMan.cc new file mode 100644 index 00000000..1afdf929 --- /dev/null +++ b/src/PieceStatMan.cc @@ -0,0 +1,218 @@ +/* */ +#include "PieceStatMan.h" + +#include + +#include "SimpleRandomizer.h" + +namespace aria2 { + +PieceStat::PieceStat(size_t index):_order(0), _index(index), _count(0) {} + +bool PieceStat::operator<(const PieceStat& pieceStat) const +{ + if(_count == pieceStat._count) { + return _order < pieceStat._order; + } else { + return _count < pieceStat._count; + } +} + +void PieceStat::addCount() +{ + if(_count < SIZE_MAX) { + ++_count; + } +} + +void PieceStat::subCount() +{ + if(_count > 0) { + --_count; + } +} + +size_t PieceStat::getIndex() const +{ + return _index; +} + +size_t PieceStat::getCount() const +{ + return _count; +} + +void PieceStat::setOrder(size_t order) +{ + _order = order; +} + +size_t PieceStat::getOrder() const +{ + return _order; +} + +class GenPieceStat { +private: + size_t _index; +public: + GenPieceStat():_index(0) {} + + SharedHandle operator()() + { + return SharedHandle(new PieceStat(_index++)); + } +}; + +PieceStatMan::PieceStatMan(size_t pieceNum, bool randomShuffle): + _pieceStats(pieceNum), + _sortedPieceStatIndexes(pieceNum) +{ + std::generate(_pieceStats.begin(), _pieceStats.end(), GenPieceStat()); + std::vector > sortedPieceStats(_pieceStats); + // we need some randomness in ordering. + if(randomShuffle) { + std::random_shuffle(sortedPieceStats.begin(), sortedPieceStats.end(), + *(SimpleRandomizer::getInstance().get())); + } + { + size_t order = 0; + for(std::vector >::iterator i = + sortedPieceStats.begin(); i != sortedPieceStats.end(); ++i) { + _sortedPieceStatIndexes[order] = (*i)->getIndex(); + (*i)->setOrder(order++); + } + } +} + +class PieceStatRarer { +private: + const std::vector >& _pieceStats; +public: + PieceStatRarer(const std::vector >& ps): + _pieceStats(ps) {} + + bool operator()(size_t lhs, size_t rhs) const + { + return _pieceStats[lhs] < _pieceStats[rhs]; + } +}; + +void PieceStatMan::addPieceStats(const unsigned char* bitfield, + size_t bitfieldLength) +{ + size_t index = 0; + for(size_t bi = 0; bi < bitfieldLength; ++bi) { + + for(size_t i = 0; i < 8; ++i, ++index) { + unsigned char mask = 128 >> i; + if(bitfield[bi]&mask) { + _pieceStats[index]->addCount(); + } + } + + } + std::sort(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(), + PieceStatRarer(_pieceStats)); +} + +void PieceStatMan::subtractPieceStats(const unsigned char* bitfield, + size_t bitfieldLength) +{ + size_t index = 0; + for(size_t bi = 0; bi < bitfieldLength; ++bi) { + + for(size_t i = 0; i < 8; ++i, ++index) { + unsigned char mask = 128 >> i; + if(bitfield[bi]&mask) { + _pieceStats[index]->subCount(); + } + } + + } + std::sort(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(), + PieceStatRarer(_pieceStats)); +} + +void PieceStatMan::updatePieceStats(const unsigned char* newBitfield, + size_t newBitfieldLength, + const unsigned char* oldBitfield) +{ + size_t index = 0; + for(size_t bi = 0; bi < newBitfieldLength; ++bi) { + + for(size_t i = 0; i < 8; ++i, ++index) { + unsigned char mask = 128 >> i; + if((newBitfield[bi]&mask) && !(oldBitfield[bi]&mask)) { + _pieceStats[index]->addCount(); + } else if(!(newBitfield[bi]&mask) && (oldBitfield[bi]&mask)) { + _pieceStats[index]->subCount(); + } + } + + } + std::sort(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(), + PieceStatRarer(_pieceStats)); +} + +void PieceStatMan::addPieceStats(size_t index) +{ + std::vector::iterator cur = + std::lower_bound(_sortedPieceStatIndexes.begin(), + _sortedPieceStatIndexes.end(), + index, PieceStatRarer(_pieceStats)); + + _pieceStats[index]->addCount(); + + std::vector::iterator to = + std::upper_bound(cur+1, _sortedPieceStatIndexes.end(), + index, PieceStatRarer(_pieceStats)); + + std::rotate(cur, cur+1, to); +} + +const std::vector& PieceStatMan::getRarerPieceIndexes() const +{ + return _sortedPieceStatIndexes; +} + +const std::vector >& +PieceStatMan::getPieceStats() const +{ + return _pieceStats; +} + +} // namespace aria2 diff --git a/src/PieceStatMan.h b/src/PieceStatMan.h new file mode 100644 index 00000000..45c26ffe --- /dev/null +++ b/src/PieceStatMan.h @@ -0,0 +1,93 @@ +/* */ +#ifndef _D_PIECE_STAT_MAN_H_ +#define _D_PIECE_STAT_MAN_H_ + +#include "common.h" + +#include + +#include "SharedHandle.h" + +namespace aria2 { + +class PieceStat { +private: + size_t _order; + size_t _index; + size_t _count; +public: + PieceStat(size_t index); + + bool operator<(const PieceStat& pieceStat) const; + + void addCount(); + void subCount(); + + size_t getOrder() const; + void setOrder(size_t order); + size_t getIndex() const; + size_t getCount() const; +}; + +class PieceStatMan { +private: + std::vector > _pieceStats; + + std::vector _sortedPieceStatIndexes; +public: + PieceStatMan(size_t pieceNum, bool randomShuffle); + + void addPieceStats(size_t index); + + void addPieceStats(const unsigned char* bitfield, + size_t bitfieldLength); + + void subtractPieceStats(const unsigned char* bitfield, + size_t bitfieldLength); + + void updatePieceStats(const unsigned char* newBitfield, + size_t newBitfieldLength, + const unsigned char* oldBitfield); + + // Returns piece index in rarest first order. + const std::vector& getRarerPieceIndexes() const; + + const std::vector >& getPieceStats() const; +}; + +} // namespace aria2 + +#endif // _D_PIECE_STAT_MAN_H_ diff --git a/src/RarestPieceSelector.cc b/src/RarestPieceSelector.cc index 0b7aabb5..2672d6a3 100644 --- a/src/RarestPieceSelector.cc +++ b/src/RarestPieceSelector.cc @@ -37,87 +37,12 @@ #include #include -#include "SimpleRandomizer.h" +#include "PieceStatMan.h" namespace aria2 { -PieceStat::PieceStat(size_t index):_order(0), _index(index), _count(0) {} - -bool PieceStat::operator<(const PieceStat& pieceStat) const -{ - if(_count == pieceStat._count) { - return _order < pieceStat._order; - } else { - return _count < pieceStat._count; - } -} - -void PieceStat::addCount() -{ - if(_count < SIZE_MAX) { - ++_count; - } -} - -void PieceStat::subCount() -{ - if(_count > 0) { - --_count; - } -} - -size_t PieceStat::getIndex() const -{ - return _index; -} - -size_t PieceStat::getCount() const -{ - return _count; -} - -void PieceStat::setOrder(size_t order) -{ - _order = order; -} - -size_t PieceStat::getOrder() const -{ - return _order; -} - -class GenPieceStat { -private: - size_t _index; -public: - GenPieceStat():_index(0) {} - - SharedHandle operator()() - { - return SharedHandle(new PieceStat(_index++)); - } -}; - -RarestPieceSelector::RarestPieceSelector(size_t pieceNum, bool randomShuffle): - _pieceStats(pieceNum), - _sortedPieceStatIndexes(pieceNum) -{ - std::generate(_pieceStats.begin(), _pieceStats.end(), GenPieceStat()); - std::vector > sortedPieceStats(_pieceStats); - // we need some randomness in ordering. - if(randomShuffle) { - std::random_shuffle(sortedPieceStats.begin(), sortedPieceStats.end(), - *(SimpleRandomizer::getInstance().get())); - } - { - size_t order = 0; - for(std::vector >::iterator i = - sortedPieceStats.begin(); i != sortedPieceStats.end(); ++i) { - _sortedPieceStatIndexes[order] = (*i)->getIndex(); - (*i)->setOrder(order++); - } - } -} +RarestPieceSelector::RarestPieceSelector +(const SharedHandle& pieceStatMan):_pieceStatMan(pieceStatMan) {} class FindRarestPiece { @@ -139,10 +64,12 @@ public: bool RarestPieceSelector::select (size_t& index, const unsigned char* bitfield, size_t nbits) const { + const std::vector& pieceIndexes = + _pieceStatMan->getRarerPieceIndexes(); std::vector::const_iterator i = - std::find_if(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(), + std::find_if(pieceIndexes.begin(), pieceIndexes.end(), FindRarestPiece(bitfield, nbits)); - if(i == _sortedPieceStatIndexes.end()) { + if(i == pieceIndexes.end()) { return false; } else { index = *i; @@ -150,102 +77,4 @@ bool RarestPieceSelector::select } } -class PieceStatRarer { -private: - const std::vector >& _pieceStats; -public: - PieceStatRarer(const std::vector >& ps): - _pieceStats(ps) {} - - bool operator()(size_t lhs, size_t rhs) const - { - return _pieceStats[lhs] < _pieceStats[rhs]; - } -}; - -void RarestPieceSelector::addPieceStats(const unsigned char* bitfield, - size_t bitfieldLength) -{ - size_t index = 0; - for(size_t bi = 0; bi < bitfieldLength; ++bi) { - - for(size_t i = 0; i < 8; ++i, ++index) { - unsigned char mask = 128 >> i; - if(bitfield[bi]&mask) { - _pieceStats[index]->addCount(); - } - } - - } - std::sort(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(), - PieceStatRarer(_pieceStats)); -} - -void RarestPieceSelector::subtractPieceStats(const unsigned char* bitfield, - size_t bitfieldLength) -{ - size_t index = 0; - for(size_t bi = 0; bi < bitfieldLength; ++bi) { - - for(size_t i = 0; i < 8; ++i, ++index) { - unsigned char mask = 128 >> i; - if(bitfield[bi]&mask) { - _pieceStats[index]->subCount(); - } - } - - } - std::sort(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(), - PieceStatRarer(_pieceStats)); -} - -void RarestPieceSelector::updatePieceStats(const unsigned char* newBitfield, - size_t newBitfieldLength, - const unsigned char* oldBitfield) -{ - size_t index = 0; - for(size_t bi = 0; bi < newBitfieldLength; ++bi) { - - for(size_t i = 0; i < 8; ++i, ++index) { - unsigned char mask = 128 >> i; - if((newBitfield[bi]&mask) && !(oldBitfield[bi]&mask)) { - _pieceStats[index]->addCount(); - } else if(!(newBitfield[bi]&mask) && (oldBitfield[bi]&mask)) { - _pieceStats[index]->subCount(); - } - } - - } - std::sort(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(), - PieceStatRarer(_pieceStats)); -} - -void RarestPieceSelector::addPieceStats(size_t index) -{ - std::vector::iterator cur = - std::lower_bound(_sortedPieceStatIndexes.begin(), - _sortedPieceStatIndexes.end(), - index, PieceStatRarer(_pieceStats)); - - _pieceStats[index]->addCount(); - - std::vector::iterator to = - std::upper_bound(cur+1, _sortedPieceStatIndexes.end(), - index, PieceStatRarer(_pieceStats)); - - std::rotate(cur, cur+1, to); -} - -const std::vector& -RarestPieceSelector::getSortedPieceStatIndexes() const -{ - return _sortedPieceStatIndexes; -} - -const std::vector >& -RarestPieceSelector::getPieceStats() const -{ - return _pieceStats; -} - } // namespace aria2 diff --git a/src/RarestPieceSelector.h b/src/RarestPieceSelector.h index 431ed406..132d22f8 100644 --- a/src/RarestPieceSelector.h +++ b/src/RarestPieceSelector.h @@ -36,56 +36,20 @@ #define _D_RAREST_PIECE_SELECTOR_H_ #include "PieceSelector.h" - -#include +#include "SharedHandle.h" namespace aria2 { -class PieceStat { -private: - size_t _order; - size_t _index; - size_t _count; -public: - PieceStat(size_t index); - - bool operator<(const PieceStat& pieceStat) const; - - void addCount(); - void subCount(); - - size_t getOrder() const; - void setOrder(size_t order); - size_t getIndex() const; - size_t getCount() const; -}; +class PieceStatMan; class RarestPieceSelector:public PieceSelector { private: - std::vector > _pieceStats; - - std::vector _sortedPieceStatIndexes; + SharedHandle _pieceStatMan; public: - RarestPieceSelector(size_t pieceNum, bool randomShuffle); + RarestPieceSelector(const SharedHandle& pieceStatMan); virtual bool select (size_t& index, const unsigned char* bitfield, size_t nbits) const; - - virtual void addPieceStats(size_t index); - - virtual void addPieceStats(const unsigned char* bitfield, - size_t bitfieldLength); - - virtual void subtractPieceStats(const unsigned char* bitfield, - size_t bitfieldLength); - - virtual void updatePieceStats(const unsigned char* newBitfield, - size_t newBitfieldLength, - const unsigned char* oldBitfield); - - const std::vector& getSortedPieceStatIndexes() const; - - const std::vector >& getPieceStats() const; }; } // namespace aria2 diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc index 697009d7..b2bb715d 100644 --- a/src/RequestGroup.cc +++ b/src/RequestGroup.cc @@ -396,17 +396,17 @@ void RequestGroup::initPieceStorage() { if(_downloadContext->knowsTotalLength()) { #ifdef ENABLE_BITTORRENT - SharedHandle ps; - SharedHandle selector; + SharedHandle ps + (new DefaultPieceStorage(_downloadContext, _option)); // Use LongestSequencePieceSelector when HTTP/FTP/BitTorrent integrated // downloads. Currently multi-file integrated download is not supported. if(!_uris.empty() && _downloadContext->getFileEntries().size() == 1 && !dynamic_pointer_cast(_downloadContext).isNull()) { _logger->debug("Using LongestSequencePieceSelector"); - selector.reset(new LongestSequencePieceSelector()); + ps->setPieceSelector + (SharedHandle(new LongestSequencePieceSelector())); } - ps.reset(new DefaultPieceStorage(_downloadContext, _option, selector)); #else // !ENABLE_BITTORRENT SharedHandle ps (new DefaultPieceStorage(_downloadContext, _option)); diff --git a/test/DefaultPieceStorageTest.cc b/test/DefaultPieceStorageTest.cc index 24b6c7a1..7d3e490f 100644 --- a/test/DefaultPieceStorageTest.cc +++ b/test/DefaultPieceStorageTest.cc @@ -13,6 +13,7 @@ #include "FileEntry.h" #include "MockBtContext.h" #include "RarestPieceSelector.h" +#include "InOrderPieceSelector.h" namespace aria2 { @@ -37,7 +38,7 @@ private: SharedHandle btContext; SharedHandle peer; Option* option; - SharedHandle _selector; + SharedHandle _pieceSelector; public: DefaultPieceStorageTest() { SharedHandle randomizer @@ -53,7 +54,7 @@ public: peer->allocateSessionResource(btContext->getPieceLength(), btContext->getTotalLength()); option = new Option(); - _selector.reset(new RarestPieceSelector(btContext->getNumPieces(), false)); + _pieceSelector.reset(new InOrderPieceSelector()); } void tearDown() @@ -87,7 +88,8 @@ void DefaultPieceStorageTest::testGetTotalLength() { } void DefaultPieceStorageTest::testGetMissingPiece() { - DefaultPieceStorage pss(btContext, option, _selector); + DefaultPieceStorage pss(btContext, option); + pss.setPieceSelector(_pieceSelector); pss.setEndGamePieceNum(0); peer->setAllBitfield(); @@ -107,7 +109,8 @@ void DefaultPieceStorageTest::testGetMissingPiece() { void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes() { - DefaultPieceStorage pss(btContext, option, _selector); + DefaultPieceStorage pss(btContext, option); + pss.setPieceSelector(_pieceSelector); pss.setEndGamePieceNum(0); peer->setAllBitfield(); @@ -128,7 +131,8 @@ void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes() } void DefaultPieceStorageTest::testGetMissingFastPiece() { - DefaultPieceStorage pss(btContext, option, _selector); + DefaultPieceStorage pss(btContext, option); + pss.setPieceSelector(_pieceSelector); pss.setEndGamePieceNum(0); peer->setAllBitfield(); @@ -144,7 +148,8 @@ void DefaultPieceStorageTest::testGetMissingFastPiece() { void DefaultPieceStorageTest::testGetMissingFastPiece_excludedIndexes() { - DefaultPieceStorage pss(btContext, option, _selector); + DefaultPieceStorage pss(btContext, option); + pss.setPieceSelector(_pieceSelector); pss.setEndGamePieceNum(0); peer->setAllBitfield(); @@ -173,7 +178,8 @@ void DefaultPieceStorageTest::testHasMissingPiece() { } void DefaultPieceStorageTest::testCompletePiece() { - DefaultPieceStorage pss(btContext, option, _selector); + DefaultPieceStorage pss(btContext, option); + pss.setPieceSelector(_pieceSelector); pss.setEndGamePieceNum(0); peer->setAllBitfield(); diff --git a/test/InOrderPieceSelector.h b/test/InOrderPieceSelector.h new file mode 100644 index 00000000..396b8879 --- /dev/null +++ b/test/InOrderPieceSelector.h @@ -0,0 +1,26 @@ +#ifndef _D_IN_ORDER_PIECE_SELECTOR_H_ +#define _D_IN_ORDER_PIECE_SELECTOR_H_ + +#include "PieceSelector.h" +#include "bitfield.h" + +namespace aria2 { + +class InOrderPieceSelector:public PieceSelector { +public: + virtual bool select + (size_t& index, const unsigned char* bitfield, size_t nbits) const + { + for(size_t i = 0; i < nbits; ++i) { + if(bitfield::test(bitfield, nbits, i)) { + index = i; + return true; + } + } + return false; + } +}; + +} // namespace aria2 + +#endif // _D_IN_ORDER_PIECE_SELECTOR_H_ diff --git a/test/Makefile.am b/test/Makefile.am index 1da8e3f7..24c6a546 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -66,6 +66,8 @@ aria2c_SOURCES = AllTest.cc\ BencodeTest.cc\ SequentialPickerTest.cc\ RarestPieceSelectorTest.cc\ + PieceStatManTest.cc\ + InOrderPieceSelector.h\ LongestSequencePieceSelectorTest.cc\ a2algoTest.cc\ bitfieldTest.cc\ diff --git a/test/Makefile.in b/test/Makefile.in index 1ea70ef0..3a503303 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.10.1 from Makefile.am. +# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -193,6 +193,7 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \ TimeTest.cc FtpConnectionTest.cc OptionParserTest.cc \ SimpleDNSCacheTest.cc DownloadHelperTest.cc BencodeTest.cc \ SequentialPickerTest.cc RarestPieceSelectorTest.cc \ + PieceStatManTest.cc InOrderPieceSelector.h \ LongestSequencePieceSelectorTest.cc a2algoTest.cc \ bitfieldTest.cc BDETest.cc FallocFileAllocationIteratorTest.cc \ GZipDecoderTest.cc Sqlite3MozCookieParserTest.cc \ @@ -363,7 +364,7 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \ OptionParserTest.$(OBJEXT) SimpleDNSCacheTest.$(OBJEXT) \ DownloadHelperTest.$(OBJEXT) BencodeTest.$(OBJEXT) \ SequentialPickerTest.$(OBJEXT) \ - RarestPieceSelectorTest.$(OBJEXT) \ + RarestPieceSelectorTest.$(OBJEXT) PieceStatManTest.$(OBJEXT) \ LongestSequencePieceSelectorTest.$(OBJEXT) \ a2algoTest.$(OBJEXT) bitfieldTest.$(OBJEXT) BDETest.$(OBJEXT) \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \ @@ -561,6 +562,7 @@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \ @@ -591,6 +593,7 @@ aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \ TimeTest.cc FtpConnectionTest.cc OptionParserTest.cc \ SimpleDNSCacheTest.cc DownloadHelperTest.cc BencodeTest.cc \ SequentialPickerTest.cc RarestPieceSelectorTest.cc \ + PieceStatManTest.cc InOrderPieceSelector.h \ LongestSequencePieceSelectorTest.cc a2algoTest.cc \ bitfieldTest.cc BDETest.cc $(am__append_1) $(am__append_2) \ $(am__append_3) $(am__append_4) $(am__append_5) \ @@ -646,8 +649,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ @@ -799,6 +802,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageUtilTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerSessionResourceTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceStatManTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ProtocolDetectorTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RarestPieceSelectorTest.Po@am__quote@ @@ -853,7 +857,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -896,7 +900,7 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \ + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ if test -n "$$list"; then \ @@ -907,7 +911,7 @@ check-TESTS: $(TESTS) if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ - *$$ws$$tst$$ws*) \ + *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ echo "XPASS: $$tst"; \ @@ -919,7 +923,7 @@ check-TESTS: $(TESTS) elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ - *$$ws$$tst$$ws*) \ + *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ echo "XFAIL: $$tst"; \ ;; \ @@ -933,23 +937,36 @@ check-TESTS: $(TESTS) echo "SKIP: $$tst"; \ fi; \ done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ - banner="All $$all tests passed"; \ + banner="$$All$$all $$tests passed"; \ else \ - banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all tests failed"; \ + banner="$$failed of $$all $$tests failed"; \ else \ - banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ - skipped="($$skip tests were not run)"; \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ diff --git a/test/PieceStatManTest.cc b/test/PieceStatManTest.cc new file mode 100644 index 00000000..3ddcdb4f --- /dev/null +++ b/test/PieceStatManTest.cc @@ -0,0 +1,194 @@ +#include "PieceStatMan.h" + +#include + +namespace aria2 { + +class PieceStatManTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(PieceStatManTest); + CPPUNIT_TEST(testAddPieceStats_index); + CPPUNIT_TEST(testAddPieceStats_bitfield); + CPPUNIT_TEST(testUpdatePieceStats); + CPPUNIT_TEST(testSubtractPieceStats); + CPPUNIT_TEST_SUITE_END(); +public: + void setUp() {} + + void tearDown() {} + + void testAddPieceStats_index(); + void testAddPieceStats_bitfield(); + void testUpdatePieceStats(); + void testSubtractPieceStats(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(PieceStatManTest); + +void PieceStatManTest::testAddPieceStats_index() +{ + PieceStatMan pieceStatMan(10, false); + pieceStatMan.addPieceStats(1); + { + size_t indexes[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 1 }; + size_t counts[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + + const std::vector& statsidx(pieceStatMan.getRarerPieceIndexes()); + const std::vector >& stats + (pieceStatMan.getPieceStats()); + + CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); + + for(size_t i = 0; i < 10; ++i) { + CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); + CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); + } + } + + pieceStatMan.addPieceStats(1); + + { + size_t indexes[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 1 }; + size_t counts[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }; + + const std::vector& statsidx(pieceStatMan.getRarerPieceIndexes()); + const std::vector >& stats + (pieceStatMan.getPieceStats()); + + for(size_t i = 0; i < 10; ++i) { + CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); + CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); + } + } + + pieceStatMan.addPieceStats(3); + pieceStatMan.addPieceStats(9); + pieceStatMan.addPieceStats(3); + pieceStatMan.addPieceStats(0); + + { + size_t indexes[] = { 2, 4, 5, 6, 7, 8, 0, 9, 1, 3 }; + size_t counts[] = { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2 }; + + const std::vector& statsidx(pieceStatMan.getRarerPieceIndexes()); + const std::vector >& stats + (pieceStatMan.getPieceStats()); + + for(size_t i = 0; i < 10; ++i) { + CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); + CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); + } + } + +} + +void PieceStatManTest::testAddPieceStats_bitfield() +{ + PieceStatMan pieceStatMan(10, false); + const unsigned char bitfield[] = { 0xaa, 0x80 }; + pieceStatMan.addPieceStats(bitfield, sizeof(bitfield)); + { + size_t indexes[] = { 1, 3, 5, 7, 9, 0, 2, 4, 6, 8 }; + size_t counts[] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 }; + + const std::vector& statsidx(pieceStatMan.getRarerPieceIndexes()); + const std::vector >& stats + (pieceStatMan.getPieceStats()); + + CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); + + for(size_t i = 0; i < 10; ++i) { + CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); + CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); + } + } + + pieceStatMan.addPieceStats(bitfield, sizeof(bitfield)); + + { + size_t indexes[] = { 1, 3, 5, 7, 9, 0, 2, 4, 6, 8 }; + size_t counts[] = { 0, 0, 0, 0, 0, 2, 2, 2, 2, 2 }; + + const std::vector& statsidx(pieceStatMan.getRarerPieceIndexes()); + const std::vector >& stats + (pieceStatMan.getPieceStats()); + + CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); + + for(size_t i = 0; i < 10; ++i) { + CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); + CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); + } + } +} + +void PieceStatManTest::testUpdatePieceStats() +{ + PieceStatMan pieceStatMan(10, false); + + const unsigned char bitfield[] = { 0xff, 0xc0 }; + pieceStatMan.addPieceStats(bitfield, sizeof(bitfield)); + + const unsigned char oldBitfield[] = { 0xf0, 0x00 }; + const unsigned char newBitfield[] = { 0x1f, 0x00 }; + + pieceStatMan.updatePieceStats(newBitfield, sizeof(newBitfield), oldBitfield); + { + // idx: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + // bf : 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + // old: 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 + // new: 0, 0, 0, 1, 1, 1, 1, 1, 0, 0 + // --------------------------------- + // res: 0, 0, 0, 1, 2, 2, 2, 2, 1, 1 + + size_t indexes[] = { 0, 1, 2, 3, 8, 9, 4, 5, 6, 7 }; + size_t counts[] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2 }; + + const std::vector& statsidx(pieceStatMan.getRarerPieceIndexes()); + const std::vector >& stats + (pieceStatMan.getPieceStats()); + + CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); + + for(size_t i = 0; i < 10; ++i) { + CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); + CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); + } + } +} + +void PieceStatManTest::testSubtractPieceStats() +{ + PieceStatMan pieceStatMan(10, false); + + const unsigned char bitfield[] = { 0xf0, 0x00 }; + pieceStatMan.addPieceStats(bitfield, sizeof(bitfield)); + + const unsigned char newBitfield[] = { 0x3f, 0x00 }; + + pieceStatMan.subtractPieceStats(newBitfield, sizeof(newBitfield)); + { + // idx: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + // bf : 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 + // new: 0, 0, 1, 1, 1, 1, 1, 1, 0, 0 + // --------------------------------- + // res: 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 + + size_t indexes[] = { 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 }; + size_t counts[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; + + const std::vector& statsidx(pieceStatMan.getRarerPieceIndexes()); + const std::vector >& stats + (pieceStatMan.getPieceStats()); + + CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); + + for(size_t i = 0; i < 10; ++i) { + CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); + CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); + } + } +} + +} // namespace aria2 diff --git a/test/RarestPieceSelectorTest.cc b/test/RarestPieceSelectorTest.cc index 0549aca9..87cd84ef 100644 --- a/test/RarestPieceSelectorTest.cc +++ b/test/RarestPieceSelectorTest.cc @@ -1,23 +1,15 @@ #include "RarestPieceSelector.h" -#include -#include - #include -#include "Exception.h" -#include "Util.h" #include "BitfieldMan.h" +#include "PieceStatMan.h" namespace aria2 { class RarestPieceSelectorTest:public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(RarestPieceSelectorTest); - CPPUNIT_TEST(testAddPieceStats_index); - CPPUNIT_TEST(testAddPieceStats_bitfield); - CPPUNIT_TEST(testUpdatePieceStats); - CPPUNIT_TEST(testSubtractPieceStats); CPPUNIT_TEST(testSelect); CPPUNIT_TEST_SUITE_END(); public: @@ -35,177 +27,21 @@ public: CPPUNIT_TEST_SUITE_REGISTRATION(RarestPieceSelectorTest); -void RarestPieceSelectorTest::testAddPieceStats_index() -{ - RarestPieceSelector selector(10, false); - selector.addPieceStats(1); - { - size_t indexes[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 1 }; - size_t counts[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; - - const std::vector& statsidx(selector.getSortedPieceStatIndexes()); - const std::vector >& stats(selector.getPieceStats()); - CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); - - for(size_t i = 0; i < 10; ++i) { - CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); - CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); - } - } - - selector.addPieceStats(1); - - { - size_t indexes[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 1 }; - size_t counts[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }; - - const std::vector& statsidx(selector.getSortedPieceStatIndexes()); - const std::vector >& stats(selector.getPieceStats()); - - for(size_t i = 0; i < 10; ++i) { - CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); - CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); - } - } - - selector.addPieceStats(3); - selector.addPieceStats(9); - selector.addPieceStats(3); - selector.addPieceStats(0); - - { - size_t indexes[] = { 2, 4, 5, 6, 7, 8, 0, 9, 1, 3 }; - size_t counts[] = { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2 }; - - const std::vector& statsidx(selector.getSortedPieceStatIndexes()); - const std::vector >& stats(selector.getPieceStats()); - - for(size_t i = 0; i < 10; ++i) { - CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); - CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); - } - } - -} - -void RarestPieceSelectorTest::testAddPieceStats_bitfield() -{ - RarestPieceSelector selector(10, false); - const unsigned char bitfield[] = { 0xaa, 0x80 }; - selector.addPieceStats(bitfield, sizeof(bitfield)); - { - size_t indexes[] = { 1, 3, 5, 7, 9, 0, 2, 4, 6, 8 }; - size_t counts[] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 }; - - const std::vector& statsidx(selector.getSortedPieceStatIndexes()); - const std::vector >& stats(selector.getPieceStats()); - - CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); - - for(size_t i = 0; i < 10; ++i) { - CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); - CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); - } - } - - selector.addPieceStats(bitfield, sizeof(bitfield)); - - { - size_t indexes[] = { 1, 3, 5, 7, 9, 0, 2, 4, 6, 8 }; - size_t counts[] = { 0, 0, 0, 0, 0, 2, 2, 2, 2, 2 }; - - const std::vector& statsidx(selector.getSortedPieceStatIndexes()); - const std::vector >& stats(selector.getPieceStats()); - - CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); - - for(size_t i = 0; i < 10; ++i) { - CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); - CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); - } - } -} - -void RarestPieceSelectorTest::testUpdatePieceStats() -{ - RarestPieceSelector selector(10, false); - - const unsigned char bitfield[] = { 0xff, 0xc0 }; - selector.addPieceStats(bitfield, sizeof(bitfield)); - - const unsigned char oldBitfield[] = { 0xf0, 0x00 }; - const unsigned char newBitfield[] = { 0x1f, 0x00 }; - - selector.updatePieceStats(newBitfield, sizeof(newBitfield), oldBitfield); - { - // idx: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 - // bf : 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 - // old: 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 - // new: 0, 0, 0, 1, 1, 1, 1, 1, 0, 0 - // --------------------------------- - // res: 0, 0, 0, 1, 2, 2, 2, 2, 1, 1 - - size_t indexes[] = { 0, 1, 2, 3, 8, 9, 4, 5, 6, 7 }; - size_t counts[] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2 }; - - const std::vector& statsidx(selector.getSortedPieceStatIndexes()); - const std::vector >& stats(selector.getPieceStats()); - - CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); - - for(size_t i = 0; i < 10; ++i) { - CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); - CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); - } - } -} - -void RarestPieceSelectorTest::testSubtractPieceStats() -{ - RarestPieceSelector selector(10, false); - - const unsigned char bitfield[] = { 0xf0, 0x00 }; - selector.addPieceStats(bitfield, sizeof(bitfield)); - - const unsigned char newBitfield[] = { 0x3f, 0x00 }; - - selector.subtractPieceStats(newBitfield, sizeof(newBitfield)); - { - // idx: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 - // bf : 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 - // new: 0, 0, 1, 1, 1, 1, 1, 1, 0, 0 - // --------------------------------- - // res: 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 - - size_t indexes[] = { 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 }; - size_t counts[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; - - const std::vector& statsidx(selector.getSortedPieceStatIndexes()); - const std::vector >& stats(selector.getPieceStats()); - - CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); - - for(size_t i = 0; i < 10; ++i) { - CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]); - CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount()); - } - } -} - void RarestPieceSelectorTest::testSelect() { - RarestPieceSelector selector(10, false); + SharedHandle pieceStatMan(new PieceStatMan(10, false)); + RarestPieceSelector selector(pieceStatMan); BitfieldMan bf(1024, 10*1024); bf.setBitRange(0, 2); size_t index; - selector.addPieceStats(0); + pieceStatMan->addPieceStats(0); CPPUNIT_ASSERT(selector.select(index, bf.getBitfield(), bf.countBlock())); CPPUNIT_ASSERT_EQUAL((size_t)1, index); - selector.addPieceStats(1); + pieceStatMan->addPieceStats(1); CPPUNIT_ASSERT(selector.select(index, bf.getBitfield(), bf.countBlock()));