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

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