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

source code of kcoreaddons/src/lib/caching/kshareddatacache.h