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

Unified Diff: components/browsing_data/content/conditional_cache_counting_helper.cc

Issue 2556363003: Refactor cache counting into a separate helper class (Closed)
Patch Set: cleanup Created 4 years 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
Index: components/browsing_data/content/conditional_cache_counting_helper.cc
diff --git a/components/browsing_data/content/conditional_cache_counting_helper.cc b/components/browsing_data/content/conditional_cache_counting_helper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bf1a9a57652942dd2c10fc82ba33b7ffd3b4d7a7
--- /dev/null
+++ b/components/browsing_data/content/conditional_cache_counting_helper.cc
@@ -0,0 +1,219 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/browsing_data/content/conditional_cache_counting_helper.h"
+
+#include "base/callback.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/storage_partition.h"
+#include "net/disk_cache/disk_cache.h"
+#include "net/http/http_cache.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+
+using content::BrowserThread;
+
+namespace browsing_data {
+
+// static.
+ConditionalCacheCountingHelper* ConditionalCacheCountingHelper::CreateForRange(
+ content::StoragePartition* storage_partition,
+ base::Time begin_time,
+ base::Time end_time) {
+ return new ConditionalCacheCountingHelper(
+ begin_time, end_time, storage_partition->GetURLRequestContext(),
+ storage_partition->GetMediaURLRequestContext());
+}
+
+ConditionalCacheCountingHelper::ConditionalCacheCountingHelper(
+ base::Time begin_time,
+ base::Time end_time,
+ net::URLRequestContextGetter* main_context_getter,
+ net::URLRequestContextGetter* media_context_getter)
+ : calculation_result_(0),
+ begin_time_(begin_time),
+ end_time_(end_time),
+ is_cancelled_(false),
+ is_finished_(false),
+ main_context_getter_(main_context_getter),
+ media_context_getter_(media_context_getter),
+ next_cache_state_(STATE_NONE),
+ cache_(nullptr),
+ iterator_(nullptr),
+ current_entry_(nullptr),
+ weak_ptr_factory_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+}
+
+ConditionalCacheCountingHelper::~ConditionalCacheCountingHelper() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+}
+
+base::WeakPtr<ConditionalCacheCountingHelper>
+ConditionalCacheCountingHelper::CountAndDestroySelfWhenFinished(
+ const CacheCountCallback& result_callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(!result_callback.is_null());
+ result_callback_ = result_callback;
+ calculation_result_ = 0;
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ConditionalCacheCountingHelper::CountHttpCacheOnIOThread,
+ base::Unretained(this)));
+ return weak_ptr_factory_.GetWeakPtr();
+}
+
+void ConditionalCacheCountingHelper::CancelCounting() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK(!is_finished_);
+ is_cancelled_ = true;
+}
+
+bool ConditionalCacheCountingHelper::IsFinished() {
+ return is_finished_;
+}
+
+void ConditionalCacheCountingHelper::Finished() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(!is_finished_);
+ is_finished_ = true;
+ result_callback_.Run(calculation_result_);
+ base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
+}
+
+void ConditionalCacheCountingHelper::CountHttpCacheOnIOThread() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ next_cache_state_ = STATE_NONE;
+ DCHECK_EQ(STATE_NONE, next_cache_state_);
+ DCHECK(main_context_getter_.get());
+ DCHECK(media_context_getter_.get());
+
+ next_cache_state_ = STATE_CREATE_MAIN;
+ DoCountCache(net::OK);
+}
+
+// The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN -->
+// STATE_PROCESS_MAIN --> STATE_CREATE_MEDIA --> STATE_PROCESS_MEDIA -->
+// STATE_DONE. On error, we jump directly to STATE_DONE.
+void ConditionalCacheCountingHelper::DoCountCache(int rv) {
+ DCHECK_NE(STATE_NONE, next_cache_state_);
+ while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) {
+ // On error, finish and return the error code. A valid result value might
+ // be of two types - either net::OK from the CREATE states, or the result
+ // of calculation from the PROCESS states. Since net::OK == 0, it is valid
+ // to simply add the value to the final calculation result.
+ if (rv < 0) {
+ calculation_result_ = rv;
+ next_cache_state_ = STATE_DONE;
+ } else {
+ DCHECK_EQ(0, net::OK);
+ calculation_result_ += rv;
+ }
+
+ switch (next_cache_state_) {
+ case STATE_CREATE_MAIN:
+ case STATE_CREATE_MEDIA: {
+ // Get a pointer to the cache.
+ net::URLRequestContextGetter* getter =
+ (next_cache_state_ == STATE_CREATE_MAIN)
+ ? main_context_getter_.get()
+ : media_context_getter_.get();
+ net::HttpCache* http_cache = getter->GetURLRequestContext()
+ ->http_transaction_factory()
+ ->GetCache();
+
+ next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN)
+ ? STATE_PROCESS_MAIN
+ : STATE_PROCESS_MEDIA;
+
+ rv = http_cache->GetBackend(
+ &cache_, base::Bind(&ConditionalCacheCountingHelper::DoCountCache,
+ base::Unretained(this)));
+ break;
+ }
+ case STATE_PROCESS_MAIN:
+ case STATE_PROCESS_MEDIA: {
+ next_cache_state_ = (next_cache_state_ == STATE_PROCESS_MAIN)
+ ? STATE_CREATE_MEDIA
+ : STATE_DONE;
+
+ // |cache_| can be null if it cannot be initialized.
+ if (cache_) {
+ if (begin_time_.is_null() && end_time_.is_max()) {
+ rv = cache_->CalculateSizeOfAllEntries(
+ base::Bind(&ConditionalCacheCountingHelper::DoCountCache,
+ base::Unretained(this)));
+ } else {
+ // TODO(dullweber): Implement faster counting for SimpleBackendImpl.
msramek 2016/12/15 15:58:51 You already implemented it in this CL, just didn't
dullweber 2016/12/16 16:41:11 I added the code to get the size of a single entry
msramek 2016/12/20 01:02:59 You seem not to have finished that sentence; howev
dullweber 2016/12/21 10:29:19 I created a separate cl and moved the GetEntrySize
+ rv = CountEntries(cache_);
+ }
+ cache_ = NULL;
+ }
+ break;
+ }
+ case STATE_DONE: {
+ cache_ = NULL;
+ next_cache_state_ = STATE_NONE;
+ // Notify the UI thread that we are done.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&ConditionalCacheCountingHelper::Finished,
+ base::Unretained(this)));
+ return;
+ }
+ default: {
msramek 2016/12/15 15:58:51 Instead of default: NOTREACHED(), we could just re
dullweber 2016/12/16 16:41:11 Done.
+ NOTREACHED() << "bad state";
+ next_cache_state_ = STATE_NONE; // Stop looping.
+ return;
+ }
+ }
+ }
+}
+
+int ConditionalCacheCountingHelper::CountEntries(disk_cache::Backend* backend) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ iterator_ = backend->CreateIterator();
+ current_entry_ = nullptr;
+ IterateOverEntries(net::OK);
+ return net::ERR_IO_PENDING;
+}
+
+void ConditionalCacheCountingHelper::IterateOverEntries(int error) {
+ while (error != net::ERR_IO_PENDING) {
+ if (is_cancelled_) {
+ if (current_entry_)
+ current_entry_->Close();
+ iterator_.reset(nullptr);
msramek 2016/12/15 15:58:50 nit: reset()
dullweber 2016/12/16 16:41:11 Done.
+ DoCountCache(net::ERR_ABORTED);
+ return;
+ }
+ if (error == net::ERR_FAILED) {
+ // The iteration finished successfully or we can no longer iterate
+ // (e.g. the cache was destroyed). We cannot distinguish between the two,
+ // but we know that there is nothing more that we can do, so we return to
+ // the main calculation loop.
+ iterator_.reset(nullptr);
+ DoCountCache(net::OK);
+ return;
+ }
+
+ if (current_entry_) {
+ if (current_entry_->GetLastUsed() >= begin_time_ &&
+ current_entry_->GetLastUsed() < end_time_) {
+ calculation_result_ += current_entry_->GetEntrySize();
+ }
+ current_entry_->Close();
+ }
+
+ error = iterator_->OpenNextEntry(
+ &current_entry_,
+ base::Bind(&ConditionalCacheCountingHelper::IterateOverEntries,
+ base::Unretained(this)));
+ }
+}
+
+} // namespace browsing_data

Powered by Google App Engine
This is Rietveld 408576698