Bug 707946 - Improve performances of hasChildren for tag queries.
authorMarco Bonardo <mbonardo@mozilla.com>
Wed, 07 Dec 2011 21:56:26 +0100
changeset 82205 1b51ee2ee38818c0f1eaaea44d0c7acd2fac33ff
parent 82204 a3d66acea00353ae7a9bf88bb4315382aa8d56ab
child 82206 8db3e759e1f3a38e965c91b369301f7635743a0c
push id21587
push userbmo@edmorley.co.uk
push dateThu, 08 Dec 2011 15:13:43 +0000
treeherdermozilla-central@98db2311a44c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs707946
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 707946 - Improve performances of hasChildren for tag queries. r=dietrich sr=gavin
toolkit/components/build/nsToolkitCompsCID.h
toolkit/components/places/nsITaggingService.idl
toolkit/components/places/nsNavHistoryResult.cpp
toolkit/components/places/nsTaggingService.js
--- a/toolkit/components/build/nsToolkitCompsCID.h
+++ b/toolkit/components/build/nsToolkitCompsCID.h
@@ -105,16 +105,19 @@
   "@mozilla.org/browser/annotation-service;1"
 
 #define NS_NAVBOOKMARKSSERVICE_CONTRACTID \
   "@mozilla.org/browser/nav-bookmarks-service;1"
 
 #define NS_LIVEMARKSERVICE_CONTRACTID \
   "@mozilla.org/browser/livemark-service;2"
 
+#define NS_TAGGINGSERVICE_CONTRACTID \
+"@mozilla.org/browser/tagging-service;1"
+
 #define NS_FAVICONSERVICE_CONTRACTID \
   "@mozilla.org/browser/favicon-service;1"
 
 #define NS_PLACESIMPORTEXPORTSERVICE_CONTRACTID \
   "@mozilla.org/browser/places/import-export-service;1"
 
 #define NS_APPSTARTUP_CONTRACTID \
   "@mozilla.org/toolkit/app-startup;1"
--- a/toolkit/components/places/nsITaggingService.idl
+++ b/toolkit/components/places/nsITaggingService.idl
@@ -36,17 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 
 interface nsIURI;
 interface nsIVariant;
 
-[scriptable, uuid(e39cea60-7e6d-4c8b-80a3-997af1c2cbcb)]
+[scriptable, uuid(f816b4df-f733-4dbd-964d-8bfc92a475b2)]
 interface nsITaggingService : nsISupports
 {
   /**
    * Tags a URL with the given set of tags. Current tags set for the URL
    * persist. Tags in aTags which are already set for the given URL are
    * ignored.
    *
    * @param aURI
@@ -90,15 +90,22 @@ interface nsITaggingService : nsISupport
   void getTagsForURI(in nsIURI aURI,
                      [optional] out unsigned long length,
                      [retval, array, size_is(length)] out wstring aTags);
 
   /**
    * Retrieves all tags used to tag URIs in the data-base (sorted by name).
    */
   readonly attribute nsIVariant allTags;
+
+  /**
+   * Whether any tags exist.
+   *
+   * @note This is faster than allTags.length, since doesn't need to sort tags.
+   */
+  readonly attribute boolean hasTags;
 };
 
 %{C++
 
 #define TAGGING_SERVICE_CID "@mozilla.org/browser/tagging-service;1"
 
 %}
--- a/toolkit/components/places/nsNavHistoryResult.cpp
+++ b/toolkit/components/places/nsNavHistoryResult.cpp
@@ -2242,41 +2242,38 @@ nsNavHistoryQueryResultNode::OpenContain
  * When we have valid results we can always give an exact answer.  When we
  * don't we just assume we'll have results, since actually doing the query
  * might be hard.  This is used to draw twisties on the tree, so precise results
  * don't matter.
  */
 NS_IMETHODIMP
 nsNavHistoryQueryResultNode::GetHasChildren(bool* aHasChildren)
 {
+  *aHasChildren = false;
+
   if (!CanExpand()) {
-    *aHasChildren = false;
     return NS_OK;
   }
 
   PRUint16 resultType = mOptions->ResultType();
+
+  // Tags are always populated, otherwise they are removed.
+  if (resultType == nsINavHistoryQueryOptions::RESULTS_AS_TAG_CONTENTS) {
+    *aHasChildren = true;
+    return NS_OK;
+  }
+
   // For tag containers query we must check if we have any tag
   if (resultType == nsINavHistoryQueryOptions::RESULTS_AS_TAG_QUERY) {
-    nsRefPtr<Database> DB = Database::GetDatabase();
-    NS_ENSURE_STATE(DB);
-    nsCOMPtr<mozIStorageStatement> stmt = DB->GetStatement(
-      "SELECT id FROM moz_bookmarks WHERE parent = :tags_folder LIMIT 1"
-    );
-    NS_ENSURE_STATE(stmt);
-    mozStorageStatementScoper scoper(stmt);
-
-    nsNavHistory* history = nsNavHistory::GetHistoryService();
-    NS_ENSURE_STATE(history);
-    nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("tags_folder"),
-                                        history->GetTagsFolder());
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = stmt->ExecuteStep(aHasChildren);
-    NS_ENSURE_SUCCESS(rv, rv);
-
+    nsCOMPtr<nsITaggingService> tagging =
+      do_GetService(NS_TAGGINGSERVICE_CONTRACTID);
+    if (tagging) {
+      bool hasTags;
+      *aHasChildren = NS_SUCCEEDED(tagging->GetHasTags(&hasTags)) && hasTags;
+    }
     return NS_OK;
   }
 
   // For history containers query we must check if we have any history
   if (resultType == nsINavHistoryQueryOptions::RESULTS_AS_DATE_QUERY ||
       resultType == nsINavHistoryQueryOptions::RESULTS_AS_DATE_SITE_QUERY ||
       resultType == nsINavHistoryQueryOptions::RESULTS_AS_SITE_QUERY) {
     nsNavHistory* history = nsNavHistory::GetHistoryService();
--- a/toolkit/components/places/nsTaggingService.js
+++ b/toolkit/components/places/nsTaggingService.js
@@ -345,16 +345,21 @@ TaggingService.prototype = {
       allTags.push(this._tagFolders[i]);
     // sort the tag list
     allTags.sort(function(a, b) {
         return a.toLowerCase().localeCompare(b.toLowerCase());
       });
     return allTags;
   },
 
+  // nsITaggingService
+  get hasTags() {
+    return this._tagFolders.length > 0;
+  },
+
   // nsIObserver
   observe: function TS_observe(aSubject, aTopic, aData) {
     if (aTopic == TOPIC_SHUTDOWN) {
       PlacesUtils.bookmarks.removeObserver(this);
       Services.obs.removeObserver(this, TOPIC_SHUTDOWN);
     }
   },