[gnome-documents] query: select for the document types as a UNION of WHERE clauses



commit 31e4c0d58b280f2b974c5be5bb11f84b16dd1fc5
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Jun 6 00:01:14 2012 -0400

    query: select for the document types as a UNION of WHERE clauses
    
    Instead of applying a FILTER on the RDF type. This avoids a lot of
    string comparisons, and makes queries go generally faster in pretty much
    all situations (I'm measuring a 5-10% speedup).

 src/query.js     |   60 ++++++++++++++++++++++++++++++++++++-----------------
 src/searchbar.js |   39 ++++++++++++++++++++++++++++------
 2 files changed, 73 insertions(+), 26 deletions(-)
---
diff --git a/src/query.js b/src/query.js
index bf1e962..1f4df54 100644
--- a/src/query.js
+++ b/src/query.js
@@ -111,7 +111,7 @@ const QueryBuilder = new Lang.Class({
         return sparql;
     },
 
-    _buildFilterString: function() {
+    _buildFilterString: function(currentType) {
         let sparql = 'FILTER (';
 
         sparql += Global.searchMatchManager.getFilter();
@@ -119,8 +119,11 @@ const QueryBuilder = new Lang.Class({
         sparql += Global.sourceManager.getFilter();
         sparql += ' && ';
         sparql += Global.searchCategoryManager.getFilter();
-        sparql += ' && ';
-        sparql += Global.searchTypeManager.getFilter();
+
+        if (currentType) {
+            sparql += ' && ';
+            sparql += currentType.getFilter();
+        }
 
         sparql += ')';
 
@@ -135,24 +138,46 @@ const QueryBuilder = new Lang.Class({
         return sparql;
     },
 
-    _buildQueryInternal: function(global, flags) {
-        let whereSparql =
-            'WHERE { ?urn a rdfs:Resource ' +
-            this._buildOptional();
+    _buildWhere: function(global, flags) {
+        let whereSparql = 'WHERE { ';
+        let whereParts = [];
+        let searchTypes = [];
 
-        if ((flags & QueryFlags.UNFILTERED) == 0) {
-            if (global)
-                whereSparql +=
-                    Global.searchCategoryManager.getWhere() +
-                    Global.collectionManager.getWhere();
+        if (flags & QueryFlags.UNFILTERED)
+            searchTypes = Global.searchTypeManager.getAllTypes();
+        else
+            searchTypes = Global.searchTypeManager.getCurrentTypes();
 
-            whereSparql += this._buildFilterString();
-        }
+        // build an array of WHERE clauses; each clause maps to one
+        // type of resource we're looking for.
+        searchTypes.forEach(Lang.bind(this,
+            function(currentType) {
+                let part = '{ ' + currentType.getWhere() + this._buildOptional();
+
+                if ((flags & QueryFlags.UNFILTERED) == 0) {
+                    if (global)
+                        part += Global.searchCategoryManager.getWhere() +
+                                Global.collectionManager.getWhere();
 
+                    part += this._buildFilterString(currentType);
+                }
+
+                part += ' }';
+                whereParts.push(part);
+            }));
+
+        // put all the clauses in an UNION
+        whereSparql += whereParts.join(' UNION ');
         whereSparql += ' }';
 
+        return whereSparql;
+    },
+
+    _buildQueryInternal: function(global, flags) {
+        let whereSparql = this._buildWhere(global, flags);
         let tailSparql = '';
 
+        // order results by mtime
         if (global) {
             tailSparql +=
                 'ORDER BY DESC (?mtime)' +
@@ -190,11 +215,8 @@ const QueryBuilder = new Lang.Class({
     },
 
     buildCountQuery: function() {
-        let sparql =
-            'SELECT DISTINCT COUNT(?urn) WHERE { ' +
-            this._buildOptional() +
-            this._buildFilterString() +
-            '}';
+        let sparql = 'SELECT DISTINCT COUNT(?urn) ' +
+            this._buildWhere(true, QueryFlags.NONE);
 
         return new Query(sparql);
     },
diff --git a/src/searchbar.js b/src/searchbar.js
index 1dd3ec5..03b2a2d 100644
--- a/src/searchbar.js
+++ b/src/searchbar.js
@@ -113,11 +113,16 @@ const SearchType = new Lang.Class({
     _init: function(params) {
         this.id = params.id;
         this.name = params.name;
-        this._filter = (params.filter) ? (params.filter) : '';
+        this._filter = (params.filter) ? (params.filter) : '(true)';
+        this._where = (params.where) ? (params.where) : '';
     },
 
     getFilter: function() {
         return this._filter;
+    },
+
+    getWhere: function() {
+        return this._where;
     }
 });
 
@@ -132,22 +137,42 @@ const SearchTypeManager = new Lang.Class({
                                       name: _("All") }));
         this.addItem(new SearchType({ id: 'collections',
                                       name: _("Collections"),
-                                      filter: '((fn:contains(rdf:type(?urn), \"nfo#DataContainer\")) && '
-                                              + '(fn:starts-with(nao:identifier(?urn), \"gd:collection\")))' }));
+                                      filter: 'fn:starts-with(nao:identifier(?urn), \"gd:collection\")',
+                                      where: '?urn rdf:type nfo:DataContainer .' }));
         this.addItem(new SearchType({ id: 'pdf',
                                       name: _("PDF Documents"),
-                                      filter: 'fn:contains(nie:mimeType(?urn), \"application/pdf\")' }));
+                                      where: '?urn nie:mimeType \"application/pdf\" .' }));
         this.addItem(new SearchType({ id: 'presentations',
                                       name: _("Presentations"),
-                                      filter: 'fn:contains(rdf:type(?urn), \"nfo#Presentation\")' }));
+                                      where: '?urn rdf:type nfo:Presentation .' }));
         this.addItem(new SearchType({ id: 'spreadsheets',
                                       name: _("Spreadsheets"),
-                                      filter: 'fn:contains(rdf:type(?urn), \"nfo#Spreadsheet\")'}));
+                                      where: '?urn rdf:type nfo:Spreadsheet .' }));
         this.addItem(new SearchType({ id: 'textdocs',
                                       name: _("Text Documents"),
-                                      filter: 'fn:contains(rdf:type(?urn), \"nfo#PaginatedTextDocument\")' }));
+                                      where: '?urn rdf:type nfo:PaginatedTextDocument .' }));
 
         this.setActiveItemById('all');
+    },
+
+    getCurrentTypes: function() {
+        let activeItem = this.getActiveItem();
+
+        if (activeItem.id == 'all')
+            return this.getAllTypes();
+
+        return [ activeItem ];
+    },
+
+    getAllTypes: function() {
+        let types = [];
+
+        this.forEachItem(function(item) {
+            if (item.id != 'all')
+                types.push(item);
+            });
+
+        return types;
     }
 });
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]