From d18d54a30085f478693c332a12b83272c75f944e Mon Sep 17 00:00:00 2001 From: smolnar Date: Tue, 2 Feb 2021 14:46:30 +0200 Subject: [PATCH] Backed out 4 changesets (bug 1685677) for causing build bustage in TestFlatten. CLOSED TREE DONTBUILD Backed out changeset 0110eb26213b (bug 1685677) Backed out changeset e3223c398959 (bug 1685677) Backed out changeset d1fbaf6882a3 (bug 1685677) Backed out changeset e1e26422161e (bug 1685677) --- dom/quota/ActorsParent.cpp | 325 +++++++++++---------------- dom/quota/Flatten.h | 118 ---------- dom/quota/QuotaManager.h | 37 +-- dom/quota/test/gtest/TestFlatten.cpp | 74 ------ dom/quota/test/gtest/moz.build | 1 - mfbt/NotNull.h | 5 +- 6 files changed, 140 insertions(+), 420 deletions(-) delete mode 100644 dom/quota/Flatten.h delete mode 100644 dom/quota/test/gtest/TestFlatten.cpp diff --git a/dom/quota/ActorsParent.cpp b/dom/quota/ActorsParent.cpp index 4f374059d1b2..20140416ecca 100644 --- a/dom/quota/ActorsParent.cpp +++ b/dom/quota/ActorsParent.cpp @@ -7,7 +7,6 @@ #include "ActorsParent.h" // Local includes -#include "Flatten.h" #include "InitializationTypes.h" #include "OriginScope.h" #include "QuotaCommon.h" @@ -951,15 +950,15 @@ class OriginInfo final { bool mDirectoryExists; }; -class OriginInfoAccessTimeComparator { +class OriginInfoLRUComparator { public: - bool Equals(const NotNull>& a, - const NotNull>& b) const { + bool Equals(const NotNull>& a, + const NotNull>& b) const { return a->LockedAccessTime() == b->LockedAccessTime(); } - bool LessThan(const NotNull>& a, - const NotNull>& b) const { + bool LessThan(const NotNull>& a, + const NotNull>& b) const { return a->LockedAccessTime() < b->LockedAccessTime(); } }; @@ -1024,11 +1023,14 @@ class GroupInfoPair { MOZ_COUNTED_DTOR(GroupInfoPair) private: - RefPtr LockedGetGroupInfo(PersistenceType aPersistenceType) { + already_AddRefed LockedGetGroupInfo( + PersistenceType aPersistenceType) { AssertCurrentThreadOwnsQuotaMutex(); MOZ_ASSERT(aPersistenceType != PERSISTENCE_TYPE_PERSISTENT); - return GetGroupInfoForPersistenceType(aPersistenceType); + RefPtr groupInfo = + GetGroupInfoForPersistenceType(aPersistenceType); + return groupInfo.forget(); } void LockedSetGroupInfo(PersistenceType aPersistenceType, @@ -3781,8 +3783,8 @@ uint64_t QuotaManager::CollectOriginsForEviction( static void GetInactiveOriginInfos( const nsTArray>>& aOriginInfos, const nsTArray>& aLocks, - OriginInfosFlatTraversable& aInactiveOriginInfos) { - for (const auto& originInfo : aOriginInfos) { + nsTArray>>& aInactiveOriginInfos) { + for (const NotNull>& originInfo : aOriginInfos) { MOZ_ASSERT(originInfo->mGroupInfo->mPersistenceType != PERSISTENCE_TYPE_PERSISTENT); @@ -3801,8 +3803,8 @@ uint64_t QuotaManager::CollectOriginsForEviction( if (!match) { MOZ_ASSERT(!originInfo->mQuotaObjects.Count(), "Inactive origin shouldn't have open files!"); - aInactiveOriginInfos.InsertElementSorted( - originInfo, OriginInfoAccessTimeComparator()); + aInactiveOriginInfos.InsertElementSorted(originInfo, + OriginInfoLRUComparator()); } } } @@ -3830,7 +3832,7 @@ uint64_t QuotaManager::CollectOriginsForEviction( } } - OriginInfosFlatTraversable inactiveOrigins; + nsTArray>> inactiveOrigins; // Enumerate and process inactive origins. This must be protected by the // mutex. @@ -6437,8 +6439,8 @@ QuotaManager::EnsurePersistentOriginIsInitialized(const QuotaInfo& aQuotaInfo) { return std::pair(std::move(directory), created); }(); - if (auto& info = mOriginInitializationInfos.GetOrInsert(aQuotaInfo.mOrigin); - !info.mPersistentOriginAttempted) { + auto& info = mOriginInitializationInfos.GetOrInsert(aQuotaInfo.mOrigin); + if (!info.mPersistentOriginAttempted) { Telemetry::Accumulate(Telemetry::QM_FIRST_INITIALIZATION_ATTEMPT, kPersistentOriginTelemetryKey, static_cast(res.isOk())); @@ -6547,7 +6549,7 @@ nsresult QuotaManager::EnsureTemporaryStorageIsInitialized() { mTemporaryStorageLimit = GetTemporaryStorageLimit( /* aAvailableSpaceBytes */ diskSpaceAvailable + mTemporaryStorageUsage); - CleanupTemporaryStorage(); + CheckTemporaryStorageLimits(); return NS_OK; } @@ -7038,8 +7040,8 @@ void QuotaManager::LockedRemoveQuotaForOrigin( MOZ_ASSERT(pair); - if (RefPtr groupInfo = - pair->LockedGetGroupInfo(aPersistenceType)) { + RefPtr groupInfo = pair->LockedGetGroupInfo(aPersistenceType); + if (groupInfo) { groupInfo->LockedRemoveOriginInfo(aGroupAndOrigin.mOrigin); if (!groupInfo->LockedHasOriginInfos()) { @@ -7089,219 +7091,150 @@ already_AddRefed QuotaManager::LockedGetOriginInfo( return nullptr; } -template -void QuotaManager::MaybeInsertOriginInfos( - Iterator aDest, const RefPtr& aTemporaryGroupInfo, - const RefPtr& aDefaultGroupInfo, Pred&& aPred) { - const auto copy = [&aDest, &aPred](const GroupInfo& groupInfo) { - std::copy_if(groupInfo.mOriginInfos.cbegin(), groupInfo.mOriginInfos.cend(), - aDest, aPred); - }; +void QuotaManager::CheckTemporaryStorageLimits() { + AssertIsOnIOThread(); - if (aTemporaryGroupInfo) { - MOZ_ASSERT(PERSISTENCE_TYPE_TEMPORARY == - aTemporaryGroupInfo->GetPersistenceType()); + const auto doomedOrigins = [this] { + const auto doomedOriginInfos = [this] { + nsTArray>> doomedOriginInfos; + MutexAutoLock lock(mQuotaMutex); - copy(*aTemporaryGroupInfo); - } - if (aDefaultGroupInfo) { - MOZ_ASSERT(PERSISTENCE_TYPE_DEFAULT == - aDefaultGroupInfo->GetPersistenceType()); + for (const auto& entry : mGroupInfoPairs) { + const auto& pair = entry.GetData(); - copy(*aDefaultGroupInfo); - } -} + MOZ_ASSERT(!entry.GetKey().IsEmpty()); + MOZ_ASSERT(pair); -template -QuotaManager::OriginInfosFlatTraversable -QuotaManager::CollectLRUOriginInfosUntil(Collect&& aCollect, Pred&& aPred) { - OriginInfosFlatTraversable originInfos; + uint64_t groupUsage = 0; - std::forward(aCollect)(MakeBackInserter(originInfos)); + RefPtr temporaryGroupInfo = + pair->LockedGetGroupInfo(PERSISTENCE_TYPE_TEMPORARY); + if (temporaryGroupInfo) { + groupUsage += temporaryGroupInfo->mUsage; + } - originInfos.Sort(OriginInfoAccessTimeComparator()); + RefPtr defaultGroupInfo = + pair->LockedGetGroupInfo(PERSISTENCE_TYPE_DEFAULT); + if (defaultGroupInfo) { + groupUsage += defaultGroupInfo->mUsage; + } - const auto foundIt = std::find_if(originInfos.cbegin(), originInfos.cend(), - std::forward(aPred)); + if (groupUsage > 0) { + QuotaManager* quotaManager = QuotaManager::Get(); + MOZ_ASSERT(quotaManager, "Shouldn't be null!"); - originInfos.TruncateLength(foundIt - originInfos.cbegin()); + if (groupUsage > quotaManager->GetGroupLimit()) { + nsTArray>> originInfos; + if (temporaryGroupInfo) { + originInfos.AppendElements(temporaryGroupInfo->mOriginInfos); + } + if (defaultGroupInfo) { + originInfos.AppendElements(defaultGroupInfo->mOriginInfos); + } + originInfos.Sort(OriginInfoLRUComparator()); - return originInfos; -} + for (uint32_t i = 0; i < originInfos.Length(); i++) { + const NotNull>& originInfo = originInfos[i]; + if (originInfo->LockedPersisted()) { + continue; + } -QuotaManager::OriginInfosNestedTraversable -QuotaManager::LockedGetOriginInfosExceedingGroupLimit() const { - mQuotaMutex.AssertCurrentThreadOwns(); - - OriginInfosNestedTraversable originInfos; - - for (const auto& entry : mGroupInfoPairs) { - const auto& pair = entry.GetData(); - - MOZ_ASSERT(!entry.GetKey().IsEmpty()); - MOZ_ASSERT(pair); - - uint64_t groupUsage = 0; - - const RefPtr temporaryGroupInfo = - pair->LockedGetGroupInfo(PERSISTENCE_TYPE_TEMPORARY); - if (temporaryGroupInfo) { - groupUsage += temporaryGroupInfo->mUsage; - } - - const RefPtr defaultGroupInfo = - pair->LockedGetGroupInfo(PERSISTENCE_TYPE_DEFAULT); - if (defaultGroupInfo) { - groupUsage += defaultGroupInfo->mUsage; - } - - if (groupUsage > 0) { - QuotaManager* quotaManager = QuotaManager::Get(); - MOZ_ASSERT(quotaManager, "Shouldn't be null!"); - - if (groupUsage > quotaManager->GetGroupLimit()) { - originInfos.AppendElement(CollectLRUOriginInfosUntil( - [&temporaryGroupInfo, &defaultGroupInfo](auto inserter) { - MaybeInsertOriginInfos(std::move(inserter), temporaryGroupInfo, - defaultGroupInfo, - [](const auto& originInfo) { - return !originInfo->LockedPersisted(); - }); - }, - [&groupUsage, quotaManager](const auto& originInfo) { + doomedOriginInfos.AppendElement(originInfo); groupUsage -= originInfo->LockedUsage(); - return groupUsage <= quotaManager->GetGroupLimit(); - })); + if (groupUsage <= quotaManager->GetGroupLimit()) { + break; + } + } + } + } } - } - } - return originInfos; -} + uint64_t usage = std::accumulate( + doomedOriginInfos.cbegin(), doomedOriginInfos.cend(), uint64_t(0), + [](uint64_t oldValue, const auto& originInfo) { + return oldValue + originInfo->LockedUsage(); + }); -QuotaManager::OriginInfosFlatTraversable -QuotaManager::LockedGetOriginInfosExceedingGlobalLimit( - const OriginInfosNestedTraversable& aAlreadyDoomedOriginInfos, - const uint64_t aAlreadyDoomedUsage) const { - mQuotaMutex.AssertCurrentThreadOwns(); + if (mTemporaryStorageUsage - usage > mTemporaryStorageLimit) { + nsTArray>> originInfos; - return CollectLRUOriginInfosUntil( - [this, &aAlreadyDoomedOriginInfos](auto inserter) { for (const auto& entry : mGroupInfoPairs) { const auto& pair = entry.GetData(); MOZ_ASSERT(!entry.GetKey().IsEmpty()); MOZ_ASSERT(pair); - MaybeInsertOriginInfos( - inserter, pair->LockedGetGroupInfo(PERSISTENCE_TYPE_TEMPORARY), - pair->LockedGetGroupInfo(PERSISTENCE_TYPE_DEFAULT), - [&aAlreadyDoomedOriginInfos](const auto& originInfo) { - return !std::any_of(aAlreadyDoomedOriginInfos.cbegin(), - aAlreadyDoomedOriginInfos.cend(), - // XXX This should capture originInfo by - // value, but it can't due to Bug 1421435. - [&originInfo](const auto& array) { - return array.Contains(originInfo); - }) && - !originInfo->LockedPersisted(); - }); - } - }, - [temporaryStorageUsage = mTemporaryStorageUsage - aAlreadyDoomedUsage, - temporaryStorageLimit = mTemporaryStorageLimit, - doomedUsage = uint64_t{0}](const auto& originInfo) mutable { - if (temporaryStorageUsage - doomedUsage <= temporaryStorageLimit) { - return true; + RefPtr groupInfo = + pair->LockedGetGroupInfo(PERSISTENCE_TYPE_TEMPORARY); + if (groupInfo) { + originInfos.AppendElements(groupInfo->mOriginInfos); + } + + groupInfo = pair->LockedGetGroupInfo(PERSISTENCE_TYPE_DEFAULT); + if (groupInfo) { + originInfos.AppendElements(groupInfo->mOriginInfos); + } } - doomedUsage += originInfo->LockedUsage(); - return false; - }); -} + originInfos.RemoveElementsBy( + [&doomedOriginInfos](const auto& originInfo) { + return doomedOriginInfos.Contains(originInfo) || + originInfo->LockedPersisted(); + }); -QuotaManager::OriginInfosNestedTraversable -QuotaManager::GetOriginInfosExceedingLimits() const { - MutexAutoLock lock(mQuotaMutex); + originInfos.Sort(OriginInfoLRUComparator()); - auto originInfos = LockedGetOriginInfosExceedingGroupLimit(); + for (uint32_t i = 0; i < originInfos.Length(); i++) { + if (mTemporaryStorageUsage - usage <= mTemporaryStorageLimit) { + originInfos.TruncateLength(i); + break; + } - const uint64_t doomedUsage = std::accumulate( - originInfos.cbegin(), originInfos.cend(), uint64_t(0), - [](uint64_t oldValue, const auto& currentOriginInfos) { - return std::accumulate(currentOriginInfos.cbegin(), - currentOriginInfos.cend(), oldValue, - [](uint64_t oldValue, const auto& originInfo) { - return oldValue + originInfo->LockedUsage(); - }); - }); + usage += originInfos[i]->LockedUsage(); + } - // Evicting origins that exceed their group limit also affects the global - // temporary storage usage. If the global temporary storage limit would still - // be exceeded after evicting the origins that were already selected, we need - // to specifically evict origins to get below the global limit. - if (mTemporaryStorageUsage - doomedUsage > mTemporaryStorageLimit) { - originInfos.AppendElement( - LockedGetOriginInfosExceedingGlobalLimit(originInfos, doomedUsage)); - } + doomedOriginInfos.AppendElements(originInfos); + } - return originInfos; -} + return doomedOriginInfos; + }(); -void QuotaManager::ClearOrigins( - const OriginInfosNestedTraversable& aDoomedOriginInfos) { - AssertIsOnIOThread(); - - // XXX Does this need to be done a) in order and/or b) sequentially? - for (const auto& doomedOriginInfo : - Flatten(aDoomedOriginInfos)) { + for (const auto& doomedOriginInfo : doomedOriginInfos) { #ifdef DEBUG - { - MutexAutoLock lock(mQuotaMutex); - MOZ_ASSERT(!doomedOriginInfo->LockedPersisted()); - } + { + MutexAutoLock lock(mQuotaMutex); + MOZ_ASSERT(!doomedOriginInfo->LockedPersisted()); + } #endif - DeleteFilesForOrigin(doomedOriginInfo->mGroupInfo->mPersistenceType, - doomedOriginInfo->mOrigin); - } - - struct OriginParams { - nsCString mOrigin; - PersistenceType mPersistenceType; - }; - - nsTArray clearedOrigins; - - { - MutexAutoLock lock(mQuotaMutex); - - for (const auto& doomedOriginInfo : - Flatten(aDoomedOriginInfos)) { - // LockedRemoveQuotaForOrigin might remove the group info; - // OriginInfo::mGroupInfo is only a raw pointer, so we need to store the - // information for calling OriginClearCompleted below in a separate array. - clearedOrigins.AppendElement( - OriginParams{doomedOriginInfo->mOrigin, - doomedOriginInfo->mGroupInfo->mPersistenceType}); - - LockedRemoveQuotaForOrigin( - doomedOriginInfo->mGroupInfo->mPersistenceType, - {doomedOriginInfo->mGroupInfo->mGroup, doomedOriginInfo->mOrigin}); + DeleteFilesForOrigin(doomedOriginInfo->mGroupInfo->mPersistenceType, + doomedOriginInfo->mOrigin); } - } - for (const auto& clearedOrigin : clearedOrigins) { - OriginClearCompleted(clearedOrigin.mPersistenceType, clearedOrigin.mOrigin, + nsTArray doomedOrigins; + { + MutexAutoLock lock(mQuotaMutex); + + for (const auto& doomedOriginInfo : doomedOriginInfos) { + PersistenceType persistenceType = + doomedOriginInfo->mGroupInfo->mPersistenceType; + const GroupAndOrigin groupAndOrigin = { + doomedOriginInfo->mGroupInfo->mGroup, doomedOriginInfo->mOrigin}; + LockedRemoveQuotaForOrigin(persistenceType, groupAndOrigin); + + doomedOrigins.EmplaceBack( + OriginParams(persistenceType, groupAndOrigin.mOrigin)); + } + } + + return doomedOrigins; + }(); + + for (const OriginParams& doomedOrigin : doomedOrigins) { + OriginClearCompleted(doomedOrigin.mPersistenceType, doomedOrigin.mOrigin, Nullable()); } -} - -void QuotaManager::CleanupTemporaryStorage() { - AssertIsOnIOThread(); - - ClearOrigins(GetOriginInfosExceedingLimits()); if (mTemporaryStorageUsage > mTemporaryStorageLimit) { // If disk space is still low after origin clear, notify storage pressure. @@ -7376,8 +7309,8 @@ bool QuotaManager::IsSanitizedOriginValid(const nsACString& aSanitizedOrigin) { int64_t QuotaManager::GenerateDirectoryLockId() { const int64_t directorylockId = mNextDirectoryLockId; - if (CheckedInt64 result = CheckedInt64(mNextDirectoryLockId) + 1; - result.isValid()) { + CheckedInt64 result = CheckedInt64(mNextDirectoryLockId) + 1; + if (result.isValid()) { mNextDirectoryLockId = result.value(); } else { NS_WARNING("Quota manager has run out of ids for directory locks!"); diff --git a/dom/quota/Flatten.h b/dom/quota/Flatten.h deleted file mode 100644 index 2eb29c6010c2..000000000000 --- a/dom/quota/Flatten.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef DOM_QUOTA_FLATTEN_H_ -#define DOM_QUOTA_FLATTEN_H_ - -#include -#include -#include - -// XXX This should be moved to MFBT. - -namespace mozilla::dom::quota { - -namespace detail { - -using std::begin; -using std::end; - -template -auto Flatten(NestedRange&& aRange) -> std::enable_if_t< - std::is_same_v()))::value_type>>, - std::conditional_t, - std::decay_t, NestedRange>> { - return std::forward(aRange); -} - -template -struct FlatIter { - using OuterIterator = - decltype(begin(std::declval&>())); - using InnerIterator = - decltype(begin(*begin(std::declval&>()))); - - explicit FlatIter(const NestedRange& aRange, OuterIterator aIter) - : mOuterIter{std::move(aIter)}, mOuterEnd{end(aRange)} { - InitInner(); - } - - const T& operator*() const { return *mInnerIter; } - - FlatIter& operator++() { - ++mInnerIter; - if (mInnerIter == mInnerEnd) { - ++mOuterIter; - InitInner(); - } - return *this; - } - - bool operator!=(const FlatIter& aOther) const { - return mOuterIter != aOther.mOuterIter || - (mOuterIter != mOuterEnd && mInnerIter != aOther.mInnerIter); - } - - private: - void InitInner() { - while (mOuterIter != mOuterEnd) { - const typename OuterIterator::value_type& innerRange = *mOuterIter; - - mInnerIter = begin(innerRange); - mInnerEnd = end(innerRange); - - if (mInnerIter != mInnerEnd) { - break; - } - - ++mOuterIter; - } - } - - OuterIterator mOuterIter; - const OuterIterator mOuterEnd; - - InnerIterator mInnerIter; - InnerIterator mInnerEnd; -}; - -template -struct FlatRange { - explicit FlatRange(NestedRange aRange) : mRange{std::move(aRange)} {} - - auto begin() const { - using std::begin; - return FlatIter{mRange, begin(mRange)}; - } - auto end() const { - using std::end; - return FlatIter{mRange, end(mRange)}; - } - - private: - NestedRange mRange; -}; - -template -auto Flatten(NestedRange&& aRange) -> std::enable_if_t< - !std::is_same_v< - T, std::decay_t&>()))::value_type>>, - FlatRange> { - return FlatRange{std::forward(aRange)}; -} - -} // namespace detail - -template -auto Flatten(NestedRange&& aRange) -> decltype(auto) { - return detail::Flatten(std::forward(aRange)); -} - -} // namespace mozilla::dom::quota - -#endif diff --git a/dom/quota/QuotaManager.h b/dom/quota/QuotaManager.h index 4ebf673f347d..b41cd8b3a634 100644 --- a/dom/quota/QuotaManager.h +++ b/dom/quota/QuotaManager.h @@ -114,6 +114,14 @@ class NS_NO_VTABLE OpenDirectoryListener : public RefCountedObject { virtual ~OpenDirectoryListener() = default; }; +struct OriginParams { + OriginParams(PersistenceType aPersistenceType, const nsACString& aOrigin) + : mOrigin(aOrigin), mPersistenceType(aPersistenceType) {} + + nsCString mOrigin; + PersistenceType mPersistenceType; +}; + class QuotaManager final : public BackgroundThreadObject { friend class DirectoryLockImpl; friend class GroupInfo; @@ -558,23 +566,7 @@ class QuotaManager final : public BackgroundThreadObject { int64_t aAccessTime, bool aPersisted, nsIFile* aDirectory); - using OriginInfosFlatTraversable = - nsTArray>>; - - using OriginInfosNestedTraversable = - nsTArray>>>; - - OriginInfosNestedTraversable LockedGetOriginInfosExceedingGroupLimit() const; - - OriginInfosFlatTraversable LockedGetOriginInfosExceedingGlobalLimit( - const OriginInfosNestedTraversable& aAlreadyDoomedOriginInfos, - uint64_t aAlreadyDoomedUsage) const; - - OriginInfosNestedTraversable GetOriginInfosExceedingLimits() const; - - void ClearOrigins(const OriginInfosNestedTraversable& aDoomedOriginInfos); - - void CleanupTemporaryStorage(); + void CheckTemporaryStorageLimits(); void DeleteFilesForOrigin(PersistenceType aPersistenceType, const nsACString& aOrigin); @@ -598,15 +590,6 @@ class QuotaManager final : public BackgroundThreadObject { void MaybeRecordShutdownStep(Maybe aClientType, const nsACString& aStepDescription); - template - static void MaybeInsertOriginInfos( - Iterator aDest, const RefPtr& aTemporaryGroupInfo, - const RefPtr& aDefaultGroupInfo, Pred&& aPred); - - template - static OriginInfosFlatTraversable CollectLRUOriginInfosUntil( - Collect&& aCollect, Pred&& aPred); - // Thread on which IO is performed. LazyInitializedOnceNotNull> mIOThread; @@ -622,7 +605,7 @@ class QuotaManager final : public BackgroundThreadObject { // Accesses to mQuotaManagerShutdownSteps must be protected by mQuotaMutex. nsCString mQuotaManagerShutdownSteps; - mutable mozilla::Mutex mQuotaMutex; + mozilla::Mutex mQuotaMutex; nsClassHashtable mGroupInfoPairs; diff --git a/dom/quota/test/gtest/TestFlatten.cpp b/dom/quota/test/gtest/TestFlatten.cpp deleted file mode 100644 index 12f4259a25a5..000000000000 --- a/dom/quota/test/gtest/TestFlatten.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "Flatten.h" - -#include "gtest/gtest.h" - -#include "mozilla/Unused.h" -#include "nsTArray.h" - -namespace mozilla::dom::quota { - -TEST(Flatten, FlatEmpty) -{ - for (const auto& item : Flatten(nsTArray{})) { - Unused << item; - FAIL(); - } -} - -TEST(Flatten, NestedOuterEmpty) -{ - for (const auto& item : Flatten(nsTArray>{})) { - Unused << item; - FAIL(); - } -} - -TEST(Flatten, NestedInnerEmpty) -{ - for (const auto& item : - Flatten(nsTArray>{CopyableTArray{}})) { - Unused << item; - FAIL(); - } -} - -TEST(Flatten, NestedInnerSingular) -{ - nsTArray flattened; - for (const auto& item : - Flatten(nsTArray>{CopyableTArray{1}})) { - flattened.AppendElement(item); - } - - EXPECT_EQ(nsTArray{1}, flattened); -} - -TEST(Flatten, NestedInnerSingulars) -{ - nsTArray flattened; - for (const auto& item : Flatten(nsTArray>{ - CopyableTArray{1}, CopyableTArray{2}})) { - flattened.AppendElement(item); - } - - EXPECT_EQ((nsTArray{1, 2}), flattened); -} - -TEST(Flatten, NestedInnerNonSingulars) -{ - nsTArray flattened; - for (const auto& item : Flatten(nsTArray>{ - CopyableTArray{1, 2}, CopyableTArray{3, 4}})) { - flattened.AppendElement(item); - } - - EXPECT_EQ((nsTArray{1, 2, 3, 4}), flattened); -} - -} // namespace mozilla::dom::quota diff --git a/dom/quota/test/gtest/moz.build b/dom/quota/test/gtest/moz.build index f91a5a867e2a..d79c10651275 100644 --- a/dom/quota/test/gtest/moz.build +++ b/dom/quota/test/gtest/moz.build @@ -7,7 +7,6 @@ UNIFIED_SOURCES = [ "TestCheckedUnsafePtr.cpp", "TestEncryptedStream.cpp", - "TestFlatten.cpp", "TestQuotaCommon.cpp", "TestQuotaManager.cpp", "TestUsageInfo.cpp", diff --git a/mfbt/NotNull.h b/mfbt/NotNull.h index b434bb64ae1b..bbb4796ec30e 100644 --- a/mfbt/NotNull.h +++ b/mfbt/NotNull.h @@ -77,10 +77,7 @@ struct CopyablePtr { T mPtr; template - explicit CopyablePtr(U&& aPtr) : mPtr{std::forward(aPtr)} {} - - template - explicit CopyablePtr(CopyablePtr aPtr) : mPtr{std::move(aPtr.mPtr)} {} + explicit CopyablePtr(U aPtr) : mPtr{std::move(aPtr)} {} }; } // namespace detail