Bug 666611 - Do not set chunksize if less than 100MiB of storage is available. r=mak
☠☠ backed out by 70416d5c5384 ☠ ☠
authorJezreel Ng <jezreel@gmail.com>
Thu, 04 Aug 2011 09:04:52 +0200
changeset 74617 4c509d9b5b597ac141215041b912465ffcbe5ba7
parent 74616 3a3e648530b2f10ae6340b5a49c7252833cdd655
child 74618 9bf06b1df4759fbf16db930037c74e22e0571e7d
push id235
push userbzbarsky@mozilla.com
push dateTue, 27 Sep 2011 17:13:04 +0000
treeherdermozilla-beta@2d1e082d176a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs666611
milestone8.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 666611 - Do not set chunksize if less than 100MiB of storage is available. r=mak
storage/public/mozIStorageConnection.idl
storage/src/mozStorageConnection.cpp
--- a/storage/public/mozIStorageConnection.idl
+++ b/storage/public/mozIStorageConnection.idl
@@ -356,18 +356,22 @@ interface mozIStorageConnection : nsISup
    * Remove a progress handler.
    *
    * @return previous registered handler.
    */
   mozIStorageProgressHandler removeProgressHandler();
 
   /**
    * Controls SQLITE_FCNTL_CHUNK_SIZE setting in sqlite. This helps avoid fragmentation
-   * by growing/shrinking the database file in SQLITE_FCNTL_CHUNK_SIZE increments.
+   * by growing/shrinking the database file in SQLITE_FCNTL_CHUNK_SIZE increments. To
+   * conserve memory on systems short on storage space, this function will have no effect
+   * on mobile devices or if less than 100MB of space is left available.
    *
    * @param aIncrement
    *        The database file will grow in multiples of chunkSize.
    * @param aDatabaseName
    *        Sqlite database name. "" means pass NULL for zDbName to sqlite3_file_control.
    *        See http://sqlite.org/c3ref/file_control.html for more details.
+   * @throws NS_ERROR_FILE_TOO_BIG
+   *         If the system is short on storage space.
    */
   void setGrowthIncrement(in PRInt32 aIncrement, in AUTF8String aDatabaseName);
 };
--- a/storage/src/mozStorageConnection.cpp
+++ b/storage/src/mozStorageConnection.cpp
@@ -42,19 +42,19 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include <stdio.h>
 
 #include "nsError.h"
 #include "nsIMutableArray.h"
 #include "nsHashSets.h"
 #include "nsAutoPtr.h"
-#include "nsIFile.h"
 #include "nsIMemoryReporter.h"
 #include "nsThreadUtils.h"
+#include "nsILocalFile.h"
 
 #include "mozIStorageAggregateFunction.h"
 #include "mozIStorageCompletionCallback.h"
 #include "mozIStorageFunction.h"
 
 #include "mozStorageAsyncStatementExecution.h"
 #include "mozStorageSQLFunctions.h"
 #include "mozStorageConnection.h"
@@ -65,16 +65,18 @@
 #include "mozStoragePrivateHelpers.h"
 #include "mozStorageStatementData.h"
 #include "StorageBaseStatementInternal.h"
 #include "SQLCollations.h"
 
 #include "prlog.h"
 #include "prprf.h"
 
+#define BYTES_PER_MEBIBYTE 1048576
+
 #ifdef PR_LOGGING
 PRLogModuleInfo* gStorageLog = nsnull;
 #endif
 
 namespace mozilla {
 namespace storage {
 
 namespace {
@@ -1240,16 +1242,26 @@ Connection::RemoveProgressHandler(mozISt
 
 NS_IMETHODIMP
 Connection::SetGrowthIncrement(PRInt32 aChunkSize, const nsACString &aDatabaseName)
 {
   // Bug 597215: Disk space is extremely limited on Android
   // so don't preallocate space. This is also not effective
   // on log structured file systems used by Android devices
 #if !defined(ANDROID) && !defined(MOZ_PLATFORM_MAEMO)
+  // Don't preallocate if less than 100MiB is available.
+  nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(mDatabaseFile);
+  NS_ENSURE_STATE(localFile);
+  PRInt64 bytesAvailable;
+  nsresult rv = localFile->GetDiskSpaceAvailable(&bytesAvailable);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (bytesAvailable < 100 * BYTES_PER_MEBIBYTE) {
+    return NS_ERROR_FILE_TOO_BIG;
+  }
+
   (void)::sqlite3_file_control(mDBConn,
                                aDatabaseName.Length() ? nsPromiseFlatCString(aDatabaseName).get() : NULL,
                                SQLITE_FCNTL_CHUNK_SIZE,
                                &aChunkSize);
 #endif
   return NS_OK;
 }