QNetworkDiskCache: optimize expire()
- Use a std::vector<struct> that has the needed info already cached (e.g. now size() isn't computed twice) - Only sort the cache items if the size exceeds the cache limit and there are files to remove Change-Id: I69a7a5d1afb26d156c4babddf6b357ec68d569d1 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
51b1a23aa1
commit
56e42f1818
@ -16,7 +16,6 @@
|
|||||||
#include <qurl.h>
|
#include <qurl.h>
|
||||||
#include <qcryptographichash.h>
|
#include <qcryptographichash.h>
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
#include <QMultiMap>
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -483,47 +482,57 @@ qint64 QNetworkDiskCache::expire()
|
|||||||
// close file handle to prevent "in use" error when QFile::remove() is called
|
// close file handle to prevent "in use" error when QFile::remove() is called
|
||||||
d->lastItem.reset();
|
d->lastItem.reset();
|
||||||
|
|
||||||
QDir::Filters filters = QDir::AllDirs | QDir:: Files | QDir::NoDotAndDotDot;
|
const QDir::Filters filters = QDir::AllDirs | QDir:: Files | QDir::NoDotAndDotDot;
|
||||||
QDirIterator it(cacheDirectory(), filters, QDirIterator::Subdirectories);
|
QDirIterator it(cacheDirectory(), filters, QDirIterator::Subdirectories);
|
||||||
|
|
||||||
QMultiMap<QDateTime, QString> cacheItems;
|
struct CacheItem
|
||||||
|
{
|
||||||
|
std::chrono::milliseconds msecs;
|
||||||
|
QString path;
|
||||||
|
qint64 size = 0;
|
||||||
|
};
|
||||||
|
std::vector<CacheItem> cacheItems;
|
||||||
qint64 totalSize = 0;
|
qint64 totalSize = 0;
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
QFileInfo info = it.nextFileInfo();
|
QFileInfo info = it.nextFileInfo();
|
||||||
QString path = info.filePath();
|
if (!info.fileName().endsWith(CACHE_POSTFIX))
|
||||||
QString fileName = info.fileName();
|
continue;
|
||||||
if (fileName.endsWith(CACHE_POSTFIX)) {
|
|
||||||
const QDateTime birthTime = info.birthTime(QTimeZone::UTC);
|
QDateTime fileTime = info.birthTime(QTimeZone::UTC);
|
||||||
cacheItems.insert(birthTime.isValid() ? birthTime
|
if (!fileTime.isValid())
|
||||||
: info.metadataChangeTime(QTimeZone::UTC), path);
|
fileTime = info.metadataChangeTime(QTimeZone::UTC);
|
||||||
totalSize += info.size();
|
const std::chrono::milliseconds msecs{fileTime.toMSecsSinceEpoch()};
|
||||||
}
|
const qint64 size = info.size();
|
||||||
|
cacheItems.push_back(CacheItem{msecs, info.filePath(), size});
|
||||||
|
totalSize += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]] int removedFiles = 0; // used under QNETWORKDISKCACHE_DEBUG
|
const qint64 goal = (maximumCacheSize() * 9) / 10;
|
||||||
qint64 goal = (maximumCacheSize() * 9) / 10;
|
if (totalSize < goal)
|
||||||
QMultiMap<QDateTime, QString>::const_iterator i = cacheItems.constBegin();
|
return totalSize; // Nothing to do
|
||||||
while (i != cacheItems.constEnd()) {
|
|
||||||
if (totalSize < goal)
|
|
||||||
break;
|
|
||||||
QString name = i.value();
|
|
||||||
QFile file(name);
|
|
||||||
|
|
||||||
if (name.contains(PREPARED_SLASH)) {
|
auto byFileTime = [&](const auto &a, const auto &b) { return a.msecs < b.msecs; };
|
||||||
for (QCacheItem *item : std::as_const(d->inserting)) {
|
std::sort(cacheItems.begin(), cacheItems.end(), byFileTime);
|
||||||
if (item && item->file && item->file->fileName() == name) {
|
|
||||||
delete item->file;
|
[[maybe_unused]] int removedFiles = 0; // used under QNETWORKDISKCACHE_DEBUG
|
||||||
item->file = nullptr;
|
for (const CacheItem &cached : cacheItems) {
|
||||||
break;
|
if (cached.path.contains(PREPARED_SLASH)) {
|
||||||
}
|
auto matchesCacheItem = [&cached](QCacheItem *item) {
|
||||||
|
return item && item->file && item->file->fileName() == cached.path;
|
||||||
|
};
|
||||||
|
auto itemIt = std::find_if(d->inserting.cbegin(), d->inserting.cend(), matchesCacheItem);
|
||||||
|
if (itemIt != d->inserting.cend()) {
|
||||||
|
auto &tempfile = (*itemIt)->file;
|
||||||
|
delete tempfile;
|
||||||
|
tempfile = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 size = file.size();
|
QFile::remove(cached.path);
|
||||||
file.remove();
|
|
||||||
totalSize -= size;
|
|
||||||
++removedFiles;
|
++removedFiles;
|
||||||
++i;
|
totalSize -= cached.size;
|
||||||
|
if (totalSize < goal)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#if defined(QNETWORKDISKCACHE_DEBUG)
|
#if defined(QNETWORKDISKCACHE_DEBUG)
|
||||||
if (removedFiles > 0) {
|
if (removedFiles > 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user