diff options
author | tzik@chromium.org <tzik@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-30 12:28:24 +0000 |
---|---|---|
committer | tzik@chromium.org <tzik@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-30 12:28:24 +0000 |
commit | ec0c85be62690694c24bcff2a40c2f9dbd9c3c74 (patch) | |
tree | e5950840b31bb9d53d28958ea92295f229bf26aa /webkit | |
parent | b347ca13aa3bfcf1bb801e6c04695654c899796c (diff) | |
download | chromium_src-ec0c85be62690694c24bcff2a40c2f9dbd9c3c74.zip chromium_src-ec0c85be62690694c24bcff2a40c2f9dbd9c3c74.tar.gz chromium_src-ec0c85be62690694c24bcff2a40c2f9dbd9c3c74.tar.bz2 |
[Quota] Wire up limited origin usage retrieving.
This CL implements UsageTracker::GetGlobalLimitedUsage without gathering usages for all origins.
Using cache-disabled temporary unlimited storage will no longer hurt performance for other origins, after the change.
The CL also fixes usage calculation: the usages of cache-disabled limited origins will be counted as limited storage,
though it was counted as unlimited, previously.
BUG=220029
TEST=UsageTrackerTest.LimitedGlobalUsageTest
Review URL: https://chromiumcodereview.appspot.com/15950004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203125 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/browser/fileapi/obfuscated_file_util.cc | 1 | ||||
-rw-r--r-- | webkit/browser/fileapi/sandbox_mount_point_provider.cc | 6 | ||||
-rw-r--r-- | webkit/browser/quota/quota_callbacks.h | 2 | ||||
-rw-r--r-- | webkit/browser/quota/usage_tracker.cc | 131 | ||||
-rw-r--r-- | webkit/browser/quota/usage_tracker.h | 22 | ||||
-rw-r--r-- | webkit/browser/quota/usage_tracker_unittest.cc | 49 |
6 files changed, 167 insertions, 44 deletions
diff --git a/webkit/browser/fileapi/obfuscated_file_util.cc b/webkit/browser/fileapi/obfuscated_file_util.cc index 59dd7a8..e4808fe 100644 --- a/webkit/browser/fileapi/obfuscated_file_util.cc +++ b/webkit/browser/fileapi/obfuscated_file_util.cc @@ -269,7 +269,6 @@ PlatformFileError ObfuscatedFileUtil::CreateOrOpen( file_flags & base::PLATFORM_FILE_WRITE && context->quota_limit_type() == quota::kQuotaLimitTypeUnlimited) { DCHECK_EQ(base::PLATFORM_FILE_OK, error); - DCHECK_EQ(kFileSystemTypePersistent, url.type()); context->file_system_context()->GetQuotaUtil(url.type())-> StickyInvalidateUsageCache(url.origin(), url.type()); } diff --git a/webkit/browser/fileapi/sandbox_mount_point_provider.cc b/webkit/browser/fileapi/sandbox_mount_point_provider.cc index 9d24b3f1..5dbb078 100644 --- a/webkit/browser/fileapi/sandbox_mount_point_provider.cc +++ b/webkit/browser/fileapi/sandbox_mount_point_provider.cc @@ -323,12 +323,6 @@ FileSystemOperation* SandboxMountPointProvider::CreateFileSystemOperation( operation_context->set_quota_limit_type(quota::kQuotaLimitTypeLimited); } - // Temporarily disable returning unlimited storage policy for non-PERSISTENT - // storage. Since it may hurt performance for all FileSystem operation. - if (url.type() != kFileSystemTypePersistent && - operation_context->quota_limit_type() == quota::kQuotaLimitTypeUnlimited) - operation_context->set_quota_limit_type(quota::kQuotaLimitTypeLimited); - return new LocalFileSystemOperation(context, operation_context.Pass()); } diff --git a/webkit/browser/quota/quota_callbacks.h b/webkit/browser/quota/quota_callbacks.h index cc0e735..84f52c0 100644 --- a/webkit/browser/quota/quota_callbacks.h +++ b/webkit/browser/quota/quota_callbacks.h @@ -70,6 +70,8 @@ class CallbackQueue { typedef CallbackQueue<GlobalUsageCallback, Tuple2<int64, int64> > GlobalUsageCallbackQueue; +typedef CallbackQueue<UsageCallback, Tuple1<int64> > + UsageCallbackQueue; typedef CallbackQueue<AvailableSpaceCallback, Tuple2<QuotaStatusCode, int64> > AvailableSpaceCallbackQueue; diff --git a/webkit/browser/quota/usage_tracker.cc b/webkit/browser/quota/usage_tracker.cc index 6026d38..07f6b16 100644 --- a/webkit/browser/quota/usage_tracker.cc +++ b/webkit/browser/quota/usage_tracker.cc @@ -29,11 +29,11 @@ void DidGetOriginUsage(const OriginUsageAccumulator& accumulator, } void DidGetHostUsage(const UsageCallback& callback, - int64 cached_usage, - int64 non_cached_usage) { - DCHECK_GE(cached_usage, 0); - DCHECK_GE(non_cached_usage, 0); - callback.Run(cached_usage + non_cached_usage); + int64 limited_usage, + int64 unlimited_usage) { + DCHECK_GE(limited_usage, 0); + DCHECK_GE(unlimited_usage, 0); + callback.Run(limited_usage + unlimited_usage); } void NoopHostUsageCallback(int64 usage) {} @@ -95,7 +95,35 @@ ClientUsageTracker* UsageTracker::GetClientTracker(QuotaClient::ID client_id) { } void UsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { - GetGlobalUsage(base::Bind(&DidGetGlobalUsageForLimitedGlobalUsage, callback)); + if (global_usage_callbacks_.HasCallbacks()) { + global_usage_callbacks_.Add(base::Bind( + &DidGetGlobalUsageForLimitedGlobalUsage, callback)); + return; + } + + if (!global_limited_usage_callbacks_.Add(callback)) + return; + + AccumulateInfo* info = new AccumulateInfo; + // Calling GetGlobalLimitedUsage(accumulator) may synchronously + // return if the usage is cached, which may in turn dispatch + // the completion callback before we finish looping over + // all clients (because info->pending_clients may reach 0 + // during the loop). + // To avoid this, we add one more pending client as a sentinel + // and fire the sentinel callback at the end. + info->pending_clients = client_tracker_map_.size() + 1; + UsageCallback accumulator = base::Bind( + &UsageTracker::AccumulateClientGlobalLimitedUsage, + weak_factory_.GetWeakPtr(), base::Owned(info)); + + for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); + iter != client_tracker_map_.end(); + ++iter) + iter->second->GetGlobalLimitedUsage(accumulator); + + // Fire the sentinel as we've now called GetGlobalUsage for all clients. + accumulator.Run(0); } void UsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { @@ -186,12 +214,22 @@ void UsageTracker::SetUsageCacheEnabled(QuotaClient::ID client_id, client_tracker->SetUsageCacheEnabled(origin, enabled); } +void UsageTracker::AccumulateClientGlobalLimitedUsage(AccumulateInfo* info, + int64 limited_usage) { + info->usage += limited_usage; + if (--info->pending_clients) + return; + + // All the clients have returned their usage data. Dispatch the + // pending callbacks. + global_limited_usage_callbacks_.Run(MakeTuple(info->usage)); +} + void UsageTracker::AccumulateClientGlobalUsage(AccumulateInfo* info, int64 usage, int64 unlimited_usage) { info->usage += usage; info->unlimited_usage += unlimited_usage; - if (--info->pending_clients) return; @@ -250,6 +288,35 @@ ClientUsageTracker::~ClientUsageTracker() { special_storage_policy_->RemoveObserver(this); } +void ClientUsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { + if (!global_usage_retrieved_) { + GetGlobalUsage(base::Bind(&DidGetGlobalUsageForLimitedGlobalUsage, + callback)); + return; + } + + if (non_cached_limited_origins_by_host_.empty()) { + callback.Run(global_limited_usage_); + return; + } + + AccumulateInfo* info = new AccumulateInfo; + info->pending_jobs = non_cached_limited_origins_by_host_.size() + 1; + UsageCallback accumulator = base::Bind( + &ClientUsageTracker::AccumulateLimitedOriginUsage, AsWeakPtr(), + base::Owned(info), callback); + + for (OriginSetByHost::iterator host_itr = + non_cached_limited_origins_by_host_.begin(); + host_itr != non_cached_limited_origins_by_host_.end(); ++host_itr) { + for (std::set<GURL>::iterator origin_itr = host_itr->second.begin(); + origin_itr != host_itr->second.end(); ++origin_itr) + client_->GetOriginUsage(*origin_itr, type_, accumulator); + } + + accumulator.Run(global_limited_usage_); +} + void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { if (global_usage_retrieved_ && non_cached_limited_origins_by_host_.empty() && @@ -274,8 +341,8 @@ void ClientUsageTracker::GetHostUsage( return; } - if (!host_usage_accumulators_.Add(host, base::Bind( - &DidGetHostUsage, callback))) + if (!host_usage_accumulators_.Add( + host, base::Bind(&DidGetHostUsage, callback))) return; client_->GetOriginsForHost(type_, host, base::Bind( &ClientUsageTracker::DidGetOriginsForHostUsage, AsWeakPtr(), host)); @@ -362,6 +429,17 @@ void ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin, } } +void ClientUsageTracker::AccumulateLimitedOriginUsage( + AccumulateInfo* info, + const UsageCallback& callback, + int64 usage) { + info->limited_usage += usage; + if (--info->pending_jobs) + return; + + callback.Run(info->limited_usage); +} + void ClientUsageTracker::DidGetOriginsForGlobalUsage( const GlobalUsageCallback& callback, const std::set<GURL>& origins) { @@ -394,23 +472,19 @@ void ClientUsageTracker::DidGetOriginsForGlobalUsage( void ClientUsageTracker::AccumulateHostUsage( AccumulateInfo* info, const GlobalUsageCallback& callback, - int64 cached_usage, - int64 non_cached_usage) { - info->cached_usage += cached_usage; - info->non_cached_usage += non_cached_usage; + int64 limited_usage, + int64 unlimited_usage) { + info->limited_usage += limited_usage; + info->unlimited_usage += unlimited_usage; if (--info->pending_jobs) return; - int64 total_usage = info->cached_usage + info->non_cached_usage; - int64 unlimited_usage = global_unlimited_usage_ + info->non_cached_usage; - - DCHECK_GE(total_usage, 0); - DCHECK_GE(unlimited_usage, 0); - if (unlimited_usage > total_usage) - unlimited_usage = total_usage; + DCHECK_GE(info->limited_usage, 0); + DCHECK_GE(info->unlimited_usage, 0); global_usage_retrieved_ = true; - callback.Run(total_usage, unlimited_usage); + callback.Run(info->limited_usage + info->unlimited_usage, + info->unlimited_usage); } void ClientUsageTracker::DidGetOriginsForHostUsage( @@ -458,25 +532,24 @@ void ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo* info, if (usage < 0) usage = 0; - if (IsUsageCacheEnabledForOrigin(origin)) { - info->cached_usage += usage; + if (IsStorageUnlimited(origin)) + info->unlimited_usage += usage; + else + info->limited_usage += usage; + if (IsUsageCacheEnabledForOrigin(origin)) AddCachedOrigin(origin, usage); - } else { - info->non_cached_usage += usage; - } } if (--info->pending_jobs) return; AddCachedHost(host); host_usage_accumulators_.Run( - host, MakeTuple(info->cached_usage, info->non_cached_usage)); + host, MakeTuple(info->limited_usage, info->unlimited_usage)); } void ClientUsageTracker::AddCachedOrigin( const GURL& origin, int64 new_usage) { - if (!IsUsageCacheEnabledForOrigin(origin)) - return; + DCHECK(IsUsageCacheEnabledForOrigin(origin)); std::string host = net::GetHostOrSpecFromURL(origin); int64* usage = &cached_usage_by_host_[host][origin]; diff --git a/webkit/browser/quota/usage_tracker.h b/webkit/browser/quota/usage_tracker.h index 973ceea..8d6b2b6 100644 --- a/webkit/browser/quota/usage_tracker.h +++ b/webkit/browser/quota/usage_tracker.h @@ -65,6 +65,8 @@ class WEBKIT_STORAGE_EXPORT UsageTracker : public QuotaTaskObserver { typedef std::map<QuotaClient::ID, ClientUsageTracker*> ClientTrackerMap; friend class ClientUsageTracker; + void AccumulateClientGlobalLimitedUsage(AccumulateInfo* info, + int64 limited_usage); void AccumulateClientGlobalUsage(AccumulateInfo* info, int64 usage, int64 unlimited_usage); @@ -75,6 +77,7 @@ class WEBKIT_STORAGE_EXPORT UsageTracker : public QuotaTaskObserver { const StorageType type_; ClientTrackerMap client_tracker_map_; + UsageCallbackQueue global_limited_usage_callbacks_; GlobalUsageCallbackQueue global_usage_callbacks_; HostUsageCallbackMap host_usage_callbacks_; @@ -88,8 +91,8 @@ class ClientUsageTracker : public SpecialStoragePolicy::Observer, public base::NonThreadSafe, public base::SupportsWeakPtr<ClientUsageTracker> { public: - typedef base::Callback<void(int64 cached_usage, - int64 non_cached_usage)> HostUsageAccumulator; + typedef base::Callback<void(int64 limited_usage, + int64 unlimited_usage)> HostUsageAccumulator; typedef base::Callback<void(const GURL& origin, int64 usage)> OriginUsageAccumulator; typedef std::map<std::string, std::set<GURL> > OriginSetByHost; @@ -100,6 +103,7 @@ class ClientUsageTracker : public SpecialStoragePolicy::Observer, SpecialStoragePolicy* special_storage_policy); virtual ~ClientUsageTracker(); + void GetGlobalLimitedUsage(const UsageCallback& callback); void GetGlobalUsage(const GlobalUsageCallback& callback); void GetHostUsage(const std::string& host, const UsageCallback& callback); void UpdateUsageCache(const GURL& origin, int64 delta); @@ -120,18 +124,22 @@ class ClientUsageTracker : public SpecialStoragePolicy::Observer, struct AccumulateInfo { int pending_jobs; - int64 cached_usage; - int64 non_cached_usage; + int64 limited_usage; + int64 unlimited_usage; - AccumulateInfo() : pending_jobs(0), cached_usage(0), non_cached_usage(0) {} + AccumulateInfo() + : pending_jobs(0), limited_usage(0), unlimited_usage(0) {} }; + void AccumulateLimitedOriginUsage(AccumulateInfo* info, + const UsageCallback& callback, + int64 usage); void DidGetOriginsForGlobalUsage(const GlobalUsageCallback& callback, const std::set<GURL>& origins); void AccumulateHostUsage(AccumulateInfo* info, const GlobalUsageCallback& callback, - int64 cached_usage, - int64 non_cached_usage); + int64 limited_usage, + int64 unlimited_usage); void DidGetOriginsForHostUsage(const std::string& host, const std::set<GURL>& origins); diff --git a/webkit/browser/quota/usage_tracker_unittest.cc b/webkit/browser/quota/usage_tracker_unittest.cc index b897cfc..b9f4856 100644 --- a/webkit/browser/quota/usage_tracker_unittest.cc +++ b/webkit/browser/quota/usage_tracker_unittest.cc @@ -136,6 +136,15 @@ class UsageTrackerTest : public testing::Test { quota_client_.UpdateUsage(origin, delta); } + void GetGlobalLimitedUsage(int64* limited_usage) { + bool done = false; + usage_tracker_.GetGlobalLimitedUsage(base::Bind( + &DidGetUsage, &done, limited_usage)); + message_loop_.RunUntilIdle(); + + EXPECT_TRUE(done); + } + void GetGlobalUsage(int64* usage, int64* unlimited_usage) { bool done = false; usage_tracker_.GetGlobalUsage(base::Bind( @@ -261,7 +270,7 @@ TEST_F(UsageTrackerTest, CacheDisabledClientTest) { GetGlobalUsage(&usage, &unlimited_usage); GetHostUsage(host, &host_usage); EXPECT_EQ(400, usage); - EXPECT_EQ(400, unlimited_usage); + EXPECT_EQ(0, unlimited_usage); EXPECT_EQ(400, host_usage); SetUsageCacheEnabled(origin, true); @@ -274,4 +283,42 @@ TEST_F(UsageTrackerTest, CacheDisabledClientTest) { EXPECT_EQ(500, host_usage); } +TEST_F(UsageTrackerTest, LimitedGlobalUsageTest) { + const GURL kNormal("http://normal"); + const GURL kUnlimited("http://unlimited"); + const GURL kNonCached("http://non_cached"); + const GURL kNonCachedUnlimited("http://non_cached-unlimited"); + + GrantUnlimitedStoragePolicy(kUnlimited); + GrantUnlimitedStoragePolicy(kNonCachedUnlimited); + + SetUsageCacheEnabled(kNonCached, false); + SetUsageCacheEnabled(kNonCachedUnlimited, false); + + UpdateUsageWithoutNotification(kNormal, 1); + UpdateUsageWithoutNotification(kUnlimited, 2); + UpdateUsageWithoutNotification(kNonCached, 4); + UpdateUsageWithoutNotification(kNonCachedUnlimited, 8); + + int64 limited_usage = 0; + int64 total_usage = 0; + int64 unlimited_usage = 0; + + GetGlobalLimitedUsage(&limited_usage); + GetGlobalUsage(&total_usage, &unlimited_usage); + EXPECT_EQ(1 + 4, limited_usage); + EXPECT_EQ(1 + 2 + 4 + 8, total_usage); + EXPECT_EQ(2 + 8, unlimited_usage); + + UpdateUsageWithoutNotification(kNonCached, 16 - 4); + UpdateUsageWithoutNotification(kNonCachedUnlimited, 32 - 8); + + GetGlobalLimitedUsage(&limited_usage); + GetGlobalUsage(&total_usage, &unlimited_usage); + EXPECT_EQ(1 + 16, limited_usage); + EXPECT_EQ(1 + 2 + 16 + 32, total_usage); + EXPECT_EQ(2 + 32, unlimited_usage); +} + + } // namespace quota |