Improved implementation efficiency of checksum calculation.

Based on Oliviers suggestions the file read routine now reuses
one buffer to read the entire file.

Other cleanups.
This commit is contained in:
Klaas Freitag 2015-05-20 21:42:08 +02:00
parent 34593cccb6
commit 64ce0cd7a2
3 changed files with 35 additions and 42 deletions

View file

@ -11,7 +11,6 @@
* for more details.
*/
#include "config.h"
#include "filesystem.h"
#include "utility.h"
@ -20,8 +19,6 @@
#include <QCoreApplication>
#include <QDebug>
#include <QCryptographicHash>
#include <QFuture>
#include <qtconcurrentrun.h>
#ifdef ZLIB_FOUND
#include <zlib.h>
@ -402,57 +399,57 @@ QString FileSystem::fileSystemForPath(const QString & path)
}
#endif
QByteArray FileSystem::calcMd5( const QString& filename )
{
QByteArray arr;
#define BUFSIZE 1024*1024*10
QCryptographicHash crypto( QCryptographicHash::Md5 );
static QByteArray readToCrypto( const QString& filename, QCryptographicHash::Algorithm algo )
{
const qint64 bufSize = BUFSIZE;
QByteArray buf(bufSize,0);
QByteArray arr;
QCryptographicHash crypto( algo );
QFile file(filename);
if (file.open(QIODevice::ReadOnly)) {
QByteArray data;
qint64 size;
while (!file.atEnd()) {
data = file.read(1024*1024*10);
crypto.addData(data);
size = file.read( buf.data(), bufSize );
if( size > 0 ) {
crypto.addData(buf.data(), size);
}
}
arr = crypto.result().toHex();
}
return arr;
}
QByteArray FileSystem::calcMd5( const QString& filename )
{
return readToCrypto( filename, QCryptographicHash::Md5 );
}
QByteArray FileSystem::calcSha1( const QString& filename )
{
QByteArray arr;
QCryptographicHash crypto( QCryptographicHash::Sha1 );
QFile file(filename);
if (file.open(QIODevice::ReadOnly)) {
QByteArray data;
while (!file.atEnd()) {
data = file.read(1024*1024*10);
crypto.addData(data);
}
arr = crypto.result().toHex();
}
return arr;
return readToCrypto( filename, QCryptographicHash::Sha1 );
}
#ifdef ZLIB_FOUND
QByteArray FileSystem::calcAdler32( const QString& filename )
{
unsigned int adler = adler32(0L, Z_NULL, 0);
const qint64 bufSize = BUFSIZE;
QByteArray buf(bufSize, 0);
QFile file(filename);
if (file.open(QIODevice::ReadOnly)) {
QByteArray data;
qint64 size;
while (!file.atEnd()) {
data = file.read(1024*1024*10);
adler = adler32(adler, (const Bytef*) data.data(), data.size());
size = file.read(buf.data(), bufSize);
if( size > 0 )
adler = adler32(adler, (const Bytef*) buf.data(), size);
}
}
return QString::number( adler, 16 ).toUtf8();
return QByteArray::number( adler, 16 );
}
#endif

View file

@ -13,8 +13,11 @@
#pragma once
#include "config.h"
#include <QString>
#include <ctime>
#include <QCryptographicHash>
#include <owncloudlib.h>
@ -123,12 +126,8 @@ QString fileSystemForPath(const QString & path);
QByteArray calcMd5( const QString& fileName );
QByteArray calcSha1( const QString& fileName );
QByteArray calcAdler32( const QString& fileName );
#ifdef ZLIB_FOUND
QByteArray calcAdler32Worker( const QString& filename );
QByteArray calcAdler32( const QString& fileName );
#endif
QByteArray calcSha1Worker( const QString& filename );
QByteArray calcMd5Worker( const QString& filename );
}}

View file

@ -72,24 +72,24 @@ using namespace OCC;
void testUploadChecksummingAdler() {
TransmissionChecksumValidator *vali = new TransmissionChecksumValidator(_testfile);
TransmissionChecksumValidator *vali = new TransmissionChecksumValidator(_testfile, this);
vali->setChecksumType("Adler32");
connect(vali, SIGNAL(validated()), this, SLOT(slotUpValidated()));
_expected = "Adler32:"+FileSystem::calcAdler32( _testfile );
QString testfile = _testfile;
_expected = "Adler32:"+FileSystem::calcAdler32( testfile );
qDebug() << "XX Expected Checksum: " << _expected;
vali->uploadValidation(_item);
usleep(5000);
_loop.processEvents();
vali->deleteLater();
}
void testUploadChecksummingMd5() {
TransmissionChecksumValidator *vali = new TransmissionChecksumValidator(_testfile);
TransmissionChecksumValidator *vali = new TransmissionChecksumValidator(_testfile, this);
vali->setChecksumType( OCC::checkSumMD5C );
connect(vali, SIGNAL(validated()), this, SLOT(slotUpValidated()));
@ -100,12 +100,11 @@ using namespace OCC;
usleep(2000);
_loop.processEvents();
vali->deleteLater();
}
void testUploadChecksummingSha1() {
TransmissionChecksumValidator *vali = new TransmissionChecksumValidator(_testfile);
TransmissionChecksumValidator *vali = new TransmissionChecksumValidator(_testfile, this);
vali->setChecksumType( OCC::checkSumSHA1C );
connect(vali, SIGNAL(validated()), this, SLOT(slotUpValidated()));
@ -117,7 +116,6 @@ using namespace OCC;
usleep(2000);
_loop.processEvents();
vali->deleteLater();
}
void testDownloadChecksummingAdler() {
@ -127,7 +125,7 @@ using namespace OCC;
adler.append(FileSystem::calcAdler32( _testfile ));
_successDown = false;
TransmissionChecksumValidator *vali = new TransmissionChecksumValidator(_testfile);
TransmissionChecksumValidator *vali = new TransmissionChecksumValidator(_testfile, this);
connect(vali, SIGNAL(validated()), this, SLOT(slotDownValidated()));
connect(vali, SIGNAL(validationFailed(QString)), this, SLOT(slotDownError(QString)));
vali->downloadValidation(adler);
@ -151,7 +149,6 @@ using namespace OCC;
_loop.processEvents();
QVERIFY(_errorSeen);
vali->deleteLater();
}