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

Side by Side Diff: chrome/browser/net/cache_stats.cc

Issue 10834313: Add histograms for network activity, and total/cumulative (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 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
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 "chrome/browser/net/cache_stats.h" 5 #include "chrome/browser/net/cache_stats.h"
6 6
7 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/string_number_conversions.h" 9 #include "base/string_number_conversions.h"
10 #include "base/timer.h" 10 #include "base/timer.h"
11 #include "chrome/browser/browser_process.h" 11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/io_thread.h" 12 #include "chrome/browser/io_thread.h"
13 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/tab_contents/tab_contents.h" 14 #include "chrome/browser/ui/tab_contents/tab_contents.h"
15 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/render_process_host.h" 16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/render_view_host.h" 17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/resource_request_info.h" 18 #include "content/public/browser/resource_request_info.h"
19 #include "content/public/browser/web_contents.h" 19 #include "content/public/browser/web_contents.h"
20 #include "net/url_request/url_request.h" 20 #include "net/url_request/url_request.h"
21 21
22 using content::BrowserThread; 22 using content::BrowserThread;
23 using content::RenderViewHost; 23 using content::RenderViewHost;
24 using content::ResourceRequestInfo; 24 using content::ResourceRequestInfo;
25 using std::string;
25 26
26 #if defined(COMPILER_GCC) 27 #if defined(COMPILER_GCC)
27 28
28 namespace BASE_HASH_NAMESPACE { 29 namespace BASE_HASH_NAMESPACE {
29 template <> 30 template <>
30 struct hash<const net::URLRequest*> { 31 struct hash<const net::URLRequest*> {
31 std::size_t operator()(const net::URLRequest* value) const { 32 std::size_t operator()(const net::URLRequest* value) const {
32 return reinterpret_cast<std::size_t>(value); 33 return reinterpret_cast<std::size_t>(value);
33 } 34 }
34 }; 35 };
(...skipping 30 matching lines...) Expand all
65 4000, 66 4000,
66 5000, 67 5000,
67 7500, 68 7500,
68 10000, 69 10000,
69 15000, 70 15000,
70 20000 71 20000
71 }; 72 };
72 73
73 static int kTabLoadStatsAutoCleanupTimeoutSeconds = 30; 74 static int kTabLoadStatsAutoCleanupTimeoutSeconds = 30;
74 75
76 const char* kRequestStatusNames[] = {
77 "CacheWait",
78 "NetworkWait",
79 "Active",
80 "None",
81 "Max"
82 };
83
84 COMPILE_ASSERT(arraysize(kRequestStatusNames) ==
85 chrome_browser_net::CacheStats::REQUEST_STATUS_MAX + 1,
86 CacheStats_RequestStatus_names_mismatch);
87
88 const char* kHistogramTypeNames[] = {
89 "FinalAggregate",
90 "FinalCumulative",
91 "FinalCumulativePercentage",
92 "IntermediateAggregate",
93 "IntermediateCumulative",
94 "IntermediateCumulativePercentage",
95 "Max"
96 };
97
98 COMPILE_ASSERT(arraysize(kHistogramTypeNames) ==
99 chrome_browser_net::CacheStats::HISTOGRAM_MAX + 1,
100 CacheStats_HistogramType_names_mismatch);
101
75 } // namespace 102 } // namespace
76 103
77 namespace chrome_browser_net { 104 namespace chrome_browser_net {
78 105
79 // Helper struct keeping stats about the page load progress & cache usage 106 // Helper struct keeping stats about the page load progress & cache usage
80 // stats during the pageload so far for a given RenderView, identified 107 // stats during the pageload so far for a given RenderView, identified
81 // by a pair of process id and route id. 108 // by a pair of process id and route id.
82 struct CacheStats::TabLoadStats { 109 struct CacheStats::TabLoadStats {
83 TabLoadStats(std::pair<int, int> render_view_id, CacheStats* owner) 110 TabLoadStats(std::pair<int, int> render_view_id, CacheStats* owner)
84 : render_view_id(render_view_id), 111 : render_view_id(render_view_id),
85 num_active(0),
86 spinner_started(false), 112 spinner_started(false),
87 next_timer_index(0), 113 next_timer_index(0),
88 timer(false, false) { 114 timer(false, false) {
89 // Initialize the timer to do an automatic cleanup. If a pageload is 115 // Initialize the timer to do an automatic cleanup. If a pageload is
90 // started for the TabLoadStats within that timeframe, CacheStats 116 // started for the TabLoadStats within that timeframe, CacheStats
91 // will start using the timer, thereby cancelling the cleanup. 117 // will start using the timer, thereby cancelling the cleanup.
92 // Once CacheStats starts the timer, the object is guaranteed to be 118 // Once CacheStats starts the timer, the object is guaranteed to be
93 // destroyed eventually, so there is no more need for automatic cleanup at 119 // destroyed eventually, so there is no more need for automatic cleanup at
94 // that point. 120 // that point.
95 timer.Start(FROM_HERE, 121 timer.Start(FROM_HERE,
96 base::TimeDelta::FromSeconds( 122 base::TimeDelta::FromSeconds(
97 kTabLoadStatsAutoCleanupTimeoutSeconds), 123 kTabLoadStatsAutoCleanupTimeoutSeconds),
98 base::Bind(&CacheStats::RemoveTabLoadStats, 124 base::Bind(&CacheStats::RemoveTabLoadStats,
99 base::Unretained(owner), 125 base::Unretained(owner),
100 render_view_id)); 126 render_view_id));
101 } 127 }
102 128
129 struct PerRequestStatusData {
mmenke 2012/08/15 18:45:41 Think a comment stating that this records the time
tburkard 2012/08/15 21:05:56 Done.
130 PerRequestStatusData()
131 : num_active(0) {
132 }
133 void UpdateTotalTimes() {
134 base::TimeTicks now = base::TimeTicks::Now();
135 if (num_active > 0) {
136 total_time += now - current_start_time;
137 total_cumulative_time +=
138 (now - current_start_time) * static_cast<int64>(num_active);
139 }
140 current_start_time = now;
141 }
142 void ResetTimes() {
143 current_start_time = base::TimeTicks::Now();
144 total_time = base::TimeDelta();
145 total_cumulative_time = base::TimeDelta();
146 }
mmenke 2012/08/15 18:45:41 suggest a blank line after every function to impro
tburkard 2012/08/15 21:05:56 Done.
147 int num_active;
148 base::TimeTicks current_start_time;
mmenke 2012/08/15 18:45:41 Think last_update_time would be more accurate.
tburkard 2012/08/15 21:05:56 Done.
149 base::TimeDelta total_time;
150 base::TimeDelta total_cumulative_time;
151 };
mmenke 2012/08/15 18:45:41 Inner classes/structs go before constructors.
tburkard 2012/08/15 21:05:56 Done.
103 std::pair<int, int> render_view_id; 152 std::pair<int, int> render_view_id;
104 int num_active; 153 PerRequestStatusData per_status_stats[REQUEST_STATUS_MAX];
mmenke 2012/08/15 18:45:41 Your variable name and struct names should be more
tburkard 2012/08/15 21:05:56 Done.
105 bool spinner_started; 154 bool spinner_started;
106 base::TimeTicks load_start_time; 155 base::TimeTicks load_start_time;
107 base::TimeTicks cache_start_time;
108 base::TimeDelta cache_total_time;
109 int next_timer_index; 156 int next_timer_index;
110 base::Timer timer; 157 base::Timer timer;
111 // URLRequest's for which there are outstanding cache transactions. 158 // Currently active URLRequests.
112 base::hash_set<const net::URLRequest*> active_requests; 159 base::hash_map<const net::URLRequest*, RequestStatus> active_requests;
113 }; 160 };
114 161
115 CacheStatsTabHelper::CacheStatsTabHelper(TabContents* tab) 162 CacheStatsTabHelper::CacheStatsTabHelper(TabContents* tab)
116 : content::WebContentsObserver(tab->web_contents()), 163 : content::WebContentsObserver(tab->web_contents()),
117 cache_stats_(NULL) { 164 cache_stats_(NULL) {
118 is_otr_profile_ = tab->profile()->IsOffTheRecord(); 165 is_otr_profile_ = tab->profile()->IsOffTheRecord();
119 } 166 }
120 167
121 CacheStatsTabHelper::~CacheStatsTabHelper() { 168 CacheStatsTabHelper::~CacheStatsTabHelper() {
122 } 169 }
(...skipping 25 matching lines...) Expand all
148 int route_id = render_view_host->GetRoutingID(); 195 int route_id = render_view_host->GetRoutingID();
149 BrowserThread::PostTask( 196 BrowserThread::PostTask(
150 BrowserThread::IO, FROM_HERE, 197 BrowserThread::IO, FROM_HERE,
151 base::Bind(&CallCacheStatsTabEventOnIOThread, 198 base::Bind(&CallCacheStatsTabEventOnIOThread,
152 std::pair<int, int>(process_id, route_id), 199 std::pair<int, int>(process_id, route_id),
153 event, 200 event,
154 base::Unretained(g_browser_process->io_thread()))); 201 base::Unretained(g_browser_process->io_thread())));
155 } 202 }
156 203
157 CacheStats::CacheStats() { 204 CacheStats::CacheStats() {
158 for (int i = 0; 205 for (int status_int = REQUEST_STATUS_CACHE_WAIT;
159 i < static_cast<int>(arraysize(kStatsCollectionTimesMs)); 206 status_int <= REQUEST_STATUS_ACTIVE;
160 i++) { 207 status_int++) {
161 final_histograms_.push_back( 208 RequestStatus status = static_cast<RequestStatus>(status_int);
mmenke 2012/08/15 18:45:41 It looks to me like we don't need this. Can just
tburkard 2012/08/15 21:05:56 Done.
162 base::LinearHistogram::FactoryGet( 209 for (int type_int = HISTOGRAM_FINAL_AGGREGATE;
163 "CacheStats.FractionCacheUseFinalPLT_" + 210 type_int < HISTOGRAM_MAX;
164 base::IntToString(kStatsCollectionTimesMs[i]), 211 type_int++) {
165 0, 101, 102, base::Histogram::kUmaTargetedHistogramFlag)); 212 HistogramType type = static_cast<HistogramType>(type_int);
mmenke 2012/08/15 18:45:41 Same as above. I'd also suggest using histogram_t
tburkard 2012/08/15 21:05:56 Done.
166 intermediate_histograms_.push_back( 213 for (int i = 0;
167 base::LinearHistogram::FactoryGet( 214 i < static_cast<int>(arraysize(kStatsCollectionTimesMs));
168 "CacheStats.FractionCacheUseIntermediatePLT_" + 215 i++) {
169 base::IntToString(kStatsCollectionTimesMs[i]), 216 string histogram_name = string("CacheStats.Fraction_") +
170 0, 101, 102, base::Histogram::kUmaTargetedHistogramFlag)); 217 string(kRequestStatusNames[status]) + string("_") +
218 string(kHistogramTypeNames[type]) + string("_") +
219 base::IntToString(kStatsCollectionTimesMs[i]);
220 if (type != HISTOGRAM_FINAL_CUMULATIVE_PERCENTAGE &&
221 type != HISTOGRAM_INTERMEDIATE_CUMULATIVE_PERCENTAGE) {
222 histograms_[status][type].push_back(
223 base::LinearHistogram::FactoryGet(
224 histogram_name,
225 0, 101, 102, base::Histogram::kUmaTargetedHistogramFlag));
226 } else {
227 histograms_[status][type].push_back(
228 base::Histogram::FactoryGet(
229 histogram_name,
230 0, 10000, 500, base::Histogram::kUmaTargetedHistogramFlag));
231 }
232 }
233 DCHECK_EQ(histograms_[status][type].size(),
234 arraysize(kStatsCollectionTimesMs));
235 }
171 } 236 }
172 DCHECK_EQ(final_histograms_.size(), arraysize(kStatsCollectionTimesMs));
173 DCHECK_EQ(intermediate_histograms_.size(),
174 arraysize(kStatsCollectionTimesMs));
175 } 237 }
176 238
177 CacheStats::~CacheStats() { 239 CacheStats::~CacheStats() {
178 STLDeleteValues(&tab_load_stats_); 240 STLDeleteValues(&tab_load_stats_);
179 } 241 }
180 242
181 CacheStats::TabLoadStats* CacheStats::GetTabLoadStats( 243 CacheStats::TabLoadStats* CacheStats::GetTabLoadStats(
182 std::pair<int, int> render_view_id) { 244 std::pair<int, int> render_view_id) {
183 TabLoadStatsMap::const_iterator it = tab_load_stats_.find(render_view_id); 245 TabLoadStatsMap::const_iterator it = tab_load_stats_.find(render_view_id);
184 if (it != tab_load_stats_.end()) 246 if (it != tab_load_stats_.end())
185 return it->second; 247 return it->second;
186 TabLoadStats* new_tab_load_stats = new TabLoadStats(render_view_id, this); 248 TabLoadStats* new_tab_load_stats = new TabLoadStats(render_view_id, this);
187 tab_load_stats_[render_view_id] = new_tab_load_stats; 249 tab_load_stats_[render_view_id] = new_tab_load_stats;
188 return new_tab_load_stats; 250 return new_tab_load_stats;
189 } 251 }
190 252
191 void CacheStats::RemoveTabLoadStats(std::pair<int, int> render_view_id) { 253 void CacheStats::RemoveTabLoadStats(std::pair<int, int> render_view_id) {
192 TabLoadStatsMap::iterator it = tab_load_stats_.find(render_view_id); 254 TabLoadStatsMap::iterator it = tab_load_stats_.find(render_view_id);
193 if (it != tab_load_stats_.end()) { 255 if (it != tab_load_stats_.end()) {
194 delete it->second; 256 delete it->second;
195 tab_load_stats_.erase(it); 257 tab_load_stats_.erase(it);
196 } 258 }
197 } 259 }
198 260
199 void CacheStats::OnCacheWaitStateChange( 261 void CacheStats::OnRequestWaitStateChange(
200 const net::URLRequest& request, 262 const net::URLRequest& request,
201 net::NetworkDelegate::CacheWaitState state) { 263 net::NetworkDelegate::RequestWaitState state) {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
203 if (main_request_contexts_.count(request.context()) < 1) 265 if (main_request_contexts_.count(request.context()) < 1)
204 return; 266 return;
205 int process_id, route_id; 267 int process_id, route_id;
206 if (!GetRenderView(request, &process_id, &route_id)) 268 if (!GetRenderView(request, &process_id, &route_id))
207 return; 269 return;
208 TabLoadStats* stats = 270 TabLoadStats* stats =
209 GetTabLoadStats(std::pair<int, int>(process_id, route_id)); 271 GetTabLoadStats(std::pair<int, int>(process_id, route_id));
210 bool newly_started = false; 272 RequestStatus old_status = REQUEST_STATUS_NONE;
211 bool newly_finished = false; 273 if (stats->active_requests.count(&request) > 0)
274 old_status = stats->active_requests[&request];
275 RequestStatus new_status = REQUEST_STATUS_NONE;
212 switch (state) { 276 switch (state) {
213 case net::NetworkDelegate::CACHE_WAIT_STATE_START: 277 case net::NetworkDelegate::REQUEST_WAIT_STATE_CACHE_START:
214 DCHECK(stats->active_requests.count(&request) == 0); 278 DCHECK(old_status == REQUEST_STATUS_NONE ||
215 newly_started = true; 279 old_status == REQUEST_STATUS_ACTIVE);
216 stats->active_requests.insert(&request); 280 new_status = REQUEST_STATUS_CACHE_WAIT;
217 break; 281 break;
218 case net::NetworkDelegate::CACHE_WAIT_STATE_FINISH: 282 case net::NetworkDelegate::REQUEST_WAIT_STATE_CACHE_FINISH:
219 if (stats->active_requests.count(&request) > 0) { 283 DCHECK(old_status == REQUEST_STATUS_NONE ||
220 stats->active_requests.erase(&request); 284 old_status == REQUEST_STATUS_CACHE_WAIT);
221 newly_finished = true; 285 new_status = REQUEST_STATUS_ACTIVE;
222 }
223 break; 286 break;
224 case net::NetworkDelegate::CACHE_WAIT_STATE_RESET: 287 case net::NetworkDelegate::REQUEST_WAIT_STATE_NETWORK_START:
225 if (stats->active_requests.count(&request) > 0) { 288 DCHECK(old_status == REQUEST_STATUS_NONE ||
226 stats->active_requests.erase(&request); 289 old_status == REQUEST_STATUS_ACTIVE);
227 newly_finished = true; 290 new_status = REQUEST_STATUS_NETWORK_WAIT;
228 } 291 break;
292 case net::NetworkDelegate::REQUEST_WAIT_STATE_NETWORK_FINISH:
293 DCHECK(old_status == REQUEST_STATUS_NONE ||
294 old_status == REQUEST_STATUS_NETWORK_WAIT);
295 new_status = REQUEST_STATUS_ACTIVE;
296 break;
297 case net::NetworkDelegate::REQUEST_WAIT_STATE_RESET:
298 new_status = REQUEST_STATUS_NONE;
229 break; 299 break;
230 } 300 }
231 DCHECK_GE(stats->num_active, 0); 301 if (old_status != new_status) {
232 if (newly_started) { 302 for (int status_int = REQUEST_STATUS_CACHE_WAIT;
233 DCHECK(!newly_finished); 303 status_int <= REQUEST_STATUS_ACTIVE; status_int++) {
234 if (stats->num_active == 0) { 304 RequestStatus status = static_cast<RequestStatus>(status_int);
mmenke 2012/08/15 18:45:41 Can just use status again.
tburkard 2012/08/15 21:05:56 Done.
235 stats->cache_start_time = base::TimeTicks::Now(); 305 TabLoadStats::PerRequestStatusData* status_stats =
306 &(stats->per_status_stats[status]);
307 DCHECK_GE(status_stats->num_active, 0);
308 if (old_status == status) {
309 status_stats->UpdateTotalTimes();
310 status_stats->num_active--;
mmenke 2012/08/15 18:45:41 Why not just mess with the stats for old_status an
tburkard 2012/08/15 21:05:56 Done.
311 }
312 if (new_status == status) {
313 status_stats->UpdateTotalTimes();
314 status_stats->num_active++;
315 }
316 DCHECK_GE(status_stats->num_active, 0);
236 } 317 }
237 stats->num_active++;
238 } 318 }
239 if (newly_finished) { 319 if (new_status == REQUEST_STATUS_NONE)
240 DCHECK(!newly_started); 320 stats->active_requests.erase(&request);
241 if (stats->num_active == 1) { 321 else
242 stats->cache_total_time += 322 stats->active_requests[&request] = new_status;
mmenke 2012/08/15 18:45:41 This could be put in the above if statement, right
tburkard 2012/08/15 21:05:56 Done.
243 base::TimeTicks::Now() - stats->cache_start_time;
244 }
245 stats->num_active--;
246 }
247 DCHECK_GE(stats->num_active, 0);
248 } 323 }
249 324
250 void CacheStats::OnTabEvent(std::pair<int, int> render_view_id, 325 void CacheStats::OnTabEvent(std::pair<int, int> render_view_id,
251 TabEvent event) { 326 TabEvent event) {
252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
253 TabLoadStats* stats = GetTabLoadStats(render_view_id); 328 TabLoadStats* stats = GetTabLoadStats(render_view_id);
254 if (event == SPINNER_START) { 329 if (event == SPINNER_START) {
255 stats->spinner_started = true; 330 stats->spinner_started = true;
256 stats->cache_total_time = base::TimeDelta(); 331 for (int status_int = REQUEST_STATUS_CACHE_WAIT;
257 stats->cache_start_time = base::TimeTicks::Now(); 332 status_int <= REQUEST_STATUS_ACTIVE; status_int++) {
258 stats->load_start_time = base::TimeTicks::Now(); 333 RequestStatus status = static_cast<RequestStatus>(status_int);
mmenke 2012/08/15 18:45:41 Again, don't need status_int and status.
tburkard 2012/08/15 21:05:56 Done.
334 stats->per_status_stats[status].ResetTimes();
335 }
259 stats->next_timer_index = 0; 336 stats->next_timer_index = 0;
260 ScheduleTimer(stats); 337 ScheduleTimer(stats);
261 } else { 338 } else {
262 DCHECK_EQ(event, SPINNER_STOP); 339 DCHECK_EQ(event, SPINNER_STOP);
263 if (stats->spinner_started) { 340 if (stats->spinner_started) {
264 stats->spinner_started = false; 341 stats->spinner_started = false;
265 base::TimeDelta load_time = 342 base::TimeDelta load_time =
266 base::TimeTicks::Now() - stats->load_start_time; 343 base::TimeTicks::Now() - stats->load_start_time;
267 if (stats->num_active > 1) 344 RecordHistograms(load_time, stats, true);
268 stats->cache_total_time +=
269 base::TimeTicks::Now() - stats->cache_start_time;
270 RecordCacheFractionHistogram(load_time, stats->cache_total_time, true,
271 stats->next_timer_index);
272 } 345 }
273 RemoveTabLoadStats(render_view_id); 346 RemoveTabLoadStats(render_view_id);
274 } 347 }
275 } 348 }
276 349
277 void CacheStats::ScheduleTimer(TabLoadStats* stats) { 350 void CacheStats::ScheduleTimer(TabLoadStats* stats) {
278 int timer_index = stats->next_timer_index; 351 int timer_index = stats->next_timer_index;
279 DCHECK(timer_index >= 0 && 352 DCHECK(timer_index >= 0 &&
280 timer_index < static_cast<int>(arraysize(kStatsCollectionTimesMs))); 353 timer_index < static_cast<int>(arraysize(kStatsCollectionTimesMs)));
281 base::TimeDelta delta = 354 base::TimeDelta delta =
(...skipping 10 matching lines...) Expand all
292 stats->timer.Start(FROM_HERE, 365 stats->timer.Start(FROM_HERE,
293 delta, 366 delta,
294 base::Bind(&CacheStats::TimerCallback, 367 base::Bind(&CacheStats::TimerCallback,
295 base::Unretained(this), 368 base::Unretained(this),
296 base::Unretained(stats))); 369 base::Unretained(stats)));
297 } 370 }
298 371
299 void CacheStats::TimerCallback(TabLoadStats* stats) { 372 void CacheStats::TimerCallback(TabLoadStats* stats) {
300 DCHECK(stats->spinner_started); 373 DCHECK(stats->spinner_started);
301 base::TimeDelta load_time = base::TimeTicks::Now() - stats->load_start_time; 374 base::TimeDelta load_time = base::TimeTicks::Now() - stats->load_start_time;
302 base::TimeDelta cache_time = stats->cache_total_time; 375 RecordHistograms(load_time, stats, false);
303 if (stats->num_active > 1)
304 cache_time += base::TimeTicks::Now() - stats->cache_start_time;
305 RecordCacheFractionHistogram(load_time, cache_time, false,
306 stats->next_timer_index);
307 stats->next_timer_index++; 376 stats->next_timer_index++;
308 if (stats->next_timer_index < 377 if (stats->next_timer_index <
309 static_cast<int>(arraysize(kStatsCollectionTimesMs))) { 378 static_cast<int>(arraysize(kStatsCollectionTimesMs))) {
310 ScheduleTimer(stats); 379 ScheduleTimer(stats);
311 } else { 380 } else {
312 RemoveTabLoadStats(stats->render_view_id); 381 RemoveTabLoadStats(stats->render_view_id);
313 } 382 }
314 } 383 }
315 384
316 void CacheStats::RecordCacheFractionHistogram(base::TimeDelta elapsed, 385 void CacheStats::RecordHistograms(base::TimeDelta elapsed,
317 base::TimeDelta cache_time, 386 TabLoadStats* stats,
318 bool is_load_done, 387 bool is_load_done) {
319 int timer_index) { 388 int timer_index = stats->next_timer_index;
320 DCHECK(timer_index >= 0 && 389 DCHECK(timer_index >= 0 &&
321 timer_index < static_cast<int>(arraysize(kStatsCollectionTimesMs))); 390 timer_index < static_cast<int>(arraysize(kStatsCollectionTimesMs)));
322 391
323 if (elapsed.InMilliseconds() <= 0) 392 if (elapsed.InMilliseconds() <= 0)
324 return; 393 return;
325 394
326 int64 cache_fraction_percentage = 395 base::TimeDelta total_cumulative;
327 100 * cache_time.InMilliseconds() / elapsed.InMilliseconds(); 396 for (int status_int = REQUEST_STATUS_CACHE_WAIT;
397 status_int <= REQUEST_STATUS_ACTIVE;
398 status_int++) {
399 RequestStatus status = static_cast<RequestStatus>(status_int);
400 total_cumulative += stats->per_status_stats[status].total_cumulative_time;
401 }
328 402
329 DCHECK(cache_fraction_percentage >= 0 && cache_fraction_percentage <= 100); 403 for (int status_int = REQUEST_STATUS_CACHE_WAIT;
404 status_int <= REQUEST_STATUS_ACTIVE;
405 status_int++) {
406 RequestStatus status = static_cast<RequestStatus>(status_int);
407 TabLoadStats::PerRequestStatusData* status_stats =
408 &(stats->per_status_stats[status]);
330 409
331 if (is_load_done) { 410 int64 fraction_percentage = 100 *
332 final_histograms_[timer_index]->Add(cache_fraction_percentage); 411 status_stats->total_time.InMilliseconds() / elapsed.InMilliseconds();
333 } else { 412 DCHECK(fraction_percentage >= 0 && fraction_percentage <= 100);
334 intermediate_histograms_[timer_index]->Add(cache_fraction_percentage); 413 if (is_load_done) {
414 histograms_[status][HISTOGRAM_FINAL_AGGREGATE][timer_index]->Add(
415 fraction_percentage);
416 } else {
417 histograms_[status][HISTOGRAM_INTERMEDIATE_AGGREGATE][timer_index]->Add(
418 fraction_percentage);
419 }
420
421 fraction_percentage = 100 *
422 status_stats->total_cumulative_time.InMilliseconds() /
423 elapsed.InMilliseconds();
424 DCHECK(fraction_percentage >= 0);
425 if (is_load_done) {
426 histograms_[status][HISTOGRAM_FINAL_CUMULATIVE][timer_index]->Add(
427 fraction_percentage);
428 } else {
429 histograms_[status][HISTOGRAM_INTERMEDIATE_CUMULATIVE][timer_index]->Add(
430 fraction_percentage);
431 }
432
433 if (total_cumulative.InMilliseconds() > 0) {
434 fraction_percentage = 100 *
435 status_stats->total_cumulative_time.InMilliseconds() /
436 total_cumulative.InMilliseconds();
437 DCHECK(fraction_percentage >= 0 && fraction_percentage <= 100);
438 if (is_load_done) {
439 histograms_[status][HISTOGRAM_FINAL_CUMULATIVE_PERCENTAGE]
440 [timer_index]->Add(fraction_percentage);
441 } else {
442 histograms_[status][HISTOGRAM_INTERMEDIATE_CUMULATIVE_PERCENTAGE]
443 [timer_index]->Add(fraction_percentage);
444 }
445 }
335 } 446 }
336 } 447 }
337 448
338 void CacheStats::RegisterURLRequestContext( 449 void CacheStats::RegisterURLRequestContext(
339 const net::URLRequestContext* context, 450 const net::URLRequestContext* context,
340 ChromeURLRequestContext::ContextType type) { 451 ChromeURLRequestContext::ContextType type) {
341 if (type == ChromeURLRequestContext::CONTEXT_TYPE_MAIN) 452 if (type == ChromeURLRequestContext::CONTEXT_TYPE_MAIN)
342 main_request_contexts_.insert(context); 453 main_request_contexts_.insert(context);
343 } 454 }
344 455
345 void CacheStats::UnregisterURLRequestContext( 456 void CacheStats::UnregisterURLRequestContext(
346 const net::URLRequestContext* context) { 457 const net::URLRequestContext* context) {
347 main_request_contexts_.erase(context); 458 main_request_contexts_.erase(context);
348 } 459 }
349 460
350 } // namespace chrome_browser_net 461 } // namespace chrome_browser_net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698