From: Ivailo Monev Date: Mon, 29 Jul 2019 17:42:30 +0000 (+0000) Subject: reimplement QCache purely based on QHash X-Git-Tag: 4.12.0~5255 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=c8e884c2d3a4dbd95973d639cf2265733e1ee24b;p=kde%2FKatie.git reimplement QCache purely based on QHash Signed-off-by: Ivailo Monev --- diff --git a/src/core/tools/qcache.h b/src/core/tools/qcache.h index 7e2a8f4b6..771557db8 100644 --- a/src/core/tools/qcache.h +++ b/src/core/tools/qcache.h @@ -43,43 +43,8 @@ QT_BEGIN_NAMESPACE template class QCache { - struct Node { - inline Node() : keyPtr(Q_NULLPTR) {} - inline Node(T *data, int cost) - : keyPtr(Q_NULLPTR), t(data), c(cost), p(Q_NULLPTR), n(Q_NULLPTR) {} - const Key *keyPtr; T *t; int c; Node *p,*n; - }; - Node *f, *l; - QHash hash; - int mx, total; - - inline void unlink(Node &n) { - if (n.p) n.p->n = n.n; - if (n.n) n.n->p = n.p; - if (l == &n) l = n.p; - if (f == &n) f = n.n; - total -= n.c; - T *obj = n.t; - hash.remove(*n.keyPtr); - delete obj; - } - inline T *relink(const Key &key) { - typename QHash::iterator i = hash.find(key); - if (typename QHash::const_iterator(i) == hash.constEnd()) - return Q_NULLPTR; - - Node &n = *i; - if (f != &n) { - if (n.p) n.p->n = n.n; - if (n.n) n.n->p = n.p; - if (l == &n) l = n.p; - n.p = 0; - n.n = f; - f->p = &n; - f = &n; - } - return n.t; - } + QHash hash; + int mx; Q_DISABLE_COPY(QCache) @@ -88,46 +53,35 @@ public: inline ~QCache() { clear(); } inline int maxCost() const { return mx; } - void setMaxCost(int m); - inline int totalCost() const { return total; } + inline void setMaxCost(int m); inline int size() const { return hash.size(); } inline int count() const { return hash.size(); } inline bool isEmpty() const { return hash.isEmpty(); } inline QList keys() const { return hash.keys(); } + inline void clear() { hash.clear(); } - void clear(); - - bool insert(const Key &key, T *object, int cost = 1); - T *object(const Key &key) const; + inline bool insert(const Key &key, T *object, int cost = 1); + inline T *object(const Key &key) const { return hash.value(key, Q_NULLPTR); } inline bool contains(const Key &key) const { return hash.contains(key); } - T *operator[](const Key &key) const; - - bool remove(const Key &key); - T *take(const Key &key); - -private: - void trim(int m); - + inline T *operator[](const Key &key) const; + inline bool remove(const Key &key); + inline T *take(const Key &key); }; template inline QCache::QCache(int amaxCost) - : f(Q_NULLPTR), l(Q_NULLPTR), mx(amaxCost), total(0) {} - -template -inline void QCache::clear() -{ while (f) { delete f->t; f = f->n; } - hash.clear(); l = Q_NULLPTR; total = 0; } + : mx(amaxCost) +{ hash.reserve(amaxCost); } template inline void QCache::setMaxCost(int m) -{ mx = m; trim(mx); } - -template -inline T *QCache::object(const Key &key) const -{ return const_cast*>(this)->relink(key); } +{ + mx = m; + hash.clear(); + hash.reserve(m); +} template inline T *QCache::operator[](const Key &key) const @@ -135,62 +89,29 @@ inline T *QCache::operator[](const Key &key) const template inline bool QCache::remove(const Key &key) -{ - typename QHash::iterator i = hash.find(key); - if (typename QHash::const_iterator(i) == hash.constEnd()) { - return false; - } else { - unlink(*i); - return true; - } -} +{ return hash.remove(key) != 0; } template inline T *QCache::take(const Key &key) { - typename QHash::iterator i = hash.find(key); - if (i == hash.end()) + if (!hash.contains(key)) return Q_NULLPTR; - - Node &n = *i; - T *t = n.t; - n.t = Q_NULLPTR; - unlink(n); - return t; + return hash.take(key); } template -bool QCache::insert(const Key &akey, T *aobject, int acost) +inline bool QCache::insert(const Key &akey, T *aobject, int acost) { - remove(akey); if (acost > mx) { delete aobject; return false; + } else if (hash.size() >= mx) { + hash.erase(hash.begin()); } - trim(mx - acost); - Node sn(aobject, acost); - typename QHash::iterator i = hash.insert(akey, sn); - total += acost; - Node *n = &i.value(); - n->keyPtr = &i.key(); - if (f) f->p = n; - n->n = f; - f = n; - if (!l) l = f; + hash.insert(akey, aobject); return true; } -template -void QCache::trim(int m) -{ - Node *n = l; - while (n && total > m) { - Node *u = n; - n = n->p; - unlink(*u); - } -} - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/core/tools/qcache.qdoc b/src/core/tools/qcache.qdoc index 81495c27e..c14311a7d 100644 --- a/src/core/tools/qcache.qdoc +++ b/src/core/tools/qcache.qdoc @@ -51,10 +51,10 @@ deletes them to make room for new objects, if necessary. When inserting an object into the cache, you can specify a \e{cost}, which should bear some approximate relationship to the amount of - memory taken by the object. When the sum of all objects' costs - (totalCost()) exceeds the cache's limit (maxCost()), QCache starts - deleting objects in the cache to keep under the limit, starting with - less recently accessed objects. + memory taken by the object. When the number of all objects' costs + exceeds the cache's limit (maxCost()), QCache starts deleting + objects in the cache to keep under the limit, starting with the + first object. By default, QCache's maxCost() is 100. You can specify a different value in the QCache constructor: