2008-05-31 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Reduced the usage of gettimeofday().
	* src/DefaultBtMessageDispatcher.cc
	
(DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing)
	(class FindStaleRequestSlot, class ProcessStaleRequestSlot)
	* src/RequestSlot.cc
	* src/RequestSlot.h
	(RequestSlot::isTimeout)
	
	Made RequestSlot have a reference to Piece object to avoid find
	Piece repeatedly.
	* src/DefaultBtMessageDispatcher.cc
	(class FindStaleRequestSlot, class ProcessStaleRequestSlot)
	* src/RequestSlot.cc
	* src/RequestSlot.h
	(RequestSlot::getPiece)
	* test/DefaultBtMessageDispatcherTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2008-05-31 05:46:16 +00:00
parent f771b42e53
commit 1d7b5e6f4a
5 changed files with 73 additions and 21 deletions

View File

@ -1,3 +1,22 @@
2008-05-31 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Reduced the usage of gettimeofday().
* src/DefaultBtMessageDispatcher.cc
(DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing)
(class FindStaleRequestSlot, class ProcessStaleRequestSlot)
* src/RequestSlot.cc
* src/RequestSlot.h
(RequestSlot::isTimeout)
Made RequestSlot have a reference to Piece object to avoid find
Piece repeatedly.
* src/DefaultBtMessageDispatcher.cc
(class FindStaleRequestSlot, class ProcessStaleRequestSlot)
* src/RequestSlot.cc
* src/RequestSlot.h
(RequestSlot::getPiece)
* test/DefaultBtMessageDispatcherTest.cc
2008-05-31 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/TimeA2.cc

View File

@ -246,6 +246,7 @@ private:
SharedHandle<PieceStorage> _pieceStorage;
BtMessageDispatcher* _messageDispatcher;
WeakHandle<BtMessageFactory> _messageFactory;
const struct timeval& _now;
time_t _requestTimeout;
Logger* _logger;
public:
@ -253,26 +254,27 @@ public:
const SharedHandle<PieceStorage>& pieceStorage,
BtMessageDispatcher* dispatcher,
const WeakHandle<BtMessageFactory>& factory,
const struct timeval& now,
time_t requestTimeout):
_cuid(cuid),
_peer(peer),
_pieceStorage(pieceStorage),
_messageDispatcher(dispatcher),
_messageFactory(factory),
_now(now),
_requestTimeout(requestTimeout),
_logger(LogFactory::getInstance()) {}
void operator()(const RequestSlot& slot)
{
SharedHandle<Piece> piece = _pieceStorage->getPiece(slot.getIndex());
if(slot.isTimeout(_requestTimeout)) {
if(slot.isTimeout(_now, _requestTimeout)) {
_logger->debug(MSG_DELETING_REQUEST_SLOT_TIMEOUT,
_cuid,
slot.getBlockIndex());
_logger->debug("index=%d, begin=%d", slot.getIndex(), slot.getBegin());
piece->cancelBlock(slot.getBlockIndex());
slot.getPiece()->cancelBlock(slot.getBlockIndex());
_peer->snubbing(true);
} else if(piece->hasBlock(slot.getBlockIndex())) {
} else if(slot.getPiece()->hasBlock(slot.getBlockIndex())) {
_logger->debug(MSG_DELETING_REQUEST_SLOT_ACQUIRED,
_cuid,
slot.getBlockIndex());
@ -288,20 +290,22 @@ public:
class FindStaleRequestSlot {
private:
SharedHandle<PieceStorage> _pieceStorage;
const struct timeval& _now;
time_t _requestTimeout;
public:
FindStaleRequestSlot(const SharedHandle<PieceStorage>& pieceStorage,
const struct timeval& now,
time_t requestTimeout):
_pieceStorage(pieceStorage),
_now(now),
_requestTimeout(requestTimeout) {}
bool operator()(const RequestSlot& slot)
{
if(slot.isTimeout(_requestTimeout)) {
if(slot.isTimeout(_now, _requestTimeout)) {
return true;
} else {
SharedHandle<Piece> piece = _pieceStorage->getPiece(slot.getIndex());
if(piece->hasBlock(slot.getBlockIndex())) {
if(slot.getPiece()->hasBlock(slot.getBlockIndex())) {
return true;
} else {
return false;
@ -312,15 +316,20 @@ public:
void DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing()
{
struct timeval now;
gettimeofday(&now, 0);
std::for_each(requestSlots.begin(), requestSlots.end(),
ProcessStaleRequestSlot(cuid,
peer,
pieceStorage,
this,
messageFactory,
now,
requestTimeout));
requestSlots.erase(std::remove_if(requestSlots.begin(), requestSlots.end(),
FindStaleRequestSlot(pieceStorage,
now,
requestTimeout)),
requestSlots.end());
}
@ -363,7 +372,7 @@ bool DefaultBtMessageDispatcher::isOutstandingRequest(size_t index, size_t block
RequestSlot
DefaultBtMessageDispatcher::getOutstandingRequest(size_t index, uint32_t begin, size_t length)
{
RequestSlot ret(0, 0, 0, 0);
RequestSlot ret;
RequestSlot rs(index, begin, length, 0);
std::deque<RequestSlot>::iterator i =
std::lower_bound(requestSlots.begin(), requestSlots.end(), rs);

View File

@ -37,21 +37,25 @@
namespace aria2 {
RequestSlot RequestSlot::nullSlot(0, 0, 0, 0);
RequestSlot RequestSlot::nullSlot = RequestSlot();
RequestSlot::RequestSlot(size_t index, uint32_t begin, size_t length, size_t blockIndex)
:index(index), begin(begin), length(length), blockIndex(blockIndex) {}
RequestSlot::RequestSlot(size_t index, uint32_t begin, size_t length, size_t blockIndex, const SharedHandle<Piece>& piece)
:index(index), begin(begin), length(length), blockIndex(blockIndex),
_piece(piece) {}
RequestSlot::RequestSlot(const RequestSlot& requestSlot) {
copy(requestSlot);
}
RequestSlot::RequestSlot():index(0), begin(0), length(0), blockIndex(0) {}
void RequestSlot::copy(const RequestSlot& requestSlot) {
index = requestSlot.index;
begin = requestSlot.begin;
length = requestSlot.length;
blockIndex = requestSlot.blockIndex;
dispatchedTime = requestSlot.dispatchedTime;
_piece = requestSlot._piece;
}
RequestSlot& RequestSlot::operator=(const RequestSlot& requestSlot)
@ -89,8 +93,8 @@ void RequestSlot::setDispatchedTime(time_t secFromEpoch) {
dispatchedTime.setTimeInSec(secFromEpoch);
}
bool RequestSlot::isTimeout(time_t timeoutSec) const {
return dispatchedTime.elapsed(timeoutSec);
bool RequestSlot::isTimeout(const struct timeval& now, time_t timeoutSec) const {
return dispatchedTime.difference(now) >= timeoutSec;
}
unsigned int RequestSlot::getLatencyInMillis() const {
@ -102,4 +106,9 @@ bool RequestSlot::isNull(const RequestSlot& requestSlot) {
requestSlot.length == 0;
}
SharedHandle<Piece> RequestSlot::getPiece() const
{
return _piece;
}
} // namespace aria2

View File

@ -37,6 +37,7 @@
#include "common.h"
#include "TimeA2.h"
#include "Piece.h"
#include <deque>
namespace aria2 {
@ -48,11 +49,23 @@ private:
uint32_t begin;
size_t length;
size_t blockIndex;
// This is the piece whose index is index of this RequestSlot has.
// To detect duplicate RequestSlot, we have to find the piece using
// PieceStorage::getPiece() repeatedly. It turns out that this process
// takes time(about 1.7% of processing time). To reduce it, we put piece here
// at the construction of RequestSlot as a cache.
SharedHandle<Piece> _piece;
void copy(const RequestSlot& requestSlot);
public:
RequestSlot(size_t index, uint32_t begin, size_t length, size_t blockIndex);
RequestSlot(size_t index, uint32_t begin, size_t length, size_t blockIndex,
const SharedHandle<Piece>& piece = SharedHandle<Piece>());
RequestSlot(const RequestSlot& requestSlot);
RequestSlot();
~RequestSlot() {}
RequestSlot& operator=(const RequestSlot& requestSlot);
@ -66,7 +79,7 @@ public:
void setDispatchedTime();
void setDispatchedTime(time_t secFromEpoch);
bool isTimeout(time_t timeoutSec) const;
bool isTimeout(const struct timeval& now, time_t timeoutSec) const;
unsigned int getLatencyInMillis() const;
size_t getIndex() const { return index; }
@ -81,6 +94,8 @@ public:
size_t getBlockIndex() const { return blockIndex; }
void setBlockIndex(size_t blockIndex) { this->blockIndex = blockIndex; }
SharedHandle<Piece> getPiece() const;
static RequestSlot nullSlot;
static bool isNull(const RequestSlot& requestSlot);

View File

@ -278,9 +278,9 @@ void DefaultBtMessageDispatcherTest::testDoCancelSendingPieceAction() {
int MY_PIECE_LENGTH = 16*1024;
void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing() {
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
SharedHandle<Piece> piece(new Piece(0, MY_PIECE_LENGTH));
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0, piece);
size_t index;
CPPUNIT_ASSERT(piece->getMissingUnusedBlockIndex(index));
CPPUNIT_ASSERT_EQUAL((size_t)0, index);
@ -305,11 +305,11 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing() {
}
void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_timeout() {
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
SharedHandle<Piece> piece(new Piece(0, MY_PIECE_LENGTH));
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0, piece);
// make this slot timeout
slot.setDispatchedTime(0);
SharedHandle<Piece> piece(new Piece(0, MY_PIECE_LENGTH));
size_t index;
CPPUNIT_ASSERT(piece->getMissingUnusedBlockIndex(index));
CPPUNIT_ASSERT_EQUAL((size_t)0, index);
@ -338,11 +338,11 @@ void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_tim
}
void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_completeBlock() {
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
SharedHandle<Piece> piece(new Piece(0, MY_PIECE_LENGTH));
piece->completeBlock(0);
RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0, piece);
SharedHandle<MockPieceStorage2> pieceStorage(new MockPieceStorage2());
pieceStorage->setPiece(piece);
BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(),