summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qhash.h20
-rw-r--r--tests/auto/corelib/tools/qhash/tst_qhash.cpp17
2 files changed, 30 insertions, 7 deletions
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 49a015f2fe..5d7c2eb80d 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -655,15 +655,21 @@ struct Data
InsertionResult findOrInsert(const Key &key) noexcept
{
- if (shouldGrow())
+ iterator it;
+ if (numBuckets > 0) {
+ it = find(key);
+ if (!it.isUnused())
+ return { it, true };
+ }
+ if (shouldGrow()) {
rehash(size + 1);
- iterator it = find(key);
- if (it.isUnused()) {
- spans[it.span()].insert(it.index());
- ++size;
- return { it, false };
+ it = find(key); // need to get a new iterator after rehashing
}
- return { it, true };
+ Q_ASSERT(it.d);
+ Q_ASSERT(it.isUnused());
+ spans[it.span()].insert(it.index());
+ ++size;
+ return { it, false };
}
iterator erase(iterator it) noexcept(std::is_nothrow_destructible<Node>::value)
diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp
index 11e7237ba4..50c2b0d84e 100644
--- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp
+++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp
@@ -101,6 +101,8 @@ private slots:
void QTBUG98265();
void detachAndReferences();
+
+ void lookupUsingKeyIterator();
};
struct IdentityTracker {
@@ -2699,5 +2701,20 @@ void tst_QHash::detachAndReferences()
#endif
}
+void tst_QHash::lookupUsingKeyIterator()
+{
+ QHash<QString, QString> hash;
+ hash.reserve(1);
+ qsizetype minCapacity = hash.capacity();
+ // Beholden to internal implementation details:
+ qsizetype rehashLimit = minCapacity == 64 ? 63 : 8;
+
+ for (char16_t c = u'a'; c <= u'a' + rehashLimit; ++c)
+ hash.insert(QString(QChar(c)), u"h"_qs);
+
+ for (auto it = hash.keyBegin(), end = hash.keyEnd(); it != end; ++it)
+ QVERIFY(!hash[*it].isEmpty());
+}
+
QTEST_APPLESS_MAIN(tst_QHash)
#include "tst_qhash.moc"