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

Unified Diff: webkit/quota/usage_tracker.cc

Issue 15857002: [Quota][Clean up] Simplify usage aggregator in ClientUsageTracker (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: buildfix for android Created 7 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/quota/usage_tracker.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/quota/usage_tracker.cc
diff --git a/webkit/quota/usage_tracker.cc b/webkit/quota/usage_tracker.cc
index 972c14c3bab804ff36729587d07f377c5bf84d17..e2f3e608e96261eacd68fad31b3a92d2056aaa59 100644
--- a/webkit/quota/usage_tracker.cc
+++ b/webkit/quota/usage_tracker.cc
@@ -19,211 +19,25 @@ namespace quota {
namespace {
-bool SortByHost(const GURL& lhs, const GURL& rhs) {
- return net::GetHostOrSpecFromURL(lhs) > net::GetHostOrSpecFromURL(rhs);
-}
-
-} // namespace
-
-// A task class for getting the total amount of data used for a collection of
-// origins. This class is self-destructed.
-class ClientUsageTracker::GatherUsageTaskBase : public QuotaTask {
- public:
- GatherUsageTaskBase(
- UsageTracker* tracker,
- QuotaClient* client)
- : QuotaTask(tracker),
- client_(client),
- tracker_(tracker),
- current_gathered_usage_(0),
- weak_factory_(this) {
- DCHECK(tracker_);
- DCHECK(client_);
- client_tracker_ = base::AsWeakPtr(
- tracker_->GetClientTracker(client_->id()));
- DCHECK(client_tracker_.get());
- }
- virtual ~GatherUsageTaskBase() {}
-
- // Get total usage for the given |origins|.
- void GetUsageForOrigins(const std::set<GURL>& origins, StorageType type) {
- DCHECK(original_task_runner()->BelongsToCurrentThread());
- if (!client_tracker()) {
- DeleteSoon();
- return;
- }
- // We do not get usage for origins for which we have valid usage cache.
- std::vector<GURL> origins_not_in_cache;
- current_gathered_usage_ = client_tracker()->GetCachedOriginsUsage(
- origins, &origins_not_in_cache);
- if (origins_not_in_cache.empty()) {
- CallCompleted();
- DeleteSoon();
- return;
- }
-
- // Sort them so we can detect when we've gathered all info for a particular
- // host in DidGetUsage.
- std::sort(origins_not_in_cache.begin(),
- origins_not_in_cache.end(), SortByHost);
-
- // First, fully populate the pending queue because GetOriginUsage may call
- // the completion callback immediately.
- for (std::vector<GURL>::const_iterator iter = origins_not_in_cache.begin();
- iter != origins_not_in_cache.end(); iter++)
- pending_origins_.push_back(*iter);
-
- for (std::vector<GURL>::const_iterator iter = origins_not_in_cache.begin();
- iter != origins_not_in_cache.end(); iter++)
- client_->GetOriginUsage(
- *iter,
- tracker_->type(),
- base::Bind(&GatherUsageTaskBase::DidGetUsage,
- weak_factory_.GetWeakPtr()));
- }
-
- protected:
- virtual void DidGetOriginUsage(const GURL& origin, int64 usage) {}
-
- virtual void Aborted() OVERRIDE {
- DeleteSoon();
- }
-
- UsageTracker* tracker() const { return tracker_; }
- ClientUsageTracker* client_tracker() const { return client_tracker_.get(); }
-
- int64 current_gathered_usage() const { return current_gathered_usage_; }
-
- private:
- void DidGetUsage(int64 usage) {
- if (!client_tracker()) {
- DeleteSoon();
- return;
- }
-
- DCHECK(original_task_runner()->BelongsToCurrentThread());
- DCHECK(!pending_origins_.empty());
-
- // Defend against confusing inputs from QuotaClients.
- DCHECK_GE(usage, 0);
- if (usage < 0)
- usage = 0;
- current_gathered_usage_ += usage;
-
- // This code assumes DidGetUsage callbacks are called in the same
- // order as we dispatched GetOriginUsage calls.
- const GURL& origin = pending_origins_.front();
- std::string host = net::GetHostOrSpecFromURL(origin);
- client_tracker_->AddCachedOrigin(origin, usage);
-
- DidGetOriginUsage(origin, usage);
+typedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator;
- pending_origins_.pop_front();
- if (pending_origins_.empty() ||
- host != net::GetHostOrSpecFromURL(pending_origins_.front())) {
- client_tracker_->AddCachedHost(host);
- }
-
- if (pending_origins_.empty()) {
- // We're done.
- CallCompleted();
- DeleteSoon();
- }
- }
-
- QuotaClient* client_;
- UsageTracker* tracker_;
- base::WeakPtr<ClientUsageTracker> client_tracker_;
- std::deque<GURL> pending_origins_;
- std::map<GURL, int64> origin_usage_map_;
- int64 current_gathered_usage_;
- base::WeakPtrFactory<GatherUsageTaskBase> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(GatherUsageTaskBase);
-};
-
-// A task class for getting the total amount of data used for a given storage
-// type. This class is self-destructed.
-class ClientUsageTracker::GatherGlobalUsageTask
- : public GatherUsageTaskBase {
- public:
- GatherGlobalUsageTask(
- UsageTracker* tracker,
- QuotaClient* client)
- : GatherUsageTaskBase(tracker, client),
- client_(client),
- non_cached_global_usage_(0),
- weak_factory_(this) {
- DCHECK(tracker);
- DCHECK(client);
- }
- virtual ~GatherGlobalUsageTask() {}
-
- protected:
- virtual void Run() OVERRIDE {
- client_->GetOriginsForType(tracker()->type(),
- base::Bind(&GatherUsageTaskBase::GetUsageForOrigins,
- weak_factory_.GetWeakPtr()));
- }
-
- virtual void DidGetOriginUsage(const GURL& origin, int64 usage) OVERRIDE {
- if (!client_tracker()->IsUsageCacheEnabledForOrigin(origin)) {
- std::string host = net::GetHostOrSpecFromURL(origin);
- non_cached_usage_by_host_[host] += usage;
- non_cached_global_usage_ += usage;
- }
- }
-
- virtual void Completed() OVERRIDE {
- client_tracker()->GatherGlobalUsageComplete(current_gathered_usage(),
- non_cached_global_usage_,
- non_cached_usage_by_host_);
- }
-
- private:
- QuotaClient* client_;
- int64 non_cached_global_usage_;
- std::map<std::string, int64> non_cached_usage_by_host_;
- base::WeakPtrFactory<GatherUsageTaskBase> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(GatherGlobalUsageTask);
-};
-
-// A task class for getting the total amount of data used for a given host.
-// This class is self-destructed.
-class ClientUsageTracker::GatherHostUsageTask
- : public GatherUsageTaskBase {
- public:
- GatherHostUsageTask(
- UsageTracker* tracker,
- QuotaClient* client,
- const std::string& host)
- : GatherUsageTaskBase(tracker, client),
- client_(client),
- host_(host),
- weak_factory_(this) {
- DCHECK(client_);
- }
- virtual ~GatherHostUsageTask() {}
-
- protected:
- virtual void Run() OVERRIDE {
- client_->GetOriginsForHost(tracker()->type(), host_,
- base::Bind(&GatherUsageTaskBase::GetUsageForOrigins,
- weak_factory_.GetWeakPtr()));
- }
+void DidGetOriginUsage(const OriginUsageAccumulator& accumulator,
+ const GURL& origin,
+ int64 usage) {
+ accumulator.Run(origin, usage);
+}
- virtual void Completed() OVERRIDE {
- client_tracker()->GatherHostUsageComplete(host_, current_gathered_usage());
- }
+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);
+}
- private:
- QuotaClient* client_;
- std::string host_;
- base::WeakPtrFactory<GatherUsageTaskBase> weak_factory_;
+void NoopHostUsageCallback(int64 usage) {}
- DISALLOW_COPY_AND_ASSIGN(GatherHostUsageTask);
-};
+} // namespace
// UsageTracker ----------------------------------------------------------
@@ -255,7 +69,7 @@ void UsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) {
if (!global_usage_callbacks_.Add(callback))
return;
- TrackingInfo* info = new TrackingInfo;
+ AccumulateInfo* info = new AccumulateInfo;
// Calling GetGlobalUsage(accumulator) may synchronously
// return if the usage is cached, which may in turn dispatch
// the completion callback before we finish looping over
@@ -265,7 +79,7 @@ void UsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) {
// and fire the sentinel callback at the end.
info->pending_clients = client_tracker_map_.size() + 1;
GlobalUsageCallback accumulator = base::Bind(
- &UsageTracker::DidGetClientGlobalUsage, weak_factory_.GetWeakPtr(),
+ &UsageTracker::AccumulateClientGlobalUsage, weak_factory_.GetWeakPtr(),
base::Owned(info));
for (ClientTrackerMap::iterator iter = client_tracker_map_.begin();
@@ -282,7 +96,7 @@ void UsageTracker::GetHostUsage(const std::string& host,
if (!host_usage_callbacks_.Add(host, callback))
return;
- TrackingInfo* info = new TrackingInfo;
+ AccumulateInfo* info = new AccumulateInfo;
// Calling GetHostUsage(accumulator) may synchronously
// return if the usage is cached, which may in turn dispatch
// the completion callback before we finish looping over
@@ -292,7 +106,7 @@ void UsageTracker::GetHostUsage(const std::string& host,
// and fire the sentinel callback at the end.
info->pending_clients = client_tracker_map_.size() + 1;
UsageCallback accumulator = base::Bind(
- &UsageTracker::DidGetClientHostUsage, weak_factory_.GetWeakPtr(),
+ &UsageTracker::AccumulateClientHostUsage, weak_factory_.GetWeakPtr(),
base::Owned(info), host);
for (ClientTrackerMap::iterator iter = client_tracker_map_.begin();
@@ -339,9 +153,9 @@ void UsageTracker::SetUsageCacheEnabled(QuotaClient::ID client_id,
client_tracker->SetUsageCacheEnabled(origin, enabled);
}
-void UsageTracker::DidGetClientGlobalUsage(TrackingInfo* info,
- int64 usage,
- int64 unlimited_usage) {
+void UsageTracker::AccumulateClientGlobalUsage(AccumulateInfo* info,
+ int64 usage,
+ int64 unlimited_usage) {
info->usage += usage;
info->unlimited_usage += unlimited_usage;
@@ -364,9 +178,9 @@ void UsageTracker::DidGetClientGlobalUsage(TrackingInfo* info,
global_usage_callbacks_.Run(MakeTuple(info->usage, info->unlimited_usage));
}
-void UsageTracker::DidGetClientHostUsage(TrackingInfo* info,
- const std::string& host,
- int64 usage) {
+void UsageTracker::AccumulateClientHostUsage(AccumulateInfo* info,
+ const std::string& host,
+ int64 usage) {
info->usage += usage;
if (--info->pending_clients)
return;
@@ -391,7 +205,6 @@ ClientUsageTracker::ClientUsageTracker(
global_usage_(0),
global_unlimited_usage_(0),
global_usage_retrieved_(false),
- global_usage_task_(NULL),
special_storage_policy_(special_storage_policy) {
DCHECK(tracker_);
DCHECK(client_);
@@ -406,13 +219,13 @@ ClientUsageTracker::~ClientUsageTracker() {
void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) {
if (global_usage_retrieved_ && non_cached_origins_by_host_.empty()) {
- callback.Run(global_usage_, GetCachedGlobalUnlimitedUsage());
+ callback.Run(global_usage_, global_unlimited_usage_);
return;
}
- DCHECK(!global_usage_callback_.HasCallbacks());
- global_usage_callback_.Add(callback);
- global_usage_task_ = new GatherGlobalUsageTask(tracker_, client_);
- global_usage_task_->Start();
+
+ client_->GetOriginsForType(type_, base::Bind(
+ &ClientUsageTracker::DidGetOriginsForGlobalUsage, AsWeakPtr(),
+ callback));
}
void ClientUsageTracker::GetHostUsage(
@@ -423,11 +236,12 @@ void ClientUsageTracker::GetHostUsage(
callback.Run(GetCachedHostUsage(host));
return;
}
- if (!host_usage_callbacks_.Add(host, callback) || global_usage_task_)
+
+ if (!host_usage_accumulators_.Add(host, base::Bind(
+ &DidGetHostUsage, callback)))
return;
- GatherHostUsageTask* task = new GatherHostUsageTask(tracker_, client_, host);
- host_usage_tasks_[host] = task;
- task->Start();
+ client_->GetOriginsForHost(type_, host, base::Bind(
+ &ClientUsageTracker::DidGetOriginsForHostUsage, AsWeakPtr(), host));
}
void ClientUsageTracker::UpdateUsageCache(
@@ -447,9 +261,7 @@ void ClientUsageTracker::UpdateUsageCache(
}
// We don't know about this host yet, so populate our cache for it.
- GetHostUsage(host,
- base::Bind(&ClientUsageTracker::NoopHostUsageCallback,
- base::Unretained(this)));
+ GetHostUsage(host, base::Bind(&NoopHostUsageCallback));
}
void ClientUsageTracker::GetCachedHostsUsage(
@@ -457,8 +269,8 @@ void ClientUsageTracker::GetCachedHostsUsage(
DCHECK(host_usage);
for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin();
host_iter != cached_usage_by_host_.end(); host_iter++) {
- host_usage->operator[](host_iter->first) +=
- GetCachedHostUsage(host_iter->first);
+ const std::string& host = host_iter->first;
+ (*host_usage)[host] += GetCachedHostUsage(host);
}
}
@@ -474,23 +286,6 @@ void ClientUsageTracker::GetCachedOrigins(std::set<GURL>* origins) const {
}
}
-int64 ClientUsageTracker::GetCachedOriginsUsage(
- const std::set<GURL>& origins,
- std::vector<GURL>* origins_not_in_cache) {
- DCHECK(origins_not_in_cache);
-
- int64 usage = 0;
- for (std::set<GURL>::const_iterator itr = origins.begin();
- itr != origins.end(); ++itr) {
- int64 origin_usage = 0;
- if (GetCachedOriginUsage(*itr, &origin_usage))
- usage += origin_usage;
- else
- origins_not_in_cache->push_back(*itr);
- }
- return usage;
-}
-
void ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin,
bool enabled) {
std::string host = net::GetHostOrSpecFromURL(origin);
@@ -529,6 +324,118 @@ void ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin,
}
}
+void ClientUsageTracker::DidGetOriginsForGlobalUsage(
+ const GlobalUsageCallback& callback,
+ const std::set<GURL>& origins, StorageType type) {
+ OriginSetByHost origins_by_host;
+ for (std::set<GURL>::const_iterator itr = origins.begin();
+ itr != origins.end(); ++itr)
+ origins_by_host[net::GetHostOrSpecFromURL(*itr)].insert(*itr);
+
+ AccumulateInfo* info = new AccumulateInfo;
+ // Getting host usage may synchronously return the result if the usage is
+ // cached, which may in turn dispatch the completion callback before we finish
+ // looping over all hosts (because info->pending_jobs may reach 0 during the
+ // loop). To avoid this, we add one more pending host as a sentinel and
+ // fire the sentinel callback at the end.
+ info->pending_jobs = origins_by_host.size() + 1;
+ HostUsageAccumulator accumulator =
+ base::Bind(&ClientUsageTracker::AccumulateHostUsage, AsWeakPtr(),
+ base::Owned(info), callback);
+
+ for (OriginSetByHost::iterator itr = origins_by_host.begin();
+ itr != origins_by_host.end(); ++itr) {
+ if (host_usage_accumulators_.Add(itr->first, accumulator))
+ GetUsageForOrigins(itr->first, itr->second);
+ }
+
+ // Fire the sentinel as we've now called GetUsageForOrigins for all clients.
+ accumulator.Run(0, 0);
+}
+
+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;
+ 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;
+
+ global_usage_retrieved_ = true;
+ callback.Run(total_usage, unlimited_usage);
+}
+
+void ClientUsageTracker::DidGetOriginsForHostUsage(
+ const std::string& host,
+ const std::set<GURL>& origins,
+ StorageType type) {
+ GetUsageForOrigins(host, origins);
+}
+
+void ClientUsageTracker::GetUsageForOrigins(
+ const std::string& host,
+ const std::set<GURL>& origins) {
+ AccumulateInfo* info = new AccumulateInfo;
+ // Getting origin usage may synchronously return the result if the usage is
+ // cached, which may in turn dispatch the completion callback before we finish
+ // looping over all origins (because info->pending_jobs may reach 0 during the
+ // loop). To avoid this, we add one more pending origin as a sentinel and
+ // fire the sentinel callback at the end.
+ info->pending_jobs = origins.size() + 1;
+ OriginUsageAccumulator accumulator =
+ base::Bind(&ClientUsageTracker::AccumulateOriginUsage, AsWeakPtr(),
+ base::Owned(info), host);
+
+ for (std::set<GURL>::const_iterator itr = origins.begin();
+ itr != origins.end(); ++itr) {
+ DCHECK_EQ(host, net::GetHostOrSpecFromURL(*itr));
+
+ int64 origin_usage = 0;
+ if (GetCachedOriginUsage(*itr, &origin_usage)) {
+ accumulator.Run(*itr, origin_usage);
+ } else {
+ client_->GetOriginUsage(*itr, type_, base::Bind(
+ &DidGetOriginUsage, accumulator, *itr));
+ }
+ }
+
+ // Fire the sentinel as we've now called GetOriginUsage for all clients.
+ accumulator.Run(GURL(), 0);
+}
+
+void ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo* info,
+ const std::string& host,
+ const GURL& origin,
+ int64 usage) {
+ if (!origin.is_empty()) {
+ if (usage < 0)
+ usage = 0;
+
+ if (IsUsageCacheEnabledForOrigin(origin)) {
+ info->cached_usage += usage;
+ 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));
+}
+
void ClientUsageTracker::AddCachedOrigin(
const GURL& origin, int64 usage) {
if (!IsUsageCacheEnabledForOrigin(origin))
@@ -553,39 +460,6 @@ void ClientUsageTracker::AddCachedHost(const std::string& host) {
cached_hosts_.insert(host);
}
-void ClientUsageTracker::GatherGlobalUsageComplete(
- int64 global_usage,
- int64 non_cached_global_usage,
- const std::map<std::string, int64>& non_cached_host_usage) {
- DCHECK(global_usage_task_ != NULL);
- global_usage_task_ = NULL;
- // TODO(kinuko): Record when it has retrieved the global usage.
- global_usage_retrieved_ = true;
-
- DCHECK(global_usage_callback_.HasCallbacks());
- global_usage_callback_.Run(
- MakeTuple(global_usage,
- GetCachedGlobalUnlimitedUsage() + non_cached_global_usage));
-
- for (HostUsageCallbackMap::iterator iter = host_usage_callbacks_.Begin();
- iter != host_usage_callbacks_.End(); ++iter) {
- int64 host_usage = GetCachedHostUsage(iter->first);
- std::map<std::string, int64>::const_iterator found =
- non_cached_host_usage.find(iter->first);
- if (found != non_cached_host_usage.end())
- host_usage += found->second;
- iter->second.Run(MakeTuple(host_usage));
- }
- host_usage_callbacks_.Clear();
-}
-
-void ClientUsageTracker::GatherHostUsageComplete(const std::string& host,
- int64 usage) {
- DCHECK(host_usage_tasks_.find(host) != host_usage_tasks_.end());
- host_usage_tasks_.erase(host);
- host_usage_callbacks_.Run(host, MakeTuple(usage));
-}
-
int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) const {
HostUsageMap::const_iterator found = cached_usage_by_host_.find(host);
if (found == cached_usage_by_host_.end())
@@ -600,10 +474,6 @@ int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) const {
return usage;
}
-int64 ClientUsageTracker::GetCachedGlobalUnlimitedUsage() {
- return global_unlimited_usage_;
-}
-
bool ClientUsageTracker::GetCachedOriginUsage(
const GURL& origin,
int64* usage) const {
@@ -616,6 +486,7 @@ bool ClientUsageTracker::GetCachedOriginUsage(
if (found == found_host->second.end())
return false;
+ DCHECK(IsUsageCacheEnabledForOrigin(origin));
*usage = found->second;
return true;
}
@@ -654,8 +525,6 @@ void ClientUsageTracker::OnCleared() {
global_unlimited_usage_ = 0;
}
-void ClientUsageTracker::NoopHostUsageCallback(int64 usage) {}
-
bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const {
if (type_ == kStorageTypeSyncable)
return false;
« 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