diff options
author | MÃ¥rten Nordheim <marten.nordheim@qt.io> | 2021-12-14 12:07:36 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2021-12-17 16:37:49 +0000 |
commit | 26267ef57eedd0ee9dc4bfa13200fdae22777084 (patch) | |
tree | 1cb24b677e5d5c913c9e311c4337bc68a07b3cf0 /tests/auto/corelib/tools/qhash | |
parent | 9c9cdbedf173e3e5f73205826deb97337f182a3e (diff) |
tst_QHash: Update the erase_edge_case test
By using the bucketForHash function we can loop through and find
some appropriate keys to test the edge-case. This will then
automatically keep the test working even if some internals
of QHash changes.
We do this because certain changes which change the bucket the
pre-selected keys would end up in could make the test a no-op,
without warning. And recent and upcoming changes have changed
both this and erase(). We limit the search-space to
the minimum numBuckets * 4, where minimum numBuckets is current
128.
Change-Id: I13b0bce15ee884144e3248846be34667fb5d35cc
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'tests/auto/corelib/tools/qhash')
-rw-r--r-- | tests/auto/corelib/tools/qhash/tst_qhash.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 50c2b0d84e..bab22c454a 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -577,14 +577,40 @@ void tst_QHash::erase() */ void tst_QHash::erase_edge_case() { + QHashSeed::setDeterministicGlobalSeed(); + auto resetSeed = qScopeGuard([&]() { + QHashSeed::resetRandomGlobalSeed(); + }); + QHash<int, int> h1; h1.reserve(2); - h1.d->seed = 10230148258692185509ull; - h1.insert(3, 4); - h1.insert(5, 6); + qsizetype capacity = h1.capacity(); + // Beholden to QHash internals: + qsizetype numBuckets = capacity << 1; + + // Find some keys which will both be slotted into the last bucket: + int keys[2]; + int index = 0; + for (qsizetype i = 0; i < numBuckets * 4 && index < 2; ++i) { + const size_t hash = qHash(i, QHashSeed::globalSeed()); + const size_t bucketForHash = QHashPrivate::GrowthPolicy::bucketForHash(numBuckets, hash); + if (bucketForHash == numBuckets - 1) + keys[index++] = i; + } + QCOMPARE(index, 2); // Sanity check. If this fails then the test needs an update! + + // As mentioned earlier these are both calculated to be in the last bucket: + h1.insert(keys[0], 4); + h1.insert(keys[1], 6); + // As a sanity-check, make sure that the key we inserted last is the first one (because its + // allocation to the last bucket would make it wrap around): + // NOTE: If this fails this then this test may need an update!!! + QCOMPARE(h1.constBegin().key(), keys[1]); + // Then we delete the last entry: QHash<int, int>::iterator it1 = h1.begin(); ++it1; it1 = h1.erase(it1); + // Now, since we deleted the last entry, the iterator should be at the end(): QVERIFY(it1 == h1.end()); } |