QDataStream::readBytes(): make the growth of the buffer geometric
The algorithm tries to allocate the memory using 1 Mb blocks. When the input data is large, this results in a lot of reallocations, which is slow and inefficient. This patch modifies the algorithm in such way that the allocation size increases at each step, resulting in geometric growth of the buffer. As all the variables in the algorithm are quint32, and the blockSize is int, we need to make sure that it does not become negative, because readBlock() is not designed to handle negative length. Note that we cannot simply "fix" the problem by converting blockSize to quint32, because that will just postpone quint32 -> int conversion until the function call. So, add an extra check to make sure that the value does not exceed INT_MAX. Change-Id: I071df68d51ba1dbd8b2eb5f94eb078a33223505f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit a1bfac287ee5d3719646d68dc91dc8e8e4cec04e) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit 44dc38ebc9fa407565ec1699bdbb1f97ffd13f1c) Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
parent
5d727ab430
commit
1ba9a1fec8
@ -1056,13 +1056,15 @@ QDataStream &QDataStream::readBytes(char *&s, uint &l)
|
||||
if (len == 0)
|
||||
return *this;
|
||||
|
||||
const quint32 Step = 1024 * 1024;
|
||||
quint32 step = 1024 * 1024;
|
||||
quint32 allocated = 0;
|
||||
char *prevBuf = nullptr;
|
||||
char *curBuf = nullptr;
|
||||
|
||||
constexpr quint32 MaxBlockSize = std::numeric_limits<int>::max();
|
||||
do {
|
||||
int blockSize = qMin(Step, len - allocated);
|
||||
const quint32 sz = qMin(step, len - allocated);
|
||||
int blockSize = qMin(sz, MaxBlockSize);
|
||||
prevBuf = curBuf;
|
||||
curBuf = new char[allocated + blockSize + 1];
|
||||
if (prevBuf) {
|
||||
@ -1074,6 +1076,7 @@ QDataStream &QDataStream::readBytes(char *&s, uint &l)
|
||||
return *this;
|
||||
}
|
||||
allocated += blockSize;
|
||||
step *= 2;
|
||||
} while (allocated < len);
|
||||
|
||||
s = curBuf;
|
||||
|
Loading…
x
Reference in New Issue
Block a user