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>
|
2009-05-06 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Added static member _protocolFamily to SocketCore. By default,
|
Added static member _protocolFamily to SocketCore. By default,
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,12 @@
|
||||||
#include "StringFormat.h"
|
#include "StringFormat.h"
|
||||||
#include "RarestPieceSelector.h"
|
#include "RarestPieceSelector.h"
|
||||||
#include "array_fun.h"
|
#include "array_fun.h"
|
||||||
|
#include "PieceStatMan.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
DefaultPieceStorage::DefaultPieceStorage
|
DefaultPieceStorage::DefaultPieceStorage
|
||||||
(const DownloadContextHandle& downloadContext,
|
(const DownloadContextHandle& downloadContext, const Option* option):
|
||||||
const Option* option,
|
|
||||||
const SharedHandle<PieceSelector>& pieceSelector):
|
|
||||||
downloadContext(downloadContext),
|
downloadContext(downloadContext),
|
||||||
bitfieldMan(BitfieldManFactory::getFactoryInstance()->
|
bitfieldMan(BitfieldManFactory::getFactoryInstance()->
|
||||||
createBitfieldMan(downloadContext->getPieceLength(),
|
createBitfieldMan(downloadContext->getPieceLength(),
|
||||||
|
|
@ -73,13 +72,9 @@ DefaultPieceStorage::DefaultPieceStorage
|
||||||
endGamePieceNum(END_GAME_PIECE_NUM),
|
endGamePieceNum(END_GAME_PIECE_NUM),
|
||||||
logger(LogFactory::getInstance()),
|
logger(LogFactory::getInstance()),
|
||||||
option(option),
|
option(option),
|
||||||
_pieceSelector(pieceSelector)
|
_pieceStatMan(new PieceStatMan(downloadContext->getNumPieces(), true)),
|
||||||
{
|
_pieceSelector(new RarestPieceSelector(_pieceStatMan))
|
||||||
if(_pieceSelector.isNull()) {
|
{}
|
||||||
_pieceSelector.reset
|
|
||||||
(new RarestPieceSelector(downloadContext->getNumPieces(), true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DefaultPieceStorage::~DefaultPieceStorage() {
|
DefaultPieceStorage::~DefaultPieceStorage() {
|
||||||
delete bitfieldMan;
|
delete bitfieldMan;
|
||||||
|
|
@ -653,26 +648,26 @@ void DefaultPieceStorage::setDiskWriterFactory(const DiskWriterFactoryHandle& di
|
||||||
void DefaultPieceStorage::addPieceStats(const unsigned char* bitfield,
|
void DefaultPieceStorage::addPieceStats(const unsigned char* bitfield,
|
||||||
size_t bitfieldLength)
|
size_t bitfieldLength)
|
||||||
{
|
{
|
||||||
_pieceSelector->addPieceStats(bitfield, bitfieldLength);
|
_pieceStatMan->addPieceStats(bitfield, bitfieldLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultPieceStorage::subtractPieceStats(const unsigned char* bitfield,
|
void DefaultPieceStorage::subtractPieceStats(const unsigned char* bitfield,
|
||||||
size_t bitfieldLength)
|
size_t bitfieldLength)
|
||||||
{
|
{
|
||||||
_pieceSelector->subtractPieceStats(bitfield, bitfieldLength);
|
_pieceStatMan->subtractPieceStats(bitfield, bitfieldLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultPieceStorage::updatePieceStats(const unsigned char* newBitfield,
|
void DefaultPieceStorage::updatePieceStats(const unsigned char* newBitfield,
|
||||||
size_t newBitfieldLength,
|
size_t newBitfieldLength,
|
||||||
const unsigned char* oldBitfield)
|
const unsigned char* oldBitfield)
|
||||||
{
|
{
|
||||||
_pieceSelector->updatePieceStats(newBitfield, newBitfieldLength,
|
_pieceStatMan->updatePieceStats(newBitfield, newBitfieldLength,
|
||||||
oldBitfield);
|
oldBitfield);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultPieceStorage::addPieceStats(size_t index)
|
void DefaultPieceStorage::addPieceStats(size_t index)
|
||||||
{
|
{
|
||||||
_pieceSelector->addPieceStats(index);
|
_pieceStatMan->addPieceStats(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ class Logger;
|
||||||
class Option;
|
class Option;
|
||||||
class DiskWriterFactory;
|
class DiskWriterFactory;
|
||||||
class FileEntry;
|
class FileEntry;
|
||||||
|
class PieceStatMan;
|
||||||
class PieceSelector;
|
class PieceSelector;
|
||||||
|
|
||||||
#define END_GAME_PIECE_NUM 20
|
#define END_GAME_PIECE_NUM 20
|
||||||
|
|
@ -81,6 +82,8 @@ private:
|
||||||
const Option* option;
|
const Option* option;
|
||||||
Haves haves;
|
Haves haves;
|
||||||
|
|
||||||
|
SharedHandle<PieceStatMan> _pieceStatMan;
|
||||||
|
|
||||||
SharedHandle<PieceSelector> _pieceSelector;
|
SharedHandle<PieceSelector> _pieceSelector;
|
||||||
|
|
||||||
bool getMissingPieceIndex(size_t& index,
|
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
|
// If it is set to false, a piece whose index is smallest has the highest
|
||||||
// priority.
|
// priority.
|
||||||
DefaultPieceStorage(const SharedHandle<DownloadContext>& downloadContext,
|
DefaultPieceStorage(const SharedHandle<DownloadContext>& downloadContext,
|
||||||
const Option* option,
|
const Option* option);
|
||||||
const SharedHandle<PieceSelector>& pieceSelector
|
|
||||||
= SharedHandle<PieceSelector>());
|
|
||||||
|
|
||||||
virtual ~DefaultPieceStorage();
|
virtual ~DefaultPieceStorage();
|
||||||
|
|
||||||
|
|
@ -223,6 +224,16 @@ public:
|
||||||
void addUsedPiece(const SharedHandle<Piece>& piece);
|
void addUsedPiece(const SharedHandle<Piece>& piece);
|
||||||
|
|
||||||
void setDiskWriterFactory(const SharedHandle<DiskWriterFactory>& diskWriterFactory);
|
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;
|
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
|
} // namespace aria2
|
||||||
|
|
|
||||||
|
|
@ -47,18 +47,6 @@ public:
|
||||||
// returns 15 because { 10, 11, 12, 13, 14, 15 } is the longest sequence.
|
// returns 15 because { 10, 11, 12, 13, 14, 15 } is the longest sequence.
|
||||||
virtual bool select
|
virtual bool select
|
||||||
(size_t& index, const unsigned char* bitfield, size_t nbits) const;
|
(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
|
} // namespace aria2
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ SRCS = Socket.h\
|
||||||
PieceStorage.h\
|
PieceStorage.h\
|
||||||
DefaultPieceStorage.cc DefaultPieceStorage.h\
|
DefaultPieceStorage.cc DefaultPieceStorage.h\
|
||||||
UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h\
|
UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h\
|
||||||
|
PieceStatMan.cc PieceStatMan.h\
|
||||||
StatCalc.h\
|
StatCalc.h\
|
||||||
ConsoleStatCalc.cc ConsoleStatCalc.h\
|
ConsoleStatCalc.cc ConsoleStatCalc.h\
|
||||||
TransferStat.cc TransferStat.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@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
# 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 \
|
AutoSaveCommand.cc AutoSaveCommand.h PieceStorage.h \
|
||||||
DefaultPieceStorage.cc DefaultPieceStorage.h \
|
DefaultPieceStorage.cc DefaultPieceStorage.h \
|
||||||
UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h \
|
UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h \
|
||||||
StatCalc.h ConsoleStatCalc.cc ConsoleStatCalc.h \
|
PieceStatMan.cc PieceStatMan.h StatCalc.h ConsoleStatCalc.cc \
|
||||||
TransferStat.cc TransferStat.h Dependency.h \
|
ConsoleStatCalc.h TransferStat.cc TransferStat.h Dependency.h \
|
||||||
BtProgressInfoFile.h DefaultBtProgressInfoFile.cc \
|
BtProgressInfoFile.h DefaultBtProgressInfoFile.cc \
|
||||||
DefaultBtProgressInfoFile.h NullProgressInfoFile.h \
|
DefaultBtProgressInfoFile.h NullProgressInfoFile.h \
|
||||||
FileAllocationIterator.h SingleFileAllocationIterator.cc \
|
FileAllocationIterator.h SingleFileAllocationIterator.cc \
|
||||||
|
|
@ -768,8 +768,9 @@ am__objects_23 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
|
||||||
PStringSegment.$(OBJEXT) PStringBuildVisitor.$(OBJEXT) \
|
PStringSegment.$(OBJEXT) PStringBuildVisitor.$(OBJEXT) \
|
||||||
ParameterizedStringParser.$(OBJEXT) TimeBasedCommand.$(OBJEXT) \
|
ParameterizedStringParser.$(OBJEXT) TimeBasedCommand.$(OBJEXT) \
|
||||||
AutoSaveCommand.$(OBJEXT) DefaultPieceStorage.$(OBJEXT) \
|
AutoSaveCommand.$(OBJEXT) DefaultPieceStorage.$(OBJEXT) \
|
||||||
UnknownLengthPieceStorage.$(OBJEXT) ConsoleStatCalc.$(OBJEXT) \
|
UnknownLengthPieceStorage.$(OBJEXT) PieceStatMan.$(OBJEXT) \
|
||||||
TransferStat.$(OBJEXT) DefaultBtProgressInfoFile.$(OBJEXT) \
|
ConsoleStatCalc.$(OBJEXT) TransferStat.$(OBJEXT) \
|
||||||
|
DefaultBtProgressInfoFile.$(OBJEXT) \
|
||||||
SingleFileAllocationIterator.$(OBJEXT) \
|
SingleFileAllocationIterator.$(OBJEXT) \
|
||||||
ContentTypeRequestGroupCriteria.$(OBJEXT) \
|
ContentTypeRequestGroupCriteria.$(OBJEXT) \
|
||||||
DownloadHandler.$(OBJEXT) DownloadHandlerConstants.$(OBJEXT) \
|
DownloadHandler.$(OBJEXT) DownloadHandlerConstants.$(OBJEXT) \
|
||||||
|
|
@ -1008,6 +1009,7 @@ target_alias = @target_alias@
|
||||||
target_cpu = @target_cpu@
|
target_cpu = @target_cpu@
|
||||||
target_os = @target_os@
|
target_os = @target_os@
|
||||||
target_vendor = @target_vendor@
|
target_vendor = @target_vendor@
|
||||||
|
top_build_prefix = @top_build_prefix@
|
||||||
top_builddir = @top_builddir@
|
top_builddir = @top_builddir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
aria2c_SOURCES = main.cc\
|
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 \
|
AutoSaveCommand.cc AutoSaveCommand.h PieceStorage.h \
|
||||||
DefaultPieceStorage.cc DefaultPieceStorage.h \
|
DefaultPieceStorage.cc DefaultPieceStorage.h \
|
||||||
UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h \
|
UnknownLengthPieceStorage.cc UnknownLengthPieceStorage.h \
|
||||||
StatCalc.h ConsoleStatCalc.cc ConsoleStatCalc.h \
|
PieceStatMan.cc PieceStatMan.h StatCalc.h ConsoleStatCalc.cc \
|
||||||
TransferStat.cc TransferStat.h Dependency.h \
|
ConsoleStatCalc.h TransferStat.cc TransferStat.h Dependency.h \
|
||||||
BtProgressInfoFile.h DefaultBtProgressInfoFile.cc \
|
BtProgressInfoFile.h DefaultBtProgressInfoFile.cc \
|
||||||
DefaultBtProgressInfoFile.h NullProgressInfoFile.h \
|
DefaultBtProgressInfoFile.h NullProgressInfoFile.h \
|
||||||
FileAllocationIterator.h SingleFileAllocationIterator.cc \
|
FileAllocationIterator.h SingleFileAllocationIterator.cc \
|
||||||
|
|
@ -1169,8 +1171,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||||
@for dep in $?; do \
|
@for dep in $?; do \
|
||||||
case '$(am__configure_deps)' in \
|
case '$(am__configure_deps)' in \
|
||||||
*$$dep*) \
|
*$$dep*) \
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
|
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||||
&& exit 0; \
|
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||||
exit 1;; \
|
exit 1;; \
|
||||||
esac; \
|
esac; \
|
||||||
done; \
|
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)/Piece.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceHashCheckIntegrityEntry.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)/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)/PiecedSegment.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PiecesMetalinkParserState.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@
|
@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 \
|
unique=`for i in $$list; do \
|
||||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
done | \
|
done | \
|
||||||
$(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
|
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||||
mkid -fID $$unique
|
mkid -fID $$unique
|
||||||
tags: TAGS
|
tags: TAGS
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,7 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <deque>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "SharedHandle.h"
|
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
|
@ -49,18 +47,6 @@ public:
|
||||||
|
|
||||||
virtual bool select
|
virtual bool select
|
||||||
(size_t& index, const unsigned char* bitfield, size_t nbits) const = 0;
|
(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
|
} // 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 <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "SimpleRandomizer.h"
|
#include "PieceStatMan.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
PieceStat::PieceStat(size_t index):_order(0), _index(index), _count(0) {}
|
RarestPieceSelector::RarestPieceSelector
|
||||||
|
(const SharedHandle<PieceStatMan>& pieceStatMan):_pieceStatMan(pieceStatMan) {}
|
||||||
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++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FindRarestPiece
|
class FindRarestPiece
|
||||||
{
|
{
|
||||||
|
|
@ -139,10 +64,12 @@ public:
|
||||||
bool RarestPieceSelector::select
|
bool RarestPieceSelector::select
|
||||||
(size_t& index, const unsigned char* bitfield, size_t nbits) const
|
(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::vector<size_t>::const_iterator i =
|
||||||
std::find_if(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(),
|
std::find_if(pieceIndexes.begin(), pieceIndexes.end(),
|
||||||
FindRarestPiece(bitfield, nbits));
|
FindRarestPiece(bitfield, nbits));
|
||||||
if(i == _sortedPieceStatIndexes.end()) {
|
if(i == pieceIndexes.end()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
index = *i;
|
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
|
} // namespace aria2
|
||||||
|
|
|
||||||
|
|
@ -36,56 +36,20 @@
|
||||||
#define _D_RAREST_PIECE_SELECTOR_H_
|
#define _D_RAREST_PIECE_SELECTOR_H_
|
||||||
|
|
||||||
#include "PieceSelector.h"
|
#include "PieceSelector.h"
|
||||||
|
#include "SharedHandle.h"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
class PieceStat {
|
class PieceStatMan;
|
||||||
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 RarestPieceSelector:public PieceSelector {
|
class RarestPieceSelector:public PieceSelector {
|
||||||
private:
|
private:
|
||||||
std::vector<SharedHandle<PieceStat> > _pieceStats;
|
SharedHandle<PieceStatMan> _pieceStatMan;
|
||||||
|
|
||||||
std::vector<size_t> _sortedPieceStatIndexes;
|
|
||||||
public:
|
public:
|
||||||
RarestPieceSelector(size_t pieceNum, bool randomShuffle);
|
RarestPieceSelector(const SharedHandle<PieceStatMan>& pieceStatMan);
|
||||||
|
|
||||||
virtual bool select
|
virtual bool select
|
||||||
(size_t& index, const unsigned char* bitfield, size_t nbits) const;
|
(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
|
} // namespace aria2
|
||||||
|
|
|
||||||
|
|
@ -396,17 +396,17 @@ void RequestGroup::initPieceStorage()
|
||||||
{
|
{
|
||||||
if(_downloadContext->knowsTotalLength()) {
|
if(_downloadContext->knowsTotalLength()) {
|
||||||
#ifdef ENABLE_BITTORRENT
|
#ifdef ENABLE_BITTORRENT
|
||||||
SharedHandle<DefaultPieceStorage> ps;
|
SharedHandle<DefaultPieceStorage> ps
|
||||||
SharedHandle<PieceSelector> selector;
|
(new DefaultPieceStorage(_downloadContext, _option));
|
||||||
// Use LongestSequencePieceSelector when HTTP/FTP/BitTorrent integrated
|
// Use LongestSequencePieceSelector when HTTP/FTP/BitTorrent integrated
|
||||||
// downloads. Currently multi-file integrated download is not supported.
|
// downloads. Currently multi-file integrated download is not supported.
|
||||||
if(!_uris.empty() &&
|
if(!_uris.empty() &&
|
||||||
_downloadContext->getFileEntries().size() == 1 &&
|
_downloadContext->getFileEntries().size() == 1 &&
|
||||||
!dynamic_pointer_cast<BtContext>(_downloadContext).isNull()) {
|
!dynamic_pointer_cast<BtContext>(_downloadContext).isNull()) {
|
||||||
_logger->debug("Using LongestSequencePieceSelector");
|
_logger->debug("Using LongestSequencePieceSelector");
|
||||||
selector.reset(new LongestSequencePieceSelector());
|
ps->setPieceSelector
|
||||||
|
(SharedHandle<PieceSelector>(new LongestSequencePieceSelector()));
|
||||||
}
|
}
|
||||||
ps.reset(new DefaultPieceStorage(_downloadContext, _option, selector));
|
|
||||||
#else // !ENABLE_BITTORRENT
|
#else // !ENABLE_BITTORRENT
|
||||||
SharedHandle<DefaultPieceStorage> ps
|
SharedHandle<DefaultPieceStorage> ps
|
||||||
(new DefaultPieceStorage(_downloadContext, _option));
|
(new DefaultPieceStorage(_downloadContext, _option));
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "FileEntry.h"
|
#include "FileEntry.h"
|
||||||
#include "MockBtContext.h"
|
#include "MockBtContext.h"
|
||||||
#include "RarestPieceSelector.h"
|
#include "RarestPieceSelector.h"
|
||||||
|
#include "InOrderPieceSelector.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
|
@ -37,7 +38,7 @@ private:
|
||||||
SharedHandle<BtContext> btContext;
|
SharedHandle<BtContext> btContext;
|
||||||
SharedHandle<Peer> peer;
|
SharedHandle<Peer> peer;
|
||||||
Option* option;
|
Option* option;
|
||||||
SharedHandle<RarestPieceSelector> _selector;
|
SharedHandle<PieceSelector> _pieceSelector;
|
||||||
public:
|
public:
|
||||||
DefaultPieceStorageTest() {
|
DefaultPieceStorageTest() {
|
||||||
SharedHandle<FixedNumberRandomizer> randomizer
|
SharedHandle<FixedNumberRandomizer> randomizer
|
||||||
|
|
@ -53,7 +54,7 @@ public:
|
||||||
peer->allocateSessionResource(btContext->getPieceLength(),
|
peer->allocateSessionResource(btContext->getPieceLength(),
|
||||||
btContext->getTotalLength());
|
btContext->getTotalLength());
|
||||||
option = new Option();
|
option = new Option();
|
||||||
_selector.reset(new RarestPieceSelector(btContext->getNumPieces(), false));
|
_pieceSelector.reset(new InOrderPieceSelector());
|
||||||
}
|
}
|
||||||
|
|
||||||
void tearDown()
|
void tearDown()
|
||||||
|
|
@ -87,7 +88,8 @@ void DefaultPieceStorageTest::testGetTotalLength() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultPieceStorageTest::testGetMissingPiece() {
|
void DefaultPieceStorageTest::testGetMissingPiece() {
|
||||||
DefaultPieceStorage pss(btContext, option, _selector);
|
DefaultPieceStorage pss(btContext, option);
|
||||||
|
pss.setPieceSelector(_pieceSelector);
|
||||||
pss.setEndGamePieceNum(0);
|
pss.setEndGamePieceNum(0);
|
||||||
|
|
||||||
peer->setAllBitfield();
|
peer->setAllBitfield();
|
||||||
|
|
@ -107,7 +109,8 @@ void DefaultPieceStorageTest::testGetMissingPiece() {
|
||||||
|
|
||||||
void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes()
|
void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes()
|
||||||
{
|
{
|
||||||
DefaultPieceStorage pss(btContext, option, _selector);
|
DefaultPieceStorage pss(btContext, option);
|
||||||
|
pss.setPieceSelector(_pieceSelector);
|
||||||
pss.setEndGamePieceNum(0);
|
pss.setEndGamePieceNum(0);
|
||||||
|
|
||||||
peer->setAllBitfield();
|
peer->setAllBitfield();
|
||||||
|
|
@ -128,7 +131,8 @@ void DefaultPieceStorageTest::testGetMissingPiece_excludedIndexes()
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultPieceStorageTest::testGetMissingFastPiece() {
|
void DefaultPieceStorageTest::testGetMissingFastPiece() {
|
||||||
DefaultPieceStorage pss(btContext, option, _selector);
|
DefaultPieceStorage pss(btContext, option);
|
||||||
|
pss.setPieceSelector(_pieceSelector);
|
||||||
pss.setEndGamePieceNum(0);
|
pss.setEndGamePieceNum(0);
|
||||||
|
|
||||||
peer->setAllBitfield();
|
peer->setAllBitfield();
|
||||||
|
|
@ -144,7 +148,8 @@ void DefaultPieceStorageTest::testGetMissingFastPiece() {
|
||||||
|
|
||||||
void DefaultPieceStorageTest::testGetMissingFastPiece_excludedIndexes()
|
void DefaultPieceStorageTest::testGetMissingFastPiece_excludedIndexes()
|
||||||
{
|
{
|
||||||
DefaultPieceStorage pss(btContext, option, _selector);
|
DefaultPieceStorage pss(btContext, option);
|
||||||
|
pss.setPieceSelector(_pieceSelector);
|
||||||
pss.setEndGamePieceNum(0);
|
pss.setEndGamePieceNum(0);
|
||||||
|
|
||||||
peer->setAllBitfield();
|
peer->setAllBitfield();
|
||||||
|
|
@ -173,7 +178,8 @@ void DefaultPieceStorageTest::testHasMissingPiece() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultPieceStorageTest::testCompletePiece() {
|
void DefaultPieceStorageTest::testCompletePiece() {
|
||||||
DefaultPieceStorage pss(btContext, option, _selector);
|
DefaultPieceStorage pss(btContext, option);
|
||||||
|
pss.setPieceSelector(_pieceSelector);
|
||||||
pss.setEndGamePieceNum(0);
|
pss.setEndGamePieceNum(0);
|
||||||
|
|
||||||
peer->setAllBitfield();
|
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\
|
BencodeTest.cc\
|
||||||
SequentialPickerTest.cc\
|
SequentialPickerTest.cc\
|
||||||
RarestPieceSelectorTest.cc\
|
RarestPieceSelectorTest.cc\
|
||||||
|
PieceStatManTest.cc\
|
||||||
|
InOrderPieceSelector.h\
|
||||||
LongestSequencePieceSelectorTest.cc\
|
LongestSequencePieceSelectorTest.cc\
|
||||||
a2algoTest.cc\
|
a2algoTest.cc\
|
||||||
bitfieldTest.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@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
# 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 \
|
TimeTest.cc FtpConnectionTest.cc OptionParserTest.cc \
|
||||||
SimpleDNSCacheTest.cc DownloadHelperTest.cc BencodeTest.cc \
|
SimpleDNSCacheTest.cc DownloadHelperTest.cc BencodeTest.cc \
|
||||||
SequentialPickerTest.cc RarestPieceSelectorTest.cc \
|
SequentialPickerTest.cc RarestPieceSelectorTest.cc \
|
||||||
|
PieceStatManTest.cc InOrderPieceSelector.h \
|
||||||
LongestSequencePieceSelectorTest.cc a2algoTest.cc \
|
LongestSequencePieceSelectorTest.cc a2algoTest.cc \
|
||||||
bitfieldTest.cc BDETest.cc FallocFileAllocationIteratorTest.cc \
|
bitfieldTest.cc BDETest.cc FallocFileAllocationIteratorTest.cc \
|
||||||
GZipDecoderTest.cc Sqlite3MozCookieParserTest.cc \
|
GZipDecoderTest.cc Sqlite3MozCookieParserTest.cc \
|
||||||
|
|
@ -363,7 +364,7 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \
|
||||||
OptionParserTest.$(OBJEXT) SimpleDNSCacheTest.$(OBJEXT) \
|
OptionParserTest.$(OBJEXT) SimpleDNSCacheTest.$(OBJEXT) \
|
||||||
DownloadHelperTest.$(OBJEXT) BencodeTest.$(OBJEXT) \
|
DownloadHelperTest.$(OBJEXT) BencodeTest.$(OBJEXT) \
|
||||||
SequentialPickerTest.$(OBJEXT) \
|
SequentialPickerTest.$(OBJEXT) \
|
||||||
RarestPieceSelectorTest.$(OBJEXT) \
|
RarestPieceSelectorTest.$(OBJEXT) PieceStatManTest.$(OBJEXT) \
|
||||||
LongestSequencePieceSelectorTest.$(OBJEXT) \
|
LongestSequencePieceSelectorTest.$(OBJEXT) \
|
||||||
a2algoTest.$(OBJEXT) bitfieldTest.$(OBJEXT) BDETest.$(OBJEXT) \
|
a2algoTest.$(OBJEXT) bitfieldTest.$(OBJEXT) BDETest.$(OBJEXT) \
|
||||||
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||||
|
|
@ -561,6 +562,7 @@ target_alias = @target_alias@
|
||||||
target_cpu = @target_cpu@
|
target_cpu = @target_cpu@
|
||||||
target_os = @target_os@
|
target_os = @target_os@
|
||||||
target_vendor = @target_vendor@
|
target_vendor = @target_vendor@
|
||||||
|
top_build_prefix = @top_build_prefix@
|
||||||
top_builddir = @top_builddir@
|
top_builddir = @top_builddir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \
|
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 \
|
TimeTest.cc FtpConnectionTest.cc OptionParserTest.cc \
|
||||||
SimpleDNSCacheTest.cc DownloadHelperTest.cc BencodeTest.cc \
|
SimpleDNSCacheTest.cc DownloadHelperTest.cc BencodeTest.cc \
|
||||||
SequentialPickerTest.cc RarestPieceSelectorTest.cc \
|
SequentialPickerTest.cc RarestPieceSelectorTest.cc \
|
||||||
|
PieceStatManTest.cc InOrderPieceSelector.h \
|
||||||
LongestSequencePieceSelectorTest.cc a2algoTest.cc \
|
LongestSequencePieceSelectorTest.cc a2algoTest.cc \
|
||||||
bitfieldTest.cc BDETest.cc $(am__append_1) $(am__append_2) \
|
bitfieldTest.cc BDETest.cc $(am__append_1) $(am__append_2) \
|
||||||
$(am__append_3) $(am__append_4) $(am__append_5) \
|
$(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 \
|
@for dep in $?; do \
|
||||||
case '$(am__configure_deps)' in \
|
case '$(am__configure_deps)' in \
|
||||||
*$$dep*) \
|
*$$dep*) \
|
||||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
|
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||||
&& exit 0; \
|
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||||
exit 1;; \
|
exit 1;; \
|
||||||
esac; \
|
esac; \
|
||||||
done; \
|
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)/PeerMessageUtilTest.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerSessionResourceTest.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)/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)/PieceTest.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ProtocolDetectorTest.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@
|
@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 \
|
unique=`for i in $$list; do \
|
||||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
done | \
|
done | \
|
||||||
$(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
|
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||||
mkid -fID $$unique
|
mkid -fID $$unique
|
||||||
tags: TAGS
|
tags: TAGS
|
||||||
|
|
@ -896,7 +900,7 @@ distclean-tags:
|
||||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
check-TESTS: $(TESTS)
|
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; \
|
srcdir=$(srcdir); export srcdir; \
|
||||||
list=' $(TESTS) '; \
|
list=' $(TESTS) '; \
|
||||||
if test -n "$$list"; then \
|
if test -n "$$list"; then \
|
||||||
|
|
@ -907,7 +911,7 @@ check-TESTS: $(TESTS)
|
||||||
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
|
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
|
||||||
all=`expr $$all + 1`; \
|
all=`expr $$all + 1`; \
|
||||||
case " $(XFAIL_TESTS) " in \
|
case " $(XFAIL_TESTS) " in \
|
||||||
*$$ws$$tst$$ws*) \
|
*[\ \ ]$$tst[\ \ ]*) \
|
||||||
xpass=`expr $$xpass + 1`; \
|
xpass=`expr $$xpass + 1`; \
|
||||||
failed=`expr $$failed + 1`; \
|
failed=`expr $$failed + 1`; \
|
||||||
echo "XPASS: $$tst"; \
|
echo "XPASS: $$tst"; \
|
||||||
|
|
@ -919,7 +923,7 @@ check-TESTS: $(TESTS)
|
||||||
elif test $$? -ne 77; then \
|
elif test $$? -ne 77; then \
|
||||||
all=`expr $$all + 1`; \
|
all=`expr $$all + 1`; \
|
||||||
case " $(XFAIL_TESTS) " in \
|
case " $(XFAIL_TESTS) " in \
|
||||||
*$$ws$$tst$$ws*) \
|
*[\ \ ]$$tst[\ \ ]*) \
|
||||||
xfail=`expr $$xfail + 1`; \
|
xfail=`expr $$xfail + 1`; \
|
||||||
echo "XFAIL: $$tst"; \
|
echo "XFAIL: $$tst"; \
|
||||||
;; \
|
;; \
|
||||||
|
|
@ -933,23 +937,36 @@ check-TESTS: $(TESTS)
|
||||||
echo "SKIP: $$tst"; \
|
echo "SKIP: $$tst"; \
|
||||||
fi; \
|
fi; \
|
||||||
done; \
|
done; \
|
||||||
|
if test "$$all" -eq 1; then \
|
||||||
|
tests="test"; \
|
||||||
|
All=""; \
|
||||||
|
else \
|
||||||
|
tests="tests"; \
|
||||||
|
All="All "; \
|
||||||
|
fi; \
|
||||||
if test "$$failed" -eq 0; then \
|
if test "$$failed" -eq 0; then \
|
||||||
if test "$$xfail" -eq 0; then \
|
if test "$$xfail" -eq 0; then \
|
||||||
banner="All $$all tests passed"; \
|
banner="$$All$$all $$tests passed"; \
|
||||||
else \
|
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; \
|
fi; \
|
||||||
else \
|
else \
|
||||||
if test "$$xpass" -eq 0; then \
|
if test "$$xpass" -eq 0; then \
|
||||||
banner="$$failed of $$all tests failed"; \
|
banner="$$failed of $$all $$tests failed"; \
|
||||||
else \
|
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; \
|
||||||
fi; \
|
fi; \
|
||||||
dashes="$$banner"; \
|
dashes="$$banner"; \
|
||||||
skipped=""; \
|
skipped=""; \
|
||||||
if test "$$skip" -ne 0; then \
|
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` || \
|
test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
|
||||||
dashes="$$skipped"; \
|
dashes="$$skipped"; \
|
||||||
fi; \
|
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 "RarestPieceSelector.h"
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <cppunit/extensions/HelperMacros.h>
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "BitfieldMan.h"
|
#include "BitfieldMan.h"
|
||||||
|
#include "PieceStatMan.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
class RarestPieceSelectorTest:public CppUnit::TestFixture {
|
class RarestPieceSelectorTest:public CppUnit::TestFixture {
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE(RarestPieceSelectorTest);
|
CPPUNIT_TEST_SUITE(RarestPieceSelectorTest);
|
||||||
CPPUNIT_TEST(testAddPieceStats_index);
|
|
||||||
CPPUNIT_TEST(testAddPieceStats_bitfield);
|
|
||||||
CPPUNIT_TEST(testUpdatePieceStats);
|
|
||||||
CPPUNIT_TEST(testSubtractPieceStats);
|
|
||||||
CPPUNIT_TEST(testSelect);
|
CPPUNIT_TEST(testSelect);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
public:
|
public:
|
||||||
|
|
@ -35,177 +27,21 @@ public:
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(RarestPieceSelectorTest);
|
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()
|
void RarestPieceSelectorTest::testSelect()
|
||||||
{
|
{
|
||||||
RarestPieceSelector selector(10, false);
|
SharedHandle<PieceStatMan> pieceStatMan(new PieceStatMan(10, false));
|
||||||
|
RarestPieceSelector selector(pieceStatMan);
|
||||||
BitfieldMan bf(1024, 10*1024);
|
BitfieldMan bf(1024, 10*1024);
|
||||||
bf.setBitRange(0, 2);
|
bf.setBitRange(0, 2);
|
||||||
size_t index;
|
size_t index;
|
||||||
|
|
||||||
selector.addPieceStats(0);
|
pieceStatMan->addPieceStats(0);
|
||||||
|
|
||||||
CPPUNIT_ASSERT(selector.select(index, bf.getBitfield(),
|
CPPUNIT_ASSERT(selector.select(index, bf.getBitfield(),
|
||||||
bf.countBlock()));
|
bf.countBlock()));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)1, index);
|
CPPUNIT_ASSERT_EQUAL((size_t)1, index);
|
||||||
|
|
||||||
selector.addPieceStats(1);
|
pieceStatMan->addPieceStats(1);
|
||||||
|
|
||||||
CPPUNIT_ASSERT(selector.select(index, bf.getBitfield(),
|
CPPUNIT_ASSERT(selector.select(index, bf.getBitfield(),
|
||||||
bf.countBlock()));
|
bf.countBlock()));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue