Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2380)

Side by Side Diff: webkit/quota/usage_tracker.cc

Issue 16067003: [Quota] Refine usage handling in ClientUsageTracker. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: buildfix Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/quota/usage_tracker.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/quota/usage_tracker.h" 5 #include "webkit/quota/usage_tracker.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <deque> 8 #include <deque>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/message_loop_proxy.h" 14 #include "base/message_loop_proxy.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "net/base/net_util.h" 16 #include "net/base/net_util.h"
17 17
18 namespace quota { 18 namespace quota {
19 19
20 namespace { 20 namespace {
21 21
22 typedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator; 22 typedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator;
23 typedef ClientUsageTracker::OriginSetByHost OriginSetByHost;
23 24
24 void DidGetOriginUsage(const OriginUsageAccumulator& accumulator, 25 void DidGetOriginUsage(const OriginUsageAccumulator& accumulator,
25 const GURL& origin, 26 const GURL& origin,
26 int64 usage) { 27 int64 usage) {
27 accumulator.Run(origin, usage); 28 accumulator.Run(origin, usage);
28 } 29 }
29 30
30 void DidGetHostUsage(const UsageCallback& callback, 31 void DidGetHostUsage(const UsageCallback& callback,
31 int64 cached_usage, 32 int64 cached_usage,
32 int64 non_cached_usage) { 33 int64 non_cached_usage) {
33 DCHECK_GE(cached_usage, 0); 34 DCHECK_GE(cached_usage, 0);
34 DCHECK_GE(non_cached_usage, 0); 35 DCHECK_GE(non_cached_usage, 0);
35 callback.Run(cached_usage + non_cached_usage); 36 callback.Run(cached_usage + non_cached_usage);
36 } 37 }
37 38
38 void NoopHostUsageCallback(int64 usage) {} 39 void NoopHostUsageCallback(int64 usage) {}
39 40
41 bool EraseOriginFromOriginSet(OriginSetByHost* origins_by_host,
42 const std::string& host,
43 const GURL& origin) {
44 OriginSetByHost::iterator found = origins_by_host->find(host);
45 if (found == origins_by_host->end())
46 return false;
47
48 if (!found->second.erase(origin))
49 return false;
50
51 if (found->second.empty())
52 origins_by_host->erase(host);
53 return true;
54 }
55
56 bool OriginSetContainsOrigin(const OriginSetByHost& origins,
57 const std::string& host,
58 const GURL& origin) {
59 OriginSetByHost::const_iterator itr = origins.find(host);
60 return itr != origins.end() && ContainsKey(itr->second, origin);
61 }
62
40 } // namespace 63 } // namespace
41 64
42 // UsageTracker ---------------------------------------------------------- 65 // UsageTracker ----------------------------------------------------------
43 66
44 UsageTracker::UsageTracker(const QuotaClientList& clients, 67 UsageTracker::UsageTracker(const QuotaClientList& clients,
45 StorageType type, 68 StorageType type,
46 SpecialStoragePolicy* special_storage_policy) 69 SpecialStoragePolicy* special_storage_policy)
47 : type_(type), 70 : type_(type),
48 weak_factory_(this) { 71 weak_factory_(this) {
49 for (QuotaClientList::const_iterator iter = clients.begin(); 72 for (QuotaClientList::const_iterator iter = clients.begin();
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 } 218 }
196 219
197 // ClientUsageTracker ---------------------------------------------------- 220 // ClientUsageTracker ----------------------------------------------------
198 221
199 ClientUsageTracker::ClientUsageTracker( 222 ClientUsageTracker::ClientUsageTracker(
200 UsageTracker* tracker, QuotaClient* client, StorageType type, 223 UsageTracker* tracker, QuotaClient* client, StorageType type,
201 SpecialStoragePolicy* special_storage_policy) 224 SpecialStoragePolicy* special_storage_policy)
202 : tracker_(tracker), 225 : tracker_(tracker),
203 client_(client), 226 client_(client),
204 type_(type), 227 type_(type),
205 global_usage_(0), 228 global_limited_usage_(0),
206 global_unlimited_usage_(0), 229 global_unlimited_usage_(0),
207 global_usage_retrieved_(false), 230 global_usage_retrieved_(false),
208 special_storage_policy_(special_storage_policy) { 231 special_storage_policy_(special_storage_policy) {
209 DCHECK(tracker_); 232 DCHECK(tracker_);
210 DCHECK(client_); 233 DCHECK(client_);
211 if (special_storage_policy_) 234 if (special_storage_policy_)
212 special_storage_policy_->AddObserver(this); 235 special_storage_policy_->AddObserver(this);
213 } 236 }
214 237
215 ClientUsageTracker::~ClientUsageTracker() { 238 ClientUsageTracker::~ClientUsageTracker() {
216 if (special_storage_policy_) 239 if (special_storage_policy_)
217 special_storage_policy_->RemoveObserver(this); 240 special_storage_policy_->RemoveObserver(this);
218 } 241 }
219 242
220 void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { 243 void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) {
221 if (global_usage_retrieved_ && non_cached_origins_by_host_.empty()) { 244 if (global_usage_retrieved_ &&
222 callback.Run(global_usage_, global_unlimited_usage_); 245 non_cached_limited_origins_by_host_.empty() &&
246 non_cached_unlimited_origins_by_host_.empty()) {
247 callback.Run(global_limited_usage_ + global_unlimited_usage_,
248 global_unlimited_usage_);
223 return; 249 return;
224 } 250 }
225 251
226 client_->GetOriginsForType(type_, base::Bind( 252 client_->GetOriginsForType(type_, base::Bind(
227 &ClientUsageTracker::DidGetOriginsForGlobalUsage, AsWeakPtr(), 253 &ClientUsageTracker::DidGetOriginsForGlobalUsage, AsWeakPtr(),
228 callback)); 254 callback));
229 } 255 }
230 256
231 void ClientUsageTracker::GetHostUsage( 257 void ClientUsageTracker::GetHostUsage(
232 const std::string& host, const UsageCallback& callback) { 258 const std::string& host, const UsageCallback& callback) {
233 if (ContainsKey(cached_hosts_, host) && 259 if (ContainsKey(cached_hosts_, host) &&
234 !ContainsKey(non_cached_origins_by_host_, host)) { 260 !ContainsKey(non_cached_limited_origins_by_host_, host) &&
261 !ContainsKey(non_cached_unlimited_origins_by_host_, host)) {
235 // TODO(kinuko): Drop host_usage_map_ cache periodically. 262 // TODO(kinuko): Drop host_usage_map_ cache periodically.
236 callback.Run(GetCachedHostUsage(host)); 263 callback.Run(GetCachedHostUsage(host));
237 return; 264 return;
238 } 265 }
239 266
240 if (!host_usage_accumulators_.Add(host, base::Bind( 267 if (!host_usage_accumulators_.Add(host, base::Bind(
241 &DidGetHostUsage, callback))) 268 &DidGetHostUsage, callback)))
242 return; 269 return;
243 client_->GetOriginsForHost(type_, host, base::Bind( 270 client_->GetOriginsForHost(type_, host, base::Bind(
244 &ClientUsageTracker::DidGetOriginsForHostUsage, AsWeakPtr(), host)); 271 &ClientUsageTracker::DidGetOriginsForHostUsage, AsWeakPtr(), host));
245 } 272 }
246 273
247 void ClientUsageTracker::UpdateUsageCache( 274 void ClientUsageTracker::UpdateUsageCache(
248 const GURL& origin, int64 delta) { 275 const GURL& origin, int64 delta) {
249 std::string host = net::GetHostOrSpecFromURL(origin); 276 std::string host = net::GetHostOrSpecFromURL(origin);
250 if (cached_hosts_.find(host) != cached_hosts_.end()) { 277 if (cached_hosts_.find(host) != cached_hosts_.end()) {
251 if (!IsUsageCacheEnabledForOrigin(origin)) 278 if (!IsUsageCacheEnabledForOrigin(origin))
252 return; 279 return;
253 280
254 cached_usage_by_host_[host][origin] += delta; 281 cached_usage_by_host_[host][origin] += delta;
255 global_usage_ += delta;
256 if (IsStorageUnlimited(origin)) 282 if (IsStorageUnlimited(origin))
257 global_unlimited_usage_ += delta; 283 global_unlimited_usage_ += delta;
284 else
285 global_limited_usage_ += delta;
258 DCHECK_GE(cached_usage_by_host_[host][origin], 0); 286 DCHECK_GE(cached_usage_by_host_[host][origin], 0);
259 DCHECK_GE(global_usage_, 0); 287 DCHECK_GE(global_limited_usage_, 0);
260 return; 288 return;
261 } 289 }
262 290
263 // We don't know about this host yet, so populate our cache for it. 291 // We don't know about this host yet, so populate our cache for it.
264 GetHostUsage(host, base::Bind(&NoopHostUsageCallback)); 292 GetHostUsage(host, base::Bind(&NoopHostUsageCallback));
265 } 293 }
266 294
267 void ClientUsageTracker::GetCachedHostsUsage( 295 void ClientUsageTracker::GetCachedHostsUsage(
268 std::map<std::string, int64>* host_usage) const { 296 std::map<std::string, int64>* host_usage) const {
269 DCHECK(host_usage); 297 DCHECK(host_usage);
(...skipping 30 matching lines...) Expand all
300 int64 usage = found->second; 328 int64 usage = found->second;
301 UpdateUsageCache(origin, -usage); 329 UpdateUsageCache(origin, -usage);
302 cached_usage_for_host.erase(found); 330 cached_usage_for_host.erase(found);
303 if (cached_usage_for_host.empty()) { 331 if (cached_usage_for_host.empty()) {
304 cached_usage_by_host_.erase(found_host); 332 cached_usage_by_host_.erase(found_host);
305 cached_hosts_.erase(host); 333 cached_hosts_.erase(host);
306 } 334 }
307 } 335 }
308 } 336 }
309 337
310 non_cached_origins_by_host_[host].insert(origin); 338 if (IsStorageUnlimited(origin))
339 non_cached_unlimited_origins_by_host_[host].insert(origin);
340 else
341 non_cached_limited_origins_by_host_[host].insert(origin);
311 } else { 342 } else {
312 // Erase |origin| from |non_cached_origins_| and invalidate the usage cache 343 // Erase |origin| from |non_cached_origins_| and invalidate the usage cache
313 // for the host. 344 // for the host.
314 OriginSetByHost::iterator found = non_cached_origins_by_host_.find(host); 345 if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_,
315 if (found == non_cached_origins_by_host_.end()) 346 host, origin) ||
316 return; 347 EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_,
317 348 host, origin)) {
318 found->second.erase(origin);
319 if (found->second.empty()) {
320 non_cached_origins_by_host_.erase(found);
321 cached_hosts_.erase(host); 349 cached_hosts_.erase(host);
322 global_usage_retrieved_ = false; 350 global_usage_retrieved_ = false;
323 } 351 }
324 } 352 }
325 } 353 }
326 354
327 void ClientUsageTracker::DidGetOriginsForGlobalUsage( 355 void ClientUsageTracker::DidGetOriginsForGlobalUsage(
328 const GlobalUsageCallback& callback, 356 const GlobalUsageCallback& callback,
329 const std::set<GURL>& origins, StorageType type) { 357 const std::set<GURL>& origins, StorageType type) {
330 OriginSetByHost origins_by_host; 358 OriginSetByHost origins_by_host;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 } 458 }
431 if (--info->pending_jobs) 459 if (--info->pending_jobs)
432 return; 460 return;
433 461
434 AddCachedHost(host); 462 AddCachedHost(host);
435 host_usage_accumulators_.Run( 463 host_usage_accumulators_.Run(
436 host, MakeTuple(info->cached_usage, info->non_cached_usage)); 464 host, MakeTuple(info->cached_usage, info->non_cached_usage));
437 } 465 }
438 466
439 void ClientUsageTracker::AddCachedOrigin( 467 void ClientUsageTracker::AddCachedOrigin(
440 const GURL& origin, int64 usage) { 468 const GURL& origin, int64 new_usage) {
441 if (!IsUsageCacheEnabledForOrigin(origin)) 469 if (!IsUsageCacheEnabledForOrigin(origin))
442 return; 470 return;
443 471
444 std::string host = net::GetHostOrSpecFromURL(origin); 472 std::string host = net::GetHostOrSpecFromURL(origin);
445 UsageMap::iterator iter = cached_usage_by_host_[host]. 473 int64* usage = &cached_usage_by_host_[host][origin];
446 insert(UsageMap::value_type(origin, 0)).first; 474 int64 delta = new_usage - *usage;
447 int64 old_usage = iter->second; 475 *usage = new_usage;
448 iter->second = usage;
449 int64 delta = usage - old_usage;
450 if (delta) { 476 if (delta) {
451 global_usage_ += delta;
452 if (IsStorageUnlimited(origin)) 477 if (IsStorageUnlimited(origin))
453 global_unlimited_usage_ += delta; 478 global_unlimited_usage_ += delta;
479 else
480 global_limited_usage_ += delta;
454 } 481 }
455 DCHECK_GE(iter->second, 0); 482 DCHECK_GE(*usage, 0);
456 DCHECK_GE(global_usage_, 0); 483 DCHECK_GE(global_limited_usage_, 0);
457 } 484 }
458 485
459 void ClientUsageTracker::AddCachedHost(const std::string& host) { 486 void ClientUsageTracker::AddCachedHost(const std::string& host) {
460 cached_hosts_.insert(host); 487 cached_hosts_.insert(host);
461 } 488 }
462 489
463 int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) const { 490 int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) const {
464 HostUsageMap::const_iterator found = cached_usage_by_host_.find(host); 491 HostUsageMap::const_iterator found = cached_usage_by_host_.find(host);
465 if (found == cached_usage_by_host_.end()) 492 if (found == cached_usage_by_host_.end())
466 return 0; 493 return 0;
(...skipping 20 matching lines...) Expand all
487 return false; 514 return false;
488 515
489 DCHECK(IsUsageCacheEnabledForOrigin(origin)); 516 DCHECK(IsUsageCacheEnabledForOrigin(origin));
490 *usage = found->second; 517 *usage = found->second;
491 return true; 518 return true;
492 } 519 }
493 520
494 bool ClientUsageTracker::IsUsageCacheEnabledForOrigin( 521 bool ClientUsageTracker::IsUsageCacheEnabledForOrigin(
495 const GURL& origin) const { 522 const GURL& origin) const {
496 std::string host = net::GetHostOrSpecFromURL(origin); 523 std::string host = net::GetHostOrSpecFromURL(origin);
497 OriginSetByHost::const_iterator found = 524 return !OriginSetContainsOrigin(non_cached_limited_origins_by_host_,
498 non_cached_origins_by_host_.find(host); 525 host, origin) &&
499 return found == non_cached_origins_by_host_.end() || 526 !OriginSetContainsOrigin(non_cached_unlimited_origins_by_host_,
500 !ContainsKey(found->second, origin); 527 host, origin);
501 } 528 }
502 529
503 void ClientUsageTracker::OnGranted(const GURL& origin, 530 void ClientUsageTracker::OnGranted(const GURL& origin,
504 int change_flags) { 531 int change_flags) {
505 DCHECK(CalledOnValidThread()); 532 DCHECK(CalledOnValidThread());
506 if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) { 533 if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) {
507 int64 usage = 0; 534 int64 usage = 0;
508 if (GetCachedOriginUsage(origin, &usage)) 535 if (GetCachedOriginUsage(origin, &usage)) {
509 global_unlimited_usage_ += usage; 536 global_unlimited_usage_ += usage;
537 global_limited_usage_ -= usage;
538 }
539
540 std::string host = net::GetHostOrSpecFromURL(origin);
541 if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_,
542 host, origin))
543 non_cached_unlimited_origins_by_host_[host].insert(origin);
510 } 544 }
511 } 545 }
512 546
513 void ClientUsageTracker::OnRevoked(const GURL& origin, 547 void ClientUsageTracker::OnRevoked(const GURL& origin,
514 int change_flags) { 548 int change_flags) {
515 DCHECK(CalledOnValidThread()); 549 DCHECK(CalledOnValidThread());
516 if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) { 550 if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) {
517 int64 usage = 0; 551 int64 usage = 0;
518 if (GetCachedOriginUsage(origin, &usage)) 552 if (GetCachedOriginUsage(origin, &usage)) {
519 global_unlimited_usage_ -= usage; 553 global_unlimited_usage_ -= usage;
554 global_limited_usage_ += usage;
555 }
556
557 std::string host = net::GetHostOrSpecFromURL(origin);
558 if (EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_,
559 host, origin))
560 non_cached_limited_origins_by_host_[host].insert(origin);
520 } 561 }
521 } 562 }
522 563
523 void ClientUsageTracker::OnCleared() { 564 void ClientUsageTracker::OnCleared() {
524 DCHECK(CalledOnValidThread()); 565 DCHECK(CalledOnValidThread());
566 global_limited_usage_ += global_unlimited_usage_;
525 global_unlimited_usage_ = 0; 567 global_unlimited_usage_ = 0;
568
569 for (OriginSetByHost::const_iterator host_itr =
570 non_cached_unlimited_origins_by_host_.begin();
571 host_itr != non_cached_unlimited_origins_by_host_.end();
572 ++host_itr) {
573 for (std::set<GURL>::const_iterator origin_itr = host_itr->second.begin();
574 origin_itr != host_itr->second.end();
575 ++origin_itr)
576 non_cached_limited_origins_by_host_[host_itr->first].insert(*origin_itr);
577 }
578 non_cached_unlimited_origins_by_host_.clear();
526 } 579 }
527 580
528 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { 581 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const {
529 if (type_ == kStorageTypeSyncable) 582 if (type_ == kStorageTypeSyncable)
530 return false; 583 return false;
531 return special_storage_policy_.get() && 584 return special_storage_policy_.get() &&
532 special_storage_policy_->IsStorageUnlimited(origin); 585 special_storage_policy_->IsStorageUnlimited(origin);
533 } 586 }
534 587
535 } // namespace quota 588 } // namespace quota
OLDNEW
« no previous file with comments | « webkit/quota/usage_tracker.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698