diff --git a/src/file/fileindexerconfig.h b/src/file/fileindexerconfig.h --- a/src/file/fileindexerconfig.h +++ b/src/file/fileindexerconfig.h @@ -27,6 +27,7 @@ #include #include "regexpcache.h" +#include "storagedevices.h" namespace Baloo { @@ -164,6 +165,8 @@ */ uint maxUncomittedFiles(); + StorageDevices* storageDevices(); + public Q_SLOTS: /** * Reread the config from disk and update the configuration cache. diff --git a/src/file/fileindexerconfig.cpp b/src/file/fileindexerconfig.cpp --- a/src/file/fileindexerconfig.cpp +++ b/src/file/fileindexerconfig.cpp @@ -312,18 +312,13 @@ return; } - if (!m_devices) { - m_devices = new StorageDevices(this); - } - KConfigGroup group = m_config.group("General"); QStringList includeFoldersPlain = group.readPathEntry("folders", QStringList() << QDir::homePath()); QStringList excludeFoldersPlain = group.readPathEntry("exclude folders", QStringList()); // Add all removable media and network shares as ignored unless they have // been explicitly added in the include list - const auto allMedia = m_devices->allMedia(); - for (const auto& device: allMedia) { + for (const auto& device: storageDevices()->allMedia()) { const QString mountPath = device.mountPath(); if (!device.isUsable() && !mountPath.isEmpty()) { if (!includeFoldersPlain.contains(mountPath)) { @@ -397,3 +392,11 @@ return m_maxUncomittedFiles; } +StorageDevices* FileIndexerConfig::storageDevices() +{ + if (!m_devices) { + m_devices = new StorageDevices(this); + } + + return m_devices; +} diff --git a/src/file/fileindexscheduler.h b/src/file/fileindexscheduler.h --- a/src/file/fileindexscheduler.h +++ b/src/file/fileindexscheduler.h @@ -45,7 +45,7 @@ public: FileIndexScheduler(Database* db, FileIndexerConfig* config, QObject* parent = nullptr); ~FileIndexScheduler() override; - int state() const { return m_indexerState; } + int state() const { return m_indexerStates.at(0); } Q_SIGNALS: Q_SCRIPTABLE void stateChanged(int state); @@ -78,22 +78,22 @@ void scheduleCheckUnindexedFiles(); void scheduleCheckStaleIndexEntries(); - Q_SCRIPTABLE void suspend() { setSuspend(true); } - Q_SCRIPTABLE void resume() { setSuspend(false); } + Q_SCRIPTABLE void suspend() { suspendContentIndexer(true); } + Q_SCRIPTABLE void resume() { suspendContentIndexer(false); } Q_SCRIPTABLE uint getRemainingTime(); Q_SCRIPTABLE void checkUnindexedFiles(); Q_SCRIPTABLE void checkStaleIndexEntries(); Q_SCRIPTABLE uint getBatchSize(); private Q_SLOTS: - void powerManagementStatusChanged(bool isOnBattery); + void suspendContentIndexer(bool suspend); private: - void setSuspend(bool suspend); - Database* m_db; FileIndexerConfig* m_config; + QList m_indexerStates; + QStringList m_newFiles; QStringList m_modifiedFiles; QStringList m_xattrFiles; @@ -105,11 +105,11 @@ PowerStateMonitor m_powerMonitor; - IndexerState m_indexerState; TimeEstimator m_timeEstimator; bool m_checkUnindexedFiles; bool m_checkStaleIndexEntries; + bool m_schedulerLocked; }; } diff --git a/src/file/fileindexscheduler.cpp b/src/file/fileindexscheduler.cpp --- a/src/file/fileindexscheduler.cpp +++ b/src/file/fileindexscheduler.cpp @@ -42,25 +42,22 @@ : QObject(parent) , m_db(db) , m_config(config) + , m_indexerStates(QList() << Idle) , m_provider(db) , m_contentIndexer(nullptr) - , m_indexerState(Idle) , m_timeEstimator(config, this) , m_checkUnindexedFiles(false) , m_checkStaleIndexEntries(false) + , m_schedulerLocked(false) { Q_ASSERT(db); Q_ASSERT(config); - m_threadPool.setMaxThreadCount(1); - connect(&m_powerMonitor, &PowerStateMonitor::powerManagementStatusChanged, - this, &FileIndexScheduler::powerManagementStatusChanged); + this, &FileIndexScheduler::suspendContentIndexer); m_contentIndexer = new FileContentIndexer(m_config, &m_provider, this); m_contentIndexer->setAutoDelete(false); - connect(m_contentIndexer, &FileContentIndexer::done, this, - &FileIndexScheduler::scheduleIndexing); connect(m_contentIndexer, &FileContentIndexer::newBatchTime, &m_timeEstimator, &TimeEstimator::handleNewBatchTime); @@ -75,83 +72,101 @@ void FileIndexScheduler::scheduleIndexing() { - if (m_threadPool.activeThreadCount() || m_indexerState == Suspended) { + if (m_schedulerLocked) { return; } - if (m_config->isInitialRun()) { + auto runnableStarted = [=] (Baloo::IndexerState state) { + m_indexerStates.prepend(state); + + Q_EMIT stateChanged(m_indexerStates.at(0)); + }; + + auto runnableStopped = [=] (Baloo::IndexerState state) { + m_schedulerLocked = false; + m_indexerStates.removeOne(state); + + Q_EMIT stateChanged(m_indexerStates.at(0)); + scheduleIndexing(); + }; + + if (m_config->isInitialRun() && !m_indexerStates.contains(FirstRun)) { auto runnable = new FirstRunIndexer(m_db, m_config, m_config->includeFolders()); - connect(runnable, &FirstRunIndexer::done, this, &FileIndexScheduler::scheduleIndexing); + connect(runnable, &FirstRunIndexer::done, this, [=] () { + runnableStopped(FirstRun); + }); + m_schedulerLocked = true; m_threadPool.start(runnable); - m_indexerState = FirstRun; - Q_EMIT stateChanged(m_indexerState); - return; + runnableStarted(FirstRun); } - if (!m_newFiles.isEmpty()) { - auto runnable = new NewFileIndexer(m_db, m_config, m_newFiles); - connect(runnable, &NewFileIndexer::done, this, &FileIndexScheduler::scheduleIndexing); + if (m_checkUnindexedFiles && !m_indexerStates.contains(UnindexedFileCheck)) { + auto runnable = new UnindexedFileIndexer(m_db, m_config); + connect(runnable, &UnindexedFileIndexer::done, this, [=] () { + m_checkUnindexedFiles = false; + runnableStopped(UnindexedFileCheck); + }); + m_schedulerLocked = true; m_threadPool.start(runnable); - m_newFiles.clear(); - m_indexerState = NewFiles; - Q_EMIT stateChanged(m_indexerState); - return; + runnableStarted(UnindexedFileCheck); } - if (!m_modifiedFiles.isEmpty()) { - auto runnable = new ModifiedFileIndexer(m_db, m_config, m_modifiedFiles); - connect(runnable, &ModifiedFileIndexer::done, this, &FileIndexScheduler::scheduleIndexing); + if (m_checkStaleIndexEntries && !m_indexerStates.contains(StaleIndexEntriesClean)) { + auto runnable = new IndexCleaner(m_db, m_config); + connect(runnable, &IndexCleaner::done, this, [=] () { + m_checkStaleIndexEntries = false; + runnableStopped(StaleIndexEntriesClean); + }); m_threadPool.start(runnable); - m_modifiedFiles.clear(); - m_indexerState = ModifiedFiles; - Q_EMIT stateChanged(m_indexerState); - return; + runnableStarted(StaleIndexEntriesClean); } - if (!m_xattrFiles.isEmpty()) { - auto runnable = new XAttrIndexer(m_db, m_config, m_xattrFiles); - connect(runnable, &XAttrIndexer::done, this, &FileIndexScheduler::scheduleIndexing); + if (!m_newFiles.isEmpty() && !m_indexerStates.contains(NewFiles)) { + auto runnable = new NewFileIndexer(m_db, m_config, m_newFiles); + connect(runnable, &NewFileIndexer::done, this, [=] () { + m_newFiles.clear(); + runnableStopped(NewFiles); + }); m_threadPool.start(runnable); - m_xattrFiles.clear(); - m_indexerState = XAttrFiles; - Q_EMIT stateChanged(m_indexerState); - return; + runnableStarted(NewFiles); } - if (m_provider.size() && !m_powerMonitor.isOnBattery()) { - m_threadPool.start(m_contentIndexer); - m_indexerState = ContentIndexing; - Q_EMIT stateChanged(m_indexerState); - return; - } + if (!m_xattrFiles.isEmpty() && !m_indexerStates.contains(XAttrFiles)) { + auto runnable = new XAttrIndexer(m_db, m_config, m_xattrFiles); + connect(runnable, &XAttrIndexer::done, this, [=] () { + m_xattrFiles.clear(); + runnableStopped(XAttrFiles); + }); - if (m_checkUnindexedFiles) { - auto runnable = new UnindexedFileIndexer(m_db, m_config); - connect(runnable, &UnindexedFileIndexer::done, this, &FileIndexScheduler::scheduleIndexing); + m_threadPool.start(runnable); + runnableStarted(XAttrFiles); + } + + if (!m_modifiedFiles.isEmpty() && !m_indexerStates.contains(ModifiedFiles)) { + auto runnable = new ModifiedFileIndexer(m_db, m_config, m_modifiedFiles); + connect(runnable, &ModifiedFileIndexer::done, this, [=] () { + m_modifiedFiles.clear(); + runnableStopped(ModifiedFiles); + }); m_threadPool.start(runnable); - m_checkUnindexedFiles = false; - m_indexerState = UnindexedFileCheck; - Q_EMIT stateChanged(m_indexerState); - return; + runnableStarted(ModifiedFiles); } - if (m_checkStaleIndexEntries) { - auto runnable = new IndexCleaner(m_db, m_config); - connect(runnable, &IndexCleaner::done, this, &FileIndexScheduler::scheduleIndexing); + if ((m_provider.size() > 0) + && !m_indexerStates.contains(ContentIndexing) + && !m_indexerStates.contains(Suspended)) { + connect(m_contentIndexer, &FileContentIndexer::done, this, [=] () { + runnableStopped(ContentIndexing); + }); - m_threadPool.start(runnable); - m_checkStaleIndexEntries = false; - m_indexerState = StaleIndexEntriesClean; - Q_EMIT stateChanged(m_indexerState); - return; + m_threadPool.start(m_contentIndexer); + runnableStarted(ContentIndexing); } - m_indexerState = Idle; - Q_EMIT stateChanged(m_indexerState); } static void removeStartsWith(QStringList& list, const QString& dir) @@ -169,48 +184,31 @@ m_newFiles.removeOne(file); m_modifiedFiles.removeOne(file); m_xattrFiles.removeOne(file); - } - else { + } else { removeStartsWith(m_newFiles, file); removeStartsWith(m_modifiedFiles, file); removeStartsWith(m_xattrFiles, file); } } -void FileIndexScheduler::powerManagementStatusChanged(bool isOnBattery) +void FileIndexScheduler::suspendContentIndexer(bool suspend) { - qDebug() << "Power state changed"; - if (isOnBattery && m_indexerState == ContentIndexing) { - qDebug() << "On battery stopping content indexer"; + if (suspend && !m_indexerStates.contains(Suspended)) { + qDebug() << "Suspending content indexing"; + + m_indexerStates.prepend(Suspended); m_contentIndexer->quit(); - //TODO: Maybe we can add a special state for suspended due to being on battery. - m_indexerState = Idle; - Q_EMIT stateChanged(m_indexerState); - } else if (!isOnBattery) { - scheduleIndexing(); - } -} + } else if (m_indexerStates.contains(Suspended)) { + qDebug() << "Resuming content indexing"; -void FileIndexScheduler::setSuspend(bool suspend) -{ - if (suspend) { - qDebug() << "Suspending"; - if (m_indexerState == ContentIndexing) { - m_contentIndexer->quit(); - } - m_indexerState = Suspended; - Q_EMIT stateChanged(m_indexerState); - } else { - qDebug() << "Resuming"; - m_indexerState = Idle; - // No need to emit here we'll be emitting in scheduling + m_indexerStates.removeOne(Suspended); scheduleIndexing(); } } uint FileIndexScheduler::getRemainingTime() { - if (m_indexerState != ContentIndexing) { + if (m_indexerStates.at(0) != ContentIndexing) { return 0; } return m_timeEstimator.calculateTimeLeft(m_provider.size()); diff --git a/src/tools/balooctl/main.cpp b/src/tools/balooctl/main.cpp --- a/src/tools/balooctl/main.cpp +++ b/src/tools/balooctl/main.cpp @@ -80,8 +80,8 @@ parser.addPositionalArgument(QStringLiteral("start"), i18n("Start the file indexer")); parser.addPositionalArgument(QStringLiteral("stop"), i18n("Stop the file indexer")); parser.addPositionalArgument(QStringLiteral("restart"), i18n("Restart the file indexer")); - parser.addPositionalArgument(QStringLiteral("suspend"), i18n("Suspend the file indexer")); - parser.addPositionalArgument(QStringLiteral("resume"), i18n("Resume the file indexer")); + parser.addPositionalArgument(QStringLiteral("suspend"), i18n("Suspend content indexing")); + parser.addPositionalArgument(QStringLiteral("resume"), i18n("Resume content indexing")); parser.addPositionalArgument(QStringLiteral("check"), i18n("Check for any unindexed files and index them")); parser.addPositionalArgument(QStringLiteral("index"), i18n("Index the specified files")); parser.addPositionalArgument(QStringLiteral("clear"), i18n("Forget the specified files"));