From df060ed6f61efd0c9fb4ff1bef0ea9016295797e Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Tue, 1 Nov 2022 21:34:16 +0200 Subject: [PATCH] always read data without intermediate buffer from QIODevice::read() the main user of QIODevice is QFile and it uses O_DSYNC/O_SYNC for unbuffered I/O meaning the QIODevice buffer does not benefit it because the filesystem cache already does that Signed-off-by: Ivailo Monev --- src/core/io/qiodevice.cpp | 44 ++++++++++++++---------------------------- tests/auto/qfile/tst_qfile.cpp | 14 +++++++------- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/src/core/io/qiodevice.cpp b/src/core/io/qiodevice.cpp index 3040d125c..58cd4d6e8 100644 --- a/src/core/io/qiodevice.cpp +++ b/src/core/io/qiodevice.cpp @@ -797,37 +797,20 @@ qint64 QIODevice::read(char *data, qint64 maxSize) // Make sure the device is positioned correctly. if (sequential || d->pos == d->devicePos || seek(d->pos)) { madeBufferReadsOnly = false; // fix readData attempt - if (maxSize >= QIODEVICE_BUFFERSIZE || (d->openMode & Unbuffered)) { - // Read big chunk directly to output buffer - readFromDevice = readData(data, maxSize); - deviceAtEof = (readFromDevice != maxSize); + // Read big chunk directly to output buffer + readFromDevice = readData(data, maxSize); + deviceAtEof = (readFromDevice != maxSize); #if defined QIODEVICE_DEBUG - printf("%p \treading %lld bytes from device (total %lld)\n", this, - readFromDevice, readSoFar); + printf("%p \treading %lld bytes from device (total %lld)\n", this, + readFromDevice, readSoFar); #endif - if (readFromDevice > 0) { - readSoFar += readFromDevice; - data += readFromDevice; - maxSize -= readFromDevice; - if (!sequential) { - d->pos += readFromDevice; - d->devicePos += readFromDevice; - } - } - } else { - const qint64 bytesToBuffer = QIODEVICE_BUFFERSIZE; - // Try to fill QIODevice buffer by single read - readFromDevice = readData(d->buffer.reserve(bytesToBuffer), bytesToBuffer); - deviceAtEof = (readFromDevice != bytesToBuffer); - d->buffer.chop(bytesToBuffer - qMax(Q_INT64_C(0), readFromDevice)); - if (readFromDevice > 0) { - if (!sequential) - d->devicePos += readFromDevice; -#if defined QIODEVICE_DEBUG - printf("%p \treading %lld from device into buffer\n", this, - readFromDevice); -#endif - continue; + if (readFromDevice > 0) { + readSoFar += readFromDevice; + data += readFromDevice; + maxSize -= readFromDevice; + if (!sequential) { + d->pos += readFromDevice; + d->devicePos += readFromDevice; } } } else { @@ -1168,8 +1151,9 @@ QByteArray QIODevice::readLine(qint64 maxSize) readBytes += readResult; } while (readResult == QIODEVICE_BUFFERSIZE && result[int(readBytes - 1)] != '\n'); - } else + } else { readBytes = readLine(result.data(), result.size()); + } if (readBytes <= 0) result.clear(); diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 898321237..0b0145102 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -824,19 +824,19 @@ void tst_QFile::readAllBuffer() QVERIFY( writer.open(QIODevice::ReadWrite | QIODevice::Unbuffered) ); QVERIFY( reader.open(QIODevice::ReadOnly) ); - QCOMPARE( writer.write(data1), qint64(data1.size()) ); - QVERIFY( writer.seek(0) ); + QCOMPARE(writer.write(data1), qint64(data1.size())); + QVERIFY(writer.seek(0)); QByteArray result; - result = reader.read(18); - QCOMPARE( result.size(), 18 ); + result = reader.read(data1.size()); + QCOMPARE(result.size(), data1.size()); - QCOMPARE( writer.write(data2), qint64(data2.size()) ); // new data, old version buffered in reader - QCOMPARE( writer.write(data2), qint64(data2.size()) ); // new data, unbuffered in reader + QCOMPARE(writer.write(data2), qint64(data2.size())); + QCOMPARE(writer.write(data2), qint64(data2.size())); result += reader.readAll(); - QCOMPARE( result, data1 + data2 ); + QCOMPARE(result, data1 + data2); QFile::remove(fileName); } -- 2.11.0