mirror of https://github.com/aria2/aria2
Fix file length information in RPC response when length > 2GB is unknown
This commit fixes the bug that aria2.tellStopped RPC method returns total length and completedLength as 0 when file size is unknown in advance and turns out > 2GB in the end. This commit and addresses the performance degradation in this case.pull/253/head
parent
620be59b1e
commit
3aaa5a7344
20
src/Piece.cc
20
src/Piece.cc
|
@ -60,7 +60,7 @@ Piece::Piece()
|
|||
usedBySegment_(false)
|
||||
{}
|
||||
|
||||
Piece::Piece(size_t index, int32_t length, int32_t blockLength)
|
||||
Piece::Piece(size_t index, int64_t length, int32_t blockLength)
|
||||
: bitfield_(new BitfieldMan(blockLength, length)),
|
||||
wrCache_(nullptr),
|
||||
index_(index),
|
||||
|
@ -181,15 +181,21 @@ bool Piece::getAllMissingBlockIndexes
|
|||
}
|
||||
|
||||
std::string Piece::toString() const {
|
||||
return fmt("piece: index=%lu, length=%d",
|
||||
return fmt("piece: index=%lu, length=%" PRId64,
|
||||
static_cast<unsigned long>(index_), length_);
|
||||
}
|
||||
|
||||
void Piece::reconfigure(int32_t length)
|
||||
void Piece::reconfigure(int64_t length)
|
||||
{
|
||||
delete bitfield_;
|
||||
length_ = length;
|
||||
bitfield_ = new BitfieldMan(blockLength_, length_);
|
||||
// TODO currently, this function is only called from
|
||||
// GrowSegment::updateWrittenLength(). If we use default block
|
||||
// length (16K), and length_ gets large (e.g., 4GB), creating
|
||||
// BitfieldMan for each call is very expensive. Therefore, we use
|
||||
// maximum block length for now to reduce the overhead. Ideally, we
|
||||
// check the code thoroughly and remove bitfield_ if we can.
|
||||
bitfield_ = new BitfieldMan(std::numeric_limits<int32_t>::max(), length_);
|
||||
}
|
||||
|
||||
void Piece::setBitfield(const unsigned char* bitfield, size_t len)
|
||||
|
@ -197,7 +203,7 @@ void Piece::setBitfield(const unsigned char* bitfield, size_t len)
|
|||
bitfield_->setBitfield(bitfield, len);
|
||||
}
|
||||
|
||||
int32_t Piece::getCompletedLength()
|
||||
int64_t Piece::getCompletedLength()
|
||||
{
|
||||
return bitfield_->getCompletedLength();
|
||||
}
|
||||
|
@ -208,13 +214,13 @@ void Piece::setHashType(const std::string& hashType)
|
|||
}
|
||||
|
||||
bool Piece::updateHash
|
||||
(int32_t begin, const unsigned char* data, size_t dataLength)
|
||||
(int64_t begin, const unsigned char* data, size_t dataLength)
|
||||
{
|
||||
if(hashType_.empty()) {
|
||||
return false;
|
||||
}
|
||||
if(begin == nextBegin_ &&
|
||||
nextBegin_+dataLength <= static_cast<size_t>(length_)) {
|
||||
nextBegin_ + static_cast<int64_t>(dataLength) <= length_) {
|
||||
if(!mdctx_) {
|
||||
mdctx_ = MessageDigest::create(hashType_);
|
||||
}
|
||||
|
|
16
src/Piece.h
16
src/Piece.h
|
@ -62,9 +62,9 @@ private:
|
|||
|
||||
size_t index_;
|
||||
|
||||
int32_t length_;
|
||||
int64_t length_;
|
||||
int32_t blockLength_;
|
||||
int32_t nextBegin_;
|
||||
int64_t nextBegin_;
|
||||
|
||||
bool usedBySegment_;
|
||||
|
||||
|
@ -75,7 +75,7 @@ public:
|
|||
static const int32_t BLOCK_LENGTH = 16*1024;
|
||||
|
||||
Piece();
|
||||
Piece(size_t index, int32_t length, int32_t blockLength = BLOCK_LENGTH);
|
||||
Piece(size_t index, int64_t length, int32_t blockLength = BLOCK_LENGTH);
|
||||
|
||||
~Piece();
|
||||
|
||||
|
@ -127,9 +127,9 @@ public:
|
|||
|
||||
void setIndex(size_t index) { index_ = index; }
|
||||
|
||||
int32_t getLength() const { return length_; }
|
||||
int64_t getLength() const { return length_; }
|
||||
|
||||
void setLength(int32_t length) { length_ = length; }
|
||||
void setLength(int64_t length) { length_ = length; }
|
||||
|
||||
const unsigned char* getBitfield() const;
|
||||
|
||||
|
@ -145,14 +145,14 @@ public:
|
|||
bool isBlockUsed(size_t index) const;
|
||||
|
||||
// Calculates completed length
|
||||
int32_t getCompletedLength();
|
||||
int64_t getCompletedLength();
|
||||
|
||||
void setHashType(const std::string& hashType);
|
||||
|
||||
// Updates hash value. This function compares begin and private variable
|
||||
// nextBegin_ and only when they are equal, hash is updated eating data and
|
||||
// returns true. Otherwise returns false.
|
||||
bool updateHash(int32_t begin, const unsigned char* data, size_t dataLength);
|
||||
bool updateHash(int64_t begin, const unsigned char* data, size_t dataLength);
|
||||
|
||||
bool isHashCalculated() const;
|
||||
|
||||
|
@ -171,7 +171,7 @@ public:
|
|||
/**
|
||||
* Loses current bitfield state.
|
||||
*/
|
||||
void reconfigure(int32_t length);
|
||||
void reconfigure(int64_t length);
|
||||
|
||||
void addUser(cuid_t cuid);
|
||||
void removeUser(cuid_t cuid);
|
||||
|
|
|
@ -361,7 +361,7 @@ void DefaultBtProgressInfoFileTest::testLoad_nonBt_compat()
|
|||
|
||||
std::shared_ptr<Piece> piece1 = inFlightPieces[0];
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)1, piece1->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(1024, piece1->getLength());
|
||||
CPPUNIT_ASSERT_EQUAL((int64_t)1024, piece1->getLength());
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)1, piece1->getBitfieldLength());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("00"), util::toHex(piece1->getBitfield(),
|
||||
piece1->getBitfieldLength()));
|
||||
|
@ -369,7 +369,7 @@ void DefaultBtProgressInfoFileTest::testLoad_nonBt_compat()
|
|||
// piece index 2
|
||||
std::shared_ptr<Piece> piece2 = inFlightPieces[1];
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, piece2->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(512, piece2->getLength());
|
||||
CPPUNIT_ASSERT_EQUAL((int64_t)512, piece2->getLength());
|
||||
}
|
||||
#endif // !WORDS_BIGENDIAN
|
||||
|
||||
|
@ -406,7 +406,7 @@ void DefaultBtProgressInfoFileTest::testLoad_nonBt()
|
|||
|
||||
std::shared_ptr<Piece> piece1 = inFlightPieces[0];
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)1, piece1->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(1024, piece1->getLength());
|
||||
CPPUNIT_ASSERT_EQUAL((int64_t)1024, piece1->getLength());
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)1, piece1->getBitfieldLength());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("00"), util::toHex(piece1->getBitfield(),
|
||||
piece1->getBitfieldLength()));
|
||||
|
@ -414,7 +414,7 @@ void DefaultBtProgressInfoFileTest::testLoad_nonBt()
|
|||
// piece index 2
|
||||
std::shared_ptr<Piece> piece2 = inFlightPieces[1];
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, piece2->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(512, piece2->getLength());
|
||||
CPPUNIT_ASSERT_EQUAL((int64_t)512, piece2->getLength());
|
||||
}
|
||||
|
||||
void DefaultBtProgressInfoFileTest::testLoad_nonBt_pieceLengthShorter()
|
||||
|
|
|
@ -67,7 +67,7 @@ void PieceTest::testGetCompletedLength()
|
|||
p.completeBlock(9);
|
||||
p.completeBlock(10); // <-- 100 bytes
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(blockLength*3+100, p.getCompletedLength());
|
||||
CPPUNIT_ASSERT_EQUAL((int64_t)(blockLength*3+100), p.getCompletedLength());
|
||||
}
|
||||
|
||||
void PieceTest::testFlushWrCache()
|
||||
|
|
Loading…
Reference in New Issue