Q[Multi]Hash::reserve(): do nothing if desired size is less than current
Calling Q[Multi]Hash::reserve(n) when n is much smaller than the current amount of elements in the hash, could result in an infinite loop, because at some point the algorithm could not find a free bucket for the element. Fixing it by returning early if the new desired capacity is less than current. Fixes: QTBUG-102067 Pick-to: 6.3 6.2 Change-Id: I38ef0b2168c4e2a317eedf91b2155b1fdffb1c27 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
87098106d0
commit
d11941db41
@ -944,6 +944,9 @@ public:
|
||||
inline qsizetype capacity() const noexcept { return d ? qsizetype(d->numBuckets >> 1) : 0; }
|
||||
void reserve(qsizetype size)
|
||||
{
|
||||
// reserve(0) is used in squeeze()
|
||||
if (size && (this->capacity() >= size))
|
||||
return;
|
||||
if (isDetached())
|
||||
d->rehash(size);
|
||||
else
|
||||
@ -1507,6 +1510,9 @@ public:
|
||||
inline qsizetype capacity() const noexcept { return d ? qsizetype(d->numBuckets >> 1) : 0; }
|
||||
void reserve(qsizetype size)
|
||||
{
|
||||
// reserve(0) is used in squeeze()
|
||||
if (size && (this->capacity() >= size))
|
||||
return;
|
||||
if (isDetached())
|
||||
d->rehash(size);
|
||||
else
|
||||
|
@ -98,6 +98,7 @@ private slots:
|
||||
void fineTuningInEmptyHash();
|
||||
|
||||
void reserveShared();
|
||||
void reserveLessThanCurrentAmount();
|
||||
|
||||
void QTBUG98265();
|
||||
|
||||
@ -2667,6 +2668,36 @@ void tst_QHash::reserveShared()
|
||||
QCOMPARE(hash.capacity(), oldCap);
|
||||
}
|
||||
|
||||
void tst_QHash::reserveLessThanCurrentAmount()
|
||||
{
|
||||
{
|
||||
QHash<int, int> hash;
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
hash.insert(i, i * 10);
|
||||
|
||||
// This used to hang in an infinite loop: QTBUG-102067
|
||||
hash.reserve(1);
|
||||
|
||||
// Make sure that hash still has all elements
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
QCOMPARE(hash.value(i), i * 10);
|
||||
}
|
||||
{
|
||||
QMultiHash<int, int> hash;
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
hash.insert(i, i * 10);
|
||||
hash.insert(i, i * 10 + 1);
|
||||
}
|
||||
|
||||
// This used to hang in infinite loop: QTBUG-102067
|
||||
hash.reserve(1);
|
||||
|
||||
// Make sure that hash still has all elements
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
QCOMPARE(hash.values(i), QList<int>() << i * 10 + 1 << i * 10);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QHash::QTBUG98265()
|
||||
{
|
||||
QMultiHash<QUuid, QByteArray> a;
|
||||
|
Loading…
x
Reference in New Issue
Block a user