1 | /* |
2 | * This file is part of the KDE project. |
3 | * Copyright © 2010 Michael Pyne <mpyne@kde.org> |
4 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Library General Public |
7 | * License version 2 as published by the Free Software Foundation. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Library General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Library General Public License |
15 | * along with this library; see the file COPYING.LIB. If not, write to |
16 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | * Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #ifndef KSHAREDDATACACHE_H |
21 | #define KSHAREDDATACACHE_H |
22 | |
23 | #include <kdecore_export.h> |
24 | |
25 | class QString; |
26 | class QByteArray; |
27 | |
28 | /** |
29 | * @brief A simple data cache which uses shared memory to quickly access data |
30 | * stored on disk. |
31 | * |
32 | * This class is meant to be used with KImageCache and similar classes but can |
33 | * be used directly if used with care. |
34 | * |
35 | * Example usage: |
36 | * |
37 | * @code |
38 | * QString loadTranslatedDocument(KSharedDataCache *cache) { |
39 | * |
40 | * // Find the data |
41 | * QByteArray document; |
42 | * |
43 | * if (!cache->find("translated-doc-template", &document)) { |
44 | * // Entry is not cached, manually generate and then add to cache. |
45 | * document = translateDocument(globalTemplate()); |
46 | * cache->insert(document); |
47 | * } |
48 | * |
49 | * // Don't forget to encode/decode properly |
50 | * return QString::fromUtf8(document); |
51 | * } |
52 | * @endcode |
53 | * |
54 | * @author Michael Pyne <mpyne@kde.org> |
55 | * @see KImageCache |
56 | * @since 4.5 |
57 | */ |
58 | class KDECORE_EXPORT KSharedDataCache |
59 | { |
60 | public: |
61 | /** |
62 | * Attaches to a shared cache, creating it if necessary. If supported, this |
63 | * data cache will be shared across all processes using this cache (with |
64 | * subsequent memory savings). If shared memory is unsupported or a |
65 | * failure occurs, caching will still be supported, but only in the same |
66 | * process, and only using the same KSharedDataCache object. |
67 | * |
68 | * @param cacheName Name of the cache to use/share. |
69 | * @param defaultCacheSize Amount of data to be able to store, in bytes. The |
70 | * actual size will be slightly larger on disk due to accounting |
71 | * overhead. If the cache already existed then it <em>will not</em> be |
72 | * resized. For this reason you should specify some reasonable size. |
73 | * @param expectedItemSize The average size of an item that would be stored |
74 | * in the cache, in bytes. Choosing an average size of zero bytes causes |
75 | * KSharedDataCache to use whatever it feels is the best default for the |
76 | * system. |
77 | */ |
78 | KSharedDataCache(const QString &cacheName, |
79 | unsigned defaultCacheSize, |
80 | unsigned expectedItemSize = 0); |
81 | ~KSharedDataCache(); |
82 | |
83 | enum EvictionPolicy |
84 | { |
85 | // The default value for data in our shared memory will be 0, so it is |
86 | // important that whatever we want for the default value is also 0. |
87 | NoEvictionPreference = 0, |
88 | EvictLeastRecentlyUsed, |
89 | EvictLeastOftenUsed, |
90 | EvictOldest |
91 | }; |
92 | |
93 | /** |
94 | * @return The removal policy in use by the shared cache. |
95 | * @see EvictionPolicy |
96 | */ |
97 | EvictionPolicy evictionPolicy() const; |
98 | |
99 | /** |
100 | * Sets the entry removal policy for the shared cache to |
101 | * @p newPolicy. The default is EvictionPolicy::NoEvictionPreference. |
102 | * |
103 | * @see EvictionPolicy |
104 | */ |
105 | void setEvictionPolicy(EvictionPolicy newPolicy); |
106 | |
107 | /** |
108 | * Attempts to insert the entry @p data into the shared cache, named by |
109 | * @p key, and returns true only if successful. |
110 | * |
111 | * Note that even if the insert was successful, that the newly added entry |
112 | * may be evicted by other processes contending for the cache. |
113 | */ |
114 | bool insert(const QString &key, const QByteArray &data); |
115 | |
116 | /** |
117 | * Returns the data in the cache named by @p key (even if it's some other |
118 | * process's data named with the same key!), stored in @p destination. If there is |
119 | * no entry named by @p key then @p destination is left unchanged. The return value |
120 | * is used to tell what happened. |
121 | * |
122 | * If you simply want to verify whether an entry is present in the cache then |
123 | * see contains(). |
124 | * |
125 | * @param key The key to find in the cache. |
126 | * @param destination Is set to the value of @p key in the cache if @p key is |
127 | * present, left unchanged otherwise. |
128 | * @return true if @p key was present in the cache (@p destination will also be |
129 | * updated), false if @p key was not present (@p destination will be |
130 | * unchanged). |
131 | */ |
132 | bool find(const QString &key, QByteArray *destination) const; |
133 | |
134 | /** |
135 | * Removes all entries from the cache. |
136 | */ |
137 | void clear(); |
138 | |
139 | /** |
140 | * Removes the underlying file from the cache. Note that this is *all* that this |
141 | * function does. The shared memory segment is still attached and will still contain |
142 | * all the data until all processes currently attached remove the mapping. |
143 | * |
144 | * In order to remove the data see clear(). |
145 | */ |
146 | static void deleteCache(const QString &cacheName); |
147 | |
148 | /** |
149 | * Returns true if the cache currently contains the image for the given |
150 | * filename. |
151 | * |
152 | * NOTE: Calling this function is threadsafe, but it is in general not |
153 | * possible to guarantee the image stays cached immediately afterwards, |
154 | * so if you need the result use find(). |
155 | */ |
156 | bool contains(const QString &key) const; |
157 | |
158 | /** |
159 | * Returns the usable cache size in bytes. The actual amount of memory |
160 | * used will be slightly larger than this to account for required |
161 | * accounting overhead. |
162 | */ |
163 | unsigned totalSize() const; |
164 | |
165 | /** |
166 | * Returns the amount of free space in the cache, in bytes. Due to |
167 | * implementation details it is possible to still not be able to fit an |
168 | * entry in the cache at any given time even if it is smaller than the |
169 | * amount of space remaining. |
170 | */ |
171 | unsigned freeSize() const; |
172 | |
173 | /** |
174 | * @return The shared timestamp of the cache. The interpretation of the |
175 | * timestamp returned is up to the application. KSharedDataCache |
176 | * will initialize the timestamp to the time returned by @c time(2) |
177 | * on cache creation, but KSharedDataCache will not touch the |
178 | * timestamp again. |
179 | * @see setTimestamp() |
180 | * @since 4.6 |
181 | */ |
182 | unsigned timestamp() const; |
183 | |
184 | /** |
185 | * Sets the shared timestamp of the cache. Timestamping is supported to |
186 | * allow applications to more effectively "version" the data stored in the |
187 | * cache. However, the timestamp is shared with <em>all</em> applications |
188 | * using the cache so you should always be prepared for invalid |
189 | * timestamps. |
190 | * |
191 | * When the cache is first created (note that this is different from |
192 | * attaching to an existing shared cache on disk), the cache timestamp is |
193 | * initialized to the time returned by @c time(2). KSharedDataCache will |
194 | * not update the timestamp again, it is only updated through this method. |
195 | * |
196 | * Example: |
197 | * @code |
198 | * QImage loadCachedImage(const QString &key) |
199 | * { |
200 | * // Check timestamp |
201 | * if (m_sharedCache->timestamp() < m_currentThemeTimestamp) { |
202 | * // Cache is stale, clean it out. |
203 | * m_sharedCache->clear(); |
204 | * m_sharedCache->setTimestamp(m_currentThemeTimestamp); |
205 | * } |
206 | * |
207 | * // Check cache and load image as usual... |
208 | * } |
209 | * @endcode |
210 | * |
211 | * @param newTimestamp The new timestamp to mark the shared cache with. |
212 | * @see timestamp() |
213 | * @since 4.6 |
214 | */ |
215 | void setTimestamp(unsigned newTimestamp); |
216 | |
217 | private: |
218 | class Private; |
219 | Private *d; |
220 | }; |
221 | |
222 | #endif |
223 | |