Bug 476299 - Decay frecency values to estimate recalculating frecencies. r=dietrich, a191=beltzner
authorEdward Lee <edilee@mozilla.com>
Sat, 14 Mar 2009 01:08:51 -0500
changeset 23897 116cd74b54f9e36ce7c7bdee6b19e7e0d569909e
parent 23896 c1b85123e48f782a1356a716d5855101400b2706
child 23906 5944071979f62be665250b15ba2938ee0f3c6386
push id977
push useredward.lee@engineering.uiuc.edu
push dateWed, 25 Mar 2009 00:22:34 +0000
reviewersdietrich
bugs476299, 482069
milestone1.9.1b4pre
Bug 476299 - Decay frecency values to estimate recalculating frecencies. r=dietrich, a191=beltzner Bug 482069 - Awesome bar adaptiveness totally sucks
toolkit/components/places/src/nsNavHistory.cpp
toolkit/components/places/src/nsNavHistoryExpire.cpp
toolkit/components/places/tests/unit/test_adaptive.js
--- a/toolkit/components/places/src/nsNavHistory.cpp
+++ b/toolkit/components/places/src/nsNavHistory.cpp
@@ -78,21 +78,22 @@
 #include "nsEscape.h"
 #include "nsIVariant.h"
 #include "nsVariant.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIIDNService.h"
 #include "nsIClassInfoImpl.h"
 #include "nsThreadUtils.h"
 
+#include "mozIStorageConnection.h"
+#include "mozIStorageFunction.h"
+#include "mozIStoragePendingStatement.h"
 #include "mozIStorageService.h"
-#include "mozIStorageConnection.h"
+#include "mozIStorageStatement.h"
 #include "mozIStorageValueArray.h"
-#include "mozIStorageStatement.h"
-#include "mozIStorageFunction.h"
 #include "mozStorageCID.h"
 #include "mozStorageHelper.h"
 #include "nsPlacesTriggers.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsIIdleService.h"
 #include "nsILivemarkService.h"
 
 #include "nsMathUtils.h" // for NS_ceilf()
@@ -5395,16 +5396,59 @@ nsNavHistory::Observe(nsISupports *aSubj
     if (oldDaysMin != mExpireDaysMin || oldDaysMax != mExpireDaysMax ||
         oldVisits != mExpireSites)
       mExpire.OnExpirationChanged();
   }
   else if (strcmp(aTopic, gIdleDaily) == 0) {
     // Recalculate some frecency values (zero time means don't recalculate)
     if (mFrecencyUpdateIdleTime)
       (void)RecalculateFrecencies(mNumCalculateFrecencyOnIdle, PR_TRUE);
+
+    if (mDBConn) {
+      // Globally decay places frecency rankings to estimate reduced frecency
+      // values of pages that haven't been visited for a while, i.e., they do
+      // not get an updated frecency. We directly modify moz_places to avoid
+      // bringing the whole database into places_temp through places_view. A
+      // scaling factor of .975 results in .5 the original value after 28 days.
+      nsCOMPtr<mozIStorageStatement> decayFrecency;
+      nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
+        "UPDATE moz_places SET frecency = ROUND(frecency * .975) "
+        "WHERE frecency > 0"),
+        getter_AddRefs(decayFrecency));
+      NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to create decayFrecency");
+
+      // Decay potentially unused adaptive entries (e.g. those that are at 1)
+      // to allow better chances for new entries that will start at 1
+      nsCOMPtr<mozIStorageStatement> decayAdaptive;
+      rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
+        "UPDATE moz_inputhistory SET use_count = use_count * .975"),
+        getter_AddRefs(decayAdaptive));
+      NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to create decayAdaptive");
+
+      // Delete any adaptive entries that won't help in ordering anymore
+      nsCOMPtr<mozIStorageStatement> deleteAdaptive;
+      rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
+        "DELETE FROM moz_inputhistory WHERE use_count < .01"),
+        getter_AddRefs(deleteAdaptive));
+      NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to create deleteAdaptive");
+
+      // Run these statements asynchronously if they were created successfully
+      if (decayFrecency && decayAdaptive && deleteAdaptive) {
+        nsCOMPtr<mozIStoragePendingStatement> ps;
+        mozIStorageStatement *stmts[] = {
+          decayFrecency,
+          decayAdaptive,
+          deleteAdaptive
+        };
+
+        rv = mDBConn->ExecuteAsync(stmts, NS_ARRAY_LENGTH(stmts), nsnull,
+                                    getter_AddRefs(ps));
+        NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to exec async idle stmts");
+      }
+    }
   }
   else if (strcmp(aTopic, NS_PRIVATE_BROWSING_SWITCH_TOPIC) == 0) {
     if (NS_LITERAL_STRING(NS_PRIVATE_BROWSING_ENTER).Equals(aData)) {
       mInPrivateBrowsing = PR_TRUE;
     } else if (NS_LITERAL_STRING(NS_PRIVATE_BROWSING_LEAVE).Equals(aData)) {
       mInPrivateBrowsing = PR_FALSE;
     }
   }
--- a/toolkit/components/places/src/nsNavHistoryExpire.cpp
+++ b/toolkit/components/places/src/nsNavHistoryExpire.cpp
@@ -995,39 +995,32 @@ nsNavHistoryExpire::ExpireAnnotationsPar
       ")"));
   NS_ENSURE_SUCCESS(rv, rv);
   return NS_OK;
 }
 
 
 // nsNavHistoryExpire::ExpireInputHistoryParanoid
 //
-//    Deletes dangling input history, decay potentially unused entries
+//    Deletes dangling input history
 
 nsresult
 nsNavHistoryExpire::ExpireInputHistoryParanoid(mozIStorageConnection* aConnection)
 {
   // Delete dangling input history that have no associated pages
   nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
       "DELETE FROM moz_inputhistory WHERE place_id IN ( "
         "SELECT place_id FROM moz_inputhistory "
         "LEFT JOIN moz_places h ON h.id = place_id "
         "LEFT JOIN moz_places_temp h_t ON h_t.id = place_id "
         "WHERE h.id IS NULL "
           "AND h_t.id IS NULL "
       ")"));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Decay potentially unused entries (e.g. those that are at 1) to allow
-  // better chances for new entries that will start at 1
-  rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-      "UPDATE moz_inputhistory "
-      "SET use_count = use_count * .9"));
-  NS_ENSURE_SUCCESS(rv, rv);
-
   return NS_OK;
 }
 
 
 // nsNavHistoryExpire::ExpireForDegenerateRuns
 //
 //    This checks for potential degenerate runs. For example, a tinderbox
 //    loads many web pages quickly and we'll never have a chance to expire.
--- a/toolkit/components/places/tests/unit/test_adaptive.js
+++ b/toolkit/components/places/tests/unit/test_adaptive.js
@@ -185,16 +185,25 @@ function setCountRank(aURI, aCount, aRan
   for (let i = 0; i < aRank; i++) {
     obs.notifyObservers(thing, "autocomplete-will-enter-text", null);
     targetUseCount = (targetUseCount * 0.9) + 1;
   }
 
   return Math.floor(targetUseCount);
 }
 
+/**
+ * Decay the adaptive entries by sending the daily idle topic
+ */
+function doAdaptiveDecay()
+{
+  for (let i = 0; i < 10; i++)
+    obs.notifyObservers(null, "idle-daily", null);
+}
+
 let uri1 = uri("http://site.tld/1");
 let uri2 = uri("http://site.tld/2");
 
 // d1 is some date for the page visit
 let d1 = new Date(Date.now() - 1000 * 60 * 60) * 1000;
 // c1 is larger (should show up higher) than c2
 let c1 = 10;
 let c2 = 1;