2007-03-16 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

To reduce overhead to find commands whose socket is either
	readable or writable in the download engine loop:
	* src/Command.h, src/Command.cc
	(STATUS): New enum.
	(status): New variable.
	(statusMatch): New function.
	(setStatusActive): New function.
	(setStatusInactive): New function.
	* src/DownloadEngine.h, src/DownloadEngine.cc
	(executeCommand): New function.
	(run): Simplified.
	(waitData): Call Command::setStatusActive() when command's 
socket is
	readable or writable.
pull/1/head
Tatsuhiro Tsujikawa 2007-03-16 14:21:29 +00:00
parent 11907c175d
commit 113c8fac7f
7 changed files with 70 additions and 32 deletions

View File

@ -1,3 +1,21 @@
2007-03-16 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To reduce overhead to find commands whose socket is either
readable or writable in the download engine loop:
* src/Command.h, src/Command.cc
(STATUS): New enum.
(status): New variable.
(statusMatch): New function.
(setStatusActive): New function.
(setStatusInactive): New function.
* src/DownloadEngine.h, src/DownloadEngine.cc
(executeCommand): New function.
(run): Simplified.
(waitData): Call Command::setStatusActive() when command's socket is
readable or writable.
2007-03-15 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2007-03-15 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To handle Segment as SegmentHandle: To handle Segment as SegmentHandle:

View File

@ -9,7 +9,7 @@
# General Public License and is *not* in the public domain. # General Public License and is *not* in the public domain.
PACKAGE = aria2c PACKAGE = aria2c
VERSION = 0.10.0+1 VERSION = 0.10.1
SHELL = /bin/sh SHELL = /bin/sh

View File

@ -35,3 +35,14 @@
#include "Command.h" #include "Command.h"
int Command::uuidGen = 0; int Command::uuidGen = 0;
bool Command::statusMatch(Command::STATUS statusFilter) const
{
if(statusFilter == STATUS_ALL) {
return true;
} else if(statusFilter == status) {
return true;
} else {
return false;
}
}

View File

@ -41,14 +41,21 @@
typedef int CommandUuid; typedef int CommandUuid;
class Command { class Command {
public:
enum STATUS {
STATUS_ALL,
STATUS_ACTIVE,
STATUS_INACTIVE
};
private: private:
CommandUuid uuid; CommandUuid uuid;
static int uuidGen; static int uuidGen;
STATUS status;
protected: protected:
int cuid; int cuid;
const Logger* logger; const Logger* logger;
public: public:
Command(int cuid):uuid(uuidGen++), cuid(cuid) { Command(int cuid):uuid(uuidGen++), status(STATUS_INACTIVE), cuid(cuid) {
logger = LogFactory::getInstance(); logger = LogFactory::getInstance();
} }
virtual ~Command() {} virtual ~Command() {}
@ -56,6 +63,12 @@ public:
int getCuid() const { return cuid; } int getCuid() const { return cuid; }
const CommandUuid& getUuid() const { return uuid; } const CommandUuid& getUuid() const { return uuid; }
void setStatusActive() { this->status = STATUS_ACTIVE; }
void setStatusInactive() { this->status = STATUS_INACTIVE; }
bool statusMatch(Command::STATUS statusFilter) const;
}; };
#endif // _D_COMMAND_H_ #endif // _D_COMMAND_H_

View File

@ -130,7 +130,6 @@ bool DownloadCommand::prepareForNextSegment() {
while(1) { while(1) {
SegmentHandle nextSegment = e->segmentMan->getSegment(cuid, SegmentHandle nextSegment = e->segmentMan->getSegment(cuid,
tempSegment->index+1); tempSegment->index+1);
cerr << nextSegment.isNull() << endl;
if(nextSegment.isNull()) { if(nextSegment.isNull()) {
break; break;
} else { } else {

View File

@ -59,6 +59,24 @@ void DownloadEngine::cleanQueue() {
commands.clear(); commands.clear();
} }
void DownloadEngine::executeCommand(Command::STATUS statusFilter)
{
int max = commands.size();
for(int i = 0; i < max; i++) {
Command* com = commands.front();
commands.pop_front();
if(com->statusMatch(statusFilter)) {
if(com->execute()) {
delete com;
} else {
com->setStatusInactive();
}
} else {
commands.push_back(com);
}
}
}
void DownloadEngine::run() { void DownloadEngine::run() {
initStatistics(); initStatistics();
Time cp; Time cp;
@ -67,31 +85,13 @@ void DownloadEngine::run() {
while(!commands.empty()) { while(!commands.empty()) {
if(cp.elapsed(1)) { if(cp.elapsed(1)) {
cp.reset(); cp.reset();
int max = commands.size(); executeCommand(Command::STATUS_ALL);
for(int i = 0; i < max; i++) {
Command* com = commands.front();
commands.pop_front();
if(com->execute()) {
delete com;
}
}
} else { } else {
for(Commands::iterator itr = activeCommands.begin(); executeCommand(Command::STATUS_ACTIVE);
itr != activeCommands.end(); itr++) {
Commands::iterator comItr = find(commands.begin(), commands.end(),
*itr);
assert(comItr != commands.end());
Command* command = *itr;
commands.erase(comItr);
if(command->execute()) {
delete command;
}
}
} }
afterEachIteration(); afterEachIteration();
activeCommands.clear();
if(!noWait && !commands.empty()) { if(!noWait && !commands.empty()) {
waitData(activeCommands); waitData();
} }
noWait = false; noWait = false;
calculateStatistics(); calculateStatistics();
@ -108,7 +108,7 @@ void DownloadEngine::shortSleep() const {
select(0, &rfds, NULL, NULL, &tv); select(0, &rfds, NULL, NULL, &tv);
} }
void DownloadEngine::waitData(Commands& activeCommands) { void DownloadEngine::waitData() {
fd_set rfds; fd_set rfds;
fd_set wfds; fd_set wfds;
int retval = 0; int retval = 0;
@ -126,9 +126,7 @@ void DownloadEngine::waitData(Commands& activeCommands) {
SocketEntry& entry = *itr; SocketEntry& entry = *itr;
if(FD_ISSET(entry.socket->getSockfd(), &rfds) || if(FD_ISSET(entry.socket->getSockfd(), &rfds) ||
FD_ISSET(entry.socket->getSockfd(), &wfds)) { FD_ISSET(entry.socket->getSockfd(), &wfds)) {
if(find(activeCommands.begin(), activeCommands.end(), entry.command) == activeCommands.end()) { entry.command->setStatusActive();
activeCommands.push_back(entry.command);
}
} }
} }
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
@ -139,9 +137,7 @@ void DownloadEngine::waitData(Commands& activeCommands) {
switch(entry.nameResolver->getStatus()) { switch(entry.nameResolver->getStatus()) {
case NameResolver::STATUS_SUCCESS: case NameResolver::STATUS_SUCCESS:
case NameResolver::STATUS_ERROR: case NameResolver::STATUS_ERROR:
if(find(activeCommands.begin(), activeCommands.end(), entry.command) == activeCommands.end()) { entry.command->setStatusActive();
activeCommands.push_back(entry.command);
}
break; break;
default: default:
break; break;

View File

@ -97,7 +97,7 @@ typedef deque<NameResolverEntry> NameResolverEntries;
class DownloadEngine { class DownloadEngine {
private: private:
void waitData(Commands& activeCommands); void waitData();
SocketEntries socketEntries; SocketEntries socketEntries;
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
NameResolverEntries nameResolverEntries; NameResolverEntries nameResolverEntries;
@ -109,6 +109,7 @@ private:
void shortSleep() const; void shortSleep() const;
bool addSocket(const SocketEntry& socketEntry); bool addSocket(const SocketEntry& socketEntry);
bool deleteSocket(const SocketEntry& socketEntry); bool deleteSocket(const SocketEntry& socketEntry);
void executeCommand(Command::STATUS statusFilter);
protected: protected:
const Logger* logger; const Logger* logger;
virtual void initStatistics() = 0; virtual void initStatistics() = 0;