7#include "fileindexscheduler.h"
10#include "firstrunindexer.h"
11#include "newfileindexer.h"
12#include "modifiedfileindexer.h"
13#include "xattrindexer.h"
14#include "filecontentindexer.h"
15#include "unindexedfileindexer.h"
16#include "indexcleaner.h"
18#include "fileindexerconfig.h"
22#include <QDBusConnection>
31 , m_contentIndexer(nullptr)
32 , m_indexerState(Startup)
33 , m_checkUnindexedFiles(false)
34 , m_checkStaleIndexEntries(false)
35 , m_isGoingIdle(false)
36 , m_isSuspended(false)
37 , m_isFirstRun(firstRun)
43 m_threadPool.setMaxThreadCount(1);
45 connect(&m_powerMonitor, &PowerStateMonitor::powerManagementStatusChanged,
46 this, &FileIndexScheduler::powerManagementStatusChanged);
48 if (m_powerMonitor.isOnBattery()) {
49 m_indexerState = LowPowerIdle;
52 m_contentIndexer =
new FileContentIndexer(m_config->maxUncomittedFiles(), &m_provider, m_indexFinishedFiles,
this);
53 m_contentIndexer->setAutoDelete(
false);
54 connect(m_contentIndexer, &FileContentIndexer::done,
this,
55 &FileIndexScheduler::runnerFinished);
56 connect(m_contentIndexer, &FileContentIndexer::committedBatch, [
this](uint time, uint batchSize) {
57 this->m_timeEstimator.handleNewBatchTime(time, batchSize);
64FileIndexScheduler::~FileIndexScheduler()
66 m_contentIndexer->quit();
70void FileIndexScheduler::startupFinished() {
75void FileIndexScheduler::scheduleIndexing()
77 if (!isIndexerIdle()) {
80 m_isGoingIdle =
false;
83 if (m_indexerState != Suspended) {
84 m_indexerState = Suspended;
85 Q_EMIT stateChanged(m_indexerState);
96 auto runnable =
new FirstRunIndexer(m_db, m_config, m_config->
includeFolders());
97 connect(runnable, &FirstRunIndexer::done,
this, &FileIndexScheduler::runnerFinished);
99 m_threadPool.
start(runnable);
100 m_indexerState = FirstRun;
101 Q_EMIT stateChanged(m_indexerState);
107 connect(runnable, &NewFileIndexer::done,
this, &FileIndexScheduler::runnerFinished);
109 m_threadPool.
start(runnable);
111 m_indexerState = NewFiles;
112 Q_EMIT stateChanged(m_indexerState);
116 if (!m_modifiedFiles.
isEmpty()) {
117 auto runnable =
new ModifiedFileIndexer(m_db, m_config, m_modifiedFiles);
118 connect(runnable, &ModifiedFileIndexer::done,
this, &FileIndexScheduler::runnerFinished);
120 m_threadPool.
start(runnable);
121 m_modifiedFiles.
clear();
122 m_indexerState = ModifiedFiles;
123 Q_EMIT stateChanged(m_indexerState);
128 auto runnable =
new XAttrIndexer(m_db, m_config, m_xattrFiles);
129 connect(runnable, &XAttrIndexer::done,
this, &FileIndexScheduler::runnerFinished);
131 m_threadPool.
start(runnable);
132 m_xattrFiles.
clear();
133 m_indexerState = XAttrFiles;
134 Q_EMIT stateChanged(m_indexerState);
139 if (m_powerMonitor.isOnBattery()) {
140 if (m_indexerState != LowPowerIdle) {
141 m_indexerState = LowPowerIdle;
142 Q_EMIT stateChanged(m_indexerState);
148 if (m_indexerState != Startup) {
149 m_indexerState = Startup;
150 Q_EMIT stateChanged(m_indexerState);
157 if (m_checkStaleIndexEntries) {
158 auto runnable =
new IndexCleaner(m_db, m_config);
159 connect(runnable, &IndexCleaner::done,
this, &FileIndexScheduler::runnerFinished);
161 m_threadPool.
start(runnable);
162 m_checkStaleIndexEntries =
false;
163 m_indexerState = StaleIndexEntriesClean;
164 Q_EMIT stateChanged(m_indexerState);
168 m_indexPendingFiles = m_provider.size();
169 m_indexFinishedFiles = 0;
170 if (m_indexPendingFiles) {
171 m_threadPool.
start(m_contentIndexer);
172 m_indexerState = ContentIndexing;
173 Q_EMIT stateChanged(m_indexerState);
177 if (m_checkUnindexedFiles) {
178 auto runnable =
new UnindexedFileIndexer(m_db, m_config);
179 connect(runnable, &UnindexedFileIndexer::done,
this, &FileIndexScheduler::runnerFinished);
181 m_threadPool.
start(runnable);
182 m_checkUnindexedFiles =
false;
183 m_indexerState = UnindexedFileCheck;
184 Q_EMIT stateChanged(m_indexerState);
188 if (m_indexerState != Idle) {
189 m_indexerState = Idle;
190 Q_EMIT stateChanged(m_indexerState);
198 return file.startsWith(dir);
206 [config](
const QString& file) {
207 return !config->shouldBeIndexed(file);
212void FileIndexScheduler::updateConfig()
216 if (m_indexerState == ContentIndexing) {
217 m_contentIndexer->quit();
219 removeShouldNotIndex(m_newFiles, m_config);
220 removeShouldNotIndex(m_modifiedFiles, m_config);
221 removeShouldNotIndex(m_xattrFiles, m_config);
222 m_checkStaleIndexEntries =
true;
223 m_checkUnindexedFiles =
true;
227void FileIndexScheduler::handleFileRemoved(
const QString& file)
235 removeStartsWith(m_newFiles, file);
236 removeStartsWith(m_modifiedFiles, file);
237 removeStartsWith(m_xattrFiles, file);
241void FileIndexScheduler::powerManagementStatusChanged(
bool isOnBattery)
243 qCDebug(BALOO) <<
"Power state changed - onBattery:" << isOnBattery;
244 if (isOnBattery && m_indexerState == ContentIndexing) {
245 qCDebug(BALOO) <<
"On battery, stopping content indexer";
246 m_contentIndexer->quit();
252void FileIndexScheduler::setSuspend(
bool suspend)
256 qCDebug(BALOO) <<
"Suspending";
257 if (m_indexerState == ContentIndexing) {
258 m_contentIndexer->quit();
263 qCDebug(BALOO) <<
"Resuming";
269uint FileIndexScheduler::getRemainingTime()
271 if (m_indexerState != ContentIndexing) {
274 uint remainingFiles = m_indexPendingFiles - m_indexFinishedFiles;
275 return m_timeEstimator.calculateTimeLeft(remainingFiles);
278void FileIndexScheduler::scheduleCheckUnindexedFiles()
280 m_checkUnindexedFiles =
true;
283void FileIndexScheduler::checkUnindexedFiles()
285 m_checkUnindexedFiles =
true;
289void FileIndexScheduler::scheduleCheckStaleIndexEntries()
291 m_checkStaleIndexEntries =
true;
294void FileIndexScheduler::checkStaleIndexEntries()
296 m_checkStaleIndexEntries =
true;
300uint FileIndexScheduler::getBatchSize()
305#include "moc_fileindexscheduler.cpp"
Active config class which emits signals if the config was changed, for example if the KCM saved the c...
uint maxUncomittedFiles() const
Returns batch size.
QStringList includeFolders() const
Folders to search for files to index and analyze.
Does not check the folder path or the mtime of the file.
Implements storage for docIds without any associated data Instantiated for:
KIOCORE_EXPORT QStringList list(const QString &fileClass)
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
QDBusConnection sessionBus()
iterator erase(const_iterator begin, const_iterator end)
bool isEmpty() const const
bool removeOne(const AT &t)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void start(Callable &&callableToRun, int priority)
bool waitForDone(int msecs)