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>
This commit is contained in:
parent
9c9cdbedf1
commit
26267ef57e
@ -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());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user