Bug 850362 - reintroduce bug 842852 - localStorage optimizations, r=mak77

This commit is contained in:
Honza Bambas 2013-04-15 14:38:58 +02:00
parent f29df2e52f
commit 53ca4cbef7
2 changed files with 68 additions and 20 deletions

View File

@ -27,6 +27,9 @@
// In milliseconds.
#define FLUSHING_INTERVAL_MS 5000
// Write Ahead Log's maximum size is 512KB
#define MAX_WAL_SIZE_BYTES 512 * 1024
namespace mozilla {
namespace dom {
@ -118,12 +121,6 @@ DOMStorageDBThread::Shutdown()
monitor.Notify();
}
mReaderStatements.FinalizeStatements();
if (mReaderConnection) {
mReaderConnection->Close();
mReaderConnection = nullptr;
}
PR_JoinThread(mThread);
mThread = nullptr;
@ -396,26 +393,22 @@ DOMStorageDBThread::OpenDatabaseConnection()
{
nsresult rv;
MOZ_ASSERT(!NS_IsMainThread());
nsCOMPtr<mozIStorageService> service
= do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<mozIStorageConnection> connection;
rv = service->OpenUnsharedDatabase(mDatabaseFile, getter_AddRefs(connection));
rv = service->OpenUnsharedDatabase(mDatabaseFile, getter_AddRefs(mWorkerConnection));
if (rv == NS_ERROR_FILE_CORRUPTED) {
// delete the db and try opening again
rv = mDatabaseFile->Remove(false);
NS_ENSURE_SUCCESS(rv, rv);
rv = service->OpenUnsharedDatabase(mDatabaseFile, getter_AddRefs(connection));
rv = service->OpenUnsharedDatabase(mDatabaseFile, getter_AddRefs(mWorkerConnection));
}
NS_ENSURE_SUCCESS(rv, rv);
if (NS_IsMainThread()) {
connection.swap(mReaderConnection);
} else {
connection.swap(mWorkerConnection);
}
return NS_OK;
}
@ -435,6 +428,10 @@ DOMStorageDBThread::InitDatabase()
rv = TryJournalMode();
NS_ENSURE_SUCCESS(rv, rv);
// Create a read-only clone
(void)mWorkerConnection->Clone(true, getter_AddRefs(mReaderConnection));
NS_ENSURE_TRUE(mReaderConnection, NS_ERROR_FAILURE);
mozStorageTransaction transaction(mWorkerConnection, false);
// Ensure Gecko 1.9.1 storage table
@ -578,18 +575,72 @@ DOMStorageDBThread::TryJournalMode()
NS_ENSURE_SUCCESS(rv, rv);
} else {
mWALModeEnabled = true;
rv = ConfigureWALBehavior();
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
nsresult
DOMStorageDBThread::ConfigureWALBehavior()
{
// Get the DB's page size
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = mWorkerConnection->CreateStatement(NS_LITERAL_CSTRING(
MOZ_STORAGE_UNIQUIFY_QUERY_STR "PRAGMA page_size"
), getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, rv);
bool hasResult = false;
rv = stmt->ExecuteStep(&hasResult);
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && hasResult, NS_ERROR_FAILURE);
int32_t pageSize = 0;
rv = stmt->GetInt32(0, &pageSize);
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && pageSize > 0, NS_ERROR_UNEXPECTED);
// Set the threshold for auto-checkpointing the WAL.
// We don't want giant logs slowing down reads & shutdown.
int32_t thresholdInPages = static_cast<int32_t>(MAX_WAL_SIZE_BYTES / pageSize);
nsAutoCString thresholdPragma("PRAGMA wal_autocheckpoint = ");
thresholdPragma.AppendInt(thresholdInPages);
rv = mWorkerConnection->ExecuteSimpleSQL(thresholdPragma);
NS_ENSURE_SUCCESS(rv, rv);
// Set the maximum WAL log size to reduce footprint on mobile (large empty
// WAL files will be truncated)
nsAutoCString journalSizePragma("PRAGMA journal_size_limit = ");
// bug 600307: mak recommends setting this to 3 times the auto-checkpoint threshold
journalSizePragma.AppendInt(MAX_WAL_SIZE_BYTES * 3);
rv = mWorkerConnection->ExecuteSimpleSQL(journalSizePragma);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
DOMStorageDBThread::ShutdownDatabase()
{
// Has to be called on the worker thread.
MOZ_ASSERT(!NS_IsMainThread());
nsresult rv = mStatus;
mDBReady = false;
// Finalize the cached statements.
mReaderStatements.FinalizeStatements();
mWorkerStatements.FinalizeStatements();
if (mReaderConnection) {
// No need to sync access to mReaderConnection since the main thread
// is right now joining this thread, unable to execute any events.
mReaderConnection->Close();
mReaderConnection = nullptr;
}
if (mWorkerConnection) {
rv = mWorkerConnection->Close();
mWorkerConnection = nullptr;
@ -744,12 +795,6 @@ DOMStorageDBThread::DBOperation::Perform(DOMStorageDBThread* aThread)
StatementCache* statements;
if (MOZ_UNLIKELY(NS_IsMainThread())) {
if (MOZ_UNLIKELY(!aThread->mReaderConnection)) {
// Do lazy main thread connection opening
rv = aThread->OpenDatabaseConnection();
NS_ENSURE_SUCCESS(rv, rv);
}
statements = &aThread->mReaderStatements;
} else {
statements = &aThread->mWorkerStatements;

View File

@ -315,6 +315,9 @@ private:
nsresult SetJournalMode(bool aIsWal);
nsresult TryJournalMode();
// Sets the threshold for auto-checkpointing the WAL.
nsresult ConfigureWALBehavior();
void SetHigherPriority();
void SetDefaultPriority();