Bug 666611 - Do not set chunksize if less than 500MiB of storage is available. r=mak

This commit is contained in:
Jezreel Ng 2011-09-05 10:29:06 +01:00
parent 18ab676d77
commit 952495179e
3 changed files with 24 additions and 3 deletions

View File

@ -361,13 +361,17 @@ interface mozIStorageConnection : nsISupports {
/**
* 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 500MiB 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);
};

View File

@ -47,9 +47,9 @@
#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"
@ -70,6 +70,8 @@
#include "prlog.h"
#include "prprf.h"
#define MIN_AVAILABLE_BYTES_PER_CHUNKED_GROWTH 524288000 // 500 MiB
#ifdef PR_LOGGING
PRLogModuleInfo* gStorageLog = nsnull;
#endif
@ -1280,6 +1282,16 @@ Connection::SetGrowthIncrement(PRInt32 aChunkSize, const nsACString &aDatabaseNa
// 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 500MiB 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 < MIN_AVAILABLE_BYTES_PER_CHUNKED_GROWTH) {
return NS_ERROR_FILE_TOO_BIG;
}
(void)::sqlite3_file_control(mDBConn,
aDatabaseName.Length() ? nsPromiseFlatCString(aDatabaseName).get() : NULL,
SQLITE_FCNTL_CHUNK_SIZE,

View File

@ -26,7 +26,12 @@ function run_test()
const filename = "chunked.sqlite";
const CHUNK_SIZE = 512 * 1024;
var d = getDatabase(new_file(filename));
d.setGrowthIncrement(CHUNK_SIZE, "");
try {
d.setGrowthIncrement(CHUNK_SIZE, "");
} catch (e if e.result == Cr.NS_ERROR_FILE_TOO_BIG) {
print("Too little free space to set CHUNK_SIZE!");
return;
}
run_sql(d, "CREATE TABLE bloat(data varchar)");
var orig_size = get_size(filename);