From ea67826b852265f3a974a740f4b81d4c41d38a8a Mon Sep 17 00:00:00 2001 From: Jan Varga Date: Mon, 29 Apr 2019 14:23:55 +0200 Subject: [PATCH] Bug 1547688 - LSNG: Preloading can use gUsages hash table to quickly finish if there's nothing to preload; r=asuth Differential Revision: https://phabricator.services.mozilla.com/D29194 --- dom/cache/Context.cpp | 3 +- dom/indexedDB/ActorsParent.cpp | 6 +- dom/localstorage/ActorsParent.cpp | 97 ++++++++++++++++++------------- dom/quota/ActorsParent.cpp | 30 +++------- dom/quota/QuotaManager.h | 14 ++--- dom/simpledb/ActorsParent.cpp | 2 +- 6 files changed, 74 insertions(+), 78 deletions(-) diff --git a/dom/cache/Context.cpp b/dom/cache/Context.cpp index d330fc973fe0..54fac9eb764d 100644 --- a/dom/cache/Context.cpp +++ b/dom/cache/Context.cpp @@ -389,8 +389,7 @@ Context::QuotaInitRunnable::Run() { MOZ_DIAGNOSTIC_ASSERT(qm); nsresult rv = qm->EnsureOriginIsInitialized( PERSISTENCE_TYPE_DEFAULT, mQuotaInfo.mSuffix, mQuotaInfo.mGroup, - mQuotaInfo.mOrigin, - /* aCreateIfNotExists */ true, getter_AddRefs(mQuotaInfo.mDir)); + mQuotaInfo.mOrigin, getter_AddRefs(mQuotaInfo.mDir)); if (NS_FAILED(rv)) { resolver->Resolve(rv); break; diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index c99a4b50fc7b..e52c3848ea1b 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -17159,8 +17159,7 @@ nsresult Maintenance::DirectoryWork() { // Ensure origin is initialized first. It will initialize all origins // for temporary storage including IDB origins. rv = quotaManager->EnsureOriginIsInitialized( - persistenceType, suffix, group, origin, - /* aCreateIfNotExists */ true, getter_AddRefs(directory)); + persistenceType, suffix, group, origin, getter_AddRefs(directory)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; @@ -19869,8 +19868,7 @@ nsresult OpenDatabaseOp::DoDatabaseWork() { nsCOMPtr dbDirectory; nsresult rv = quotaManager->EnsureOriginIsInitialized( - persistenceType, mSuffix, mGroup, mOrigin, - /* aCreateIfNotExists */ true, getter_AddRefs(dbDirectory)); + persistenceType, mSuffix, mGroup, mOrigin, getter_AddRefs(dbDirectory)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/dom/localstorage/ActorsParent.cpp b/dom/localstorage/ActorsParent.cpp index 85b3f4c9d1a0..f7684ebf984e 100644 --- a/dom/localstorage/ActorsParent.cpp +++ b/dom/localstorage/ActorsParent.cpp @@ -2900,6 +2900,22 @@ void InitUsageForOrigin(const nsACString& aOrigin, int64_t aUsage) { gUsages->Put(aOrigin, aUsage); } +bool GetUsageForOrigin(const nsACString& aOrigin, int64_t& aUsage) { + AssertIsOnIOThread(); + + if (gUsages) { + int64_t usage; + if (gUsages->Get(aOrigin, &usage)) { + MOZ_ASSERT(usage >= 0); + + aUsage = usage; + return true; + } + } + + return false; +} + void UpdateUsageForOrigin(const nsACString& aOrigin, int64_t aUsage) { AssertIsOnIOThread(); MOZ_ASSERT(gUsages); @@ -6694,7 +6710,18 @@ nsresult PrepareDatastoreOp::DatabaseWork() { QuotaManager* quotaManager = QuotaManager::Get(); MOZ_ASSERT(quotaManager); - nsresult rv; + // This must be called before EnsureTemporaryStorageIsInitialized. + nsresult rv = quotaManager->EnsureStorageIsInitialized(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + // This ensures that gUsages gets populated with usages for existings origin + // directories. + rv = quotaManager->EnsureTemporaryStorageIsInitialized(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } if (!gArchivedOrigins) { rv = LoadArchivedOrigins(); @@ -6706,17 +6733,23 @@ nsresult PrepareDatastoreOp::DatabaseWork() { bool hasDataForMigration = mArchivedOriginScope->HasMatches(gArchivedOrigins); - // Initialize the origin even when the origin directory doesn't exist and we - // don't have data for migration (except the case when we are just trying to - // preload data). GetQuotaObject in GetResponse would fail otherwise. - nsCOMPtr directoryEntry; - rv = quotaManager->EnsureOriginIsInitialized( - PERSISTENCE_TYPE_DEFAULT, mSuffix, mGroup, mOrigin, - /* aCreateIfNotExists */ !mForPreload || hasDataForMigration, - getter_AddRefs(directoryEntry)); - if (rv == NS_ERROR_NOT_AVAILABLE) { + // If there's nothing to preload (except the case when we want to migrate data + // during preloading), then we can finish the operation without creating a + // datastore in GetResponse (GetResponse won't create a datastore if + // mDatatabaseNotAvailable and mForPreload are both true). + int64_t usage; + if (mForPreload && !GetUsageForOrigin(mOrigin, usage) && + !hasDataForMigration) { return DatabaseNotAvailable(); } + + // Initialize the origin even when the origin directory doesn't exist and we + // don't have data for migration. GetQuotaObject in GetResponse would fail + // otherwise. + nsCOMPtr directoryEntry; + rv = quotaManager->EnsureOriginIsInitialized(PERSISTENCE_TYPE_DEFAULT, + mSuffix, mGroup, mOrigin, + getter_AddRefs(directoryEntry)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -6737,18 +6770,7 @@ nsresult PrepareDatastoreOp::DatabaseWork() { rv = EnsureDirectoryEntry(directoryEntry, /* aCreateIfNotExists */ hasDataForMigration, /* aIsDirectory */ true); - if (rv == NS_ERROR_NOT_AVAILABLE) { - if (mForPreload) { - // There's nothing to preload. Finish the operation without creating a - // datastore in GetResponse (GetResponse won't create a datastore if - // mDatatabaseNotAvailable and mForPreload are both true). - return DatabaseNotAvailable(); - } - - // Keep going if !mForPreload so that we will populate mDatabaseFilePath - // which is needed by GetQuotaObject. We will still return via call to - // DatabaseNotAvailable() below in the !alreadyExisted else branch. - } else if (NS_WARN_IF(NS_FAILED(rv))) { + if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -6769,14 +6791,7 @@ nsresult PrepareDatastoreOp::DatabaseWork() { rv = EnsureDirectoryEntry(directoryEntry, /* aCreateIfNotExists */ hasDataForMigration, /* aIsDirectory */ false, &alreadyExisted); - if (rv == NS_ERROR_NOT_AVAILABLE) { - if (mForPreload) { - // There's nothing to preload, finish the operation without creating a - // datastore in GetResponse (GetResponse won't create a datastore if - // mDatatabaseNotAvailable and mForPreload are both true). - return DatabaseNotAvailable(); - } - } else if (NS_WARN_IF(NS_FAILED(rv))) { + if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -6785,13 +6800,13 @@ nsresult PrepareDatastoreOp::DatabaseWork() { DebugOnly hasUsage = gUsages->Get(mOrigin, &mUsage); MOZ_ASSERT(hasUsage); } else { - MOZ_ASSERT(!mForPreload); + // The database doesn't exist. if (!hasDataForMigration) { - // The ls directory or database doesn't exist and we don't have data for - // migration. Finish the operation, but create an empty datastore in - // GetResponse (GetResponse will create an empty datastore if - // mDatabaseNotAvailable is true and mForPreload is false). + // The database doesn't exist and we don't have data for migration. + // Finish the operation, but create an empty datastore in GetResponse + // (GetResponse will create an empty datastore if mDatabaseNotAvailable + // is true and mForPreload is false). return DatabaseNotAvailable(); } @@ -6996,7 +7011,7 @@ nsresult PrepareDatastoreOp::EnsureDirectoryEntry(nsIFile* aEntry, if (aAlreadyExisted) { *aAlreadyExisted = false; } - return NS_ERROR_NOT_AVAILABLE; + return NS_OK; } if (aIsDirectory) { @@ -8289,12 +8304,10 @@ nsresult QuotaClient::GetUsageForOrigin(PersistenceType aPersistenceType, // We can't open the database at this point, since it can be already used // by the connection thread. Use the cached value instead. - if (gUsages) { - int64_t usage; - if (gUsages->Get(aOrigin, &usage)) { - MOZ_ASSERT(usage >= 0); - aUsageInfo->AppendToDatabaseUsage(usage); - } + int64_t usage; + if (mozilla::dom::GetUsageForOrigin(aOrigin, usage)) { + MOZ_ASSERT(usage >= 0); + aUsageInfo->AppendToDatabaseUsage(usage); } return NS_OK; diff --git a/dom/quota/ActorsParent.cpp b/dom/quota/ActorsParent.cpp index f16f619b8bf9..f763c1ef8a73 100644 --- a/dom/quota/ActorsParent.cpp +++ b/dom/quota/ActorsParent.cpp @@ -5629,19 +5629,15 @@ void QuotaManager::OpenDirectoryInternal( nsresult QuotaManager::EnsureOriginIsInitialized( PersistenceType aPersistenceType, const nsACString& aSuffix, - const nsACString& aGroup, const nsACString& aOrigin, - bool aCreateIfNotExists, nsIFile** aDirectory) { + const nsACString& aGroup, const nsACString& aOrigin, nsIFile** aDirectory) { AssertIsOnIOThread(); MOZ_ASSERT(aDirectory); nsCOMPtr directory; bool created; nsresult rv = EnsureOriginIsInitializedInternal( - aPersistenceType, aSuffix, aGroup, aOrigin, aCreateIfNotExists, - getter_AddRefs(directory), &created); - if (rv == NS_ERROR_NOT_AVAILABLE) { - return rv; - } + aPersistenceType, aSuffix, aGroup, aOrigin, getter_AddRefs(directory), + &created); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -5652,8 +5648,8 @@ nsresult QuotaManager::EnsureOriginIsInitialized( nsresult QuotaManager::EnsureOriginIsInitializedInternal( PersistenceType aPersistenceType, const nsACString& aSuffix, - const nsACString& aGroup, const nsACString& aOrigin, - bool aCreateIfNotExists, nsIFile** aDirectory, bool* aCreated) { + const nsACString& aGroup, const nsACString& aOrigin, nsIFile** aDirectory, + bool* aCreated) { AssertIsOnIOThread(); MOZ_ASSERT(aDirectory); MOZ_ASSERT(aCreated); @@ -5681,10 +5677,7 @@ nsresult QuotaManager::EnsureOriginIsInitializedInternal( } bool created; - rv = EnsureOriginDirectory(directory, aCreateIfNotExists, &created); - if (rv == NS_ERROR_NOT_AVAILABLE) { - return rv; - } + rv = EnsureOriginDirectory(directory, &created); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -5803,7 +5796,6 @@ nsresult QuotaManager::EnsureTemporaryStorageIsInitialized() { } nsresult QuotaManager::EnsureOriginDirectory(nsIFile* aDirectory, - bool aCreateIfNotExists, bool* aCreated) { AssertIsOnIOThread(); MOZ_ASSERT(aDirectory); @@ -5816,10 +5808,6 @@ nsresult QuotaManager::EnsureOriginDirectory(nsIFile* aDirectory, } if (!exists) { - if (!aCreateIfNotExists) { - return NS_ERROR_NOT_AVAILABLE; - } - nsString leafName; rv = aDirectory->GetLeafName(leafName); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -7926,7 +7914,7 @@ nsresult InitOriginOp::DoDirectoryWork(QuotaManager* aQuotaManager) { bool created; nsresult rv = aQuotaManager->EnsureOriginIsInitializedInternal( mPersistenceType.Value(), mSuffix, mGroup, mOriginScope.GetOrigin(), - /* aCreateIfNotExists */ true, getter_AddRefs(directory), &created); + getter_AddRefs(directory), &created); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -8439,9 +8427,7 @@ nsresult PersistOp::DoDirectoryWork(QuotaManager* aQuotaManager) { } bool created; - rv = aQuotaManager->EnsureOriginDirectory(directory, - /* aCreateIfNotExists */ true, - &created); + rv = aQuotaManager->EnsureOriginDirectory(directory, &created); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/dom/quota/QuotaManager.h b/dom/quota/QuotaManager.h index 85c3a06f5930..294d8042a05f 100644 --- a/dom/quota/QuotaManager.h +++ b/dom/quota/QuotaManager.h @@ -262,18 +262,18 @@ class QuotaManager final : public BackgroundThreadObject { const nsACString& aSuffix, const nsACString& aGroup, const nsACString& aOrigin, - bool aCreateIfNotExists, nsIFile** aDirectory); - nsresult EnsureOriginIsInitializedInternal( - PersistenceType aPersistenceType, const nsACString& aSuffix, - const nsACString& aGroup, const nsACString& aOrigin, - bool aCreateIfNotExists, nsIFile** aDirectory, bool* aCreated); + nsresult EnsureOriginIsInitializedInternal(PersistenceType aPersistenceType, + const nsACString& aSuffix, + const nsACString& aGroup, + const nsACString& aOrigin, + nsIFile** aDirectory, + bool* aCreated); nsresult EnsureTemporaryStorageIsInitialized(); - nsresult EnsureOriginDirectory(nsIFile* aDirectory, bool aCreateIfNotExists, - bool* aCreated); + nsresult EnsureOriginDirectory(nsIFile* aDirectory, bool* aCreated); nsresult AboutToClearOrigins( const Nullable& aPersistenceType, diff --git a/dom/simpledb/ActorsParent.cpp b/dom/simpledb/ActorsParent.cpp index 5ce7bf38782b..9c9f3c485873 100644 --- a/dom/simpledb/ActorsParent.cpp +++ b/dom/simpledb/ActorsParent.cpp @@ -1152,7 +1152,7 @@ nsresult OpenOp::DatabaseWork() { nsCOMPtr dbDirectory; nsresult rv = quotaManager->EnsureOriginIsInitialized( PERSISTENCE_TYPE_DEFAULT, mSuffix, mGroup, mOrigin, - /* aCreateIfNotExists */ true, getter_AddRefs(dbDirectory)); + getter_AddRefs(dbDirectory)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }