X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/7a2885853a424042cb631f83a1db278560679d9e..f6afbbc2401cdd2e722e2ea5d3ad59b960370433:/src/kitemviews/private/kdirectorycontentscounter.cpp diff --git a/src/kitemviews/private/kdirectorycontentscounter.cpp b/src/kitemviews/private/kdirectorycontentscounter.cpp index bd204fe8e..05a6ff447 100644 --- a/src/kitemviews/private/kdirectorycontentscounter.cpp +++ b/src/kitemviews/private/kdirectorycontentscounter.cpp @@ -24,8 +24,14 @@ #include #include +#include #include +namespace { + /// cache of directory counting result + static QHash> *s_cache; +} + KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObject* parent) : QObject(parent), m_model(model), @@ -43,9 +49,12 @@ KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObj m_workerThread->start(); } + if (s_cache == nullptr) { + s_cache = new QHash>(); + } + m_worker = new KDirectoryContentsCounterWorker(); m_worker->moveToThread(m_workerThread); - ++m_workersCount; connect(this, &KDirectoryContentsCounter::requestDirectoryContentsCount, m_worker, &KDirectoryContentsCounterWorker::countDirectoryContents); @@ -58,9 +67,7 @@ KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObj KDirectoryContentsCounter::~KDirectoryContentsCounter() { - --m_workersCount; - - if (m_workersCount > 0) { + if (m_workerThread->isRunning()) { // The worker thread will continue running. It could even be running // a method of m_worker at the moment, so we delete it using // deleteLater() to prevent a crash. @@ -79,49 +86,45 @@ KDirectoryContentsCounter::~KDirectoryContentsCounter() } } -void KDirectoryContentsCounter::addDirectory(const QString& path) +void KDirectoryContentsCounter::scanDirectory(const QString& path) { startWorker(path); } -int KDirectoryContentsCounter::countDirectoryContentsSynchronously(const QString& path) +void KDirectoryContentsCounter::slotResult(const QString& path, int count, long size) { - const QString resolvedPath = QFileInfo(path).canonicalFilePath(); + m_workerIsBusy = false; + + const QFileInfo info = QFileInfo(path); + const QString resolvedPath = info.canonicalFilePath(); if (!m_dirWatcher->contains(resolvedPath)) { m_dirWatcher->addDir(resolvedPath); m_watchedDirs.insert(resolvedPath); } - KDirectoryContentsCounterWorker::Options options; - - if (m_model->showHiddenFiles()) { - options |= KDirectoryContentsCounterWorker::CountHiddenFiles; - } - - if (m_model->showDirectoriesOnly()) { - options |= KDirectoryContentsCounterWorker::CountDirectoriesOnly; + if (!m_priorityQueue.isEmpty()) { + startWorker(m_priorityQueue.takeLast()); + } else if (!m_queue.isEmpty()) { + startWorker(m_queue.takeFirst()); } - return KDirectoryContentsCounterWorker::subItemsCount(path, options); -} - -void KDirectoryContentsCounter::slotResult(const QString& path, int count) -{ - m_workerIsBusy = false; - - const QString resolvedPath = QFileInfo(path).canonicalFilePath(); - - if (!m_dirWatcher->contains(resolvedPath)) { - m_dirWatcher->addDir(resolvedPath); - m_watchedDirs.insert(resolvedPath); + if (s_cache->contains(resolvedPath)) { + const auto pair = s_cache->value(resolvedPath); + if (pair.first == count && pair.second == size) { + // no change no need to send another result event + return; + } } - if (!m_queue.isEmpty()) { - startWorker(m_queue.dequeue()); + if (info.dir().path() == m_model->rootItem().url().path()) { + // update cache or overwrite value + // when path is a direct children of the current model root + s_cache->insert(resolvedPath, QPair(count, size)); } - emit result(path, count); + // sends the results + emit result(resolvedPath, count, size); } void KDirectoryContentsCounter::slotDirWatchDirty(const QString& path) @@ -146,7 +149,7 @@ void KDirectoryContentsCounter::slotItemsRemoved() if (!m_watchedDirs.isEmpty()) { // Don't let KDirWatch watch for removed items if (allItemsRemoved) { - foreach (const QString& path, m_watchedDirs) { + for (const QString& path : qAsConst(m_watchedDirs)) { m_dirWatcher->removeDir(path); } m_watchedDirs.clear(); @@ -166,8 +169,23 @@ void KDirectoryContentsCounter::slotItemsRemoved() void KDirectoryContentsCounter::startWorker(const QString& path) { + const bool alreadyInCache = s_cache->contains(path); + if (alreadyInCache) { + // fast path when in cache + // will be updated later if result has changed + const auto pair = s_cache->value(path); + emit result(path, pair.first, pair.second); + } + if (m_workerIsBusy) { - m_queue.enqueue(path); + if (!m_queue.contains(path) && !m_priorityQueue.contains(path)) { + if (alreadyInCache) { + m_queue.append(path); + } else { + // append to priority queue + m_priorityQueue.append(path); + } + } } else { KDirectoryContentsCounterWorker::Options options; @@ -185,4 +203,3 @@ void KDirectoryContentsCounter::startWorker(const QString& path) } QThread* KDirectoryContentsCounter::m_workerThread = nullptr; -int KDirectoryContentsCounter::m_workersCount = 0;