summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qiodevice.cpp
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2020-08-11 19:30:15 +0300
committerAlex Trotsenko <alex1973tr@gmail.com>2020-08-20 18:24:15 +0300
commita41c61fb2d2f973fd1cd5e95ee5be1ac1a4f8433 (patch)
tree857130e663aa61ebbf09d7da9a1670aa81a9e69b /src/corelib/io/qiodevice.cpp
parent729d102b1c5273087c54d1584c80f1a1e6eef86c (diff)
QIODevice: implement a "zero-copy" strategy for buffered writes
It works as follows: - user calls write(const QByteArray &); - this function keeps a pointer to the chunk and calls a regular write(data, len); - write(data, len) calls a virtual writeData(); - subclass calls a new QIODevicePrivate::write(); - QIODevicePrivate::write() makes a shallow copy of the byte array. Proposed solution is fully compatible with existing subclasses. By replacing a call to d->writeBuffer.append() with d->write(), subclasses can improve their performance. Bump the TypeInformationVersion field in qtHookData, to notify the Qt Creator developers that the offset of QFilePrivate::fileName was changed and dumpers should be adapted. Change-Id: I24713386cc74a9f37e5223c617e4b1ba97f968dc Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/io/qiodevice.cpp')
-rw-r--r--src/corelib/io/qiodevice.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 3d64e8820f..b920fbb17b 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -158,13 +158,14 @@ static void checkWarnMessage(const QIODevice *device, const char *function, cons
QIODevicePrivate::QIODevicePrivate()
: openMode(QIODevice::NotOpen),
pos(0), devicePos(0),
+ transactionPos(0),
readChannelCount(0),
writeChannelCount(0),
currentReadChannel(0),
currentWriteChannel(0),
readBufferChunkSize(QIODEVICE_BUFFERSIZE),
writeBufferChunkSize(0),
- transactionPos(0),
+ currentWriteChunk(nullptr),
transactionStarted(false)
, baseReadLineDataCalled(false)
, accessMode(Unset)
@@ -1750,7 +1751,34 @@ qint64 QIODevice::write(const char *data)
qint64 QIODevice::write(const QByteArray &data)
{
- return write(data.constData(), data.size());
+ Q_D(QIODevice);
+
+ // Keep the chunk pointer for further processing in
+ // QIODevicePrivate::write(). To reduce fragmentation,
+ // the chunk size must be sufficiently large.
+ if (data.size() >= QRINGBUFFER_CHUNKSIZE)
+ d->currentWriteChunk = &data;
+
+ const qint64 ret = write(data.constData(), data.size());
+
+ d->currentWriteChunk = nullptr;
+ return ret;
+}
+
+/*!
+ \internal
+*/
+void QIODevicePrivate::write(const char *data, qint64 size)
+{
+ if (currentWriteChunk != nullptr
+ && currentWriteChunk->constData() == data
+ && currentWriteChunk->size() == size) {
+ // We are called from write(const QByteArray &) overload.
+ // So, we can make a shallow copy of chunk.
+ writeBuffer.append(*currentWriteChunk);
+ } else {
+ writeBuffer.append(data, size);
+ }
}
/*!