6#include "QtCore/qpointer.h"
7#include "QtCore/qdeadlinetimer.h"
18struct QNetworkAccessCache::Node
23 Node *previous =
nullptr;
25 CacheableObject *object =
nullptr;
40 if (!key.isEmpty() && Ptr()->hasEntry(key))
41 qWarning() <<
"QNetworkAccessCache: object" << (
void*)
this <<
"key" << key
42 <<
"destroyed without being removed from cache first!";
57 NodeHash::Iterator it = hashCopy.begin();
58 NodeHash::Iterator end = hashCopy.end();
59 for ( ; it != end; ++it) {
60 (*it)->object->key.clear();
61 (*it)->object->dispose();
70 firstExpiringNode = lastExpiringNode =
nullptr;
74
75
76
79 Node *
const node = hash.value(key);
83 Q_ASSERT(node != firstExpiringNode && node != lastExpiringNode);
84 Q_ASSERT(node->previous ==
nullptr && node->next ==
nullptr);
85 Q_ASSERT(node->useCount == 0);
88 node->timer.setPreciseRemainingTime(node->object->expiryTimeoutSeconds);
89#ifdef DEBUG_ACCESSCACHE
90 qDebug() <<
"QNetworkAccessCache case trying to insert=" << QString::fromUtf8(key)
91 << node->timer.remainingTime() <<
"milliseconds";
92 Node *current = lastExpiringNode;
94 qDebug() <<
"QNetworkAccessCache item=" << QString::fromUtf8(current->key)
95 << current->timer.remainingTime() <<
"milliseconds"
96 << (current == lastExpiringNode ?
"[last to expire]" :
"")
97 << (current == firstExpiringNode ?
"[first to expire]" :
"");
98 current = current->previous;
102 if (lastExpiringNode) {
103 Q_ASSERT(lastExpiringNode->next ==
nullptr);
104 if (lastExpiringNode->timer < node->timer) {
106 node->previous = lastExpiringNode;
107 lastExpiringNode->next = node;
108 lastExpiringNode = node;
111 Node *current = lastExpiringNode;
112 while (current->previous !=
nullptr && current->previous->timer >= node->timer)
113 current = current->previous;
114 node->previous = current->previous;
116 node->previous->next = node;
117 node->next = current;
118 current->previous = node;
119 if (node->previous ==
nullptr)
120 firstExpiringNode = node;
124 lastExpiringNode = node;
126 if (!firstExpiringNode) {
128 firstExpiringNode = node;
130 Q_ASSERT(firstExpiringNode->previous ==
nullptr);
131 Q_ASSERT(lastExpiringNode->next ==
nullptr);
135
136
137
140 Node *
const node = hash.value(key);
144 bool wasFirst =
false;
145 if (node == firstExpiringNode) {
146 firstExpiringNode = node->next;
149 if (node == lastExpiringNode)
150 lastExpiringNode = node->previous;
152 node->previous->next = node->next;
154 node->next->previous = node->previous;
156 node->next = node->previous =
nullptr;
164 if (!firstExpiringNode)
167 qint64 interval = firstExpiringNode->timer.remainingTime();
176 timer.start(interval + 10,
this);
181 while (firstExpiringNode && firstExpiringNode->timer.hasExpired()) {
182 Node *next = firstExpiringNode->next;
183 firstExpiringNode->object->dispose();
184 hash.remove(firstExpiringNode->key);
185 delete firstExpiringNode;
186 firstExpiringNode = next;
190 if (firstExpiringNode)
191 firstExpiringNode->previous =
nullptr;
193 lastExpiringNode =
nullptr;
200 Q_ASSERT(!key.isEmpty());
202 if (unlinkEntry(key))
205 Node *node = hash.value(key);
208 hash.insert(key, node);
212 qWarning(
"QNetworkAccessCache::addEntry: overriding active cache entry '%s'", key.constData());
214 node->object->dispose();
215 node->object = entry;
216 node->object->key = key;
217 if (connectionCacheExpiryTimeoutSeconds > -1) {
218 node->object->expiryTimeoutSeconds = connectionCacheExpiryTimeoutSeconds;
220 node->object->expiryTimeoutSeconds = ExpiryTime;
230 return hash.contains(key);
235 Node *node = hash.value(key);
239 if (node->useCount > 0) {
240 if (node->object->shareable) {
250 bool wasNext = unlinkEntry(key);
260 Node *node = hash.value(key);
262 qWarning(
"QNetworkAccessCache::releaseEntry: trying to release key '%s' that is not in cache", key.constData());
266 Q_ASSERT(node->useCount > 0);
268 if (!--node->useCount) {
270 if (node->object->expires)
273 if (firstExpiringNode == node)
280 Node *node = hash.value(key);
282 qWarning(
"QNetworkAccessCache::removeEntry: trying to remove key '%s' that is not in cache", key.constData());
286 if (unlinkEntry(key))
288 if (node->useCount > 1)
289 qWarning(
"QNetworkAccessCache::removeEntry: removing active cache entry '%s'",
292 node->object->key.clear();
293 hash.remove(node->key);
299#include "moc_qnetworkaccesscache_p.cpp"
virtual ~CacheableObject()
CacheableObject(Options options)
QHash< QByteArray, Node * > NodeHash
bool hasEntry(const QByteArray &key) const
void removeEntry(const QByteArray &key)
CacheableObject * requestEntryNow(const QByteArray &key)
void addEntry(const QByteArray &key, CacheableObject *entry, qint64 connectionCacheExpiryTimeoutSeconds=-1)
void releaseEntry(const QByteArray &key)
void timerEvent(QTimerEvent *) override
This event handler can be reimplemented in a subclass to receive timer events for the object.