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>
|
||||
|
||||
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
|
||||
// to exit rather than doing seeding. So, it would be good to toggle this
|
||||
// behavior.
|
||||
// TODO If FileAllocationEntry is not going to be used, call
|
||||
// DiskAdaptor::disableDirectIO() manually here.
|
||||
return onDownloadIncomplete(e);
|
||||
}
|
||||
|
|
|
@ -36,14 +36,27 @@
|
|||
#include "Command.h"
|
||||
#include "RequestGroup.h"
|
||||
#include "IteratableValidator.h"
|
||||
#include "prefs.h"
|
||||
#include "PieceStorage.h"
|
||||
#include "DownloadContext.h"
|
||||
#include "DiskAdaptor.h"
|
||||
#include "Option.h"
|
||||
|
||||
CheckIntegrityEntry::CheckIntegrityEntry(RequestGroup* requestGroup,
|
||||
Command* nextCommand):
|
||||
RequestGroupEntry(requestGroup, nextCommand),
|
||||
_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()
|
||||
{
|
||||
|
|
|
@ -43,7 +43,8 @@
|
|||
#include "DiskAdaptor.h"
|
||||
#include "BitfieldMan.h"
|
||||
|
||||
#define BUFSIZE 16*1024
|
||||
#define BUFSIZE (256*1024)
|
||||
#define ALIGNMENT 512
|
||||
|
||||
IteratableChecksumValidator::IteratableChecksumValidator(const SingleFileDownloadContextHandle& dctx,
|
||||
const PieceStorageHandle& pieceStorage):
|
||||
|
@ -51,16 +52,21 @@ IteratableChecksumValidator::IteratableChecksumValidator(const SingleFileDownloa
|
|||
_pieceStorage(pieceStorage),
|
||||
_currentOffset(0),
|
||||
_ctx(0),
|
||||
_logger(LogFactory::getInstance()) {}
|
||||
_logger(LogFactory::getInstance()),
|
||||
_buffer(0) {}
|
||||
|
||||
IteratableChecksumValidator::~IteratableChecksumValidator() {}
|
||||
IteratableChecksumValidator::~IteratableChecksumValidator()
|
||||
{
|
||||
delete [] _buffer;
|
||||
}
|
||||
|
||||
void IteratableChecksumValidator::validateChunk()
|
||||
{
|
||||
if(!finished()) {
|
||||
unsigned char data[BUFSIZE];
|
||||
int32_t length = _pieceStorage->getDiskAdaptor()->readData(data, sizeof(data), _currentOffset);
|
||||
_ctx->digestUpdate(data, length);
|
||||
int32_t length = _pieceStorage->getDiskAdaptor()->readData(_buffer,
|
||||
BUFSIZE,
|
||||
_currentOffset);
|
||||
_ctx->digestUpdate(_buffer, length);
|
||||
_currentOffset += length;
|
||||
if(finished()) {
|
||||
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()
|
||||
{
|
||||
#ifdef HAVE_POSIX_MEMALIGN
|
||||
_buffer = (unsigned char*)Util::allocateAlignedMemory(ALIGNMENT, BUFSIZE);
|
||||
#else
|
||||
_buffer = new unsigned char[BUFSIZE];
|
||||
#endif // HAVE_POSIX_MEMALIGN
|
||||
_currentOffset = 0;
|
||||
_ctx = new MessageDigestContext();
|
||||
_ctx->trySetAlgo(_dctx->getChecksumHashAlgo());
|
||||
|
|
|
@ -58,6 +58,8 @@ private:
|
|||
|
||||
const Logger* _logger;
|
||||
|
||||
unsigned char* _buffer;
|
||||
|
||||
public:
|
||||
IteratableChecksumValidator(const SingleFileDownloadContextHandle& dctx,
|
||||
const PieceStorageHandle& pieceStorage);
|
||||
|
|
|
@ -43,6 +43,11 @@
|
|||
#include "BitfieldMan.h"
|
||||
#include "LogFactory.h"
|
||||
#include "Logger.h"
|
||||
#include "messageDigest.h"
|
||||
#include <cerrno>
|
||||
|
||||
#define BUFSIZE (256*1024)
|
||||
#define ALIGNMENT 512
|
||||
|
||||
IteratableChunkChecksumValidator::
|
||||
IteratableChunkChecksumValidator(const DownloadContextHandle& dctx,
|
||||
|
@ -51,9 +56,14 @@ IteratableChunkChecksumValidator(const DownloadContextHandle& dctx,
|
|||
_pieceStorage(pieceStorage),
|
||||
_bitfield(new BitfieldMan(_dctx->getPieceLength(), _dctx->getTotalLength())),
|
||||
_currentIndex(0),
|
||||
_logger(LogFactory::getInstance()) {}
|
||||
_logger(LogFactory::getInstance()),
|
||||
_ctx(0),
|
||||
_buffer(0) {}
|
||||
|
||||
IteratableChunkChecksumValidator::~IteratableChunkChecksumValidator() {}
|
||||
IteratableChunkChecksumValidator::~IteratableChunkChecksumValidator()
|
||||
{
|
||||
delete [] _buffer;
|
||||
}
|
||||
|
||||
|
||||
void IteratableChunkChecksumValidator::validateChunk()
|
||||
|
@ -96,17 +106,55 @@ string IteratableChunkChecksumValidator::calculateActualChecksum()
|
|||
} else {
|
||||
length = _dctx->getPieceLength();
|
||||
}
|
||||
return MessageDigestHelper::digest(_dctx->getPieceHashAlgo(),
|
||||
_pieceStorage->getDiskAdaptor(),
|
||||
offset, length);
|
||||
return digest(offset, length);
|
||||
}
|
||||
|
||||
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();
|
||||
_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
|
||||
{
|
||||
return _currentIndex >= (uint32_t)_dctx->getNumPieces();
|
||||
|
|
|
@ -43,6 +43,8 @@ class PieceStorage;
|
|||
typedef SharedHandle<PieceStorage> PieceStorageHandle;
|
||||
class BitfieldMan;
|
||||
class Logger;
|
||||
class MessageDigestContext;
|
||||
typedef SharedHandle<MessageDigestContext> MessageDigestContextHandle;
|
||||
|
||||
class IteratableChunkChecksumValidator:public IteratableValidator
|
||||
{
|
||||
|
@ -52,8 +54,13 @@ private:
|
|||
BitfieldMan* _bitfield;
|
||||
uint32_t _currentIndex;
|
||||
const Logger* _logger;
|
||||
MessageDigestContextHandle _ctx;
|
||||
unsigned char* _buffer;
|
||||
|
||||
string calculateActualChecksum();
|
||||
|
||||
string digest(int64_t offset, int32_t length);
|
||||
|
||||
public:
|
||||
IteratableChunkChecksumValidator(const DownloadContextHandle& dctx,
|
||||
const PieceStorageHandle& pieceStorage);
|
||||
|
|
|
@ -58,6 +58,7 @@ void PieceHashCheckIntegrityEntry::initValidator()
|
|||
IteratableChunkChecksumValidatorHandle validator =
|
||||
new IteratableChunkChecksumValidator(_requestGroup->getDownloadContext(),
|
||||
_requestGroup->getPieceStorage());
|
||||
validator->init();
|
||||
_validator = validator;
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
}
|
||||
|
|
|
@ -40,7 +40,8 @@ void IteratableChunkChecksumValidatorTest::testValidate() {
|
|||
ps->getDiskAdaptor()->openFile();
|
||||
|
||||
IteratableChunkChecksumValidator validator(dctx, ps);
|
||||
|
||||
validator.init();
|
||||
|
||||
validator.validateChunk();
|
||||
CPPUNIT_ASSERT(!validator.finished());
|
||||
validator.validateChunk();
|
||||
|
|
Loading…
Reference in New Issue