2009-03-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Replaced std::vector<SharedHandle<PieceStats> _sortedPieceStats
	with std::vector<size_t> _sortedPieceStatIndexes to reduce the
	cost of std::rotate().
	* src/RarestPieceSelector.cc
	* src/RarestPieceSelector.h
	* test/RarestPieceSelectorTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2009-03-24 15:24:30 +00:00
parent 1e17795a84
commit 289ae1b635
4 changed files with 101 additions and 48 deletions

View File

@ -1,3 +1,18 @@
2009-03-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Replaced std::vector<SharedHandle<PieceStats> _sortedPieceStats
with std::vector<size_t> _sortedPieceStatIndexes to reduce the
cost of std::rotate().
* src/RarestPieceSelector.cc
* src/RarestPieceSelector.h
* test/RarestPieceSelectorTest.cc
2009-03-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Updated usage doc for --bt-tracker-interval option.
* src/usage_text.h
* doc/aria2c.1.txt
2009-03-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> 2009-03-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Documented --bt-tracker-interval option in man page. Documented --bt-tracker-interval option in man page.

View File

@ -98,19 +98,21 @@ public:
}; };
RarestPieceSelector::RarestPieceSelector(size_t pieceNum, bool randomShuffle): RarestPieceSelector::RarestPieceSelector(size_t pieceNum, bool randomShuffle):
_pieceStats(pieceNum) _pieceStats(pieceNum),
_sortedPieceStatIndexes(pieceNum)
{ {
std::generate(_pieceStats.begin(), _pieceStats.end(), GenPieceStat()); std::generate(_pieceStats.begin(), _pieceStats.end(), GenPieceStat());
_sortedPieceStats = _pieceStats; std::vector<SharedHandle<PieceStat> > sortedPieceStats(_pieceStats);
// we need some randomness in ordering. // we need some randomness in ordering.
if(randomShuffle) { if(randomShuffle) {
std::random_shuffle(_sortedPieceStats.begin(), _sortedPieceStats.end(), std::random_shuffle(sortedPieceStats.begin(), sortedPieceStats.end(),
*(SimpleRandomizer::getInstance().get())); *(SimpleRandomizer::getInstance().get()));
} }
{ {
size_t order = 0; size_t order = 0;
for(std::vector<SharedHandle<PieceStat> >::iterator i = _sortedPieceStats.begin(); for(std::vector<SharedHandle<PieceStat> >::iterator i =
i != _sortedPieceStats.end(); ++i) { sortedPieceStats.begin(); i != sortedPieceStats.end(); ++i) {
_sortedPieceStatIndexes[order] = (*i)->getIndex();
(*i)->setOrder(order++); (*i)->setOrder(order++);
} }
} }
@ -123,9 +125,9 @@ private:
public: public:
FindRarestPiece(const std::deque<size_t>& indexes):_indexes(indexes) {} FindRarestPiece(const std::deque<size_t>& indexes):_indexes(indexes) {}
bool operator()(const SharedHandle<PieceStat>& pieceStat) bool operator()(const size_t& index)
{ {
return std::binary_search(_indexes.begin(), _indexes.end(), pieceStat->getIndex()); return std::binary_search(_indexes.begin(), _indexes.end(), index);
} }
}; };
@ -133,17 +135,30 @@ bool RarestPieceSelector::select
(size_t& index, (size_t& index,
const std::deque<size_t>& candidateIndexes) const const std::deque<size_t>& candidateIndexes) const
{ {
std::vector<SharedHandle<PieceStat> >::const_iterator i = std::vector<size_t>::const_iterator i =
std::find_if(_sortedPieceStats.begin(), _sortedPieceStats.end(), std::find_if(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(),
FindRarestPiece(candidateIndexes)); FindRarestPiece(candidateIndexes));
if(i == _sortedPieceStats.end()) { if(i == _sortedPieceStatIndexes.end()) {
return false; return false;
} else { } else {
index = (*i)->getIndex(); index = *i;
return true; return true;
} }
} }
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, void RarestPieceSelector::addPieceStats(const unsigned char* bitfield,
size_t bitfieldLength) size_t bitfieldLength)
{ {
@ -158,7 +173,8 @@ void RarestPieceSelector::addPieceStats(const unsigned char* bitfield,
} }
} }
std::sort(_sortedPieceStats.begin(), _sortedPieceStats.end()); std::sort(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(),
PieceStatRarer(_pieceStats));
} }
void RarestPieceSelector::subtractPieceStats(const unsigned char* bitfield, void RarestPieceSelector::subtractPieceStats(const unsigned char* bitfield,
@ -175,7 +191,8 @@ void RarestPieceSelector::subtractPieceStats(const unsigned char* bitfield,
} }
} }
std::sort(_sortedPieceStats.begin(), _sortedPieceStats.end()); std::sort(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(),
PieceStatRarer(_pieceStats));
} }
void RarestPieceSelector::updatePieceStats(const unsigned char* newBitfield, void RarestPieceSelector::updatePieceStats(const unsigned char* newBitfield,
@ -195,28 +212,36 @@ void RarestPieceSelector::updatePieceStats(const unsigned char* newBitfield,
} }
} }
std::sort(_sortedPieceStats.begin(), _sortedPieceStats.end()); std::sort(_sortedPieceStatIndexes.begin(), _sortedPieceStatIndexes.end(),
PieceStatRarer(_pieceStats));
} }
void RarestPieceSelector::addPieceStats(size_t index) void RarestPieceSelector::addPieceStats(size_t index)
{ {
SharedHandle<PieceStat> pieceStat(_pieceStats[index]); std::vector<size_t>::iterator cur =
std::vector<SharedHandle<PieceStat> >::iterator cur = std::lower_bound(_sortedPieceStatIndexes.begin(),
std::lower_bound(_sortedPieceStats.begin(), _sortedPieceStats.end(), _sortedPieceStatIndexes.end(),
pieceStat); index, PieceStatRarer(_pieceStats));
pieceStat->addCount(); _pieceStats[index]->addCount();
std::vector<SharedHandle<PieceStat> >::iterator to = std::vector<size_t>::iterator to =
std::upper_bound(cur+1, _sortedPieceStats.end(), pieceStat); std::upper_bound(cur+1, _sortedPieceStatIndexes.end(),
index, PieceStatRarer(_pieceStats));
std::rotate(cur, cur+1, to); std::rotate(cur, cur+1, to);
} }
const std::vector<SharedHandle<PieceStat> >& const std::vector<size_t>&
RarestPieceSelector::getSortedPieceStats() const RarestPieceSelector::getSortedPieceStatIndexes() const
{ {
return _sortedPieceStats; return _sortedPieceStatIndexes;
}
const std::vector<SharedHandle<PieceStat> >&
RarestPieceSelector::getPieceStats() const
{
return _pieceStats;
} }
} // namespace aria2 } // namespace aria2

View File

@ -64,7 +64,7 @@ class RarestPieceSelector:public PieceSelector {
private: private:
std::vector<SharedHandle<PieceStat> > _pieceStats; std::vector<SharedHandle<PieceStat> > _pieceStats;
std::vector<SharedHandle<PieceStat> > _sortedPieceStats; std::vector<size_t> _sortedPieceStatIndexes;
public: public:
RarestPieceSelector(size_t pieceNum, bool randomShuffle); RarestPieceSelector(size_t pieceNum, bool randomShuffle);
@ -83,7 +83,9 @@ public:
size_t newBitfieldLength, size_t newBitfieldLength,
const unsigned char* oldBitfield); const unsigned char* oldBitfield);
const std::vector<SharedHandle<PieceStat> >& getSortedPieceStats() const; const std::vector<size_t>& getSortedPieceStatIndexes() const;
const std::vector<SharedHandle<PieceStat> >& getPieceStats() const;
}; };
} // namespace aria2 } // namespace aria2

View File

@ -40,12 +40,13 @@ void RarestPieceSelectorTest::testAddPieceStats_index()
size_t indexes[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 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 }; size_t counts[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
const std::vector<SharedHandle<PieceStat> >& stats(selector.getSortedPieceStats()); const std::vector<size_t>& statsidx(selector.getSortedPieceStatIndexes());
const std::vector<SharedHandle<PieceStat> >& stats(selector.getPieceStats());
CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size());
for(size_t i = 0; i < 10; ++i) { for(size_t i = 0; i < 10; ++i) {
CPPUNIT_ASSERT_EQUAL(indexes[i], stats[i]->getIndex()); CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]);
CPPUNIT_ASSERT_EQUAL(counts[i], stats[i]->getCount()); CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount());
} }
} }
@ -55,11 +56,12 @@ void RarestPieceSelectorTest::testAddPieceStats_index()
size_t indexes[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 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 }; size_t counts[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
const std::vector<SharedHandle<PieceStat> >& stats(selector.getSortedPieceStats()); const std::vector<size_t>& statsidx(selector.getSortedPieceStatIndexes());
const std::vector<SharedHandle<PieceStat> >& stats(selector.getPieceStats());
for(size_t i = 0; i < 10; ++i) { for(size_t i = 0; i < 10; ++i) {
CPPUNIT_ASSERT_EQUAL(indexes[i], stats[i]->getIndex()); CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]);
CPPUNIT_ASSERT_EQUAL(counts[i], stats[i]->getCount()); CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount());
} }
} }
@ -72,11 +74,12 @@ void RarestPieceSelectorTest::testAddPieceStats_index()
size_t indexes[] = { 2, 4, 5, 6, 7, 8, 0, 9, 1, 3 }; 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 }; size_t counts[] = { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2 };
const std::vector<SharedHandle<PieceStat> >& stats(selector.getSortedPieceStats()); const std::vector<size_t>& statsidx(selector.getSortedPieceStatIndexes());
const std::vector<SharedHandle<PieceStat> >& stats(selector.getPieceStats());
for(size_t i = 0; i < 10; ++i) { for(size_t i = 0; i < 10; ++i) {
CPPUNIT_ASSERT_EQUAL(indexes[i], stats[i]->getIndex()); CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]);
CPPUNIT_ASSERT_EQUAL(counts[i], stats[i]->getCount()); CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount());
} }
} }
@ -91,12 +94,14 @@ void RarestPieceSelectorTest::testAddPieceStats_bitfield()
size_t indexes[] = { 1, 3, 5, 7, 9, 0, 2, 4, 6, 8 }; 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 }; size_t counts[] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 };
const std::vector<SharedHandle<PieceStat> >& stats(selector.getSortedPieceStats()); const std::vector<size_t>& statsidx(selector.getSortedPieceStatIndexes());
const std::vector<SharedHandle<PieceStat> >& stats(selector.getPieceStats());
CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size());
for(size_t i = 0; i < 10; ++i) { for(size_t i = 0; i < 10; ++i) {
CPPUNIT_ASSERT_EQUAL(indexes[i], stats[i]->getIndex()); CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]);
CPPUNIT_ASSERT_EQUAL(counts[i], stats[i]->getCount()); CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount());
} }
} }
@ -106,12 +111,14 @@ void RarestPieceSelectorTest::testAddPieceStats_bitfield()
size_t indexes[] = { 1, 3, 5, 7, 9, 0, 2, 4, 6, 8 }; 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 }; size_t counts[] = { 0, 0, 0, 0, 0, 2, 2, 2, 2, 2 };
const std::vector<SharedHandle<PieceStat> >& stats(selector.getSortedPieceStats()); const std::vector<size_t>& statsidx(selector.getSortedPieceStatIndexes());
const std::vector<SharedHandle<PieceStat> >& stats(selector.getPieceStats());
CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size());
for(size_t i = 0; i < 10; ++i) { for(size_t i = 0; i < 10; ++i) {
CPPUNIT_ASSERT_EQUAL(indexes[i], stats[i]->getIndex()); CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]);
CPPUNIT_ASSERT_EQUAL(counts[i], stats[i]->getCount()); CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount());
} }
} }
} }
@ -138,12 +145,14 @@ void RarestPieceSelectorTest::testUpdatePieceStats()
size_t indexes[] = { 0, 1, 2, 3, 8, 9, 4, 5, 6, 7 }; 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 }; size_t counts[] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2 };
const std::vector<SharedHandle<PieceStat> >& stats(selector.getSortedPieceStats()); const std::vector<size_t>& statsidx(selector.getSortedPieceStatIndexes());
const std::vector<SharedHandle<PieceStat> >& stats(selector.getPieceStats());
CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size());
for(size_t i = 0; i < 10; ++i) { for(size_t i = 0; i < 10; ++i) {
CPPUNIT_ASSERT_EQUAL(indexes[i], stats[i]->getIndex()); CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]);
CPPUNIT_ASSERT_EQUAL(counts[i], stats[i]->getCount()); CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount());
} }
} }
} }
@ -168,12 +177,14 @@ void RarestPieceSelectorTest::testSubtractPieceStats()
size_t indexes[] = { 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 }; 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 }; size_t counts[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 };
const std::vector<SharedHandle<PieceStat> >& stats(selector.getSortedPieceStats()); const std::vector<size_t>& statsidx(selector.getSortedPieceStatIndexes());
const std::vector<SharedHandle<PieceStat> >& stats(selector.getPieceStats());
CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size()); CPPUNIT_ASSERT_EQUAL((size_t)10, stats.size());
for(size_t i = 0; i < 10; ++i) { for(size_t i = 0; i < 10; ++i) {
CPPUNIT_ASSERT_EQUAL(indexes[i], stats[i]->getIndex()); CPPUNIT_ASSERT_EQUAL(indexes[i], statsidx[i]);
CPPUNIT_ASSERT_EQUAL(counts[i], stats[i]->getCount()); CPPUNIT_ASSERT_EQUAL(counts[i], stats[statsidx[i]]->getCount());
} }
} }
} }