6#include "QtCore/qpointer.h"
7#include "QtCore/qdeadlinetimer.h"
23struct QNetworkAccessCache::Node
28 Node *previous =
nullptr;
30 CacheableObject *object =
nullptr;
45 if (!key.isEmpty() && Ptr()->hasEntry(key))
46 qWarning() <<
"QNetworkAccessCache: object" << (
void*)
this <<
"key" << key
47 <<
"destroyed without being removed from cache first!";
62 NodeHash::Iterator it = hashCopy.begin();
63 NodeHash::Iterator end = hashCopy.end();
64 for ( ; it != end; ++it) {
65 (*it)->object->key.clear();
66 (*it)->object->dispose();
75 firstExpiringNode = lastExpiringNode =
nullptr;
79
80
81
84 Node *
const node = hash.value(key);
88 Q_ASSERT(node != firstExpiringNode && node != lastExpiringNode);
89 Q_ASSERT(node->previous ==
nullptr && node->next ==
nullptr);
90 Q_ASSERT(node->useCount == 0);
93 node->timer.setPreciseRemainingTime(node->object->expiryTimeoutSeconds);
94#ifdef DEBUG_ACCESSCACHE
95 qDebug() <<
"QNetworkAccessCache case trying to insert=" << QString::fromUtf8(key)
96 << node->timer.remainingTime() <<
"milliseconds";
97 Node *current = lastExpiringNode;
99 qDebug() <<
"QNetworkAccessCache item=" << QString::fromUtf8(current->key)
100 << current->timer.remainingTime() <<
"milliseconds"
101 << (current == lastExpiringNode ?
"[last to expire]" :
"")
102 << (current == firstExpiringNode ?
"[first to expire]" :
"");
103 current = current->previous;
107 if (lastExpiringNode) {
108 Q_ASSERT(lastExpiringNode->next ==
nullptr);
109 if (lastExpiringNode->timer < node->timer) {
111 node->previous = lastExpiringNode;
112 lastExpiringNode->next = node;
113 lastExpiringNode = node;
116 Node *current = lastExpiringNode;
117 while (current->previous !=
nullptr && current->previous->timer >= node->timer)
118 current = current->previous;
119 node->previous = current->previous;
121 node->previous->next = node;
122 node->next = current;
123 current->previous = node;
124 if (node->previous ==
nullptr)
125 firstExpiringNode = node;
129 lastExpiringNode = node;
131 if (!firstExpiringNode) {
133 firstExpiringNode = node;
135 Q_ASSERT(firstExpiringNode->previous ==
nullptr);
136 Q_ASSERT(lastExpiringNode->next ==
nullptr);
140
141
142
145 Node *
const node = hash.value(key);
149 bool wasFirst =
false;
150 if (node == firstExpiringNode) {
151 firstExpiringNode = node->next;
154 if (node == lastExpiringNode)
155 lastExpiringNode = node->previous;
157 node->previous->next = node->next;
159 node->next->previous = node->previous;
161 node->next = node->previous =
nullptr;
169 if (!firstExpiringNode)
172 qint64 interval = firstExpiringNode->timer.remainingTime();
181 timer.start(interval + 10,
this);
186 if (!connect(
this, SIGNAL(entryReady(QNetworkAccessCache::CacheableObject*)),
187 target, member, Qt::QueuedConnection))
190 emit entryReady(node->object);
191 disconnect(SIGNAL(entryReady(QNetworkAccessCache::CacheableObject*)));
198 while (firstExpiringNode && firstExpiringNode->timer.hasExpired()) {
199 Node *next = firstExpiringNode->next;
200 firstExpiringNode->object->dispose();
201 hash.remove(firstExpiringNode->key);
202 delete firstExpiringNode;
203 firstExpiringNode = next;
207 if (firstExpiringNode)
208 firstExpiringNode->previous =
nullptr;
210 lastExpiringNode =
nullptr;
217 Q_ASSERT(!key.isEmpty());
219 if (unlinkEntry(key))
222 Node *node = hash.value(key);
225 hash.insert(key, node);
229 qWarning(
"QNetworkAccessCache::addEntry: overriding active cache entry '%s'", key.constData());
231 node->object->dispose();
232 node->object = entry;
233 node->object->key = key;
234 if (connectionCacheExpiryTimeoutSeconds > -1) {
235 node->object->expiryTimeoutSeconds = connectionCacheExpiryTimeoutSeconds;
237 node->object->expiryTimeoutSeconds = ExpiryTime;
247 return hash.contains(key);
252 Node *node = hash.value(key);
256 if (node->useCount > 0) {
257 if (node->object->shareable) {
267 bool wasNext = unlinkEntry(key);
277 Node *node = hash.value(key);
279 qWarning(
"QNetworkAccessCache::releaseEntry: trying to release key '%s' that is not in cache", key.constData());
283 Q_ASSERT(node->useCount > 0);
285 if (!--node->useCount) {
287 if (node->object->expires)
290 if (firstExpiringNode == node)
297 Node *node = hash.value(key);
299 qWarning(
"QNetworkAccessCache::removeEntry: trying to remove key '%s' that is not in cache", key.constData());
303 if (unlinkEntry(key))
305 if (node->useCount > 1)
306 qWarning(
"QNetworkAccessCache::removeEntry: removing active cache entry '%s'",
309 node->object->key.clear();
310 hash.remove(node->key);
316#include "moc_qnetworkaccesscache_p.cpp"
virtual ~CacheableObject()
CacheableObject(Options options)
QHash< QByteArray, Node * > NodeHash
void timerEvent(QTimerEvent *) override
This event handler can be reimplemented in a subclass to receive timer events for the object.