qcache.h
上传用户:detong
上传日期:2022-06-22
资源大小:20675k
文件大小:6k
源码类别:

系统编程

开发平台:

Unix_Linux

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
  4. ** Contact: Qt Software Information (qt-info@nokia.com)
  5. **
  6. ** This file is part of the QtCore module of the Qt Toolkit.
  7. **
  8. ** Commercial Usage
  9. ** Licensees holding valid Qt Commercial licenses may use this file in
  10. ** accordance with the Qt Commercial License Agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and Nokia.
  13. **
  14. **
  15. ** GNU General Public License Usage
  16. ** Alternatively, this file may be used under the terms of the GNU
  17. ** General Public License versions 2.0 or 3.0 as published by the Free
  18. ** Software Foundation and appearing in the file LICENSE.GPL included in
  19. ** the packaging of this file.  Please review the following information
  20. ** to ensure GNU General Public Licensing requirements will be met:
  21. ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
  22. ** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
  23. ** exception, Nokia gives you certain additional rights. These rights
  24. ** are described in the Nokia Qt GPL Exception version 1.3, included in
  25. ** the file GPL_EXCEPTION.txt in this package.
  26. **
  27. ** Qt for Windows(R) Licensees
  28. ** As a special exception, Nokia, as the sole copyright holder for Qt
  29. ** Designer, grants users of the Qt/Eclipse Integration plug-in the
  30. ** right for the Qt/Eclipse Integration to link to functionality
  31. ** provided by Qt Designer and its related libraries.
  32. **
  33. ** If you are unsure which license is appropriate for your use, please
  34. ** contact the sales department at qt-sales@nokia.com.
  35. **
  36. ****************************************************************************/
  37. #ifndef QCACHE_H
  38. #define QCACHE_H
  39. #include <QtCore/qhash.h>
  40. QT_BEGIN_HEADER
  41. QT_BEGIN_NAMESPACE
  42. QT_MODULE(Core)
  43. template <class Key, class T>
  44. class QCache
  45. {
  46.     struct Node {
  47.         inline Node() : keyPtr(0) {}
  48.         inline Node(T *data, int cost)
  49.             : keyPtr(0), t(data), c(cost), p(0), n(0) {}
  50.         const Key *keyPtr; T *t; int c; Node *p,*n;
  51.     };
  52.     Node *f, *l;
  53.     QHash<Key, Node> hash;
  54.     void *unused;
  55.     int mx, total;
  56.     inline void unlink(Node &n) {
  57.         if (n.p) n.p->n = n.n;
  58.         if (n.n) n.n->p = n.p;
  59.         if (l == &n) l = n.p;
  60.         if (f == &n) f = n.n;
  61.         total -= n.c;
  62.         delete n.t;
  63.         hash.remove(*n.keyPtr);
  64.     }
  65.     inline T *relink(const Key &key) {
  66.         typename QHash<Key, Node>::iterator i = hash.find(key);
  67.         if (typename QHash<Key, Node>::const_iterator(i) == hash.constEnd())
  68.             return 0;
  69.         Node &n = *i;
  70.         if (f != &n) {
  71.             if (n.p) n.p->n = n.n;
  72.             if (n.n) n.n->p = n.p;
  73.             if (l == &n) l = n.p;
  74.             n.p = 0;
  75.             n.n = f;
  76.             f->p = &n;
  77.             f = &n;
  78.         }
  79.         return n.t;
  80.     }
  81.     Q_DISABLE_COPY(QCache)
  82. public:
  83.     inline explicit QCache(int maxCost = 100);
  84. #ifdef QT3_SUPPORT
  85.     inline QT3_SUPPORT_CONSTRUCTOR QCache(int maxCost, int /* dummy */)
  86.         : f(0), l(0), mx(maxCost), total(0) {}
  87. #endif
  88.     inline ~QCache() { clear(); }
  89.     inline int maxCost() const { return mx; }
  90.     void setMaxCost(int m);
  91.     inline int totalCost() const { return total; }
  92.     inline int size() const { return hash.size(); }
  93.     inline int count() const { return hash.size(); }
  94.     inline bool isEmpty() const { return hash.isEmpty(); }
  95.     inline QList<Key> keys() const { return hash.keys(); }
  96.     void clear();
  97.     bool insert(const Key &key, T *object, int cost = 1);
  98.     T *object(const Key &key) const;
  99.     inline bool contains(const Key &key) const { return hash.contains(key); }
  100.     T *operator[](const Key &key) const;
  101.     bool remove(const Key &key);
  102.     T *take(const Key &key);
  103. private:
  104.     void trim(int m);
  105. #ifdef QT3_SUPPORT
  106.     inline QT3_SUPPORT T *find(const Key &key) const { return object(key); }
  107. #endif
  108. };
  109. template <class Key, class T>
  110. inline QCache<Key, T>::QCache(int amaxCost)
  111.     : f(0), l(0), mx(amaxCost), total(0) {}
  112. template <class Key, class T>
  113. inline void QCache<Key,T>::clear()
  114. { while (f) { delete f->t; f = f->n; }
  115.  hash.clear(); l = 0; total = 0; }
  116. template <class Key, class T>
  117. inline void QCache<Key,T>::setMaxCost(int m)
  118. { mx = m; trim(mx); }
  119. template <class Key, class T>
  120. inline T *QCache<Key,T>::object(const Key &key) const
  121. { return const_cast<QCache<Key,T>*>(this)->relink(key); }
  122. template <class Key, class T>
  123. inline T *QCache<Key,T>::operator[](const Key &key) const
  124. { return object(key); }
  125. template <class Key, class T>
  126. inline bool QCache<Key,T>::remove(const Key &key)
  127. {
  128.     typename QHash<Key, Node>::iterator i = hash.find(key);
  129.     if (typename QHash<Key, Node>::const_iterator(i) == hash.constEnd()) {
  130.         return false;
  131.     } else {
  132.         unlink(*i);
  133.         return true;
  134.     }
  135. }
  136. template <class Key, class T>
  137. inline T *QCache<Key,T>::take(const Key &key)
  138. {
  139.     typename QHash<Key, Node>::iterator i = hash.find(key);
  140.     if (i == hash.end())
  141.         return 0;
  142.     Node &n = *i;
  143.     T *t = n.t;
  144.     n.t = 0;
  145.     unlink(n);
  146.     return t;
  147. }
  148. template <class Key, class T>
  149. bool QCache<Key,T>::insert(const Key &akey, T *aobject, int acost)
  150. {
  151.     remove(akey);
  152.     if (acost > mx) {
  153.         delete aobject;
  154.         return false;
  155.     }
  156.     trim(mx - acost);
  157.     Node sn(aobject, acost);
  158.     typename QHash<Key, Node>::iterator i = hash.insert(akey, sn);
  159.     total += acost;
  160.     Node *n = &i.value();
  161.     n->keyPtr = &i.key();
  162.     if (f) f->p = n;
  163.     n->n = f;
  164.     f = n;
  165.     if (!l) l = f;
  166.     return true;
  167. }
  168. template <class Key, class T>
  169. void QCache<Key,T>::trim(int m)
  170. {
  171.     Node *n = l;
  172.     while (n && total > m) {
  173.         Node *u = n;
  174.         n = n->p;
  175.         if (qIsDetached(*u->t))
  176.             unlink(*u);
  177.     }
  178. }
  179. QT_END_NAMESPACE
  180. QT_END_HEADER
  181. #endif // QCACHE_H