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

Side by Side Diff: components/browsing_data/content/conditional_cache_counting_helper.cc

Issue 2556363003: Refactor cache counting into a separate helper class (Closed)
Patch Set: extract cache_test_util and fixes 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/browsing_data/content/conditional_cache_counting_helper.h"
6
7 #include "base/callback.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/threading/thread_task_runner_handle.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/storage_partition.h"
12 #include "net/disk_cache/disk_cache.h"
13 #include "net/http/http_cache.h"
14 #include "net/url_request/url_request_context.h"
15 #include "net/url_request/url_request_context_getter.h"
16
17 using content::BrowserThread;
18
19 namespace browsing_data {
20
21 // static.
22 ConditionalCacheCountingHelper* ConditionalCacheCountingHelper::CreateForRange(
23 content::StoragePartition* storage_partition,
24 base::Time begin_time,
25 base::Time end_time) {
26 return new ConditionalCacheCountingHelper(
27 begin_time, end_time, storage_partition->GetURLRequestContext(),
28 storage_partition->GetMediaURLRequestContext());
29 }
30
31 ConditionalCacheCountingHelper::ConditionalCacheCountingHelper(
32 base::Time begin_time,
33 base::Time end_time,
34 net::URLRequestContextGetter* main_context_getter,
35 net::URLRequestContextGetter* media_context_getter)
36 : calculation_result_(0),
37 begin_time_(begin_time),
38 end_time_(end_time),
39 is_cancelled_(false),
40 is_finished_(false),
41 main_context_getter_(main_context_getter),
42 media_context_getter_(media_context_getter),
43 next_cache_state_(CacheState::NONE),
44 cache_(nullptr),
45 iterator_(nullptr),
46 current_entry_(nullptr),
47 weak_ptr_factory_(this) {
48 DCHECK_CURRENTLY_ON(BrowserThread::UI);
49 }
50
51 ConditionalCacheCountingHelper::~ConditionalCacheCountingHelper() {
52 DCHECK_CURRENTLY_ON(BrowserThread::UI);
53 }
54
55 base::WeakPtr<ConditionalCacheCountingHelper>
56 ConditionalCacheCountingHelper::CountAndDestroySelfWhenFinished(
57 const CacheCountCallback& result_callback) {
58 DCHECK_CURRENTLY_ON(BrowserThread::UI);
59 DCHECK(!result_callback.is_null());
60 result_callback_ = result_callback;
61 calculation_result_ = 0;
62
63 BrowserThread::PostTask(
64 BrowserThread::IO, FROM_HERE,
65 base::Bind(&ConditionalCacheCountingHelper::CountHttpCacheOnIOThread,
66 base::Unretained(this)));
67 return weak_ptr_factory_.GetWeakPtr();
68 }
69
70 void ConditionalCacheCountingHelper::CancelCounting() {
71 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
72 DCHECK(!is_finished_);
73 is_cancelled_ = true;
74 }
75
76 bool ConditionalCacheCountingHelper::IsFinished() {
77 return is_finished_;
78 }
79
80 void ConditionalCacheCountingHelper::Finished() {
81 DCHECK_CURRENTLY_ON(BrowserThread::UI);
82 DCHECK(!is_finished_);
83 is_finished_ = true;
84 result_callback_.Run(calculation_result_);
85 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
86 }
87
88 void ConditionalCacheCountingHelper::CountHttpCacheOnIOThread() {
89 DCHECK_CURRENTLY_ON(BrowserThread::IO);
90 next_cache_state_ = CacheState::NONE;
91 DCHECK_EQ(CacheState::NONE, next_cache_state_);
92 DCHECK(main_context_getter_.get());
93 DCHECK(media_context_getter_.get());
94
95 next_cache_state_ = CacheState::CREATE_MAIN;
96 DoCountCache(net::OK);
97 }
98
99 // The expected state sequence is CacheState::NONE --> CacheState::CREATE_MAIN
100 // -->
msramek 2016/12/20 01:03:00 nit: Why the line break?
dullweber 2016/12/21 10:29:19 Oh, I guess changing to an enum class made the lin
101 // CacheState::PROCESS_MAIN --> CacheState::CREATE_MEDIA -->
102 // CacheState::PROCESS_MEDIA -->
103 // CacheState::DONE. On error, we jump directly to CacheState::DONE.
104 void ConditionalCacheCountingHelper::DoCountCache(int rv) {
105 DCHECK_NE(CacheState::NONE, next_cache_state_);
106 while (rv != net::ERR_IO_PENDING && next_cache_state_ != CacheState::NONE) {
107 // On error, finish and return the error code. A valid result value might
108 // be of two types - either net::OK from the CREATE states, or the result
109 // of calculation from the PROCESS states. Since net::OK == 0, it is valid
110 // to simply add the value to the final calculation result.
111 if (rv < 0) {
112 calculation_result_ = rv;
113 next_cache_state_ = CacheState::DONE;
114 } else {
115 DCHECK_EQ(0, net::OK);
116 calculation_result_ += rv;
117 }
118
119 switch (next_cache_state_) {
120 case CacheState::CREATE_MAIN:
121 case CacheState::CREATE_MEDIA: {
122 // Get a pointer to the cache.
123 net::URLRequestContextGetter* getter =
124 (next_cache_state_ == CacheState::CREATE_MAIN)
125 ? main_context_getter_.get()
126 : media_context_getter_.get();
127 net::HttpCache* http_cache = getter->GetURLRequestContext()
128 ->http_transaction_factory()
129 ->GetCache();
130
131 next_cache_state_ = (next_cache_state_ == CacheState::CREATE_MAIN)
132 ? CacheState::COUNT_MAIN
133 : CacheState::COUNT_MEDIA;
134
135 rv = http_cache->GetBackend(
136 &cache_, base::Bind(&ConditionalCacheCountingHelper::DoCountCache,
137 base::Unretained(this)));
138 break;
139 }
140 case CacheState::COUNT_MAIN:
141 case CacheState::COUNT_MEDIA: {
142 next_cache_state_ = (next_cache_state_ == CacheState::COUNT_MAIN)
143 ? CacheState::CREATE_MEDIA
144 : CacheState::DONE;
145
146 // |cache_| can be null if it cannot be initialized.
147 if (cache_) {
148 if (begin_time_.is_null() && end_time_.is_max()) {
149 rv = cache_->CalculateSizeOfAllEntries(
150 base::Bind(&ConditionalCacheCountingHelper::DoCountCache,
151 base::Unretained(this)));
152 } else {
153 // TODO(dullweber): Implement faster counting for SimpleBackendImpl.
154 rv = CountEntries(cache_);
155 }
156 cache_ = NULL;
157 }
158 break;
159 }
160 case CacheState::DONE: {
161 cache_ = NULL;
162 next_cache_state_ = CacheState::NONE;
163 // Notify the UI thread that we are done.
164 BrowserThread::PostTask(
165 BrowserThread::UI, FROM_HERE,
166 base::Bind(&ConditionalCacheCountingHelper::Finished,
167 base::Unretained(this)));
168 return;
169 }
170 case CacheState::NONE: {
171 NOTREACHED() << "bad state";
172 return;
173 }
174 }
175 }
176 }
177
178 int ConditionalCacheCountingHelper::CountEntries(disk_cache::Backend* backend) {
179 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
180 iterator_ = backend->CreateIterator();
181 current_entry_ = nullptr;
182 IterateOverEntries(net::OK);
183 return net::ERR_IO_PENDING;
184 }
185
186 void ConditionalCacheCountingHelper::IterateOverEntries(int error) {
187 while (error != net::ERR_IO_PENDING) {
188 if (is_cancelled_) {
189 if (current_entry_)
190 current_entry_->Close();
191 iterator_.reset();
192 DoCountCache(net::ERR_ABORTED);
193 return;
194 }
195 if (error == net::ERR_FAILED) {
196 // The iteration finished successfully or we can no longer iterate
197 // (e.g. the cache was destroyed). We cannot distinguish between the two,
198 // but we know that there is nothing more that we can do, so we return to
199 // the main calculation loop.
200 iterator_.reset();
201 DoCountCache(net::OK);
202 return;
203 }
204
205 if (current_entry_) {
206 if (current_entry_->GetLastUsed() >= begin_time_ &&
207 current_entry_->GetLastUsed() < end_time_) {
208 calculation_result_ += current_entry_->GetEntrySize();
209 }
210 current_entry_->Close();
211 }
212
213 error = iterator_->OpenNextEntry(
214 &current_entry_,
215 base::Bind(&ConditionalCacheCountingHelper::IterateOverEntries,
216 base::Unretained(this)));
217 }
218 }
219
220 } // namespace browsing_data
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698