[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [nepomuk-core/feature/virtuosoInference] /: New resource visibility handling.
From:       Sebastian Trueg <trueg () kde ! org>
Date:       2012-03-31 19:00:30
Message-ID: 20120331190030.B6835A60A9 () git ! kde ! org
[Download RAW message or body]

Git commit 9476df60687ecb133ebc9dd2f9c893edc1ab097a by Sebastian Trueg.
Committed on 31/03/2012 at 20:46.
Pushed by trueg into branch 'feature/virtuosoInference'.

New resource visibility handling.

Until now the query api would use the nao:userVisible values stored for
each resource to determine if a resource should be returned.
This requires a lot of nao:userVisible value maintenance and makes for
slower queries.
The new solution is much simpler: only types have nao:userVisible values
and the query api simply checks if the result candidate has a type
which is visible.
In contrast to the old one the new solution does not allow to hide a
sub-class of a visible class. But since we never did that anyway and
the resulting queries are faster and it allows us to remove a lot
maintenance code (which eats CPU cycles and disk space) the change is
worth it.

M  +8    -13   libnepomukcore/query/query.cpp
M  +52   -0    services/storage/ontologyloader.cpp
M  +2    -1    services/storage/ontologyloader.h

http://commits.kde.org/nepomuk-core/9476df60687ecb133ebc9dd2f9c893edc1ab097a

diff --git a/libnepomukcore/query/query.cpp b/libnepomukcore/query/query.cpp
index 943705d..6e242f4 100644
--- a/libnepomukcore/query/query.cpp
+++ b/libnepomukcore/query/query.cpp
@@ -1,6 +1,6 @@
 /*
    This file is part of the Nepomuk KDE project.
-   Copyright (C) 2008-2010 Sebastian Trueg <trueg@kde.org>
+   Copyright (C) 2008-2012 Sebastian Trueg <trueg@kde.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -450,22 +450,17 @@ QString Nepomuk::Query::Query::toSparqlQuery( SparqlFlags \
sparqlFlags ) const  QueryBuilderData qbd( d.constData(), sparqlFlags );
 
 
-    // We restrict results to user visible types only. There is no need for this \
with file queries as normally all files are visible.  //
-    // Here we use an optimizations:
-    // The storage service creates "nao:userVisible 1" entries for all visible \
                resources. This contains two optimizations:
-    // - We use an integer instead of a boolean because Virtuoso does not support \
                booleans and, thus, Soprano converts
-    //   booleans into a fake type which is stored as a string. This makes \
                comparision much slower.
-    // - Instead of using crappy inference via "?r a ?t . ?t nao:userVisible true" \
                we can directly check the resources.
-    // - Instead of restricting the visibility to 1 we trick the Virtuoso query \
                optimizer so it won't try to use the visibility
-    //   as priority. We do this with a filter that does not test for equality. \
                Using "?r nao:userVisible 1" has a drastic
-    //   performance impact which the filter has not.
+    // We restrict results to user visible types only. There is no need for this \
with file queries as normally all files are visible. +    // We need the additional \
type pattern to ensure that the variable ?r is actually available to the filter (in \
case there is only +    // UNIONs before.
     //
     QString userVisibilityRestriction;
     if( !(queryFlags()&NoResultRestrictions) && !d->m_isFileQuery ) {
-        userVisibilityRestriction = QString::fromLatin1("?r %1 %2 . FILTER(%2>0) . \
                ")
-                .arg(Soprano::Node::resourceToN3(Soprano::Vocabulary::NAO::userVisible()),
                
-                     qbd.uniqueVarName());
+        userVisibilityRestriction = QString::fromLatin1("?r a %1 . FILTER EXISTS { \
?r a [ %2 %3 ] . } . ") +                                    \
.arg(qbd.uniqueVarName(), +                                         \
Soprano::Node::resourceToN3(Soprano::Vocabulary::NAO::userVisible()), +               \
Soprano::Node::literalToN3(Soprano::LiteralValue(true)));  }
 
 
diff --git a/services/storage/ontologyloader.cpp \
b/services/storage/ontologyloader.cpp index c06a297..a09665b 100644
--- a/services/storage/ontologyloader.cpp
+++ b/services/storage/ontologyloader.cpp
@@ -27,6 +27,7 @@
 #include <Soprano/PluginManager>
 #include <Soprano/StatementIterator>
 #include <Soprano/Parser>
+#include <Soprano/QueryResultIterator>
 
 #include <KConfig>
 #include <KConfigGroup>
@@ -42,14 +43,23 @@
 #include <kpluginfactory.h>
 #include <kpluginloader.h>
 
+#include <Soprano/Vocabulary/RDFS>
+#include <Soprano/Vocabulary/NAO>
+#include <Soprano/Vocabulary/XMLSchema>
 
 using namespace Soprano;
+using namespace Soprano::Vocabulary;
+
+namespace {
+    const char* s_typeVisibilityGraph = "nepomuk:/ctx/typevisibility";
+}
 
 class Nepomuk::OntologyLoader::Private
 {
 public:
     Private( OntologyLoader* p )
         : forceOntologyUpdate( false ),
+          someOntologyUpdated( false ),
           q( p ) {
     }
 
@@ -59,6 +69,9 @@ public:
     bool forceOntologyUpdate;
     QStringList desktopFilesToUpdate;
 
+    // true if at least one ontology has been updated
+    bool someOntologyUpdated;
+
     void updateOntology( const QString& filename );
 
 private:
@@ -110,6 +123,8 @@ void Nepomuk::OntologyLoader::Private::updateOntology( const \
QString& filename )  }
 
     if( update ) {
+        someOntologyUpdated = true;
+
         QString mimeType = df.readEntry( "MimeType", QString() );
 
         const Soprano::Parser* parser
@@ -179,6 +194,7 @@ Nepomuk::OntologyLoader::~OntologyLoader()
 
 void Nepomuk::OntologyLoader::updateLocalOntologies()
 {
+    d->someOntologyUpdated = false;
     d->desktopFilesToUpdate = KGlobal::dirs()->findAllResources( "xdgdata-ontology", \
"*.ontology", KStandardDirs::Recursive|KStandardDirs::NoDuplicates );  \
                if(d->desktopFilesToUpdate.isEmpty())
         kError() << "No ontology files found! Make sure the \
shared-desktop-ontologies project is installed and XDG_DATA_DIRS is set properly."; \
@@ -201,6 +217,16 @@ void Nepomuk::OntologyLoader::updateNextOntology()  else {
         d->forceOntologyUpdate = false;
         d->updateTimer.stop();
+
+        // update graph visibility if something has changed or if we never did it
+        const QUrl visibilityGraph = QUrl::fromEncoded(s_typeVisibilityGraph);
+        if(d->someOntologyUpdated ||
+           !d->model->executeQuery(QString::fromLatin1("ask where { graph %1 { ?s ?p \
?o . } }") +                                   \
.arg(Soprano::Node::resourceToN3(visibilityGraph)), +                                 \
Soprano::Query::QueryLanguageSparql).boolValue()) { +            \
updateTypeVisibility(); +        }
+
         emit ontologyLoadingFinished(this);
     }
 }
@@ -229,6 +255,7 @@ void Nepomuk::OntologyLoader::slotGraphRetrieverResult( KJob* job \
                )
         // TODO: find a way to check if the imported version of the ontology
         // is newer than the already installed one
         if ( d->model->updateOntology( graphRetriever->statements(), \
QUrl()/*graphRetriever->url()*/ ) ) { +            updateTypeVisibility();
             emit ontologyUpdated( QString::fromAscii( \
graphRetriever->url().toEncoded() ) );  }
         else {
@@ -237,4 +264,29 @@ void Nepomuk::OntologyLoader::slotGraphRetrieverResult( KJob* \
job )  }
 }
 
+void Nepomuk::OntologyLoader::updateTypeVisibility()
+{
+    const QUrl visibilityGraph = QUrl::fromEncoded(s_typeVisibilityGraph);
+
+    // 1. remove all visibility values we added ourselves
+    d->model->removeContext(visibilityGraph);
+
+    // 2. make rdfs:Resource non-visible (this is required since with KDE 4.9 we \
introduced a new +    //    way of visibility handling which relies on types alone \
rather than visibility values on +    //    resources. Any visible type will make all \
sub-types visible, too. If rdfs:Resource were +    //    visible everything would be.
+    d->model->removeAllStatements(RDFS::Resource(), NAO::userVisible(), \
Soprano::Node()); +
+    // 3. Set each type visible which is not rdfs:Resource and does not have a \
non-visible parent +    d->model->executeQuery(QString::fromLatin1("insert into %1 { \
" +                                               "?t %2 'true'^^%3 . "
+                                               "} where { "
+                                               "?t a rdfs:Class . "
+                                               "filter not exists { ?tt %2 \
'false'^^%3 .  ?t rdfs:subClassOf ?tt . } }") +                           \
.arg(Soprano::Node::resourceToN3(visibilityGraph), +                                \
Soprano::Node::resourceToN3(NAO::userVisible()), +                                \
Soprano::Node::resourceToN3(XMLSchema::boolean())), +                           \
Soprano::Query::QueryLanguageSparql); +}
+
 #include "ontologyloader.moc"
diff --git a/services/storage/ontologyloader.h b/services/storage/ontologyloader.h
index 4e0ce26..d714249 100644
--- a/services/storage/ontologyloader.h
+++ b/services/storage/ontologyloader.h
@@ -1,5 +1,5 @@
 /* This file is part of the KDE Project
-   Copyright (c) 2007-2010 Sebastian Trueg <trueg@kde.org>
+   Copyright (c) 2007-2012 Sebastian Trueg <trueg@kde.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -91,6 +91,7 @@ namespace Nepomuk {
         // a little async updating
         void updateNextOntology();
         void slotGraphRetrieverResult( KJob* job );
+        void updateTypeVisibility();
 
     private:
         class Private;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic