mirror of https://github.com/aria2/aria2
2007-12-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Enable direct I/O support in checksum checking. * src/IteratableChunkChecksumValidator.{h, cc} * test/IteratableChunkChecksumValidatorTest.cc * src/CheckIntegrityEntry.cc * src/PieceHashCheckIntegrityEntry.cc * src/IteratableChecksumValidator.{h, cc} * src/BtCheckIntegrityEntry.cc: Added doc.pull/1/head
parent
24bdbf9aa6
commit
b75dbc4bbe
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2007-12-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
Enable direct I/O support in checksum checking.
|
||||||
|
* src/IteratableChunkChecksumValidator.{h, cc}
|
||||||
|
* test/IteratableChunkChecksumValidatorTest.cc
|
||||||
|
* src/CheckIntegrityEntry.cc
|
||||||
|
* src/PieceHashCheckIntegrityEntry.cc
|
||||||
|
* src/IteratableChecksumValidator.{h, cc}
|
||||||
|
* src/BtCheckIntegrityEntry.cc: Added doc.
|
||||||
|
|
||||||
2007-12-04 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2007-12-04 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
Added --allow-piece-length-change option.
|
Added --allow-piece-length-change option.
|
||||||
|
|
|
@ -66,5 +66,7 @@ Commands BtCheckIntegrityEntry::onDownloadFinished(DownloadEngine* e)
|
||||||
// are valid, then aira2 goes to seeding mode. Sometimes it is better
|
// are valid, then aira2 goes to seeding mode. Sometimes it is better
|
||||||
// to exit rather than doing seeding. So, it would be good to toggle this
|
// to exit rather than doing seeding. So, it would be good to toggle this
|
||||||
// behavior.
|
// behavior.
|
||||||
|
// TODO If FileAllocationEntry is not going to be used, call
|
||||||
|
// DiskAdaptor::disableDirectIO() manually here.
|
||||||
return onDownloadIncomplete(e);
|
return onDownloadIncomplete(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,14 +36,27 @@
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include "RequestGroup.h"
|
#include "RequestGroup.h"
|
||||||
#include "IteratableValidator.h"
|
#include "IteratableValidator.h"
|
||||||
|
#include "prefs.h"
|
||||||
|
#include "PieceStorage.h"
|
||||||
|
#include "DownloadContext.h"
|
||||||
|
#include "DiskAdaptor.h"
|
||||||
|
#include "Option.h"
|
||||||
|
|
||||||
CheckIntegrityEntry::CheckIntegrityEntry(RequestGroup* requestGroup,
|
CheckIntegrityEntry::CheckIntegrityEntry(RequestGroup* requestGroup,
|
||||||
Command* nextCommand):
|
Command* nextCommand):
|
||||||
RequestGroupEntry(requestGroup, nextCommand),
|
RequestGroupEntry(requestGroup, nextCommand),
|
||||||
_validator(0)
|
_validator(0)
|
||||||
{}
|
{
|
||||||
|
if(_requestGroup->getOption()->getAsBool(PREF_ENABLE_DIRECT_IO) &&
|
||||||
|
_requestGroup->getDownloadContext()->getFileEntries().size() == 1) {
|
||||||
|
_requestGroup->getPieceStorage()->getDiskAdaptor()->enableDirectIO();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CheckIntegrityEntry::~CheckIntegrityEntry() {}
|
CheckIntegrityEntry::~CheckIntegrityEntry()
|
||||||
|
{
|
||||||
|
// TODO DiskAdaptor::disableIO() will be called from ~FileAllocationEntry
|
||||||
|
}
|
||||||
|
|
||||||
void CheckIntegrityEntry::validateChunk()
|
void CheckIntegrityEntry::validateChunk()
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,7 +43,8 @@
|
||||||
#include "DiskAdaptor.h"
|
#include "DiskAdaptor.h"
|
||||||
#include "BitfieldMan.h"
|
#include "BitfieldMan.h"
|
||||||
|
|
||||||
#define BUFSIZE 16*1024
|
#define BUFSIZE (256*1024)
|
||||||
|
#define ALIGNMENT 512
|
||||||
|
|
||||||
IteratableChecksumValidator::IteratableChecksumValidator(const SingleFileDownloadContextHandle& dctx,
|
IteratableChecksumValidator::IteratableChecksumValidator(const SingleFileDownloadContextHandle& dctx,
|
||||||
const PieceStorageHandle& pieceStorage):
|
const PieceStorageHandle& pieceStorage):
|
||||||
|
@ -51,16 +52,21 @@ IteratableChecksumValidator::IteratableChecksumValidator(const SingleFileDownloa
|
||||||
_pieceStorage(pieceStorage),
|
_pieceStorage(pieceStorage),
|
||||||
_currentOffset(0),
|
_currentOffset(0),
|
||||||
_ctx(0),
|
_ctx(0),
|
||||||
_logger(LogFactory::getInstance()) {}
|
_logger(LogFactory::getInstance()),
|
||||||
|
_buffer(0) {}
|
||||||
|
|
||||||
IteratableChecksumValidator::~IteratableChecksumValidator() {}
|
IteratableChecksumValidator::~IteratableChecksumValidator()
|
||||||
|
{
|
||||||
|
delete [] _buffer;
|
||||||
|
}
|
||||||
|
|
||||||
void IteratableChecksumValidator::validateChunk()
|
void IteratableChecksumValidator::validateChunk()
|
||||||
{
|
{
|
||||||
if(!finished()) {
|
if(!finished()) {
|
||||||
unsigned char data[BUFSIZE];
|
int32_t length = _pieceStorage->getDiskAdaptor()->readData(_buffer,
|
||||||
int32_t length = _pieceStorage->getDiskAdaptor()->readData(data, sizeof(data), _currentOffset);
|
BUFSIZE,
|
||||||
_ctx->digestUpdate(data, length);
|
_currentOffset);
|
||||||
|
_ctx->digestUpdate(_buffer, length);
|
||||||
_currentOffset += length;
|
_currentOffset += length;
|
||||||
if(finished()) {
|
if(finished()) {
|
||||||
string actualChecksum = Util::toHex((const unsigned char*)_ctx->digestFinal().c_str(), _ctx->digestLength());
|
string actualChecksum = Util::toHex((const unsigned char*)_ctx->digestFinal().c_str(), _ctx->digestLength());
|
||||||
|
@ -86,6 +92,11 @@ int64_t IteratableChecksumValidator::getTotalLength() const
|
||||||
|
|
||||||
void IteratableChecksumValidator::init()
|
void IteratableChecksumValidator::init()
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_POSIX_MEMALIGN
|
||||||
|
_buffer = (unsigned char*)Util::allocateAlignedMemory(ALIGNMENT, BUFSIZE);
|
||||||
|
#else
|
||||||
|
_buffer = new unsigned char[BUFSIZE];
|
||||||
|
#endif // HAVE_POSIX_MEMALIGN
|
||||||
_currentOffset = 0;
|
_currentOffset = 0;
|
||||||
_ctx = new MessageDigestContext();
|
_ctx = new MessageDigestContext();
|
||||||
_ctx->trySetAlgo(_dctx->getChecksumHashAlgo());
|
_ctx->trySetAlgo(_dctx->getChecksumHashAlgo());
|
||||||
|
|
|
@ -58,6 +58,8 @@ private:
|
||||||
|
|
||||||
const Logger* _logger;
|
const Logger* _logger;
|
||||||
|
|
||||||
|
unsigned char* _buffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IteratableChecksumValidator(const SingleFileDownloadContextHandle& dctx,
|
IteratableChecksumValidator(const SingleFileDownloadContextHandle& dctx,
|
||||||
const PieceStorageHandle& pieceStorage);
|
const PieceStorageHandle& pieceStorage);
|
||||||
|
|
|
@ -43,6 +43,11 @@
|
||||||
#include "BitfieldMan.h"
|
#include "BitfieldMan.h"
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "messageDigest.h"
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
|
#define BUFSIZE (256*1024)
|
||||||
|
#define ALIGNMENT 512
|
||||||
|
|
||||||
IteratableChunkChecksumValidator::
|
IteratableChunkChecksumValidator::
|
||||||
IteratableChunkChecksumValidator(const DownloadContextHandle& dctx,
|
IteratableChunkChecksumValidator(const DownloadContextHandle& dctx,
|
||||||
|
@ -51,9 +56,14 @@ IteratableChunkChecksumValidator(const DownloadContextHandle& dctx,
|
||||||
_pieceStorage(pieceStorage),
|
_pieceStorage(pieceStorage),
|
||||||
_bitfield(new BitfieldMan(_dctx->getPieceLength(), _dctx->getTotalLength())),
|
_bitfield(new BitfieldMan(_dctx->getPieceLength(), _dctx->getTotalLength())),
|
||||||
_currentIndex(0),
|
_currentIndex(0),
|
||||||
_logger(LogFactory::getInstance()) {}
|
_logger(LogFactory::getInstance()),
|
||||||
|
_ctx(0),
|
||||||
|
_buffer(0) {}
|
||||||
|
|
||||||
IteratableChunkChecksumValidator::~IteratableChunkChecksumValidator() {}
|
IteratableChunkChecksumValidator::~IteratableChunkChecksumValidator()
|
||||||
|
{
|
||||||
|
delete [] _buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void IteratableChunkChecksumValidator::validateChunk()
|
void IteratableChunkChecksumValidator::validateChunk()
|
||||||
|
@ -96,17 +106,55 @@ string IteratableChunkChecksumValidator::calculateActualChecksum()
|
||||||
} else {
|
} else {
|
||||||
length = _dctx->getPieceLength();
|
length = _dctx->getPieceLength();
|
||||||
}
|
}
|
||||||
return MessageDigestHelper::digest(_dctx->getPieceHashAlgo(),
|
return digest(offset, length);
|
||||||
_pieceStorage->getDiskAdaptor(),
|
|
||||||
offset, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IteratableChunkChecksumValidator::init()
|
void IteratableChunkChecksumValidator::init()
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_POSIX_MEMALIGN
|
||||||
|
_buffer = (unsigned char*)Util::allocateAlignedMemory(ALIGNMENT, BUFSIZE);
|
||||||
|
#else
|
||||||
|
_buffer = new unsigned char[BUFSIZE];
|
||||||
|
#endif // HAVE_POSIX_MEMALIGN
|
||||||
|
_ctx = new MessageDigestContext();
|
||||||
|
_ctx->trySetAlgo(_dctx->getPieceHashAlgo());
|
||||||
|
_ctx->digestInit();
|
||||||
_bitfield->clearAllBit();
|
_bitfield->clearAllBit();
|
||||||
_currentIndex = 0;
|
_currentIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string IteratableChunkChecksumValidator::digest(int64_t offset, int32_t length)
|
||||||
|
{
|
||||||
|
_ctx->digestReset();
|
||||||
|
int64_t curoffset = offset/ALIGNMENT*ALIGNMENT;
|
||||||
|
int64_t max = offset+length;
|
||||||
|
int32_t woffset;
|
||||||
|
if(curoffset < offset) {
|
||||||
|
woffset = offset-curoffset;
|
||||||
|
} else {
|
||||||
|
woffset = 0;
|
||||||
|
}
|
||||||
|
while(curoffset < max) {
|
||||||
|
int32_t r = _pieceStorage->getDiskAdaptor()->readData(_buffer, BUFSIZE,
|
||||||
|
curoffset);
|
||||||
|
if(r == 0) {
|
||||||
|
throw new DlAbortEx(EX_FILE_READ, _dctx->getActualBasePath().c_str(),
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
int32_t wlength;
|
||||||
|
if(max < curoffset+r) {
|
||||||
|
wlength = max-curoffset-woffset;
|
||||||
|
} else {
|
||||||
|
wlength = r-woffset;
|
||||||
|
}
|
||||||
|
_ctx->digestUpdate(_buffer+woffset, wlength);
|
||||||
|
curoffset += r;
|
||||||
|
woffset = 0;
|
||||||
|
}
|
||||||
|
return Util::toHex((const unsigned char*)_ctx->digestFinal().c_str(), _ctx->digestLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IteratableChunkChecksumValidator::finished() const
|
bool IteratableChunkChecksumValidator::finished() const
|
||||||
{
|
{
|
||||||
return _currentIndex >= (uint32_t)_dctx->getNumPieces();
|
return _currentIndex >= (uint32_t)_dctx->getNumPieces();
|
||||||
|
|
|
@ -43,6 +43,8 @@ class PieceStorage;
|
||||||
typedef SharedHandle<PieceStorage> PieceStorageHandle;
|
typedef SharedHandle<PieceStorage> PieceStorageHandle;
|
||||||
class BitfieldMan;
|
class BitfieldMan;
|
||||||
class Logger;
|
class Logger;
|
||||||
|
class MessageDigestContext;
|
||||||
|
typedef SharedHandle<MessageDigestContext> MessageDigestContextHandle;
|
||||||
|
|
||||||
class IteratableChunkChecksumValidator:public IteratableValidator
|
class IteratableChunkChecksumValidator:public IteratableValidator
|
||||||
{
|
{
|
||||||
|
@ -52,8 +54,13 @@ private:
|
||||||
BitfieldMan* _bitfield;
|
BitfieldMan* _bitfield;
|
||||||
uint32_t _currentIndex;
|
uint32_t _currentIndex;
|
||||||
const Logger* _logger;
|
const Logger* _logger;
|
||||||
|
MessageDigestContextHandle _ctx;
|
||||||
|
unsigned char* _buffer;
|
||||||
|
|
||||||
string calculateActualChecksum();
|
string calculateActualChecksum();
|
||||||
|
|
||||||
|
string digest(int64_t offset, int32_t length);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IteratableChunkChecksumValidator(const DownloadContextHandle& dctx,
|
IteratableChunkChecksumValidator(const DownloadContextHandle& dctx,
|
||||||
const PieceStorageHandle& pieceStorage);
|
const PieceStorageHandle& pieceStorage);
|
||||||
|
|
|
@ -58,6 +58,7 @@ void PieceHashCheckIntegrityEntry::initValidator()
|
||||||
IteratableChunkChecksumValidatorHandle validator =
|
IteratableChunkChecksumValidatorHandle validator =
|
||||||
new IteratableChunkChecksumValidator(_requestGroup->getDownloadContext(),
|
new IteratableChunkChecksumValidator(_requestGroup->getDownloadContext(),
|
||||||
_requestGroup->getPieceStorage());
|
_requestGroup->getPieceStorage());
|
||||||
|
validator->init();
|
||||||
_validator = validator;
|
_validator = validator;
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
#endif // ENABLE_MESSAGE_DIGEST
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,8 @@ void IteratableChunkChecksumValidatorTest::testValidate() {
|
||||||
ps->getDiskAdaptor()->openFile();
|
ps->getDiskAdaptor()->openFile();
|
||||||
|
|
||||||
IteratableChunkChecksumValidator validator(dctx, ps);
|
IteratableChunkChecksumValidator validator(dctx, ps);
|
||||||
|
validator.init();
|
||||||
|
|
||||||
validator.validateChunk();
|
validator.validateChunk();
|
||||||
CPPUNIT_ASSERT(!validator.finished());
|
CPPUNIT_ASSERT(!validator.finished());
|
||||||
validator.validateChunk();
|
validator.validateChunk();
|
||||||
|
|
Loading…
Reference in New Issue