| Index: webkit/quota/usage_tracker.cc
|
| diff --git a/webkit/quota/usage_tracker.cc b/webkit/quota/usage_tracker.cc
|
| index e2f3e608e96261eacd68fad31b3a92d2056aaa59..1cc72052e81430c966706361dd3fb5c8b27ec36e 100644
|
| --- a/webkit/quota/usage_tracker.cc
|
| +++ b/webkit/quota/usage_tracker.cc
|
| @@ -20,6 +20,7 @@ namespace quota {
|
| namespace {
|
|
|
| typedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator;
|
| +typedef ClientUsageTracker::OriginSetByHost OriginSetByHost;
|
|
|
| void DidGetOriginUsage(const OriginUsageAccumulator& accumulator,
|
| const GURL& origin,
|
| @@ -37,6 +38,28 @@ void DidGetHostUsage(const UsageCallback& callback,
|
|
|
| void NoopHostUsageCallback(int64 usage) {}
|
|
|
| +bool EraseOriginFromOriginSet(OriginSetByHost* origins_by_host,
|
| + const std::string& host,
|
| + const GURL& origin) {
|
| + OriginSetByHost::iterator found = origins_by_host->find(host);
|
| + if (found == origins_by_host->end())
|
| + return false;
|
| +
|
| + if (!found->second.erase(origin))
|
| + return false;
|
| +
|
| + if (found->second.empty())
|
| + origins_by_host->erase(host);
|
| + return true;
|
| +}
|
| +
|
| +bool OriginSetContainsOrigin(const OriginSetByHost& origins,
|
| + const std::string& host,
|
| + const GURL& origin) {
|
| + OriginSetByHost::const_iterator itr = origins.find(host);
|
| + return itr != origins.end() && ContainsKey(itr->second, origin);
|
| +}
|
| +
|
| } // namespace
|
|
|
| // UsageTracker ----------------------------------------------------------
|
| @@ -202,7 +225,7 @@ ClientUsageTracker::ClientUsageTracker(
|
| : tracker_(tracker),
|
| client_(client),
|
| type_(type),
|
| - global_usage_(0),
|
| + global_limited_usage_(0),
|
| global_unlimited_usage_(0),
|
| global_usage_retrieved_(false),
|
| special_storage_policy_(special_storage_policy) {
|
| @@ -218,8 +241,11 @@ ClientUsageTracker::~ClientUsageTracker() {
|
| }
|
|
|
| void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) {
|
| - if (global_usage_retrieved_ && non_cached_origins_by_host_.empty()) {
|
| - callback.Run(global_usage_, global_unlimited_usage_);
|
| + if (global_usage_retrieved_ &&
|
| + non_cached_limited_origins_by_host_.empty() &&
|
| + non_cached_unlimited_origins_by_host_.empty()) {
|
| + callback.Run(global_limited_usage_ + global_unlimited_usage_,
|
| + global_unlimited_usage_);
|
| return;
|
| }
|
|
|
| @@ -231,7 +257,8 @@ void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) {
|
| void ClientUsageTracker::GetHostUsage(
|
| const std::string& host, const UsageCallback& callback) {
|
| if (ContainsKey(cached_hosts_, host) &&
|
| - !ContainsKey(non_cached_origins_by_host_, host)) {
|
| + !ContainsKey(non_cached_limited_origins_by_host_, host) &&
|
| + !ContainsKey(non_cached_unlimited_origins_by_host_, host)) {
|
| // TODO(kinuko): Drop host_usage_map_ cache periodically.
|
| callback.Run(GetCachedHostUsage(host));
|
| return;
|
| @@ -252,11 +279,12 @@ void ClientUsageTracker::UpdateUsageCache(
|
| return;
|
|
|
| cached_usage_by_host_[host][origin] += delta;
|
| - global_usage_ += delta;
|
| if (IsStorageUnlimited(origin))
|
| global_unlimited_usage_ += delta;
|
| + else
|
| + global_limited_usage_ += delta;
|
| DCHECK_GE(cached_usage_by_host_[host][origin], 0);
|
| - DCHECK_GE(global_usage_, 0);
|
| + DCHECK_GE(global_limited_usage_, 0);
|
| return;
|
| }
|
|
|
| @@ -307,17 +335,17 @@ void ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin,
|
| }
|
| }
|
|
|
| - non_cached_origins_by_host_[host].insert(origin);
|
| + if (IsStorageUnlimited(origin))
|
| + non_cached_unlimited_origins_by_host_[host].insert(origin);
|
| + else
|
| + non_cached_limited_origins_by_host_[host].insert(origin);
|
| } else {
|
| // Erase |origin| from |non_cached_origins_| and invalidate the usage cache
|
| // for the host.
|
| - OriginSetByHost::iterator found = non_cached_origins_by_host_.find(host);
|
| - if (found == non_cached_origins_by_host_.end())
|
| - return;
|
| -
|
| - found->second.erase(origin);
|
| - if (found->second.empty()) {
|
| - non_cached_origins_by_host_.erase(found);
|
| + if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_,
|
| + host, origin) ||
|
| + EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_,
|
| + host, origin)) {
|
| cached_hosts_.erase(host);
|
| global_usage_retrieved_ = false;
|
| }
|
| @@ -437,23 +465,22 @@ void ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo* info,
|
| }
|
|
|
| void ClientUsageTracker::AddCachedOrigin(
|
| - const GURL& origin, int64 usage) {
|
| + const GURL& origin, int64 new_usage) {
|
| if (!IsUsageCacheEnabledForOrigin(origin))
|
| return;
|
|
|
| std::string host = net::GetHostOrSpecFromURL(origin);
|
| - UsageMap::iterator iter = cached_usage_by_host_[host].
|
| - insert(UsageMap::value_type(origin, 0)).first;
|
| - int64 old_usage = iter->second;
|
| - iter->second = usage;
|
| - int64 delta = usage - old_usage;
|
| + int64* usage = &cached_usage_by_host_[host][origin];
|
| + int64 delta = new_usage - *usage;
|
| + *usage = new_usage;
|
| if (delta) {
|
| - global_usage_ += delta;
|
| if (IsStorageUnlimited(origin))
|
| global_unlimited_usage_ += delta;
|
| + else
|
| + global_limited_usage_ += delta;
|
| }
|
| - DCHECK_GE(iter->second, 0);
|
| - DCHECK_GE(global_usage_, 0);
|
| + DCHECK_GE(*usage, 0);
|
| + DCHECK_GE(global_limited_usage_, 0);
|
| }
|
|
|
| void ClientUsageTracker::AddCachedHost(const std::string& host) {
|
| @@ -494,10 +521,10 @@ bool ClientUsageTracker::GetCachedOriginUsage(
|
| bool ClientUsageTracker::IsUsageCacheEnabledForOrigin(
|
| const GURL& origin) const {
|
| std::string host = net::GetHostOrSpecFromURL(origin);
|
| - OriginSetByHost::const_iterator found =
|
| - non_cached_origins_by_host_.find(host);
|
| - return found == non_cached_origins_by_host_.end() ||
|
| - !ContainsKey(found->second, origin);
|
| + return !OriginSetContainsOrigin(non_cached_limited_origins_by_host_,
|
| + host, origin) &&
|
| + !OriginSetContainsOrigin(non_cached_unlimited_origins_by_host_,
|
| + host, origin);
|
| }
|
|
|
| void ClientUsageTracker::OnGranted(const GURL& origin,
|
| @@ -505,8 +532,15 @@ void ClientUsageTracker::OnGranted(const GURL& origin,
|
| DCHECK(CalledOnValidThread());
|
| if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) {
|
| int64 usage = 0;
|
| - if (GetCachedOriginUsage(origin, &usage))
|
| + if (GetCachedOriginUsage(origin, &usage)) {
|
| global_unlimited_usage_ += usage;
|
| + global_limited_usage_ -= usage;
|
| + }
|
| +
|
| + std::string host = net::GetHostOrSpecFromURL(origin);
|
| + if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_,
|
| + host, origin))
|
| + non_cached_unlimited_origins_by_host_[host].insert(origin);
|
| }
|
| }
|
|
|
| @@ -515,14 +549,33 @@ void ClientUsageTracker::OnRevoked(const GURL& origin,
|
| DCHECK(CalledOnValidThread());
|
| if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) {
|
| int64 usage = 0;
|
| - if (GetCachedOriginUsage(origin, &usage))
|
| + if (GetCachedOriginUsage(origin, &usage)) {
|
| global_unlimited_usage_ -= usage;
|
| + global_limited_usage_ += usage;
|
| + }
|
| +
|
| + std::string host = net::GetHostOrSpecFromURL(origin);
|
| + if (EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_,
|
| + host, origin))
|
| + non_cached_limited_origins_by_host_[host].insert(origin);
|
| }
|
| }
|
|
|
| void ClientUsageTracker::OnCleared() {
|
| DCHECK(CalledOnValidThread());
|
| + global_limited_usage_ += global_unlimited_usage_;
|
| global_unlimited_usage_ = 0;
|
| +
|
| + for (OriginSetByHost::const_iterator host_itr =
|
| + non_cached_unlimited_origins_by_host_.begin();
|
| + host_itr != non_cached_unlimited_origins_by_host_.end();
|
| + ++host_itr) {
|
| + for (std::set<GURL>::const_iterator origin_itr = host_itr->second.begin();
|
| + origin_itr != host_itr->second.end();
|
| + ++origin_itr)
|
| + non_cached_limited_origins_by_host_[host_itr->first].insert(*origin_itr);
|
| + }
|
| + non_cached_unlimited_origins_by_host_.clear();
|
| }
|
|
|
| bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const {
|
|
|