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

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

Issue 8802014: Add new histograms to track down cookie performance issues. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/sqlite_persistent_cookie_store.h" 5 #include "chrome/browser/net/sqlite_persistent_cookie_store.h"
6 6
7 #include <list> 7 #include <list>
8 #include <map> 8 #include <map>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 class SQLitePersistentCookieStore::Backend 58 class SQLitePersistentCookieStore::Backend
59 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { 59 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> {
60 public: 60 public:
61 Backend(const FilePath& path, bool restore_old_session_cookies) 61 Backend(const FilePath& path, bool restore_old_session_cookies)
62 : path_(path), 62 : path_(path),
63 db_(NULL), 63 db_(NULL),
64 num_pending_(0), 64 num_pending_(0),
65 clear_local_state_on_exit_(false), 65 clear_local_state_on_exit_(false),
66 initialized_(false), 66 initialized_(false),
67 restore_old_session_cookies_(restore_old_session_cookies), 67 restore_old_session_cookies_(restore_old_session_cookies),
68 num_cookies_read_(0),
68 num_priority_waiting_(0), 69 num_priority_waiting_(0),
69 total_priority_requests_(0) { 70 total_priority_requests_(0) {
70 } 71 }
71 72
72 // Creates or loads the SQLite database. 73 // Creates or loads the SQLite database.
73 void Load(const LoadedCallback& loaded_callback); 74 void Load(const LoadedCallback& loaded_callback);
74 75
75 // Loads cookies for the domain key (eTLD+1). 76 // Loads cookies for the domain key (eTLD+1).
76 void LoadCookiesForKey(const std::string& domain, 77 void LoadCookiesForKey(const std::string& domain,
77 const LoadedCallback& loaded_callback); 78 const LoadedCallback& loaded_callback);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 OperationType op() const { return op_; } 122 OperationType op() const { return op_; }
122 const net::CookieMonster::CanonicalCookie& cc() const { return cc_; } 123 const net::CookieMonster::CanonicalCookie& cc() const { return cc_; }
123 124
124 private: 125 private:
125 OperationType op_; 126 OperationType op_;
126 net::CookieMonster::CanonicalCookie cc_; 127 net::CookieMonster::CanonicalCookie cc_;
127 }; 128 };
128 129
129 private: 130 private:
130 // Creates or loads the SQLite database on DB thread. 131 // Creates or loads the SQLite database on DB thread.
131 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback); 132 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback,
133 const base::Time& posted_at);
132 134
133 // Loads cookies for the domain key (eTLD+1) on DB thread. 135 // Loads cookies for the domain key (eTLD+1) on DB thread.
134 void LoadKeyAndNotifyOnDBThread(const std::string& domains, 136 void LoadKeyAndNotifyOnDBThread(const std::string& domains,
135 const LoadedCallback& loaded_callback); 137 const LoadedCallback& loaded_callback,
138 const base::Time& posted_at);
136 139
137 // Notifies the CookieMonster when loading completes for a specific domain key 140 // Notifies the CookieMonster when loading completes for a specific domain key
138 // or for all domain keys. Triggers the callback and passes it all cookies 141 // or for all domain keys. Triggers the callback and passes it all cookies
139 // that have been loaded from DB since last IO notification. 142 // that have been loaded from DB since last IO notification.
140 void Notify(const LoadedCallback& loaded_callback, bool load_success); 143 void Notify(const LoadedCallback& loaded_callback, bool load_success);
141 144
142 // Sends notification when the entire store is loaded, and reports metrics 145 // Sends notification when the entire store is loaded, and reports metrics
143 // for the total time to load and aggregated results from any priority loads 146 // for the total time to load and aggregated results from any priority loads
144 // that occurred. 147 // that occurred.
145 void CompleteLoadOnIOThread(const LoadedCallback& loaded_callback, 148 void CompleteLoadOnIOThread(const LoadedCallback& loaded_callback,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 // Indicates if DB has been initialized. 205 // Indicates if DB has been initialized.
203 bool initialized_; 206 bool initialized_;
204 207
205 // If false, we should filter out session cookies when reading the DB. 208 // If false, we should filter out session cookies when reading the DB.
206 bool restore_old_session_cookies_; 209 bool restore_old_session_cookies_;
207 210
208 // The cumulative time spent loading the cookies on the DB thread. Incremented 211 // The cumulative time spent loading the cookies on the DB thread. Incremented
209 // and reported from the DB thread. 212 // and reported from the DB thread.
210 base::TimeDelta cookie_load_duration_; 213 base::TimeDelta cookie_load_duration_;
211 214
215 // The total number of cookies read. Incremented and reported on the DB
216 // thread.
217 int num_cookies_read_;
218
212 // Guards the following metrics-related properties (only accessed when 219 // Guards the following metrics-related properties (only accessed when
213 // starting/completing priority loads or completing the total load). 220 // starting/completing priority loads or completing the total load).
214 base::Lock metrics_lock_; 221 base::Lock metrics_lock_;
215 int num_priority_waiting_; 222 int num_priority_waiting_;
216 // The total number of priority requests. 223 // The total number of priority requests.
217 int total_priority_requests_; 224 int total_priority_requests_;
218 // The time when |num_priority_waiting_| incremented to 1. 225 // The time when |num_priority_waiting_| incremented to 1.
219 base::Time current_priority_wait_start_; 226 base::Time current_priority_wait_start_;
220 // The cumulative duration of time when |num_priority_waiting_| was greater 227 // The cumulative duration of time when |num_priority_waiting_| was greater
221 // than 1. 228 // than 1.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 } 303 }
297 304
298 } // namespace 305 } // namespace
299 306
300 void SQLitePersistentCookieStore::Backend::Load( 307 void SQLitePersistentCookieStore::Backend::Load(
301 const LoadedCallback& loaded_callback) { 308 const LoadedCallback& loaded_callback) {
302 // This function should be called only once per instance. 309 // This function should be called only once per instance.
303 DCHECK(!db_.get()); 310 DCHECK(!db_.get());
304 BrowserThread::PostTask( 311 BrowserThread::PostTask(
305 BrowserThread::DB, FROM_HERE, 312 BrowserThread::DB, FROM_HERE,
306 base::Bind(&Backend::LoadAndNotifyOnDBThread, this, loaded_callback)); 313 base::Bind(&Backend::LoadAndNotifyOnDBThread, this, loaded_callback,
314 base::Time::Now()));
307 } 315 }
308 316
309 void SQLitePersistentCookieStore::Backend::LoadCookiesForKey( 317 void SQLitePersistentCookieStore::Backend::LoadCookiesForKey(
310 const std::string& key, 318 const std::string& key,
311 const LoadedCallback& loaded_callback) { 319 const LoadedCallback& loaded_callback) {
312 { 320 {
313 base::AutoLock locked(metrics_lock_); 321 base::AutoLock locked(metrics_lock_);
314 if (num_priority_waiting_ == 0) 322 if (num_priority_waiting_ == 0)
315 current_priority_wait_start_ = base::Time::Now(); 323 current_priority_wait_start_ = base::Time::Now();
316 num_priority_waiting_++; 324 num_priority_waiting_++;
317 total_priority_requests_++; 325 total_priority_requests_++;
318 } 326 }
319 327
320 BrowserThread::PostTask( 328 BrowserThread::PostTask(
321 BrowserThread::DB, FROM_HERE, 329 BrowserThread::DB, FROM_HERE,
322 base::Bind(&Backend::LoadKeyAndNotifyOnDBThread, this, 330 base::Bind(&Backend::LoadKeyAndNotifyOnDBThread, this,
323 key, 331 key,
324 loaded_callback)); 332 loaded_callback,
333 base::Time::Now()));
325 } 334 }
326 335
327 void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread( 336 void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread(
328 const LoadedCallback& loaded_callback) { 337 const LoadedCallback& loaded_callback, const base::Time& posted_at) {
329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
330 IncrementTimeDelta increment(&cookie_load_duration_); 339 IncrementTimeDelta increment(&cookie_load_duration_);
331 340
341 UMA_HISTOGRAM_CUSTOM_TIMES(
342 "Cookie.TimeLoadDBQueueWait",
343 base::Time::Now() - posted_at,
344 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
345 50);
Randy Smith (Not in Mondays) 2011/12/05 22:18:08 Do the queue load histograms give us a lot more in
erikwright (departed) 2011/12/06 00:07:09 AFAIK, task profiler data is not yet available fro
346
332 if (!InitializeDatabase()) { 347 if (!InitializeDatabase()) {
333 BrowserThread::PostTask( 348 BrowserThread::PostTask(
334 BrowserThread::IO, FROM_HERE, 349 BrowserThread::IO, FROM_HERE,
335 base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread, 350 base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread,
336 this, loaded_callback, false)); 351 this, loaded_callback, false));
337 } else { 352 } else {
338 ChainLoadCookies(loaded_callback); 353 ChainLoadCookies(loaded_callback);
339 } 354 }
340 } 355 }
341 356
342 void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread( 357 void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread(
343 const std::string& key, 358 const std::string& key,
344 const LoadedCallback& loaded_callback) { 359 const LoadedCallback& loaded_callback,
360 const base::Time& posted_at) {
345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
346 IncrementTimeDelta increment(&cookie_load_duration_); 362 IncrementTimeDelta increment(&cookie_load_duration_);
347 363
364 UMA_HISTOGRAM_CUSTOM_TIMES(
365 "Cookie.TimeKeyLoadDBQueueWait",
366 base::Time::Now() - posted_at,
367 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
368 50);
369
348 bool success = false; 370 bool success = false;
349 if (InitializeDatabase()) { 371 if (InitializeDatabase()) {
350 std::map<std::string, std::set<std::string> >::iterator 372 std::map<std::string, std::set<std::string> >::iterator
351 it = keys_to_load_.find(key); 373 it = keys_to_load_.find(key);
352 if (it != keys_to_load_.end()) { 374 if (it != keys_to_load_.end()) {
353 success = LoadCookiesForDomains(it->second); 375 success = LoadCookiesForDomains(it->second);
354 keys_to_load_.erase(it); 376 keys_to_load_.erase(it);
355 } else { 377 } else {
356 success = true; 378 success = true;
357 } 379 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 base::AutoLock locked(metrics_lock_); 418 base::AutoLock locked(metrics_lock_);
397 UMA_HISTOGRAM_CUSTOM_TIMES( 419 UMA_HISTOGRAM_CUSTOM_TIMES(
398 "Cookie.PriorityBlockingTime", 420 "Cookie.PriorityBlockingTime",
399 priority_wait_duration_, 421 priority_wait_duration_,
400 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 422 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
401 50); 423 50);
402 424
403 UMA_HISTOGRAM_COUNTS_100( 425 UMA_HISTOGRAM_COUNTS_100(
404 "Cookie.PriorityLoadCount", 426 "Cookie.PriorityLoadCount",
405 total_priority_requests_); 427 total_priority_requests_);
428
429 UMA_HISTOGRAM_COUNTS_10000(
430 "Cookie.NumberOfLoadedCookies",
431 num_cookies_read_);
406 } 432 }
407 } 433 }
408 434
409 void SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread( 435 void SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread(
410 const LoadedCallback& loaded_callback, bool load_success) { 436 const LoadedCallback& loaded_callback, bool load_success) {
411 Notify(loaded_callback, load_success); 437 Notify(loaded_callback, load_success);
412 438
413 if (load_success) 439 if (load_success)
414 ReportMetrics(); 440 ReportMetrics();
415 } 441 }
(...skipping 12 matching lines...) Expand all
428 loaded_callback.Run(cookies); 454 loaded_callback.Run(cookies);
429 } 455 }
430 456
431 bool SQLitePersistentCookieStore::Backend::InitializeDatabase() { 457 bool SQLitePersistentCookieStore::Backend::InitializeDatabase() {
432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 458 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
433 459
434 if (initialized_) { 460 if (initialized_) {
435 return true; 461 return true;
436 } 462 }
437 463
464 base::Time start = base::Time::Now();
465
438 const FilePath dir = path_.DirName(); 466 const FilePath dir = path_.DirName();
439 if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) { 467 if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) {
440 return false; 468 return false;
441 } 469 }
442 470
471 int64 db_size = 0;
472 if (file_util::GetFileSize(path_, &db_size)) {
473 base::ThreadRestrictions::ScopedAllowIO allow_io;
474 UMA_HISTOGRAM_COUNTS("Cookie.DBSizeInKB", db_size / 1024 );
475 }
476
443 db_.reset(new sql::Connection); 477 db_.reset(new sql::Connection);
444 if (!db_->Open(path_)) { 478 if (!db_->Open(path_)) {
445 NOTREACHED() << "Unable to open cookie DB."; 479 NOTREACHED() << "Unable to open cookie DB.";
446 db_.reset(); 480 db_.reset();
447 return false; 481 return false;
448 } 482 }
449 483
450 db_->set_error_delegate(GetErrorHandlerForCookieDb()); 484 db_->set_error_delegate(GetErrorHandlerForCookieDb());
451 485
452 if (!EnsureDatabaseVersion() || !InitTable(db_.get())) { 486 if (!EnsureDatabaseVersion() || !InitTable(db_.get())) {
453 NOTREACHED() << "Unable to open cookie DB."; 487 NOTREACHED() << "Unable to open cookie DB.";
454 db_.reset(); 488 db_.reset();
455 return false; 489 return false;
456 } 490 }
457 491
458 db_->Preload(); 492 db_->Preload();
Randy Smith (Not in Mondays) 2011/12/05 22:18:08 Didn't we nuke this? Is there context I'm missing
erikwright (departed) 2011/12/06 00:07:09 After uploading that CL I decided I would prefer t
459 493
494 UMA_HISTOGRAM_CUSTOM_TIMES(
495 "Cookie.TimeInitializeDB",
496 base::Time::Now() - start,
497 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
498 50);
499
500 start = base::Time::Now();
501
460 // Retrieve all the domains 502 // Retrieve all the domains
461 sql::Statement smt(db_->GetUniqueStatement( 503 sql::Statement smt(db_->GetUniqueStatement(
462 "SELECT DISTINCT host_key FROM cookies")); 504 "SELECT DISTINCT host_key FROM cookies"));
463 505
464 if (!smt) { 506 if (!smt) {
465 NOTREACHED() << "select statement prep failed"; 507 NOTREACHED() << "select statement prep failed";
466 db_.reset(); 508 db_.reset();
467 return false; 509 return false;
468 } 510 }
469 511
470 // Build a map of domain keys (always eTLD+1) to domains. 512 // Build a map of domain keys (always eTLD+1) to domains.
471 while (smt.Step()) { 513 while (smt.Step()) {
472 std::string domain = smt.ColumnString(0); 514 std::string domain = smt.ColumnString(0);
473 std::string key = 515 std::string key =
474 net::RegistryControlledDomainService::GetDomainAndRegistry(domain); 516 net::RegistryControlledDomainService::GetDomainAndRegistry(domain);
475 517
476 std::map<std::string, std::set<std::string> >::iterator it = 518 std::map<std::string, std::set<std::string> >::iterator it =
477 keys_to_load_.find(key); 519 keys_to_load_.find(key);
478 if (it == keys_to_load_.end()) 520 if (it == keys_to_load_.end())
479 it = keys_to_load_.insert(std::make_pair 521 it = keys_to_load_.insert(std::make_pair
480 (key, std::set<std::string>())).first; 522 (key, std::set<std::string>())).first;
481 it->second.insert(domain); 523 it->second.insert(domain);
482 } 524 }
483 525
526 UMA_HISTOGRAM_CUSTOM_TIMES(
527 "Cookie.TimeInitializeDomainMap",
528 base::Time::Now() - start,
529 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
530 50);
531
484 initialized_ = true; 532 initialized_ = true;
485 return true; 533 return true;
486 } 534 }
487 535
488 void SQLitePersistentCookieStore::Backend::ChainLoadCookies( 536 void SQLitePersistentCookieStore::Backend::ChainLoadCookies(
489 const LoadedCallback& loaded_callback) { 537 const LoadedCallback& loaded_callback) {
490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
491 IncrementTimeDelta increment(&cookie_load_duration_); 539 IncrementTimeDelta increment(&cookie_load_duration_);
492 540
493 bool load_success = true; 541 bool load_success = true;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc 606 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc
559 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc 607 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc
560 Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc 608 Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc
561 smt.ColumnInt(6) != 0, // secure 609 smt.ColumnInt(6) != 0, // secure
562 smt.ColumnInt(7) != 0, // httponly 610 smt.ColumnInt(7) != 0, // httponly
563 smt.ColumnInt(9) != 0, // has_expires 611 smt.ColumnInt(9) != 0, // has_expires
564 smt.ColumnInt(10) != 0)); // is_persistent 612 smt.ColumnInt(10) != 0)); // is_persistent
565 DLOG_IF(WARNING, 613 DLOG_IF(WARNING,
566 cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; 614 cc->CreationDate() > Time::Now()) << L"CreationDate too recent";
567 cookies.push_back(cc.release()); 615 cookies.push_back(cc.release());
616 ++num_cookies_read_;
568 } 617 }
569 smt.Reset(); 618 smt.Reset();
570 } 619 }
571 { 620 {
572 base::AutoLock locked(lock_); 621 base::AutoLock locked(lock_);
573 cookies_.insert(cookies_.end(), cookies.begin(), cookies.end()); 622 cookies_.insert(cookies_.end(), cookies.begin(), cookies.end());
574 } 623 }
575 return true; 624 return true;
576 } 625 }
577 626
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 if (backend_.get()) 955 if (backend_.get())
907 backend_->SetClearLocalStateOnExit(clear_local_state); 956 backend_->SetClearLocalStateOnExit(clear_local_state);
908 } 957 }
909 958
910 void SQLitePersistentCookieStore::Flush(Task* completion_task) { 959 void SQLitePersistentCookieStore::Flush(Task* completion_task) {
911 if (backend_.get()) 960 if (backend_.get())
912 backend_->Flush(completion_task); 961 backend_->Flush(completion_task);
913 else if (completion_task) 962 else if (completion_task)
914 MessageLoop::current()->PostTask(FROM_HERE, completion_task); 963 MessageLoop::current()->PostTask(FROM_HERE, completion_task);
915 } 964 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698