QCache: when overwriting, store the new cost instead of the delta

The delta was clearly intended to be used on the total (and still is)
but it also wound up getting stored in the cache, which wouldn't be a
big problem unless the object was removed, in which case we could
incidentally 'free up more space' than intended.

Pick-to: 6.0
Change-Id: Ib2b0f072d30da6d16a93dce60e4c5f6080c109fc
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
bb10
Mårten Nordheim 2021-01-12 17:25:03 +01:00
parent cb4f853cb0
commit d2e2d0d3a6
2 changed files with 16 additions and 1 deletions

View File

@ -245,8 +245,9 @@ public:
auto result = d.findOrInsert(key);
Node *n = result.it.node();
if (result.initialized) {
cost -= n->value.cost;
auto prevCost = n->value.cost;
result.it.node()->emplace(object, cost);
cost -= prevCost;
relink(key);
} else {
Node::createInPlace(n, key, object, cost);

View File

@ -49,6 +49,7 @@ private slots:
void axioms_on_key_type();
void largeCache();
void internalChainOrderAfterEntryUpdate();
void emplaceLowerCost();
};
@ -431,5 +432,18 @@ void tst_QCache::internalChainOrderAfterEntryUpdate()
QCOMPARE(cache.size(), 0);
}
void tst_QCache::emplaceLowerCost()
{
QCache<QString, int> cache;
cache.setMaxCost(5);
cache.insert("a", new int, 3); // insert high cost
cache.insert("a", new int, 1); // and then exchange it with a lower-cost object
QCOMPARE(cache.totalCost(), 1);
cache.remove("a"); // then remove the object
// The cache should now have a cost == 0 and be empty.
QCOMPARE(cache.totalCost(), 0);
QVERIFY(cache.isEmpty());
}
QTEST_APPLESS_MAIN(tst_QCache)
#include "tst_qcache.moc"