Stuff memory holes

Padding changes on x86_64:
- RequestGroup: 29 -> 5 bytes
- DownloadContext:  25 -> 1 bytes
- Cookie: 20 -> 4 bytes
- Command: 8 -> 0 bytes (affects many derived as well)
- HttpRequest: 20 -> 4 bytes
- DownloadCommand: 18 -> 2 bytes
- TimeBasedCommand: 14 -> 6 bytes
- AbstractCommand: 13 -> 5 bytes
- HttpSkipResponseCommand: 12 -> 4 bytes
- FileEntry: 10 -> 2 bytes
- DownloadResult: 15 -> 7 bytes
- UriStruct: 12 -> 4 bytes
- Piece: 11 -> 3 bytes
- BitfieldMan -> 11 -> 3 bytes
pull/159/merge
Nils Maier 2013-11-26 02:59:51 +01:00
parent 1323048ab1
commit 2db0c81fc8
28 changed files with 385 additions and 368 deletions

View File

@ -76,26 +76,29 @@
namespace aria2 { namespace aria2 {
AbstractCommand::AbstractCommand AbstractCommand::AbstractCommand(cuid_t cuid,
(cuid_t cuid,
const std::shared_ptr<Request>& req, const std::shared_ptr<Request>& req,
const std::shared_ptr<FileEntry>& fileEntry, const std::shared_ptr<FileEntry>& fileEntry,
RequestGroup* requestGroup, RequestGroup* requestGroup, DownloadEngine* e,
DownloadEngine* e,
const std::shared_ptr<SocketCore>& s, const std::shared_ptr<SocketCore>& s,
const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer, const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer,
bool incNumConnection) bool incNumConnection)
: Command(cuid), checkPoint_(global::wallclock()), : Command(cuid),
timeout_(requestGroup->getTimeout()), req_(req),
requestGroup_(requestGroup), fileEntry_(fileEntry),
req_(req), fileEntry_(fileEntry), e_(e), socket_(s), socket_(s),
socketRecvBuffer_(socketRecvBuffer), socketRecvBuffer_(socketRecvBuffer),
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
asyncNameResolverMan_(make_unique<AsyncNameResolverMan>()), asyncNameResolverMan_(make_unique<AsyncNameResolverMan>()),
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
checkSocketIsReadable_(false), checkSocketIsWritable_(false), requestGroup_(requestGroup),
incNumConnection_(incNumConnection), e_(e),
serverStatTimer_(global::wallclock()) checkPoint_(global::wallclock()),
serverStatTimer_(global::wallclock()),
timeout_(requestGroup->getTimeout()),
checkSocketIsReadable_(false),
checkSocketIsWritable_(false),
incNumConnection_(incNumConnection)
{ {
if(socket_ && socket_->isOpen()) { if(socket_ && socket_->isOpen()) {
setReadCheckSocket(socket_); setReadCheckSocket(socket_);

View File

@ -64,31 +64,34 @@ class AsyncNameResolverMan;
class AbstractCommand : public Command { class AbstractCommand : public Command {
private: private:
Timer checkPoint_;
time_t timeout_;
RequestGroup* requestGroup_;
std::shared_ptr<Request> req_; std::shared_ptr<Request> req_;
std::shared_ptr<FileEntry> fileEntry_; std::shared_ptr<FileEntry> fileEntry_;
DownloadEngine* e_;
std::shared_ptr<SocketCore> socket_; std::shared_ptr<SocketCore> socket_;
std::shared_ptr<SocketRecvBuffer> socketRecvBuffer_; std::shared_ptr<SocketRecvBuffer> socketRecvBuffer_;
std::vector<std::shared_ptr<Segment> > segments_; std::shared_ptr<SocketCore> readCheckTarget_;
std::shared_ptr<SocketCore> writeCheckTarget_;
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
std::unique_ptr<AsyncNameResolverMan> asyncNameResolverMan_; std::unique_ptr<AsyncNameResolverMan> asyncNameResolverMan_;
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
RequestGroup* requestGroup_;
DownloadEngine* e_;
std::vector<std::shared_ptr<Segment> > segments_;
Timer checkPoint_;
Timer serverStatTimer_;
time_t timeout_;
bool checkSocketIsReadable_; bool checkSocketIsReadable_;
bool checkSocketIsWritable_; bool checkSocketIsWritable_;
std::shared_ptr<SocketCore> readCheckTarget_;
std::shared_ptr<SocketCore> writeCheckTarget_;
bool incNumConnection_; bool incNumConnection_;
Timer serverStatTimer_;
int32_t calculateMinSplitSize() const; int32_t calculateMinSplitSize() const;
void useFasterRequest(const std::shared_ptr<Request>& fasterRequest); void useFasterRequest(const std::shared_ptr<Request>& fasterRequest);
public: public:
RequestGroup* getRequestGroup() const RequestGroup* getRequestGroup() const
{ {
@ -234,8 +237,7 @@ protected:
} }
public: public:
AbstractCommand AbstractCommand(cuid_t cuid, const std::shared_ptr<Request>& req,
(cuid_t cuid, const std::shared_ptr<Request>& req,
const std::shared_ptr<FileEntry>& fileEntry, const std::shared_ptr<FileEntry>& fileEntry,
RequestGroup* requestGroup, DownloadEngine* e, RequestGroup* requestGroup, DownloadEngine* e,
const std::shared_ptr<SocketCore>& s = nullptr, const std::shared_ptr<SocketCore>& s = nullptr,

View File

@ -45,19 +45,19 @@ using namespace aria2::expr;
namespace aria2 { namespace aria2 {
BitfieldMan::BitfieldMan(int32_t blockLength, int64_t totalLength) BitfieldMan::BitfieldMan(int32_t blockLength, int64_t totalLength)
:blockLength_(blockLength), : totalLength_(totalLength),
totalLength_(totalLength), cachedCompletedLength_(0),
bitfieldLength_(0), cachedFilteredCompletedLength_(0),
blocks_(0), cachedFilteredTotalLength_(0),
filterEnabled_(false),
bitfield_(nullptr), bitfield_(nullptr),
useBitfield_(nullptr), useBitfield_(nullptr),
filterBitfield_(nullptr), filterBitfield_(nullptr),
bitfieldLength_(0),
cachedNumMissingBlock_(0), cachedNumMissingBlock_(0),
cachedNumFilteredBlock_(0), cachedNumFilteredBlock_(0),
cachedCompletedLength_(0), blocks_(0),
cachedFilteredCompletedLength_(0), blockLength_(blockLength),
cachedFilteredTotalLength_(0) filterEnabled_(false)
{ {
if(blockLength_ > 0 && totalLength_ > 0) { if(blockLength_ > 0 && totalLength_ > 0) {
blocks_ = (totalLength_+blockLength_-1)/blockLength_; blocks_ = (totalLength_+blockLength_-1)/blockLength_;
@ -71,19 +71,19 @@ BitfieldMan::BitfieldMan(int32_t blockLength, int64_t totalLength)
} }
BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan) BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan)
:blockLength_(bitfieldMan.blockLength_), : totalLength_(bitfieldMan.totalLength_),
totalLength_(bitfieldMan.totalLength_),
bitfieldLength_(bitfieldMan.bitfieldLength_),
blocks_(bitfieldMan.blocks_),
filterEnabled_(bitfieldMan.filterEnabled_),
bitfield_(new unsigned char[bitfieldLength_]),
useBitfield_(new unsigned char[bitfieldLength_]),
filterBitfield_(nullptr),
cachedNumMissingBlock_(0),
cachedNumFilteredBlock_(0),
cachedCompletedLength_(0), cachedCompletedLength_(0),
cachedFilteredCompletedLength_(0), cachedFilteredCompletedLength_(0),
cachedFilteredTotalLength_(0) cachedFilteredTotalLength_(0),
bitfield_(new unsigned char[bitfieldMan.bitfieldLength_]),
useBitfield_(new unsigned char[bitfieldMan.bitfieldLength_]),
filterBitfield_(nullptr),
bitfieldLength_(bitfieldMan.bitfieldLength_),
cachedNumMissingBlock_(0),
cachedNumFilteredBlock_(0),
blocks_(bitfieldMan.blocks_),
blockLength_(bitfieldMan.blockLength_),
filterEnabled_(bitfieldMan.filterEnabled_)
{ {
memcpy(bitfield_, bitfieldMan.bitfield_, bitfieldLength_); memcpy(bitfield_, bitfieldMan.bitfield_, bitfieldLength_);
memcpy(useBitfield_, bitfieldMan.useBitfield_, bitfieldLength_); memcpy(useBitfield_, bitfieldMan.useBitfield_, bitfieldLength_);
@ -97,8 +97,8 @@ BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan)
BitfieldMan& BitfieldMan::operator=(const BitfieldMan& bitfieldMan) BitfieldMan& BitfieldMan::operator=(const BitfieldMan& bitfieldMan)
{ {
if(this != &bitfieldMan) { if(this != &bitfieldMan) {
blockLength_ = bitfieldMan.blockLength_;
totalLength_ = bitfieldMan.totalLength_; totalLength_ = bitfieldMan.totalLength_;
blockLength_ = bitfieldMan.blockLength_;
blocks_ = bitfieldMan.blocks_; blocks_ = bitfieldMan.blocks_;
bitfieldLength_ = bitfieldMan.bitfieldLength_; bitfieldLength_ = bitfieldMan.bitfieldLength_;
filterEnabled_ = bitfieldMan.filterEnabled_; filterEnabled_ = bitfieldMan.filterEnabled_;

View File

@ -43,21 +43,23 @@ namespace aria2 {
class BitfieldMan { class BitfieldMan {
private: private:
int32_t blockLength_;
int64_t totalLength_; int64_t totalLength_;
size_t bitfieldLength_; int64_t cachedCompletedLength_;
size_t blocks_; int64_t cachedFilteredCompletedLength_;
bool filterEnabled_; int64_t cachedFilteredTotalLength_;
unsigned char* bitfield_; unsigned char* bitfield_;
unsigned char* useBitfield_; unsigned char* useBitfield_;
unsigned char* filterBitfield_; unsigned char* filterBitfield_;
// for caching size_t bitfieldLength_;
size_t cachedNumMissingBlock_; size_t cachedNumMissingBlock_;
size_t cachedNumFilteredBlock_; size_t cachedNumFilteredBlock_;
int64_t cachedCompletedLength_; size_t blocks_;
int64_t cachedFilteredCompletedLength_;
int64_t cachedFilteredTotalLength_; int32_t blockLength_;
bool filterEnabled_;
bool setBitInternal(unsigned char* bitfield, size_t index, bool on); bool setBitInternal(unsigned char* bitfield, size_t index, bool on);
bool setFilterBit(size_t index); bool setFilterBit(size_t index);
@ -70,6 +72,7 @@ private:
// If filterBitfield_ is 0, allocate bitfieldLength_ bytes to it and // If filterBitfield_ is 0, allocate bitfieldLength_ bytes to it and
// set 0 to all bytes. // set 0 to all bytes.
void ensureFilterBitfield(); void ensureFilterBitfield();
public: public:
// [startIndex, endIndex) // [startIndex, endIndex)
struct Range { struct Range {
@ -81,6 +84,7 @@ public:
bool operator<(const Range& range) const; bool operator<(const Range& range) const;
bool operator==(const Range& range) const; bool operator==(const Range& range) const;
}; };
public: public:
BitfieldMan(int32_t blockLength, int64_t totalLength); BitfieldMan(int32_t blockLength, int64_t totalLength);
BitfieldMan(const BitfieldMan& bitfieldMan); BitfieldMan(const BitfieldMan& bitfieldMan);

View File

@ -38,8 +38,8 @@
namespace aria2 { namespace aria2 {
Command::Command(cuid_t cuid) Command::Command(cuid_t cuid)
: status_(STATUS_INACTIVE), : cuid_(cuid),
cuid_(cuid), status_(STATUS_INACTIVE),
readEvent_(false), readEvent_(false),
writeEvent_(false), writeEvent_(false),
errorEvent_(false), errorEvent_(false),

View File

@ -50,15 +50,17 @@ public:
STATUS_REALTIME, STATUS_REALTIME,
STATUS_ONESHOT_REALTIME STATUS_ONESHOT_REALTIME
}; };
private:
STATUS status_;
private:
cuid_t cuid_; cuid_t cuid_;
STATUS status_;
bool readEvent_; bool readEvent_;
bool writeEvent_; bool writeEvent_;
bool errorEvent_; bool errorEvent_;
bool hupEvent_; bool hupEvent_;
protected: protected:
bool readEventEnabled() const bool readEventEnabled() const
{ {
@ -79,6 +81,7 @@ protected:
{ {
return hupEvent_; return hupEvent_;
} }
public: public:
Command(cuid_t cuid); Command(cuid_t cuid);

View File

@ -42,37 +42,32 @@
namespace aria2 { namespace aria2 {
Cookie::Cookie Cookie::Cookie(std::string name, std::string value, time_t expiryTime,
(std::string name, bool persistent, std::string domain, bool hostOnly,
std::string value, std::string path, bool secure, bool httpOnly,
time_t expiryTime, time_t creationTime)
bool persistent, : expiryTime_(expiryTime),
std::string domain, creationTime_(creationTime),
bool hostOnly, lastAccessTime_(creationTime),
std::string path,
bool secure,
bool httpOnly,
time_t creationTime):
name_(std::move(name)), name_(std::move(name)),
value_(std::move(value)), value_(std::move(value)),
expiryTime_(expiryTime),
persistent_(persistent),
domain_(std::move(domain)), domain_(std::move(domain)),
hostOnly_(hostOnly),
path_(std::move(path)), path_(std::move(path)),
persistent_(persistent),
hostOnly_(hostOnly),
secure_(secure), secure_(secure),
httpOnly_(httpOnly), httpOnly_(httpOnly)
creationTime_(creationTime), {}
lastAccessTime_(creationTime) {}
Cookie::Cookie(): Cookie::Cookie()
expiryTime_(0), : expiryTime_(0),
creationTime_(0),
lastAccessTime_(0),
persistent_(false), persistent_(false),
hostOnly_(false), hostOnly_(false),
secure_(false), secure_(false),
httpOnly_(false), httpOnly_(false)
creationTime_(0), {}
lastAccessTime_(0) {}
std::string Cookie::toString() const std::string Cookie::toString() const
{ {
@ -82,8 +77,7 @@ std::string Cookie::toString() const
return s; return s;
} }
bool Cookie::match bool Cookie::match(const std::string& requestHost,
(const std::string& requestHost,
const std::string& requestPath, const std::string& requestPath,
time_t date, bool secure) const time_t date, bool secure) const
{ {

View File

@ -45,39 +45,30 @@ namespace aria2 {
class Cookie { class Cookie {
private: private:
time_t expiryTime_;
time_t creationTime_;
time_t lastAccessTime_;
std::string name_; std::string name_;
std::string value_; std::string value_;
time_t expiryTime_; std::string domain_;
std::string path_;
// If persistent_ is false, this is a session scope cookie and it is // If persistent_ is false, this is a session scope cookie and it is
// never expired during session. So isExpired() always returns // never expired during session. So isExpired() always returns
// false. // false.
bool persistent_; bool persistent_;
std::string domain_;
bool hostOnly_; bool hostOnly_;
std::string path_;
bool secure_; bool secure_;
bool httpOnly_; bool httpOnly_;
time_t creationTime_;
time_t lastAccessTime_;
public: public:
Cookie(); Cookie();
Cookie(std::string name, std::string value, time_t expiryTime,
Cookie bool persistent, std::string domain, bool hostOnly, std::string path,
(std::string name, bool secure, bool httpOnly, time_t creationTime);
std::string value,
time_t expiryTime,
bool persistent,
std::string domain,
bool hostOnly,
std::string path,
bool secure,
bool httpOnly,
time_t creationTime);
std::string toString() const; std::string toString() const;
bool match bool match(const std::string& requestHost, const std::string& requestPath,
(const std::string& requestHost, const std::string& requestPath,
time_t date, bool secure) const; time_t date, bool secure) const;
bool operator==(const Cookie& cookie) const; bool operator==(const Cookie& cookie) const;

View File

@ -79,12 +79,10 @@ namespace {
const size_t BUFSIZE = 16*1024; const size_t BUFSIZE = 16*1024;
} // namespace } // namespace
DownloadCommand::DownloadCommand DownloadCommand::DownloadCommand(cuid_t cuid,
(cuid_t cuid,
const std::shared_ptr<Request>& req, const std::shared_ptr<Request>& req,
const std::shared_ptr<FileEntry>& fileEntry, const std::shared_ptr<FileEntry>& fileEntry,
RequestGroup* requestGroup, RequestGroup* requestGroup, DownloadEngine* e,
DownloadEngine* e,
const std::shared_ptr<SocketCore>& s, const std::shared_ptr<SocketCore>& s,
const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer) const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer)
: AbstractCommand(cuid, req, fileEntry, requestGroup, e, s, socketRecvBuffer), : AbstractCommand(cuid, req, fileEntry, requestGroup, e, s, socketRecvBuffer),

View File

@ -49,17 +49,21 @@ class MessageDigest;
class DownloadCommand : public AbstractCommand { class DownloadCommand : public AbstractCommand {
private: private:
time_t startupIdleTime_;
int lowestDownloadSpeedLimit_;
std::shared_ptr<PeerStat> peerStat_; std::shared_ptr<PeerStat> peerStat_;
std::unique_ptr<StreamFilter> streamFilter_;
#ifdef ENABLE_MESSAGE_DIGEST
std::unique_ptr<MessageDigest> messageDigest_;
#endif // ENABLE_MESSAGE_DIGEST
time_t startupIdleTime_;
int lowestDownloadSpeedLimit_;
bool pieceHashValidationEnabled_; bool pieceHashValidationEnabled_;
#ifdef ENABLE_MESSAGE_DIGEST bool sinkFilterOnly_;
std::unique_ptr<MessageDigest> messageDigest_;
#endif // ENABLE_MESSAGE_DIGEST
void validatePieceHash(const std::shared_ptr<Segment>& segment, void validatePieceHash(const std::shared_ptr<Segment>& segment,
const std::string& expectedPieceHash, const std::string& expectedPieceHash,
@ -69,9 +73,6 @@ private:
void completeSegment(cuid_t cuid, const std::shared_ptr<Segment>& segment); void completeSegment(cuid_t cuid, const std::shared_ptr<Segment>& segment);
std::unique_ptr<StreamFilter> streamFilter_;
bool sinkFilterOnly_;
protected: protected:
virtual bool executeInternal() CXX11_OVERRIDE; virtual bool executeInternal() CXX11_OVERRIDE;

View File

@ -47,24 +47,25 @@
namespace aria2 { namespace aria2 {
DownloadContext::DownloadContext(): DownloadContext::DownloadContext()
: ownerRequestGroup_(nullptr),
attrs_(MAX_CTX_ATTR),
downloadStopTime_(0),
pieceLength_(0), pieceLength_(0),
checksumVerified_(false), checksumVerified_(false),
knowsTotalLength_(true), knowsTotalLength_(true),
ownerRequestGroup_(nullptr), acceptMetalink_(true)
attrs_(MAX_CTX_ATTR), {}
downloadStopTime_(0),
acceptMetalink_(true) {}
DownloadContext::DownloadContext(int32_t pieceLength, DownloadContext::DownloadContext(int32_t pieceLength,
int64_t totalLength, int64_t totalLength,
const std::string& path): const std::string& path)
: ownerRequestGroup_(nullptr),
attrs_(MAX_CTX_ATTR),
downloadStopTime_(0),
pieceLength_(pieceLength), pieceLength_(pieceLength),
checksumVerified_(false), checksumVerified_(false),
knowsTotalLength_(true), knowsTotalLength_(true),
ownerRequestGroup_(nullptr),
attrs_(MAX_CTX_ATTR),
downloadStopTime_(0),
acceptMetalink_(true) acceptMetalink_(true)
{ {
std::shared_ptr<FileEntry> fileEntry(new FileEntry(path, totalLength, 0)); std::shared_ptr<FileEntry> fileEntry(new FileEntry(path, totalLength, 0));

View File

@ -58,11 +58,19 @@ class FileEntry;
class DownloadContext class DownloadContext
{ {
private: private:
std::unique_ptr<Signature> signature_;
RequestGroup* ownerRequestGroup_;
std::vector<std::unique_ptr<ContextAttribute> > attrs_;
std::vector<std::shared_ptr<FileEntry> > fileEntries_; std::vector<std::shared_ptr<FileEntry> > fileEntries_;
std::vector<std::string> pieceHashes_; std::vector<std::string> pieceHashes_;
int32_t pieceLength_; NetStat netStat_;
Timer downloadStopTime_;
std::string pieceHashType_; std::string pieceHashType_;
@ -70,24 +78,18 @@ private:
std::string hashType_; std::string hashType_;
bool checksumVerified_;
std::string basePath_; std::string basePath_;
int32_t pieceLength_;
bool checksumVerified_;
bool knowsTotalLength_; bool knowsTotalLength_;
RequestGroup* ownerRequestGroup_;
std::vector<std::unique_ptr<ContextAttribute> > attrs_;
NetStat netStat_;
Timer downloadStopTime_;
std::unique_ptr<Signature> signature_;
// This member variable is required to avoid to use parse Metalink // This member variable is required to avoid to use parse Metalink
// (including both Metalink XML and Metalink/HTTP) twice. // (including both Metalink XML and Metalink/HTTP) twice.
bool acceptMetalink_; bool acceptMetalink_;
public: public:
DownloadContext(); DownloadContext();

View File

@ -40,17 +40,16 @@
namespace aria2 { namespace aria2 {
DownloadResult::DownloadResult() DownloadResult::DownloadResult()
: gid(nullptr), : belongsTo(0),
inMemoryDownload(false),
sessionDownloadLength(0), sessionDownloadLength(0),
sessionTime(0), sessionTime(0),
result(error_code::UNDEFINED),
belongsTo(0),
totalLength(0), totalLength(0),
completedLength(0), completedLength(0),
uploadLength(0), uploadLength(0),
numPieces(0),
pieceLength(0), pieceLength(0),
numPieces(0) result(error_code::UNDEFINED),
inMemoryDownload(false)
{} {}
DownloadResult::~DownloadResult() {} DownloadResult::~DownloadResult() {}

View File

@ -54,46 +54,46 @@ class MetadataInfo;
struct DownloadResult struct DownloadResult
{ {
std::shared_ptr<GroupId> gid; // This field contains GID. See comment in
// RequestGroup.cc::belongsToGID_.
std::vector<std::shared_ptr<FileEntry> > fileEntries; a2_gid_t belongsTo;
bool inMemoryDownload;
uint64_t sessionDownloadLength; uint64_t sessionDownloadLength;
// milliseconds // milliseconds
int64_t sessionTime; int64_t sessionTime;
error_code::Value result;
// This field contains GIDs. See comment in
// RequestGroup.cc::followedByGIDs_.
std::vector<a2_gid_t> followedBy;
// This field contains GID. See comment in
// RequestGroup.cc::belongsToGID_.
a2_gid_t belongsTo;
std::shared_ptr<Option> option;
std::shared_ptr<MetadataInfo> metadataInfo;
int64_t totalLength; int64_t totalLength;
int64_t completedLength; int64_t completedLength;
int64_t uploadLength; int64_t uploadLength;
std::shared_ptr<GroupId> gid;
std::shared_ptr<Option> option;
std::shared_ptr<MetadataInfo> metadataInfo;
std::vector<std::shared_ptr<FileEntry> > fileEntries;
// This field contains GIDs. See comment in
// RequestGroup.cc::followedByGIDs_.
std::vector<a2_gid_t> followedBy;
std::string bitfield; std::string bitfield;
std::string infoHash; std::string infoHash;
int32_t pieceLength; std::string dir;
size_t numPieces; size_t numPieces;
std::string dir; int32_t pieceLength;
error_code::Value result;
bool inMemoryDownload;
DownloadResult(); DownloadResult();
~DownloadResult(); ~DownloadResult();

View File

@ -66,27 +66,24 @@ bool FileEntry::RequestFaster::operator()
return lspd > rspd || (lspd == rspd && lhs.get() < rhs.get()); return lspd > rspd || (lspd == rspd && lhs.get() < rhs.get());
} }
FileEntry::FileEntry FileEntry::FileEntry(const std::string& path, int64_t length, int64_t offset,
(const std::string& path,
int64_t length,
int64_t offset,
const std::vector<std::string>& uris) const std::vector<std::string>& uris)
: path_(path), : length_(length),
uris_(uris.begin(), uris.end()),
length_(length),
offset_(offset), offset_(offset),
requested_(true), uris_(uris.begin(), uris.end()),
uniqueProtocol_(false), path_(path),
lastFasterReplace_(0),
maxConnectionPerServer_(1), maxConnectionPerServer_(1),
lastFasterReplace_(0) requested_(true),
uniqueProtocol_(false)
{} {}
FileEntry::FileEntry() FileEntry::FileEntry()
: length_(0), : length_(0),
offset_(0), offset_(0),
maxConnectionPerServer_(1),
requested_(false), requested_(false),
uniqueProtocol_(false), uniqueProtocol_(false)
maxConnectionPerServer_(1)
{} {}
FileEntry::~FileEntry() {} FileEntry::~FileEntry() {}

View File

@ -62,31 +62,35 @@ class FileEntry {
public: public:
typedef std::set<std::shared_ptr<Request>, RefLess<Request> > typedef std::set<std::shared_ptr<Request>, RefLess<Request> >
InFlightRequestSet; InFlightRequestSet;
private:
std::string path_;
std::deque<std::string> uris_;
std::deque<std::string> spentUris_;
int64_t length_;
int64_t offset_;
bool requested_;
private:
class RequestFaster { class RequestFaster {
public: public:
bool operator()(const std::shared_ptr<Request>& lhs, bool operator()(const std::shared_ptr<Request>& lhs,
const std::shared_ptr<Request>& rhs) const; const std::shared_ptr<Request>& rhs) const;
}; };
typedef std::set<std::shared_ptr<Request>, RequestFaster> RequestPool; typedef std::set<std::shared_ptr<Request>, RequestFaster> RequestPool;
RequestPool requestPool_;
InFlightRequestSet inFlightRequests_; int64_t length_;
std::string contentType_; int64_t offset_;
std::deque<std::string> uris_;
std::deque<std::string> spentUris_;
// URIResult is stored in the ascending order of the time when its result is // URIResult is stored in the ascending order of the time when its result is
// available. // available.
std::deque<URIResult> uriResults_; std::deque<URIResult> uriResults_;
bool uniqueProtocol_; RequestPool requestPool_;
int maxConnectionPerServer_; InFlightRequestSet inFlightRequests_;
std::string path_;
std::string contentType_;
std::string originalName_; std::string originalName_;
Timer lastFasterReplace_; Timer lastFasterReplace_;
int maxConnectionPerServer_;
bool requested_;
bool uniqueProtocol_;
void storePool(const std::shared_ptr<Request>& request); void storePool(const std::shared_ptr<Request>& request);
public: public:

View File

@ -58,15 +58,15 @@ namespace aria2 {
const std::string HttpRequest::USER_AGENT("aria2"); const std::string HttpRequest::USER_AGENT("aria2");
HttpRequest::HttpRequest() HttpRequest::HttpRequest()
: contentEncodingEnabled_(true), : cookieStorage_(nullptr),
userAgent_(USER_AGENT),
acceptMetalink_(false),
cookieStorage_(nullptr),
authConfigFactory_(nullptr), authConfigFactory_(nullptr),
option_(nullptr), option_(nullptr),
endOffsetOverride_(0),
userAgent_(USER_AGENT),
contentEncodingEnabled_(true),
acceptMetalink_(false),
noCache_(true), noCache_(true),
acceptGzip_(false), acceptGzip_(false)
endOffsetOverride_(0)
{} {}
HttpRequest::~HttpRequest() {} HttpRequest::~HttpRequest() {}

View File

@ -65,14 +65,9 @@ private:
std::shared_ptr<Segment> segment_; std::shared_ptr<Segment> segment_;
bool contentEncodingEnabled_; std::shared_ptr<Request> proxyRequest_;
std::string userAgent_; std::unique_ptr<AuthConfig> authConfig_;
std::vector<std::string> headers_;
// If true, metalink content types are sent in Accept header field.
bool acceptMetalink_;
CookieStorage* cookieStorage_; CookieStorage* cookieStorage_;
@ -80,14 +75,6 @@ private:
const Option* option_; const Option* option_;
std::unique_ptr<AuthConfig> authConfig_;
std::shared_ptr<Request> proxyRequest_;
bool noCache_;
bool acceptGzip_;
// Historically, aria2 did not specify end byte marker unless http // Historically, aria2 did not specify end byte marker unless http
// pipelining is enabled. Sometimes end byte is known because the // pipelining is enabled. Sometimes end byte is known because the
// segment/piece ahead of this request was already acquired. In this // segment/piece ahead of this request was already acquired. In this
@ -97,9 +84,23 @@ private:
// bytes and it is also true if it is used via HTTP proxy. // bytes and it is also true if it is used via HTTP proxy.
int64_t endOffsetOverride_; int64_t endOffsetOverride_;
std::vector<std::string> headers_;
std::string userAgent_;
std::string ifModSinceHeader_; std::string ifModSinceHeader_;
bool contentEncodingEnabled_;
// If true, metalink content types are sent in Accept header field.
bool acceptMetalink_;
bool noCache_;
bool acceptGzip_;
std::pair<std::string, std::string> getProxyAuthString() const; std::pair<std::string, std::string> getProxyAuthString() const;
public: public:
HttpRequest(); HttpRequest();
~HttpRequest(); ~HttpRequest();

View File

@ -74,12 +74,12 @@ HttpSkipResponseCommand::HttpSkipResponseCommand
const std::shared_ptr<SocketCore>& s) const std::shared_ptr<SocketCore>& s)
: AbstractCommand(cuid, req, fileEntry, requestGroup, e, s, : AbstractCommand(cuid, req, fileEntry, requestGroup, e, s,
httpConnection->getSocketRecvBuffer()), httpConnection->getSocketRecvBuffer()),
httpConnection_(httpConnection),
httpResponse_(std::move(httpResponse)),
streamFilter_(new NullSinkStreamFilter()),
sinkFilterOnly_(true), sinkFilterOnly_(true),
totalLength_(httpResponse_->getEntityLength()), totalLength_(httpResponse_->getEntityLength()),
receivedBytes_(0) receivedBytes_(0),
httpConnection_(httpConnection),
httpResponse_(std::move(httpResponse)),
streamFilter_(new NullSinkStreamFilter())
{ {
checkSocketRecvBuffer(); checkSocketRecvBuffer();
} }

View File

@ -45,11 +45,7 @@ class StreamFilter;
class HttpSkipResponseCommand : public AbstractCommand { class HttpSkipResponseCommand : public AbstractCommand {
private: private:
std::shared_ptr<HttpConnection> httpConnection_; // hole from AbstractCommand (5 bytes on x86_64)
std::unique_ptr<HttpResponse> httpResponse_;
std::unique_ptr<StreamFilter> streamFilter_;
bool sinkFilterOnly_; bool sinkFilterOnly_;
@ -57,15 +53,21 @@ private:
int64_t receivedBytes_; int64_t receivedBytes_;
std::shared_ptr<HttpConnection> httpConnection_;
std::unique_ptr<HttpResponse> httpResponse_;
std::unique_ptr<StreamFilter> streamFilter_;
bool processResponse(); bool processResponse();
void poolConnection() const; void poolConnection() const;
protected: protected:
virtual bool executeInternal() CXX11_OVERRIDE; virtual bool executeInternal() CXX11_OVERRIDE;
public: public:
HttpSkipResponseCommand HttpSkipResponseCommand(cuid_t cuid, const std::shared_ptr<Request>& req,
(cuid_t cuid,
const std::shared_ptr<Request>& req,
const std::shared_ptr<FileEntry>& fileEntry, const std::shared_ptr<FileEntry>& fileEntry,
RequestGroup* requestGroup, RequestGroup* requestGroup,
const std::shared_ptr<HttpConnection>& httpConnection, const std::shared_ptr<HttpConnection>& httpConnection,

View File

@ -52,22 +52,28 @@
namespace aria2 { namespace aria2 {
Piece::Piece():index_(0), length_(0), blockLength_(BLOCK_LENGTH), bitfield_(nullptr), Piece::Piece()
usedBySegment_(false), wrCache_(nullptr) : bitfield_(nullptr),
wrCache_(nullptr),
index_(0),
length_(0),
blockLength_(BLOCK_LENGTH),
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
, nextBegin_(0) nextBegin_(0),
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
usedBySegment_(false)
{} {}
Piece::Piece(size_t index, int32_t length, int32_t blockLength) Piece::Piece(size_t index, int32_t length, int32_t blockLength)
: index_(index), : bitfield_(new BitfieldMan(blockLength, length)),
wrCache_(nullptr),
index_(index),
length_(length), length_(length),
blockLength_(blockLength), blockLength_(blockLength),
bitfield_(new BitfieldMan(blockLength_, length)),
usedBySegment_(false), wrCache_(nullptr)
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
,nextBegin_(0) nextBegin_(0),
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
usedBySegment_(false)
{} {}
Piece::~Piece() Piece::~Piece()

View File

@ -59,32 +59,33 @@ class MessageDigest;
class Piece { class Piece {
private: private:
size_t index_;
int32_t length_;
int32_t blockLength_;
BitfieldMan* bitfield_; BitfieldMan* bitfield_;
std::vector<cuid_t> users_;
bool usedBySegment_;
WrDiskCacheEntry* wrCache_; WrDiskCacheEntry* wrCache_;
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
int32_t nextBegin_;
std::string hashType_;
std::unique_ptr<MessageDigest> mdctx_; std::unique_ptr<MessageDigest> mdctx_;
#endif // ENABLE_MESSAGE_DIGEST
std::vector<cuid_t> users_;
#ifdef ENABLE_MESSAGE_DIGEST
std::string hashType_;
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
Piece(const Piece& piece); size_t index_;
int32_t length_;
int32_t blockLength_;
#ifdef ENABLE_MESSAGE_DIGEST
int32_t nextBegin_;
#endif // ENABLE_MESSAGE_DIGEST
bool usedBySegment_;
Piece(const Piece& piece) = delete;
Piece& operator=(const Piece& piece) = delete;
Piece& operator=(const Piece& piece);
public: public:
static const int32_t BLOCK_LENGTH = 16*1024; static const int32_t BLOCK_LENGTH = 16*1024;
Piece(); Piece();
Piece(size_t index, int32_t length, int32_t blockLength = BLOCK_LENGTH); Piece(size_t index, int32_t length, int32_t blockLength = BLOCK_LENGTH);
~Piece(); ~Piece();

View File

@ -123,35 +123,35 @@ namespace aria2 {
RequestGroup::RequestGroup(const std::shared_ptr<GroupId>& gid, RequestGroup::RequestGroup(const std::shared_ptr<GroupId>& gid,
const std::shared_ptr<Option>& option) const std::shared_ptr<Option>& option)
: gid_(gid), : belongsToGID_(0),
state_(STATE_WAITING), gid_(gid),
option_(option), option_(option),
numConcurrentCommand_(option->getAsInt(PREF_SPLIT)),
numStreamConnection_(0),
numStreamCommand_(0),
numCommand_(0),
saveControlFile_(true),
progressInfoFile_(new NullProgressInfoFile()), progressInfoFile_(new NullProgressInfoFile()),
preLocalFileCheckEnabled_(true),
haltRequested_(false),
forceHaltRequested_(false),
haltReason_(RequestGroup::NONE),
pauseRequested_(false),
uriSelector_(make_unique<InorderURISelector>()), uriSelector_(make_unique<InorderURISelector>()),
lastModifiedTime_(Time::null()), requestGroupMan_(nullptr),
fileNotFoundCount_(0),
timeout_(option->getAsInt(PREF_TIMEOUT)),
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
btRuntime_(nullptr), btRuntime_(nullptr),
peerStorage_(nullptr), peerStorage_(nullptr),
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
inMemoryDownload_(false), lastModifiedTime_(Time::null()),
timeout_(option->getAsInt(PREF_TIMEOUT)),
state_(STATE_WAITING),
numConcurrentCommand_(option->getAsInt(PREF_SPLIT)),
numStreamConnection_(0),
numStreamCommand_(0),
numCommand_(0),
fileNotFoundCount_(0),
maxDownloadSpeedLimit_(option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT)), maxDownloadSpeedLimit_(option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT)),
maxUploadSpeedLimit_(option->getAsInt(PREF_MAX_UPLOAD_LIMIT)), maxUploadSpeedLimit_(option->getAsInt(PREF_MAX_UPLOAD_LIMIT)),
resumeFailureCount_(0),
haltReason_(RequestGroup::NONE),
lastErrorCode_(error_code::UNDEFINED), lastErrorCode_(error_code::UNDEFINED),
belongsToGID_(0), saveControlFile_(true),
requestGroupMan_(nullptr), preLocalFileCheckEnabled_(true),
resumeFailureCount_(0) haltRequested_(false),
forceHaltRequested_(false),
pauseRequested_(false),
inMemoryDownload_(false)
{ {
fileAllocationEnabled_ = option_->get(PREF_FILE_ALLOCATION) != V_NONE; fileAllocationEnabled_ = option_->get(PREF_FILE_ALLOCATION) != V_NONE;
if(!option_->getAsBool(PREF_DRY_RUN)) { if(!option_->getAsBool(PREF_DRY_RUN)) {

View File

@ -87,13 +87,59 @@ public:
// Download has begun // Download has begun
STATE_ACTIVE STATE_ACTIVE
}; };
private: private:
// If this download is a part of another download(for example,
// downloading torrent file described in Metalink file), this field
// has the GID of parent RequestGroup. 0 means this is a parent
// RequestGroup.
a2_gid_t belongsToGID_;
std::shared_ptr<GroupId> gid_; std::shared_ptr<GroupId> gid_;
int state_;
std::shared_ptr<Option> option_; std::shared_ptr<Option> option_;
std::shared_ptr<SegmentMan> segmentMan_;
std::shared_ptr<DownloadContext> downloadContext_;
std::shared_ptr<PieceStorage> pieceStorage_;
std::shared_ptr<BtProgressInfoFile> progressInfoFile_;
std::shared_ptr<DiskWriterFactory> diskWriterFactory_;
std::shared_ptr<Dependency> dependency_;
std::unique_ptr<URISelector> uriSelector_;
std::shared_ptr<MetadataInfo> metadataInfo_;
RequestGroupMan* requestGroupMan_;
#ifdef ENABLE_BITTORRENT
BtRuntime* btRuntime_;
PeerStorage* peerStorage_;
#endif // ENABLE_BITTORRENT
// If this download generates another downloads when completed(for
// example, downloads generated by PostDownloadHandler), this field
// has the GID of generated RequestGroups. empty list means there is
// no such RequestGroup.
std::vector<a2_gid_t> followedByGIDs_;
std::vector<const PreDownloadHandler*> preDownloadHandlers_;
std::vector<const PostDownloadHandler*> postDownloadHandlers_;
Time lastModifiedTime_;
// Timeout used for HTTP/FTP downloads.
time_t timeout_;
int state_;
int numConcurrentCommand_; int numConcurrentCommand_;
/** /**
@ -105,20 +151,20 @@ private:
int numCommand_; int numCommand_;
std::shared_ptr<SegmentMan> segmentMan_; int fileNotFoundCount_;
std::shared_ptr<DownloadContext> downloadContext_; int maxDownloadSpeedLimit_;
std::shared_ptr<PieceStorage> pieceStorage_; int maxUploadSpeedLimit_;
int resumeFailureCount_;
HaltReason haltReason_;
error_code::Value lastErrorCode_;
bool saveControlFile_; bool saveControlFile_;
std::shared_ptr<BtProgressInfoFile> progressInfoFile_;
std::shared_ptr<DiskWriterFactory> diskWriterFactory_;
std::shared_ptr<Dependency> dependency_;
bool fileAllocationEnabled_; bool fileAllocationEnabled_;
bool preLocalFileCheckEnabled_; bool preLocalFileCheckEnabled_;
@ -127,56 +173,12 @@ private:
bool forceHaltRequested_; bool forceHaltRequested_;
HaltReason haltReason_;
bool pauseRequested_; bool pauseRequested_;
std::vector<const PreDownloadHandler*> preDownloadHandlers_;
std::vector<const PostDownloadHandler*> postDownloadHandlers_;
std::unique_ptr<URISelector> uriSelector_;
Time lastModifiedTime_;
int fileNotFoundCount_;
// Timeout used for HTTP/FTP downloads.
time_t timeout_;
#ifdef ENABLE_BITTORRENT
BtRuntime* btRuntime_;
PeerStorage* peerStorage_;
#endif // ENABLE_BITTORRENT
// This flag just indicates that the downloaded file is not saved disk but // This flag just indicates that the downloaded file is not saved disk but
// just sits in memory. // just sits in memory.
bool inMemoryDownload_; bool inMemoryDownload_;
int maxDownloadSpeedLimit_;
int maxUploadSpeedLimit_;
error_code::Value lastErrorCode_;
// If this download generates another downloads when completed(for
// example, downloads generated by PostDownloadHandler), this field
// has the GID of generated RequestGroups. empty list means there is
// no such RequestGroup.
std::vector<a2_gid_t> followedByGIDs_;
// If this download is a part of another download(for example,
// downloading torrent file described in Metalink file), this field
// has the GID of parent RequestGroup. 0 means this is a parent
// RequestGroup.
a2_gid_t belongsToGID_;
std::shared_ptr<MetadataInfo> metadataInfo_;
RequestGroupMan* requestGroupMan_;
int resumeFailureCount_;
void validateFilename(const std::string& expectedFilename, void validateFilename(const std::string& expectedFilename,
const std::string& actualFilename) const; const std::string& actualFilename) const;

View File

@ -40,9 +40,14 @@ namespace aria2 {
TimeBasedCommand::TimeBasedCommand(cuid_t cuid, DownloadEngine* e, TimeBasedCommand::TimeBasedCommand(cuid_t cuid, DownloadEngine* e,
time_t interval, time_t interval,
bool routineCommand): bool routineCommand)
Command(cuid), e_(e),exit_(false), interval_(interval), : Command(cuid),
routineCommand_(routineCommand), checkPoint_(global::wallclock()) {} e_(e),
checkPoint_(global::wallclock()),
interval_(interval),
exit_(false),
routineCommand_(routineCommand)
{}
TimeBasedCommand::~TimeBasedCommand() {} TimeBasedCommand::~TimeBasedCommand() {}

View File

@ -47,6 +47,10 @@ class TimeBasedCommand : public Command
private: private:
DownloadEngine* e_; DownloadEngine* e_;
Timer checkPoint_;
time_t interval_; // unit: sec
/** /**
* setting exit_ to true if this command's job has finished and you want to * setting exit_ to true if this command's job has finished and you want to
* delete this command. * delete this command.
@ -56,11 +60,8 @@ private:
*/ */
bool exit_; bool exit_;
time_t interval_; // unit: sec
bool routineCommand_; bool routineCommand_;
Timer checkPoint_;
protected: protected:
DownloadEngine* getDownloadEngine() const DownloadEngine* getDownloadEngine() const
{ {

View File

@ -48,12 +48,12 @@ UriStruct::UriStruct()
UriStruct::UriStruct(const UriStruct& c) UriStruct::UriStruct(const UriStruct& c)
: protocol(c.protocol), : protocol(c.protocol),
host(c.host), host(c.host),
port(c.port),
dir(c.dir), dir(c.dir),
file(c.file), file(c.file),
query(c.query), query(c.query),
username(c.username), username(c.username),
password(c.password), password(c.password),
port(c.port),
hasPassword(c.hasPassword), hasPassword(c.hasPassword),
ipv6LiteralAddress(c.ipv6LiteralAddress) ipv6LiteralAddress(c.ipv6LiteralAddress)
{} {}
@ -65,12 +65,12 @@ UriStruct& UriStruct::operator=(const UriStruct& c)
if(this != &c) { if(this != &c) {
protocol = c.protocol; protocol = c.protocol;
host = c.host; host = c.host;
port = c.port;
dir = c.dir; dir = c.dir;
file = c.file; file = c.file;
query = c.query; query = c.query;
username = c.username; username = c.username;
password = c.password; password = c.password;
port = c.port;
hasPassword = c.hasPassword; hasPassword = c.hasPassword;
ipv6LiteralAddress = c.ipv6LiteralAddress; ipv6LiteralAddress = c.ipv6LiteralAddress;
} }
@ -83,12 +83,12 @@ void UriStruct::swap(UriStruct& other)
if(this != &other) { if(this != &other) {
swap(protocol, other.protocol); swap(protocol, other.protocol);
swap(host, other.host); swap(host, other.host);
swap(port, other.port);
swap(dir, other.dir); swap(dir, other.dir);
swap(file, other.file); swap(file, other.file);
swap(query, other.query); swap(query, other.query);
swap(username, other.username); swap(username, other.username);
swap(password, other.password); swap(password, other.password);
swap(port, other.port);
swap(hasPassword, other.hasPassword); swap(hasPassword, other.hasPassword);
swap(ipv6LiteralAddress, other.ipv6LiteralAddress); swap(ipv6LiteralAddress, other.ipv6LiteralAddress);
} }

View File

@ -48,12 +48,12 @@ namespace uri {
struct UriStruct { struct UriStruct {
std::string protocol; std::string protocol;
std::string host; std::string host;
uint16_t port;
std::string dir; std::string dir;
std::string file; std::string file;
std::string query; std::string query;
std::string username; std::string username;
std::string password; std::string password;
uint16_t port;
bool hasPassword; bool hasPassword;
bool ipv6LiteralAddress; bool ipv6LiteralAddress;