34 #include <QtConcurrentRun>
35 #include <QFutureWatcher>
37 #include <QDirIterator>
38 #include <QMutexLocker>
46 : QNetworkDiskCache (parent)
48 , InsertRemoveMutex_ (QMutex::Recursive)
49 , GarbageCollectorWatcher_ (nullptr)
52 auto timer =
new QTimer (
this);
53 timer->setInterval (60 * 60 * 1000);
62 if (GarbageCollectorWatcher_)
63 GarbageCollectorWatcher_->waitForFinished ();
73 QMutexLocker lock (&InsertRemoveMutex_);
74 return QNetworkDiskCache::data (url);
79 QMutexLocker lock (&InsertRemoveMutex_);
80 if (!PendingDev2Url_.contains (device))
82 qWarning () << Q_FUNC_INFO
83 <<
"stall device detected";
87 PendingUrl2Devs_ [PendingDev2Url_.take (device)].removeAll (device);
89 CurrentSize_ += device->size ();
90 QNetworkDiskCache::insert (device);
95 QMutexLocker lock (&InsertRemoveMutex_);
96 return QNetworkDiskCache::metaData (url);
101 QMutexLocker lock (&InsertRemoveMutex_);
102 const auto dev = QNetworkDiskCache::prepare (metadata);
103 PendingDev2Url_ [dev] = metadata.url ();
104 PendingUrl2Devs_ [metadata.url ()] << dev;
110 QMutexLocker lock (&InsertRemoveMutex_);
111 for (
const auto dev : PendingUrl2Devs_.take (url))
112 PendingDev2Url_.remove (dev);
113 return QNetworkDiskCache::remove (url);
118 QMutexLocker lock (&InsertRemoveMutex_);
119 QNetworkDiskCache::updateMetaData (metaData);
124 if (CurrentSize_ < 0)
127 return maximumCacheSize () * 8 / 10;
130 if (CurrentSize_ > maximumCacheSize ())
138 qint64 Collector (
const QString& cacheDirectory, qint64 goal, QMutex *fileOpMutex)
140 if (cacheDirectory.isEmpty ())
143 qDebug () << Q_FUNC_INFO <<
"running..." << cacheDirectory;
145 QDir::Filters filters = QDir::AllDirs | QDir:: Files | QDir::NoDotAndDotDot;
146 QDirIterator it (cacheDirectory, filters, QDirIterator::Subdirectories);
148 QMultiMap<QDateTime, QString> cacheItems;
149 qint64 totalSize = 0;
150 while (it.hasNext ())
152 const auto& path = it.next ();
153 const auto& info = it.fileInfo ();
154 cacheItems.insert (info.created (), path);
155 totalSize += info.size ();
158 auto i = cacheItems.constBegin ();
159 while (i != cacheItems.constEnd ())
161 if (totalSize < goal)
165 const auto size = file.size ();
169 QMutexLocker lock (fileOpMutex);
173 qDebug () <<
"collector finished" << totalSize;
181 if (GarbageCollectorWatcher_)
184 if (cacheDirectory ().isEmpty ())
188 connect (GarbageCollectorWatcher_,
189 SIGNAL (finished ()),
191 SLOT (handleCollectorFinished ()));
193 auto future = QtConcurrent::run (Collector,
194 cacheDirectory (), maximumCacheSize () * 9 / 10, &InsertRemoveMutex_);
195 GarbageCollectorWatcher_->setFuture (future);
198 void NetworkDiskCache::handleCollectorFinished ()
200 CurrentSize_ = GarbageCollectorWatcher_->result ();
201 GarbageCollectorWatcher_->deleteLater ();
202 GarbageCollectorWatcher_ =
nullptr;
virtual qint64 expire()
Reimplemented from QNetworkDiskCache.
virtual void insert(QIODevice *device)
Reimplemented from QNetworkDiskCache.
virtual qint64 cacheSize() const
Reimplemented from QNetworkDiskCache.
virtual QIODevice * data(const QUrl &url)
Reimplemented from QNetworkDiskCache.
~NetworkDiskCache()
Destroys the cache.
virtual bool remove(const QUrl &url)
Reimplemented from QNetworkDiskCache.
NetworkDiskCache(const QString &subpath, QObject *parent=0)
Constructs the new disk cache.
virtual QIODevice * prepare(const QNetworkCacheMetaData &)
Reimplemented from QNetworkDiskCache.
void collectGarbage()
Runs the garbage collector.
QDir GetUserDir(UserDir dir, const QString &subpath)
virtual QNetworkCacheMetaData metaData(const QUrl &url)
Reimplemented from QNetworkDiskCache.
virtual void updateMetaData(const QNetworkCacheMetaData &metaData)
Reimplemented from QNetworkDiskCache.