Bug 723611 - Remove mainthread pragmas executed by the VacuumManager.
authorMarco Bonardo <mbonardo@mozilla.com>
Wed, 22 Feb 2012 12:23:05 +0100
changeset 90703 616f4f937da252656e06da2fb8e671b245cfd4fe
parent 90702 499846502bf3ed37b3d18cf0ba8ae753a1f79194
child 90704 75bb9debefe9692c336748355dfd215f1856a2f1
push id136
push userlsblakk@mozilla.com
push dateFri, 01 Jun 2012 02:39:32 +0000
treeherdermozilla-release@7ebf7352c959 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs723611
milestone13.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 723611 - Remove mainthread pragmas executed by the VacuumManager. r=sdwilsh
storage/src/VacuumManager.cpp
--- a/storage/src/VacuumManager.cpp
+++ b/storage/src/VacuumManager.cpp
@@ -146,183 +146,109 @@ public:
 
 private:
   nsCOMPtr<mozIStorageVacuumParticipant> mParticipant;
   nsCString mDBFilename;
   nsCOMPtr<mozIStorageConnection> mDBConn;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
-// NotifyCallback
-/**
- * This class handles an async statement execution and notifies completion
- * through a passed in callback.
- * Errors are handled through warnings in HandleError.
- */
-class NotifyCallback : public BaseCallback
-{
-public:
-  NS_IMETHOD HandleCompletion(PRUint16 aReason);
-
-  NotifyCallback(Vacuumer *aVacuumer, bool aVacuumSucceeded);
-
-private:
-  nsCOMPtr<Vacuumer> mVacuumer;
-  bool mVacuumSucceeded;
-};
-
-NotifyCallback::NotifyCallback(Vacuumer *aVacuumer,
-                               bool aVacuumSucceeded)
-  : mVacuumer(aVacuumer)
-  , mVacuumSucceeded(aVacuumSucceeded)
-{
-}
-
-NS_IMETHODIMP
-NotifyCallback::HandleCompletion(PRUint16 aReason)
-{
-  // We succeeded if vacuum succeeded.
-  nsresult rv = mVacuumer->notifyCompletion(mVacuumSucceeded);
-  NS_ENSURE_SUCCESS(rv, rv);
-  return NS_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 //// Vacuumer implementation.
 
 Vacuumer::Vacuumer(mozIStorageVacuumParticipant *aParticipant)
   : mParticipant(aParticipant)
 {
 }
 
 bool
 Vacuumer::execute()
 {
-  NS_PRECONDITION(NS_IsMainThread(), "Must be running on the main thread!");
+  MOZ_ASSERT(NS_IsMainThread(), "Must be running on the main thread!");
 
   // Get the connection and check its validity.
   nsresult rv = mParticipant->GetDatabaseConnection(getter_AddRefs(mDBConn));
   NS_ENSURE_SUCCESS(rv, false);
-  bool ready;
+  bool ready = false;
   if (!mDBConn || NS_FAILED(mDBConn->GetConnectionReady(&ready)) || !ready) {
-    NS_WARNING(NS_LITERAL_CSTRING("Unable to get a connection to vacuum database").get());
+    NS_WARNING("Unable to get a connection to vacuum database");
     return false;
   }
 
-  // Compare current page size with the expected one.  Vacuum can change the
-  // page size value if needed.  Even if a vacuum happened recently, if the
-  // page size can be optimized we should do it.
+  // Ask for the expected page size.  Vacuum can change the page size, unless
+  // the database is using WAL journaling.
+  // TODO Bug 634374: figure out a strategy to fix page size with WAL.
   PRInt32 expectedPageSize = 0;
   rv = mParticipant->GetExpectedDatabasePageSize(&expectedPageSize);
   if (NS_FAILED(rv) || expectedPageSize < 512 || expectedPageSize > 65536) {
     NS_WARNING("Invalid page size requested for database, will use default ");
     NS_WARNING(mDBFilename.get());
     expectedPageSize = mozIStorageConnection::DEFAULT_PAGE_SIZE;
   }
 
-  bool canOptimizePageSize = false;
-  {
-    nsCOMPtr<mozIStorageStatement> stmt;
-    rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      MOZ_STORAGE_UNIQUIFY_QUERY_STR "PRAGMA page_size"
-    ), getter_AddRefs(stmt));
-    NS_ENSURE_SUCCESS(rv, false);
-    bool hasResult;
-    rv = stmt->ExecuteStep(&hasResult);
-    NS_ENSURE_SUCCESS(rv, false);
-    NS_ENSURE_TRUE(hasResult, false);
-    PRInt32 currentPageSize;
-    rv = stmt->GetInt32(0, &currentPageSize);
-    NS_ENSURE_SUCCESS(rv, false);
-    NS_ASSERTION(currentPageSize > 0, "Got invalid page size value?");
-    if (currentPageSize != expectedPageSize) {
-      // Check journal mode.  WAL journaling does not allow vacuum to change
-      // the page size.
-      // TODO Bug 634374: figure out a strategy to fix page size with WAL.
-      nsCAutoString journalMode;
-      {
-        nsCOMPtr<mozIStorageStatement> stmt;
-        rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-          MOZ_STORAGE_UNIQUIFY_QUERY_STR "PRAGMA journal_mode"
-        ), getter_AddRefs(stmt));
-        NS_ENSURE_SUCCESS(rv, false);
-        bool hasResult;
-        rv = stmt->ExecuteStep(&hasResult);
-        NS_ENSURE_SUCCESS(rv, false);
-        NS_ENSURE_TRUE(hasResult, false);
-        rv = stmt->GetUTF8String(0, journalMode);
-        NS_ENSURE_SUCCESS(rv, false);
-      }
-      canOptimizePageSize = !journalMode.EqualsLiteral("wal");
-    }
-  }
-
   // Get the database filename.  Last vacuum time is stored under this name
   // in PREF_VACUUM_BRANCH.
   nsCOMPtr<nsIFile> databaseFile;
   mDBConn->GetDatabaseFile(getter_AddRefs(databaseFile));
   if (!databaseFile) {
     NS_WARNING("Trying to vacuum a in-memory database!");
     return false;
   }
   nsAutoString databaseFilename;
   rv = databaseFile->GetLeafName(databaseFilename);
   NS_ENSURE_SUCCESS(rv, false);
   mDBFilename = NS_ConvertUTF16toUTF8(databaseFilename);
-  NS_ASSERTION(!mDBFilename.IsEmpty(), "Database filename cannot be empty");
+  MOZ_ASSERT(!mDBFilename.IsEmpty(), "Database filename cannot be empty");
 
   // Check interval from last vacuum.
   PRInt32 now = static_cast<PRInt32>(PR_Now() / PR_USEC_PER_SEC);
   PRInt32 lastVacuum;
   nsCAutoString prefName(PREF_VACUUM_BRANCH);
   prefName += mDBFilename;
   rv = Preferences::GetInt(prefName.get(), &lastVacuum);
-  if (NS_SUCCEEDED(rv) && (now - lastVacuum) < VACUUM_INTERVAL_SECONDS &&
-      !canOptimizePageSize) {
-    // This database was vacuumed recently and has optimal page size, skip it. 
+  if (NS_SUCCEEDED(rv) && (now - lastVacuum) < VACUUM_INTERVAL_SECONDS) {
+    // This database was vacuumed recently, skip it.
     return false;
   }
 
   // Notify that we are about to start vacuuming.  The participant can opt-out
   // if it cannot handle a vacuum at this time, and then we'll move to the next
   // one.
   bool vacuumGranted = false;
   rv = mParticipant->OnBeginVacuum(&vacuumGranted);
   NS_ENSURE_SUCCESS(rv, false);
   if (!vacuumGranted) {
     return false;
   }
 
   // Notify a heavy IO task is about to start.
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (os) {
-    (void)os->NotifyObservers(nsnull, OBSERVER_TOPIC_HEAVY_IO,
-                              OBSERVER_DATA_VACUUM_BEGIN.get());
+    DebugOnly<nsresult> rv =
+      os->NotifyObservers(nsnull, OBSERVER_TOPIC_HEAVY_IO,
+                          OBSERVER_DATA_VACUUM_BEGIN.get());
+    MOZ_ASSERT(NS_SUCCEEDED(rv), "Should be able to notify");
   }
 
-  if (canOptimizePageSize) {
-    nsCOMPtr<mozIStorageAsyncStatement> pageSizeStmt;
-    rv = mDBConn->CreateAsyncStatement(nsPrintfCString(
-      MOZ_STORAGE_UNIQUIFY_QUERY_STR "PRAGMA page_size = %ld", expectedPageSize
-    ), getter_AddRefs(pageSizeStmt));
-    NS_ENSURE_SUCCESS(rv, false);
-    nsCOMPtr<BaseCallback> callback = new BaseCallback();
-    NS_ENSURE_TRUE(callback, false);
-    nsCOMPtr<mozIStoragePendingStatement> ps;
-    rv = pageSizeStmt->ExecuteAsync(callback, getter_AddRefs(ps));
-    NS_ENSURE_SUCCESS(rv, false);
-  }
+  // Execute the statements separately, since the pragma may conflict with the
+  // vacuum, if they are executed in the same transaction.
+  nsCOMPtr<mozIStorageAsyncStatement> pageSizeStmt;
+  rv = mDBConn->CreateAsyncStatement(nsPrintfCString(
+    MOZ_STORAGE_UNIQUIFY_QUERY_STR "PRAGMA page_size = %ld", expectedPageSize
+  ), getter_AddRefs(pageSizeStmt));
+  NS_ENSURE_SUCCESS(rv, false);
+  nsCOMPtr<BaseCallback> callback = new BaseCallback();
+  nsCOMPtr<mozIStoragePendingStatement> ps;
+  rv = pageSizeStmt->ExecuteAsync(callback, getter_AddRefs(ps));
+  NS_ENSURE_SUCCESS(rv, false);
 
   nsCOMPtr<mozIStorageAsyncStatement> stmt;
   rv = mDBConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
     "VACUUM"
   ), getter_AddRefs(stmt));
   NS_ENSURE_SUCCESS(rv, false);
-
-  nsCOMPtr<mozIStoragePendingStatement> ps;
   rv = stmt->ExecuteAsync(this, getter_AddRefs(ps));
   NS_ENSURE_SUCCESS(rv, false);
 
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// mozIStorageStatementCallback
@@ -372,20 +298,21 @@ Vacuumer::HandleResult(mozIStorageResult
 }
 
 NS_IMETHODIMP
 Vacuumer::HandleCompletion(PRUint16 aReason)
 {
   if (aReason == REASON_FINISHED) {
     // Update last vacuum time.
     PRInt32 now = static_cast<PRInt32>(PR_Now() / PR_USEC_PER_SEC);
-    NS_ASSERTION(!mDBFilename.IsEmpty(), "Database filename cannot be empty");
+    MOZ_ASSERT(!mDBFilename.IsEmpty(), "Database filename cannot be empty");
     nsCAutoString prefName(PREF_VACUUM_BRANCH);
     prefName += mDBFilename;
-    (void)Preferences::SetInt(prefName.get(), now);
+    DebugOnly<nsresult> rv = Preferences::SetInt(prefName.get(), now);
+    MOZ_ASSERT(NS_SUCCEEDED(rv), "Should be able to set a preference"); 
   }
 
   notifyCompletion(aReason == REASON_FINISHED);
 
   return NS_OK;
 }
 
 nsresult
@@ -428,27 +355,27 @@ VacuumManager::getSingleton()
     NS_ADDREF(gVacuumManager);
   }
   return gVacuumManager;
 }
 
 VacuumManager::VacuumManager()
   : mParticipants("vacuum-participant")
 {
-  NS_ASSERTION(!gVacuumManager,
-               "Attempting to create two instances of the service!");
+  MOZ_ASSERT(!gVacuumManager,
+             "Attempting to create two instances of the service!");
   gVacuumManager = this;
 }
 
 VacuumManager::~VacuumManager()
 {
   // Remove the static reference to the service.  Check to make sure its us
   // in case somebody creates an extra instance of the service.
-  NS_ASSERTION(gVacuumManager == this,
-               "Deleting a non-singleton instance of the service");
+  MOZ_ASSERT(gVacuumManager == this,
+             "Deleting a non-singleton instance of the service");
   if (gVacuumManager == this) {
     gVacuumManager = nsnull;
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsIObserver
 
@@ -472,16 +399,17 @@ VacuumManager::Observe(nsISupports *aSub
     PRInt32 index;
     for (index = startIndex; index < entries.Count(); ++index) {
       nsCOMPtr<Vacuumer> vacuum = new Vacuumer(entries[index]);
       // Only vacuum one database per day.
       if (vacuum->execute()) {
         break;
       }
     }
-    (void)Preferences::SetInt(kPrefName, index);
+    DebugOnly<nsresult> rv = Preferences::SetInt(kPrefName, index);
+    MOZ_ASSERT(NS_SUCCEEDED(rv), "Should be able to set a preference");
   }
 
   return NS_OK;
 }
 
 } // namespace storage
 } // namespace mozilla