mirror of https://github.com/aria2/aria2
2009-05-06 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
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.ccpull/1/head
parent
d05d8bbddc
commit
4da631bef6
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
|||
2009-05-06 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
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 <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Added static member _protocolFamily to SocketCore. By default,
|
||||
|
|
|
@ -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>& 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
|
||||
|
|
|
@ -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> _pieceStatMan;
|
||||
|
||||
SharedHandle<PieceSelector> _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>& downloadContext,
|
||||
const Option* option,
|
||||
const SharedHandle<PieceSelector>& pieceSelector
|
||||
= SharedHandle<PieceSelector>());
|
||||
const Option* option);
|
||||
|
||||
virtual ~DefaultPieceStorage();
|
||||
|
||||
|
@ -223,6 +224,16 @@ public:
|
|||
void addUsedPiece(const SharedHandle<Piece>& piece);
|
||||
|
||||
void setDiskWriterFactory(const SharedHandle<DiskWriterFactory>& diskWriterFactory);
|
||||
|
||||
const SharedHandle<PieceStatMan>& getPieceStatMan() const
|
||||
{
|
||||
return _pieceStatMan;
|
||||
}
|
||||
|
||||
void setPieceSelector(const SharedHandle<PieceSelector>& pieceSelector)
|
||||
{
|
||||
_pieceSelector = pieceSelector;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<DefaultPieceStorage> DefaultPieceStorageHandle;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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\
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -37,9 +37,7 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include "SharedHandle.h"
|
||||
#include <cstdlib>
|
||||
|
||||
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
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* Copyright (C) 2009 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#include "PieceStatMan.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#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<PieceStat> operator()()
|
||||
{
|
||||
return SharedHandle<PieceStat>(new PieceStat(_index++));
|
||||
}
|
||||
};
|
||||
|
||||
PieceStatMan::PieceStatMan(size_t pieceNum, bool randomShuffle):
|
||||
_pieceStats(pieceNum),
|
||||
_sortedPieceStatIndexes(pieceNum)
|
||||
{
|
||||
std::generate(_pieceStats.begin(), _pieceStats.end(), GenPieceStat());
|
||||
std::vector<SharedHandle<PieceStat> > 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<SharedHandle<PieceStat> >::iterator i =
|
||||
sortedPieceStats.begin(); i != sortedPieceStats.end(); ++i) {
|
||||
_sortedPieceStatIndexes[order] = (*i)->getIndex();
|
||||
(*i)->setOrder(order++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PieceStatRarer {
|
||||
private:
|
||||
const std::vector<SharedHandle<PieceStat> >& _pieceStats;
|
||||
public:
|
||||
PieceStatRarer(const std::vector<SharedHandle<PieceStat> >& 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<size_t>::iterator cur =
|
||||
std::lower_bound(_sortedPieceStatIndexes.begin(),
|
||||
_sortedPieceStatIndexes.end(),
|
||||
index, PieceStatRarer(_pieceStats));
|
||||
|
||||
_pieceStats[index]->addCount();
|
||||
|
||||
std::vector<size_t>::iterator to =
|
||||
std::upper_bound(cur+1, _sortedPieceStatIndexes.end(),
|
||||
index, PieceStatRarer(_pieceStats));
|
||||
|
||||
std::rotate(cur, cur+1, to);
|
||||
}
|
||||
|
||||
const std::vector<size_t>& PieceStatMan::getRarerPieceIndexes() const
|
||||
{
|
||||
return _sortedPieceStatIndexes;
|
||||
}
|
||||
|
||||
const std::vector<SharedHandle<PieceStat> >&
|
||||
PieceStatMan::getPieceStats() const
|
||||
{
|
||||
return _pieceStats;
|
||||
}
|
||||
|
||||
} // namespace aria2
|
|
@ -0,0 +1,93 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* Copyright (C) 2009 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_PIECE_STAT_MAN_H_
|
||||
#define _D_PIECE_STAT_MAN_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#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<SharedHandle<PieceStat> > _pieceStats;
|
||||
|
||||
std::vector<size_t> _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<size_t>& getRarerPieceIndexes() const;
|
||||
|
||||
const std::vector<SharedHandle<PieceStat> >& getPieceStats() const;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
||||
#endif // _D_PIECE_STAT_MAN_H_
|
|
@ -37,87 +37,12 @@
|
|||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#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<PieceStat> operator()()
|
||||
{
|
||||
return SharedHandle<PieceStat>(new PieceStat(_index++));
|
||||
}
|
||||
};
|
||||
|
||||
RarestPieceSelector::RarestPieceSelector(size_t pieceNum, bool randomShuffle):
|
||||
_pieceStats(pieceNum),
|
||||
_sortedPieceStatIndexes(pieceNum)
|
||||
{
|
||||
std::generate(_pieceStats.begin(), _pieceStats.end(), GenPieceStat());
|
||||
std::vector<SharedHandle<PieceStat> > 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<SharedHandle<PieceStat> >::iterator i =
|
||||
sortedPieceStats.begin(); i != sortedPieceStats.end(); ++i) {
|
||||
_sortedPieceStatIndexes[order] = (*i)->getIndex();
|
||||
(*i)->setOrder(order++);
|
||||
}
|
||||
}
|
||||
}
|
||||
RarestPieceSelector::RarestPieceSelector
|
||||
(const SharedHandle<PieceStatMan>& 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<size_t>& pieceIndexes =
|
||||
_pieceStatMan->getRarerPieceIndexes();
|
||||
std::vector<size_t>::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<SharedHandle<PieceStat> >& _pieceStats;
|
||||
public:
|
||||
PieceStatRarer(const std::vector<SharedHandle<PieceStat> >& 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<size_t>::iterator cur =
|
||||
std::lower_bound(_sortedPieceStatIndexes.begin(),
|
||||
_sortedPieceStatIndexes.end(),
|
||||
index, PieceStatRarer(_pieceStats));
|
||||
|
||||
_pieceStats[index]->addCount();
|
||||
|
||||
std::vector<size_t>::iterator to =
|
||||
std::upper_bound(cur+1, _sortedPieceStatIndexes.end(),
|
||||
index, PieceStatRarer(_pieceStats));
|
||||
|
||||
std::rotate(cur, cur+1, to);
|
||||
}
|
||||
|
||||
const std::vector<size_t>&
|
||||
RarestPieceSelector::getSortedPieceStatIndexes() const
|
||||
{
|
||||
return _sortedPieceStatIndexes;
|
||||
}
|
||||
|
||||
const std::vector<SharedHandle<PieceStat> >&
|
||||
RarestPieceSelector::getPieceStats() const
|
||||
{
|
||||
return _pieceStats;
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -36,56 +36,20 @@
|
|||
#define _D_RAREST_PIECE_SELECTOR_H_
|
||||
|
||||
#include "PieceSelector.h"
|
||||
|
||||
#include <vector>
|
||||
#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<SharedHandle<PieceStat> > _pieceStats;
|
||||
|
||||
std::vector<size_t> _sortedPieceStatIndexes;
|
||||
SharedHandle<PieceStatMan> _pieceStatMan;
|
||||
public:
|
||||
RarestPieceSelector(size_t pieceNum, bool randomShuffle);
|
||||
RarestPieceSelector(const SharedHandle<PieceStatMan>& 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<size_t>& getSortedPieceStatIndexes() const;
|
||||
|
||||
const std::vector<SharedHandle<PieceStat> >& getPieceStats() const;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -396,17 +396,17 @@ void RequestGroup::initPieceStorage()
|
|||
{
|
||||
if(_downloadContext->knowsTotalLength()) {
|
||||
#ifdef ENABLE_BITTORRENT
|
||||
SharedHandle<DefaultPieceStorage> ps;
|
||||
SharedHandle<PieceSelector> selector;
|
||||
SharedHandle<DefaultPieceStorage> 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<BtContext>(_downloadContext).isNull()) {
|
||||
_logger->debug("Using LongestSequencePieceSelector");
|
||||
selector.reset(new LongestSequencePieceSelector());
|
||||
ps->setPieceSelector
|
||||
(SharedHandle<PieceSelector>(new LongestSequencePieceSelector()));
|
||||
}
|
||||
ps.reset(new DefaultPieceStorage(_downloadContext, _option, selector));
|
||||
#else // !ENABLE_BITTORRENT
|
||||
SharedHandle<DefaultPieceStorage> ps
|
||||
(new DefaultPieceStorage(_downloadContext, _option));
|
||||
|
|
|
@ -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> btContext;
|
||||
SharedHandle<Peer> peer;
|
||||
Option* option;
|
||||
SharedHandle<RarestPieceSelector> _selector;
|
||||
SharedHandle<PieceSelector> _pieceSelector;
|
||||
public:
|
||||
DefaultPieceStorageTest() {
|
||||
SharedHandle<FixedNumberRandomizer> 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();
|
||||
|
|
|
@ -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_
|
|
@ -66,6 +66,8 @@ aria2c_SOURCES = AllTest.cc\
|
|||
BencodeTest.cc\
|
||||
SequentialPickerTest.cc\
|
||||
RarestPieceSelectorTest.cc\
|
||||
PieceStatManTest.cc\
|
||||
InOrderPieceSelector.h\
|
||||
LongestSequencePieceSelectorTest.cc\
|
||||
a2algoTest.cc\
|
||||
bitfieldTest.cc\
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
#include "PieceStatMan.h"
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
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<size_t>& statsidx(pieceStatMan.getRarerPieceIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(pieceStatMan.getRarerPieceIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(pieceStatMan.getRarerPieceIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(pieceStatMan.getRarerPieceIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(pieceStatMan.getRarerPieceIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(pieceStatMan.getRarerPieceIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(pieceStatMan.getRarerPieceIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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
|
|
@ -1,23 +1,15 @@
|
|||
#include "RarestPieceSelector.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
#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<size_t>& statsidx(selector.getSortedPieceStatIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(selector.getSortedPieceStatIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(selector.getSortedPieceStatIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(selector.getSortedPieceStatIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(selector.getSortedPieceStatIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(selector.getSortedPieceStatIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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<size_t>& statsidx(selector.getSortedPieceStatIndexes());
|
||||
const std::vector<SharedHandle<PieceStat> >& 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> 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()));
|
||||
|
|
Loading…
Reference in New Issue