• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

Nepomuk-Core

  • sources
  • kde-4.12
  • kdelibs
  • nepomuk-core
  • services
  • fileindexer
indexscheduler.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE Project
2  Copyright (c) 2008-2010 Sebastian Trueg <trueg@kde.org>
3  Copyright (c) 2010-2013 Vishesh Handa <handa.vish@gmail.com>
4 
5  Parts of this file are based on code from Strigi
6  Copyright (C) 2006-2007 Jos van den Oever <jos@vandenoever.info>
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Library General Public
10  License version 2 as published by the Free Software Foundation.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include "indexscheduler.h"
24 #include "fileindexerconfig.h"
25 #include "fileindexingqueue.h"
26 #include "basicindexingqueue.h"
27 #include "eventmonitor.h"
28 #include "indexcleaner.h"
29 
30 #include <QtCore/QList>
31 #include <QtCore/QFile>
32 #include <QtCore/QFileInfo>
33 #include <QtCore/QDirIterator>
34 #include <QtCore/QDateTime>
35 #include <QtCore/QByteArray>
36 #include <QtCore/QUrl>
37 
38 #include <KDebug>
39 #include <KUrl>
40 #include <KStandardDirs>
41 #include <KConfigGroup>
42 #include <KLocale>
43 
44 
45 Nepomuk2::IndexScheduler::IndexScheduler( QObject* parent )
46  : QObject( parent )
47  , m_indexing( false )
48  , m_lastBasicIndexingFile( QDateTime::currentDateTime() )
49  , m_basicIndexingFileCount( 0 )
50 {
51  // remove old indexing error log
52  if(FileIndexerConfig::self()->isDebugModeEnabled()) {
53  QFile::remove(KStandardDirs::locateLocal("data", QLatin1String("nepomuk/file-indexer-error-log")));
54  }
55 
56  FileIndexerConfig* indexConfig = FileIndexerConfig::self();
57  connect( indexConfig, SIGNAL(includeFolderListChanged(QStringList,QStringList)),
58  this, SLOT(slotIncludeFolderListChanged(QStringList,QStringList)) );
59  connect( indexConfig, SIGNAL(excludeFolderListChanged(QStringList,QStringList)),
60  this, SLOT(slotExcludeFolderListChanged(QStringList,QStringList)) );
61 
62  // FIXME: What if both the signals are emitted?
63  connect( indexConfig, SIGNAL(fileExcludeFiltersChanged()),
64  this, SLOT(slotConfigFiltersChanged()) );
65  connect( indexConfig, SIGNAL(mimeTypeFiltersChanged()),
66  this, SLOT(slotConfigFiltersChanged()) );
67 
68  // Stop indexing when a device is unmounted
69  RemovableMediaCache* cache = new RemovableMediaCache( this );
70  connect( cache, SIGNAL(deviceTeardownRequested(const Nepomuk2::RemovableMediaCache::Entry*)),
71  this, SLOT(slotTeardownRequested(const Nepomuk2::RemovableMediaCache::Entry*)) );
72 
73  m_basicIQ = new BasicIndexingQueue( this );
74  m_fileIQ = new FileIndexingQueue( this );
75 
76  connect( m_basicIQ, SIGNAL(finishedIndexing()), this, SIGNAL(basicIndexingDone()) );
77  connect( m_fileIQ, SIGNAL(finishedIndexing()), this, SIGNAL(fileIndexingDone()) );
78 
79  connect( m_basicIQ, SIGNAL(beginIndexingFile(QUrl)), this, SLOT(slotBeginIndexingFile(QUrl)) );
80  connect( m_basicIQ, SIGNAL(endIndexingFile(QUrl)), this, SLOT(slotEndIndexingFile(QUrl)) );
81  connect( m_basicIQ, SIGNAL(endIndexingFile(QUrl)), this, SLOT(slotEndBasicIndexingFile()) );
82  connect( m_fileIQ, SIGNAL(beginIndexingFile(QUrl)), this, SLOT(slotBeginIndexingFile(QUrl)) );
83  connect( m_fileIQ, SIGNAL(endIndexingFile(QUrl)), this, SLOT(slotEndIndexingFile(QUrl)) );
84 
85  connect( m_basicIQ, SIGNAL(startedIndexing()), this, SLOT(slotStartedIndexing()) );
86  connect( m_basicIQ, SIGNAL(finishedIndexing()), this, SLOT(slotFinishedIndexing()) );
87  connect( m_fileIQ, SIGNAL(startedIndexing()), this, SLOT(slotStartedIndexing()) );
88  connect( m_fileIQ, SIGNAL(finishedIndexing()), this, SLOT(slotFinishedIndexing()) );
89 
90  // Connect both the queues together
91  connect( m_basicIQ, SIGNAL(endIndexingFile(QUrl)), m_fileIQ, SLOT(enqueue(QUrl)) );
92 
93  // Status String
94  connect( m_basicIQ, SIGNAL(startedIndexing()), this, SLOT(emitStatusStringChanged()) );
95  connect( m_basicIQ, SIGNAL(finishedIndexing()), this, SLOT(emitStatusStringChanged()) );
96  connect( m_fileIQ, SIGNAL(startedIndexing()), this, SLOT(emitStatusStringChanged()) );
97  connect( m_fileIQ, SIGNAL(finishedIndexing()), this, SLOT(emitStatusStringChanged()) );
98  connect( this, SIGNAL(indexingSuspended(bool)), this, SLOT(emitStatusStringChanged()) );
99 
100  m_eventMonitor = new EventMonitor( this );
101  connect( m_eventMonitor, SIGNAL(diskSpaceStatusChanged(bool)),
102  this, SLOT(slotScheduleIndexing()) );
103  connect( m_eventMonitor, SIGNAL(idleStatusChanged(bool)),
104  this, SLOT(slotScheduleIndexing()) );
105  connect( m_eventMonitor, SIGNAL(powerManagementStatusChanged(bool)),
106  this, SLOT(slotScheduleIndexing()) );
107 
108  m_cleaner = new IndexCleaner(this);
109  connect( m_cleaner, SIGNAL(finished(KJob*)), this, SLOT(slotCleaningDone()) );
110 
111  m_state = State_Normal;
112  slotScheduleIndexing();
113 }
114 
115 
116 Nepomuk2::IndexScheduler::~IndexScheduler()
117 {
118 }
119 
120 
121 void Nepomuk2::IndexScheduler::suspend()
122 {
123  if ( m_state != State_Suspended ) {
124  m_state = State_Suspended;
125  slotScheduleIndexing();
126 
127  m_eventMonitor->disable();
128  emit indexingSuspended( true );
129  }
130 }
131 
132 
133 void Nepomuk2::IndexScheduler::resume()
134 {
135  if( m_state == State_Suspended ) {
136  m_state = State_Normal;
137  slotScheduleIndexing();
138 
139  m_eventMonitor->enable();
140  emit indexingSuspended( false );
141  }
142 }
143 
144 
145 void Nepomuk2::IndexScheduler::setSuspended( bool suspended )
146 {
147  if ( suspended )
148  suspend();
149  else
150  resume();
151 }
152 
153 bool Nepomuk2::IndexScheduler::isSuspended() const
154 {
155  return m_state == State_Suspended;
156 }
157 
158 bool Nepomuk2::IndexScheduler::isCleaning() const
159 {
160  return m_state == State_Cleaning;
161 }
162 
163 bool Nepomuk2::IndexScheduler::isIndexing() const
164 {
165  return m_indexing;
166 }
167 
168 QUrl Nepomuk2::IndexScheduler::currentUrl() const
169 {
170  if( !m_fileIQ->currentUrl().isEmpty() )
171  return m_fileIQ->currentUrl();
172  else
173  return m_basicIQ->currentUrl();
174 }
175 
176 Nepomuk2::UpdateDirFlags Nepomuk2::IndexScheduler::currentFlags() const
177 {
178  return m_basicIQ->currentFlags();
179 }
180 
181 
182 void Nepomuk2::IndexScheduler::setIndexingStarted( bool started )
183 {
184  if ( started != m_indexing ) {
185  m_indexing = started;
186  emit indexingStateChanged( m_indexing );
187  if ( m_indexing )
188  emit indexingStarted();
189  else
190  emit indexingStopped();
191  }
192 }
193 
194 void Nepomuk2::IndexScheduler::slotStartedIndexing()
195 {
196  m_eventMonitor->enable();
197 }
198 
199 void Nepomuk2::IndexScheduler::slotFinishedIndexing()
200 {
201  m_eventMonitor->suspendDiskSpaceMonitor();
202 }
203 
204 void Nepomuk2::IndexScheduler::slotCleaningDone()
205 {
206  m_cleaner = 0;
207 
208  m_state = State_Normal;
209  slotScheduleIndexing();
210 }
211 
212 void Nepomuk2::IndexScheduler::updateDir( const QString& path, UpdateDirFlags flags )
213 {
214  m_basicIQ->enqueue( path, flags );
215 }
216 
217 
218 void Nepomuk2::IndexScheduler::updateAll( bool forceUpdate )
219 {
220  queueAllFoldersForUpdate( forceUpdate );
221 }
222 
223 
224 void Nepomuk2::IndexScheduler::queueAllFoldersForUpdate( bool forceUpdate )
225 {
226  m_basicIQ->clear();
227 
228  UpdateDirFlags flags = UpdateRecursive|AutoUpdateFolder;
229  if ( forceUpdate )
230  flags |= ForceUpdate;
231 
232  // update everything again in case the folders changed
233  foreach( const QString& f, FileIndexerConfig::self()->includeFolders() ) {
234  m_basicIQ->enqueue( f, flags );
235  }
236 }
237 
238 
239 void Nepomuk2::IndexScheduler::slotIncludeFolderListChanged(const QStringList& added, const QStringList& removed)
240 {
241  kDebug() << added << removed;
242  foreach( const QString& path, removed ) {
243  m_basicIQ->clear( path );
244  m_fileIQ->clear( path );
245  }
246 
247  restartCleaner();
248 
249  foreach( const QString& path, added ) {
250  m_basicIQ->enqueue( path, UpdateRecursive );
251  }
252 }
253 
254 void Nepomuk2::IndexScheduler::slotExcludeFolderListChanged(const QStringList& added, const QStringList& removed)
255 {
256  kDebug() << added << removed;
257  foreach( const QString& path, added ) {
258  m_basicIQ->clear( path );
259  m_fileIQ->clear( path );
260  }
261 
262  restartCleaner();
263 
264  foreach( const QString& path, removed ) {
265  m_basicIQ->enqueue( path, UpdateRecursive );
266  }
267 }
268 
269 void Nepomuk2::IndexScheduler::restartCleaner()
270 {
271  if( m_cleaner ) {
272  m_cleaner->kill();
273  delete m_cleaner;
274  }
275 
276  // TODO: only clean the filters that were changed from the config
277  m_cleaner = new IndexCleaner( this );
278  connect( m_cleaner, SIGNAL(finished(KJob*)), this, SLOT(slotCleaningDone()) );
279 
280  m_state = State_Normal;
281  slotScheduleIndexing();
282 }
283 
284 
285 void Nepomuk2::IndexScheduler::slotConfigFiltersChanged()
286 {
287  restartCleaner();
288 
289  // We need to this - there is no way to avoid it
290  m_basicIQ->clear();
291  m_fileIQ->clear();
292 
293  queueAllFoldersForUpdate();
294 }
295 
296 
297 void Nepomuk2::IndexScheduler::analyzeFile( const QString& path )
298 {
299  m_basicIQ->enqueue( path );
300 }
301 
302 
303 void Nepomuk2::IndexScheduler::slotBeginIndexingFile(const QUrl&)
304 {
305  setIndexingStarted( true );
306 }
307 
308 void Nepomuk2::IndexScheduler::slotEndIndexingFile(const QUrl&)
309 {
310  const QUrl basicUrl = m_basicIQ->currentUrl();
311  const QUrl fileUrl = m_fileIQ->currentUrl();
312 
313  if( basicUrl.isEmpty() && fileUrl.isEmpty() ) {
314  setIndexingStarted( false );
315  }
316 }
317 
318 //
319 // Slow down the Basic Indexing if we have > x files
320 //
321 void Nepomuk2::IndexScheduler::slotEndBasicIndexingFile()
322 {
323  QDateTime current = QDateTime::currentDateTime();
324  if( current.secsTo(m_lastBasicIndexingFile) > 60 ) {
325  m_basicIQ->setDelay( 0 );
326  m_basicIndexingFileCount = 0;
327  }
328  else {
329  if ( m_basicIndexingFileCount > 1000 ) {
330  m_basicIQ->setDelay( 400 );
331  }
332  else if ( m_basicIndexingFileCount > 750 ) {
333  m_basicIQ->setDelay( 300 );
334  }
335  else if ( m_basicIndexingFileCount > 500 ) {
336  m_basicIQ->setDelay( 200 );
337  }
338  else if ( m_basicIndexingFileCount > 200 ) {
339  m_basicIQ->setDelay( 100 );
340  }
341  else
342  m_basicIQ->setDelay( 0 );
343  }
344 
345  m_basicIndexingFileCount++;
346 }
347 
348 
349 void Nepomuk2::IndexScheduler::slotTeardownRequested(const Nepomuk2::RemovableMediaCache::Entry* entry)
350 {
351  const QString path = entry->mountPath();
352 
353  m_basicIQ->clear( path );
354  m_fileIQ->clear( path );
355 }
356 
357 void Nepomuk2::IndexScheduler::slotScheduleIndexing()
358 {
359  if( m_state == State_Suspended ) {
360  kDebug() << "Suspended";
361  m_basicIQ->suspend();
362  m_fileIQ->suspend();
363  if( m_cleaner )
364  m_cleaner->suspend();
365  }
366 
367  else if( m_state == State_Cleaning ) {
368  kDebug() << "Cleaning";
369  m_basicIQ->suspend();
370  m_fileIQ->suspend();
371  if( m_cleaner )
372  m_cleaner->resume();
373  }
374 
375  else if( m_eventMonitor->isDiskSpaceLow() ) {
376  kDebug() << "Disk Space";
377  m_state = State_LowDiskSpace;
378 
379  m_basicIQ->suspend();
380  m_fileIQ->suspend();
381  }
382 
383  else if( m_eventMonitor->isOnBattery() ) {
384  kDebug() << "Battery";
385  m_state = State_OnBattery;
386 
387  m_basicIQ->setDelay(0);
388  m_basicIQ->resume();
389 
390  m_fileIQ->suspend();
391  if( m_cleaner )
392  m_cleaner->suspend();
393  }
394 
395  else if( m_eventMonitor->isIdle() ) {
396  kDebug() << "Idle";
397  if( m_cleaner ) {
398  m_state = State_Cleaning;
399  m_cleaner->start();
400  slotScheduleIndexing();
401  }
402  else {
403  m_state = State_UserIdle;
404  m_basicIQ->setDelay( 0 );
405  m_basicIQ->resume();
406 
407  m_fileIQ->setDelay( 0 );
408  m_fileIQ->resume();
409  }
410  }
411 
412  else {
413  kDebug() << "Normal";
414  m_state = State_Normal;
415 
416  m_basicIQ->setDelay( 0 );
417  m_basicIQ->resume();
418 
419  m_fileIQ->setDelay( 3000 );
420  m_fileIQ->resume();
421  }
422 }
423 
424 QString Nepomuk2::IndexScheduler::userStatusString() const
425 {
426  bool indexing = isIndexing();
427  bool suspended = isSuspended();
428  bool cleaning = isCleaning();
429  bool processing = !m_basicIQ->isEmpty();
430 
431  if ( suspended ) {
432  return i18nc( "@info:status", "File indexer is suspended." );
433  }
434  else if ( cleaning ) {
435  return i18nc( "@info:status", "Cleaning invalid file metadata");
436  }
437  else if ( indexing ) {
438  return i18nc( "@info:status", "Indexing files for desktop search." );
439  }
440  else if ( processing ) {
441  return i18nc( "@info:status", "Scanning for recent changes in files for desktop search");
442  }
443  else {
444  return i18nc( "@info:status", "File indexer is idle." );
445  }
446 }
447 
448 Nepomuk2::IndexScheduler::State Nepomuk2::IndexScheduler::currentStatus() const
449 {
450  return m_state;
451 }
452 
453 void Nepomuk2::IndexScheduler::emitStatusStringChanged()
454 {
455  QString status = userStatusString();
456  if( status != m_oldStatus ) {
457  emit statusStringChanged();
458  m_oldStatus = status;
459  }
460 }
461 
462 
463 
464 #include "indexscheduler.moc"
fileindexerconfig.h
Nepomuk2::IndexScheduler::fileIndexingDone
void fileIndexingDone()
Nepomuk2::ForceUpdate
The files in the folder should be updated regardless of their state.
Definition: basicindexingqueue.h:51
Nepomuk2::IndexScheduler::suspend
void suspend()
Definition: indexscheduler.cpp:121
fileindexingqueue.h
Nepomuk2::IndexScheduler::setSuspended
void setSuspended(bool)
Definition: indexscheduler.cpp:145
Nepomuk2::FileIndexingQueue
Definition: fileindexingqueue.h:31
indexscheduler.h
Nepomuk2::RemovableMediaCache::Entry::mountPath
QString mountPath() const
Definition: removablemediacache.cpp:322
Nepomuk2::IndexScheduler::currentFlags
UpdateDirFlags currentFlags() const
The UpdateDirFlags of the the current url that is being indexed.
Definition: indexscheduler.cpp:176
indexcleaner.h
Nepomuk2::FileIndexerConfig
Active config class which emits signals if the config was changed, for example if the KCM saved the c...
Definition: fileindexerconfig.h:38
QObject
Nepomuk2::RemovableMediaCache
The removable media cache provides access to all removable media that are supported by Nepomuk...
Definition: removablemediacache.h:45
Nepomuk2::IndexScheduler::basicIndexingDone
void basicIndexingDone()
basicindexingqueue.h
Nepomuk2::IndexScheduler::indexingSuspended
void indexingSuspended(bool suspended)
Nepomuk2::IndexScheduler::updateDir
void updateDir(const QString &path, UpdateDirFlags flags=NoUpdateFlags)
Slot to connect to certain event systems like KDirNotify or KDirWatch.
Definition: indexscheduler.cpp:212
eventmonitor.h
Nepomuk2::RemovableMediaCache::Entry
Definition: removablemediacache.h:53
Nepomuk2::IndexScheduler::~IndexScheduler
~IndexScheduler()
Definition: indexscheduler.cpp:116
Nepomuk2::BasicIndexingQueue
This class represents a simple queue that iterates over the file system tree and indexes each file wh...
Definition: basicindexingqueue.h:60
Nepomuk2::IndexScheduler::updateAll
void updateAll(bool forceUpdate=false)
Updates all configured folders.
Definition: indexscheduler.cpp:218
Nepomuk2::IndexScheduler::State_Normal
Definition: indexscheduler.h:53
Nepomuk2::UpdateRecursive
The folder should be updated recursive.
Definition: basicindexingqueue.h:39
Nepomuk2::IndexScheduler::resume
void resume()
Definition: indexscheduler.cpp:133
Nepomuk2::IndexScheduler::isIndexing
bool isIndexing() const
Definition: indexscheduler.cpp:163
Nepomuk2::IndexScheduler::currentUrl
QUrl currentUrl() const
The current uri being indexed.
Definition: indexscheduler.cpp:168
Nepomuk2::IndexScheduler::userStatusString
QString userStatusString() const
A user readable description of the scheduler's status.
Definition: indexscheduler.cpp:424
Nepomuk2::EventMonitor
Definition: eventmonitor.h:32
Nepomuk2::AutoUpdateFolder
The folder has been scheduled to update by the update system, not by a call to updateDir.
Definition: basicindexingqueue.h:45
Nepomuk2::IndexScheduler::State
State
Represents the current state of the indexer.
Definition: indexscheduler.h:52
Nepomuk2::IndexScheduler::isSuspended
bool isSuspended() const
Definition: indexscheduler.cpp:153
Nepomuk2::IndexScheduler::currentStatus
State currentStatus() const
Returns the internal stateof the indexer as enum.
Definition: indexscheduler.cpp:448
Nepomuk2::IndexScheduler::IndexScheduler
IndexScheduler(QObject *parent=0)
Definition: indexscheduler.cpp:45
Nepomuk2::IndexScheduler::isCleaning
bool isCleaning() const
Definition: indexscheduler.cpp:158
Nepomuk2::FileIndexerConfig::self
static FileIndexerConfig * self()
Get the first created instance of FileIndexerConfig.
Definition: fileindexerconfig.cpp:82
Nepomuk2::IndexCleaner
Definition: indexcleaner.h:35
KJob
Nepomuk2::IndexScheduler::analyzeFile
void analyzeFile(const QString &path)
Analyze the one file without conditions.
Definition: indexscheduler.cpp:297
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:08 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Nepomuk-Core

Skip menu "Nepomuk-Core"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal