diff options
-rw-r--r-- | src/corelib/io/qfile.cpp | 3 | ||||
-rw-r--r-- | tests/auto/qfile/tst_qfile.cpp | 55 | ||||
-rw-r--r-- | tests/benchmarks/corelib/io/qfile/main.cpp | 104 |
3 files changed, 162 insertions, 0 deletions
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index cfe0700..c8b349a 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -1692,6 +1692,9 @@ bool QFile::seek(qint64 off) return false; } + if (off == d->pos && off == d->devicePos) + return true; //avoid expensive flush for NOP seek to current position + if (!d->ensureFlushed()) return false; diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 7c5ae6f..832a7ef 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -128,6 +128,7 @@ private slots: void seek(); void setSize(); void setSizeSeek(); + void seekToSamePosition(); void atEnd(); void readLine(); void readLine2(); @@ -458,6 +459,7 @@ void tst_QFile::cleanupTestCase() QFile::remove("readAllBuffer.txt"); QFile::remove("qt_file.tmp"); QFile::remove("File.txt"); + QFile::remove("seekToSamePosition.txt"); } //------------------------------------------ @@ -756,6 +758,59 @@ void tst_QFile::setSizeSeek() QCOMPARE(f.pos(), qint64(2)); } +void tst_QFile::seekToSamePosition() +{ + QFile in("testfile.txt"); + QFile out("seekToSamePosition.txt"); + QVERIFY(in.open(QFile::ReadOnly)); + QVERIFY(out.open(QFile::WriteOnly)); + QByteArray plusses; + plusses.fill('+', 58); + + qint64 cursor = 0; + QVERIFY(in.seek(cursor)); + QVERIFY(out.seek(cursor)); + + QVERIFY(out.write(plusses)); + + cursor += 58; + QVERIFY(in.seek(cursor)); + QVERIFY(out.seek(cursor)); + + QByteArray copy = in.read(60); + QVERIFY(out.write(copy)); + + cursor += 60; + QVERIFY(in.seek(cursor)); + QVERIFY(out.seek(cursor)); + + QVERIFY(out.write(plusses)); + + cursor += 58; + QVERIFY(in.seek(cursor)); + QVERIFY(out.seek(cursor)); + + copy = in.readAll(); + QVERIFY(out.write(copy)); + + //compare + out.close(); + QVERIFY(out.open(QFile::ReadOnly)); + QVERIFY(in.seek(0)); + + QByteArray clean = in.readAll(); + QByteArray dirty = out.readAll(); + out.close(); + + QVERIFY(clean.size() == dirty.size()); + for (int i=0;i<clean.size();i++) { + if (clean[i] == '-') + QVERIFY2(dirty[i] == '+', qPrintable(QString("no + at pos %1").arg(i))); + else + QVERIFY2(dirty[i] == clean[i], qPrintable(QString("char at pos %1 mismatched, %2 vs %3").arg(i).arg(clean[i]).arg(dirty[i]))); + } +} + void tst_QFile::atEnd() { QFile f( SRCDIR "testfile.txt" ); diff --git a/tests/benchmarks/corelib/io/qfile/main.cpp b/tests/benchmarks/corelib/io/qfile/main.cpp index a37b11a..00d6d79 100644 --- a/tests/benchmarks/corelib/io/qfile/main.cpp +++ b/tests/benchmarks/corelib/io/qfile/main.cpp @@ -113,6 +113,13 @@ private slots: void readBigFile_posix(); void readBigFile_Win32(); + void writeFileSequential_data(); + void writeFileSequential(); + void writeFileBackwards_data(); + void writeFileBackwards(); + void writeFileSequentialWithSeeks_data(); + void writeFileSequentialWithSeeks(); + private: void readBigFile_data(BenchmarkType type, QIODevice::OpenModeFlag t, QIODevice::OpenModeFlag b); void readBigFile(); @@ -678,6 +685,103 @@ void tst_qfile::readSmallFiles() delete[] buffer; } +void tst_qfile::writeFileSequential_data() +{ + QTest::addColumn<int>("blockSize"); + QTest::addColumn<QString>("path"); + + QTest::newRow("internal 16b") << 16 << QDir::tempPath(); + QTest::newRow("internal 512b") << 512 << QDir::tempPath(); + QTest::newRow("internal 4k") << 4096 << QDir::tempPath(); + QTest::newRow("internal 16k") << 16384 << QDir::tempPath(); + QTest::newRow("internal 64k") << 65536 << QDir::tempPath(); + + //slow media (e.g. SD card) + QString externalPath; +#ifdef Q_OS_SYMBIAN + externalPath = "E:/"; +#endif + if (!externalPath.isEmpty()) { + QTest::newRow("external 16b") << 16 << externalPath; + QTest::newRow("external 512b") << 512 << externalPath; + QTest::newRow("external 4k") << 4096 << externalPath; + QTest::newRow("external 16k") << 16384 << externalPath; + QTest::newRow("external 64k") << 65536 << externalPath; + } +} + +void tst_qfile::writeFileSequential() +{ + const qint64 limit = 1024 * 1024; + QFETCH(int, blockSize); + QFETCH(QString, path); + QTemporaryFile f; + f.setFileTemplate(path); + QByteArray block; + block.fill('@', blockSize); + QBENCHMARK { + QVERIFY(f.open()); + for (qint64 pos = 0; pos < limit; pos += blockSize) { + QVERIFY(f.write(block)); + } + QVERIFY(f.flush()); + QCOMPARE(f.size(), limit); + f.close(); + } +} + +void tst_qfile::writeFileBackwards_data() +{ + writeFileSequential_data(); +} + +void tst_qfile::writeFileBackwards() +{ + const qint64 limit = 1024 * 1024; + QFETCH(int, blockSize); + QFETCH(QString, path); + QTemporaryFile f; + f.setFileTemplate(path); + QByteArray block; + block.fill('@', blockSize); + QBENCHMARK { + QVERIFY(f.open()); + for (qint64 pos = limit - blockSize; pos >= 0; pos -= blockSize) { + QVERIFY(f.seek(pos)); + QVERIFY(f.write(block)); + } + QVERIFY(f.flush()); + QCOMPARE(f.size(), limit); + f.close(); + } +} + +void tst_qfile::writeFileSequentialWithSeeks_data() +{ + writeFileSequential_data(); +} + +void tst_qfile::writeFileSequentialWithSeeks() +{ + const qint64 limit = 1024 * 1024; + QFETCH(int, blockSize); + QFETCH(QString, path); + QTemporaryFile f; + f.setFileTemplate(path); + QByteArray block; + block.fill('@', blockSize); + QBENCHMARK { + QVERIFY(f.open()); + for (qint64 pos = 0; pos < limit; pos += blockSize) { + QVERIFY(f.seek(pos)); + QVERIFY(f.write(block)); + } + QVERIFY(f.flush()); + QCOMPARE(f.size(), limit); + f.close(); + } +} + QTEST_MAIN(tst_qfile) #include "main.moc" |