diff options
author | Ahmad Samir <a.samirh78@gmail.com> | 2023-01-04 18:31:12 +0200 |
---|---|---|
committer | Ahmad Samir <a.samirh78@gmail.com> | 2023-01-12 21:16:27 +0200 |
commit | 56e42f18180d7d31b4d0b152d2b841ea096e7bb4 (patch) | |
tree | c13ca3ba7f83d7cd3a4cb6ad83167e63a6171e49 /src/network/access | |
parent | 51b1a23aa10d37e937a17dc4d79ae84388e3dceb (diff) |
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>
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qnetworkdiskcache.cpp | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp index 72923543b5..a860d3ce41 100644 --- a/src/network/access/qnetworkdiskcache.cpp +++ b/src/network/access/qnetworkdiskcache.cpp @@ -16,7 +16,6 @@ #include <qurl.h> #include <qcryptographichash.h> #include <qdebug.h> -#include <QMultiMap> #include <memory> @@ -483,47 +482,57 @@ qint64 QNetworkDiskCache::expire() // close file handle to prevent "in use" error when QFile::remove() is called 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); - QMultiMap<QDateTime, QString> cacheItems; + struct CacheItem + { + std::chrono::milliseconds msecs; + QString path; + qint64 size = 0; + }; + std::vector<CacheItem> cacheItems; qint64 totalSize = 0; while (it.hasNext()) { QFileInfo info = it.nextFileInfo(); - QString path = info.filePath(); - QString fileName = info.fileName(); - if (fileName.endsWith(CACHE_POSTFIX)) { - const QDateTime birthTime = info.birthTime(QTimeZone::UTC); - cacheItems.insert(birthTime.isValid() ? birthTime - : info.metadataChangeTime(QTimeZone::UTC), path); - totalSize += info.size(); - } + if (!info.fileName().endsWith(CACHE_POSTFIX)) + continue; + + QDateTime fileTime = info.birthTime(QTimeZone::UTC); + if (!fileTime.isValid()) + fileTime = info.metadataChangeTime(QTimeZone::UTC); + const std::chrono::milliseconds msecs{fileTime.toMSecsSinceEpoch()}; + const qint64 size = info.size(); + cacheItems.push_back(CacheItem{msecs, info.filePath(), size}); + totalSize += size; } + const qint64 goal = (maximumCacheSize() * 9) / 10; + if (totalSize < goal) + return totalSize; // Nothing to do + + auto byFileTime = [&](const auto &a, const auto &b) { return a.msecs < b.msecs; }; + std::sort(cacheItems.begin(), cacheItems.end(), byFileTime); + [[maybe_unused]] int removedFiles = 0; // used under QNETWORKDISKCACHE_DEBUG - qint64 goal = (maximumCacheSize() * 9) / 10; - QMultiMap<QDateTime, QString>::const_iterator i = cacheItems.constBegin(); - while (i != cacheItems.constEnd()) { - if (totalSize < goal) - break; - QString name = i.value(); - QFile file(name); - - if (name.contains(PREPARED_SLASH)) { - for (QCacheItem *item : std::as_const(d->inserting)) { - if (item && item->file && item->file->fileName() == name) { - delete item->file; - item->file = nullptr; - break; - } + for (const CacheItem &cached : cacheItems) { + 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(); - file.remove(); - totalSize -= size; + QFile::remove(cached.path); ++removedFiles; - ++i; + totalSize -= cached.size; + if (totalSize < goal) + break; } #if defined(QNETWORKDISKCACHE_DEBUG) if (removedFiles > 0) { |