source: trunk/src/corelib/tools/qcache.h@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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