summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVishesh Handa <me@vhanda.in>2012-08-27 19:45:00 (GMT)
committerVishesh Handa <me@vhanda.in>2012-08-29 12:32:24 (GMT)
commitead226c9571a15da8d7a92810f5c4afd35bf9de8 (patch)
treed16473120b7868fbd08c662c93d2b9ea1efe6e79
parent68dde513c437a218143fc8cd319b4897a64b8c20 (diff)
QueryService: Use heuristics to determine when to re-run the query
Instead of running all the queries any time ANY data in the database changes. REVIEW: 106238
-rw-r--r--services/queryservice/folder.cpp76
1 files changed, 70 insertions, 6 deletions
diff --git a/services/queryservice/folder.cpp b/services/queryservice/folder.cpp
index e95be8d..b7125cb 100644
--- a/services/queryservice/folder.cpp
+++ b/services/queryservice/folder.cpp
@@ -25,6 +25,14 @@
#include "resource.h"
#include "resourcemanager.h"
+#include "andterm.h"
+#include "orterm.h"
+#include "resourcetypeterm.h"
+#include "optionalterm.h"
+#include "comparisonterm.h"
+#include "negationterm.h"
+#include "resourcewatcher.h"
+
#include <Soprano/Model>
#include <KDebug>
@@ -58,6 +66,51 @@ Nepomuk2::Query::Folder::Folder( const QString& query, const RequestPropertyMap&
init();
}
+namespace {
+ using namespace Nepomuk2::Query;
+ using namespace Nepomuk2;
+
+ void initWatcherForGroupTerms(ResourceWatcher* watcher, const GroupTerm& groupTerm, bool& emptyProperty);
+
+ void initWatcherForTerm(ResourceWatcher* watcher, const Term& term, bool &emptyProperty ) {
+ if( term.isAndTerm() )
+ initWatcherForGroupTerms( watcher, term.toAndTerm(), emptyProperty );
+ else if( term.isOrTerm() )
+ initWatcherForGroupTerms( watcher, term.toOrTerm(), emptyProperty );
+ else if( term.isOptionalTerm() )
+ initWatcherForTerm( watcher, term.toOptionalTerm().subTerm(), emptyProperty );
+ else if( term.isNegationTerm() )
+ initWatcherForTerm( watcher, term.toNegationTerm().subTerm(), emptyProperty );
+ else if( term.isResourceTypeTerm() )
+ watcher->addType( term.toResourceTypeTerm().type() );
+ else if( term.isComparisonTerm() ) {
+ const QUrl prop = term.toComparisonTerm().property().uri();
+ if( prop.isEmpty() ) {
+ emptyProperty = true;
+ }
+ else {
+ watcher->addProperty( term.toComparisonTerm().property().uri() );
+ }
+ }
+ }
+
+ void initWatcherForGroupTerms(ResourceWatcher* watcher, const GroupTerm& groupTerm, bool &emptyProperty) {
+ QList<Term> terms = groupTerm.subTerms();
+ foreach(const Term& term, terms) {
+ initWatcherForTerm( watcher, term, emptyProperty );
+ }
+ }
+
+ void intiWatcherForQuery(ResourceWatcher* watcher, const Query::Query& query) {
+ // The empty property is for comparison terms which do not have a property
+ // in that case we want to monitor all properties
+ bool emptyProperty = false;
+ initWatcherForTerm( watcher, query.term(), emptyProperty );
+ if( emptyProperty )
+ watcher->setProperties( QList<Types::Property>() );
+ }
+}
+
void Nepomuk2::Query::Folder::init()
{
@@ -68,12 +121,23 @@ void Nepomuk2::Query::Folder::init()
m_updateTimer.setSingleShot( true );
m_updateTimer.setInterval( 2000 );
- // use the special signal from the ResourceWatcher which is not exposed in the public API (yet)
- QDBusConnection::sessionBus().connect(QLatin1String("org.kde.NepomukStorage"),
- QLatin1String("/resourcewatcher"),
- QLatin1String("org.kde.nepomuk.ResourceWatcher"),
- QLatin1String("somethingChanged"),
- this, SLOT( slotStorageChanged() ) );
+ ResourceWatcher* watcher = new ResourceWatcher( this );
+ intiWatcherForQuery( watcher, m_query );
+
+ connect( watcher, SIGNAL(propertyAdded(Nepomuk2::Resource,Nepomuk2::Types::Property,QVariant)),
+ this, SLOT(slotStorageChanged()) );
+ connect( watcher, SIGNAL(propertyRemoved(Nepomuk2::Resource,Nepomuk2::Types::Property,QVariant)),
+ this, SLOT(slotStorageChanged()) );
+ connect( watcher, SIGNAL(resourceCreated(Nepomuk2::Resource,QList<QUrl>)),
+ this, SLOT(slotStorageChanged()) );
+ connect( watcher, SIGNAL(resourceRemoved(QUrl,QList<QUrl>)),
+ this, SLOT(slotStorageChanged()) );
+ connect( watcher, SIGNAL(resourceTypeAdded(Nepomuk2::Resource,Nepomuk2::Types::Class)),
+ this, SLOT(slotStorageChanged()) );
+ connect( watcher, SIGNAL(resourceTypeRemoved(Nepomuk2::Resource,Nepomuk2::Types::Class)),
+ this, SLOT(slotStorageChanged()) );
+ watcher->start();
+
connect( &m_updateTimer, SIGNAL( timeout() ),
this, SLOT( slotUpdateTimeout() ) );
}