source: trunk/src/qt3support/tools/q3gcache.cpp@ 504

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

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

File size: 20.2 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 Qt3Support 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#include "q3gcache.h"
43#include "q3ptrlist.h"
44#include "q3dict.h"
45#include "qstring.h"
46
47QT_BEGIN_NAMESPACE
48
49/*!
50 \class Q3GCache
51 \reentrant
52 \brief The Q3GCache class is an internal class for implementing Q3Cache
53 template classes.
54
55 \internal
56
57 Q3GCache is a strictly internal class that acts as a base class for the
58 \link collection.html collection classes\endlink Q3Cache and QIntCache.
59*/
60
61
62/*****************************************************************************
63 Q3GCacheItem class (internal cache item)
64 *****************************************************************************/
65
66struct Q3CacheItem
67{
68 Q3CacheItem(void *k, Q3PtrCollection::Item d, int c, short p)
69 : priority(p), skipPriority(p), cost(c), key(k), data(d), node(0) {}
70 short priority;
71 short skipPriority;
72 int cost;
73 void *key;
74 Q3PtrCollection::Item data;
75 Q3LNode *node;
76};
77
78
79/*****************************************************************************
80 Q3CList class (internal list of cache items)
81 *****************************************************************************/
82
83class Q3CList : private Q3PtrList<Q3CacheItem>
84{
85friend class Q3GCacheIterator;
86friend class Q3CListIt;
87public:
88 Q3CList() {}
89 ~Q3CList();
90
91 void insert(Q3CacheItem *); // insert according to priority
92 void insert(int, Q3CacheItem *);
93 void take(Q3CacheItem *);
94 void reference(Q3CacheItem *);
95
96 void setAutoDelete(bool del) { Q3PtrCollection::setAutoDelete(del); }
97
98 bool removeFirst() { return Q3PtrList<Q3CacheItem>::removeFirst(); }
99 bool removeLast() { return Q3PtrList<Q3CacheItem>::removeLast(); }
100
101 Q3CacheItem *first() { return Q3PtrList<Q3CacheItem>::first(); }
102 Q3CacheItem *last() { return Q3PtrList<Q3CacheItem>::last(); }
103 Q3CacheItem *prev() { return Q3PtrList<Q3CacheItem>::prev(); }
104 Q3CacheItem *next() { return Q3PtrList<Q3CacheItem>::next(); }
105
106#if defined(QT_DEBUG)
107 int inserts; // variables for statistics
108 int insertCosts;
109 int insertMisses;
110 int finds;
111 int hits;
112 int hitCosts;
113 int dumps;
114 int dumpCosts;
115#endif
116};
117
118
119Q3CList::~Q3CList()
120{
121#if defined(QT_DEBUG)
122 Q_ASSERT(count() == 0);
123#endif
124}
125
126
127void Q3CList::insert(Q3CacheItem *ci)
128{
129 Q3CacheItem *item = first();
130 while(item && item->skipPriority > ci->priority) {
131 item->skipPriority--;
132 item = next();
133 }
134 if (item)
135 Q3PtrList<Q3CacheItem>::insert(at(), ci);
136 else
137 append(ci);
138#if defined(QT_DEBUG)
139 Q_ASSERT(ci->node == 0);
140#endif
141 ci->node = currentNode();
142}
143
144inline void Q3CList::insert(int i, Q3CacheItem *ci)
145{
146 Q3PtrList<Q3CacheItem>::insert(i, ci);
147#if defined(QT_DEBUG)
148 Q_ASSERT(ci->node == 0);
149#endif
150 ci->node = currentNode();
151}
152
153
154void Q3CList::take(Q3CacheItem *ci)
155{
156 if (ci) {
157#if defined(QT_DEBUG)
158 Q_ASSERT(ci->node != 0);
159#endif
160 takeNode(ci->node);
161 ci->node = 0;
162 }
163}
164
165
166inline void Q3CList::reference(Q3CacheItem *ci)
167{
168#if defined(QT_DEBUG)
169 Q_ASSERT(ci != 0 && ci->node != 0);
170#endif
171 ci->skipPriority = ci->priority;
172 relinkNode(ci->node); // relink as first item
173}
174
175
176class Q3CListIt: public Q3PtrListIterator<Q3CacheItem>
177{
178public:
179 Q3CListIt(const Q3CList *p): Q3PtrListIterator<Q3CacheItem>(*p) {}
180 Q3CListIt(const Q3CListIt *p): Q3PtrListIterator<Q3CacheItem>(*p) {}
181};
182
183
184/*****************************************************************************
185 Q3CDict class (internal dictionary of cache items)
186 *****************************************************************************/
187
188//
189// Since we need to decide if the dictionary should use an int or const
190// char * key (the "bool trivial" argument in the constructor below)
191// we cannot use the macro/template dict, but inherit directly from Q3GDict.
192//
193
194class Q3CDict : public Q3GDict
195{
196public:
197 Q3CDict(uint size, uint kt, bool caseSensitive, bool copyKeys)
198 : Q3GDict(size, (KeyType)kt, caseSensitive, copyKeys) {}
199 ~Q3CDict();
200
201 void clear() { Q3GDict::clear(); }
202
203 Q3CacheItem *find_string(const QString &key) const
204 { return (Q3CacheItem*)((Q3CDict*)this)->look_string(key, 0, 0); }
205 Q3CacheItem *find_ascii(const char *key) const
206 { return (Q3CacheItem*)((Q3CDict*)this)->look_ascii(key, 0, 0); }
207 Q3CacheItem *find_int(long key) const
208 { return (Q3CacheItem*)((Q3CDict*)this)->look_int(key, 0, 0); }
209
210 Q3CacheItem *take_string(const QString &key)
211 { return (Q3CacheItem*)Q3GDict::take_string(key); }
212 Q3CacheItem *take_ascii(const char *key)
213 { return (Q3CacheItem*)Q3GDict::take_ascii(key); }
214 Q3CacheItem *take_int(long key)
215 { return (Q3CacheItem*)Q3GDict::take_int(key); }
216
217 bool insert_string(const QString &key, const Q3CacheItem *ci)
218 { return Q3GDict::look_string(key,(Item)ci,1)!=0;}
219 bool insert_ascii(const char *key, const Q3CacheItem *ci)
220 { return Q3GDict::look_ascii(key,(Item)ci,1)!=0;}
221 bool insert_int(long key, const Q3CacheItem *ci)
222 { return Q3GDict::look_int(key,(Item)ci,1)!=0;}
223
224 bool remove_string(Q3CacheItem *item)
225 { return Q3GDict::remove_string(*((QString*)(item->key)),item); }
226 bool remove_ascii(Q3CacheItem *item)
227 { return Q3GDict::remove_ascii((const char *)item->key,item); }
228 bool remove_int(Q3CacheItem *item)
229 { return Q3GDict::remove_int((long)item->key,item);}
230
231 void statistics() { Q3GDict::statistics(); }
232
233private:
234 void deleteItem(void *item)
235 { if (del_item) { Q3CacheItem *d = (Q3CacheItem*)item; delete d; } }
236};
237
238inline Q3CDict::~Q3CDict()
239{
240 clear();
241}
242
243/*****************************************************************************
244 Q3GDict member functions
245 *****************************************************************************/
246
247/*!
248 Constructs a cache.
249 The maximum cost of the cache is given by \a maxCost and the size by \a
250 size. The key type is \a kt which may be \c StringKey, \c AsciiKey,