Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "components/history/core/browser/thumbnail_database.h" | 5 #include "components/history/core/browser/thumbnail_database.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 // redownloaded from the web. | 67 // redownloaded from the web. |
| 68 // image_data PNG encoded data of the favicon. | 68 // image_data PNG encoded data of the favicon. |
| 69 // width Pixel width of |image_data|. | 69 // width Pixel width of |image_data|. |
| 70 // height Pixel height of |image_data|. | 70 // height Pixel height of |image_data|. |
| 71 // last_requested The time at which this bitmap was last requested. This is | 71 // last_requested The time at which this bitmap was last requested. This is |
| 72 // used to determine the priority with which the bitmap | 72 // used to determine the priority with which the bitmap |
| 73 // should be retained on cleanup. | 73 // should be retained on cleanup. |
| 74 | 74 |
| 75 namespace { | 75 namespace { |
| 76 | 76 |
| 77 const int kFaviconUpdateLastRequestedAfterDays = 14; | |
| 78 | |
| 77 // For this database, schema migrations are deprecated after two | 79 // For this database, schema migrations are deprecated after two |
| 78 // years. This means that the oldest non-deprecated version should be | 80 // years. This means that the oldest non-deprecated version should be |
| 79 // two years old or greater (thus the migrations to get there are | 81 // two years old or greater (thus the migrations to get there are |
| 80 // older). Databases containing deprecated versions will be cleared | 82 // older). Databases containing deprecated versions will be cleared |
| 81 // at startup. Since this database is a cache, losing old data is not | 83 // at startup. Since this database is a cache, losing old data is not |
| 82 // fatal (in fact, very old data may be expired immediately at startup | 84 // fatal (in fact, very old data may be expired immediately at startup |
| 83 // anyhow). | 85 // anyhow). |
| 84 | 86 |
| 85 // Version 8: 982ef2c1/r323176 by rogerm@chromium.org on 2015-03-31 | 87 // Version 8: 982ef2c1/r323176 by rogerm@chromium.org on 2015-03-31 |
| 86 // Version 7: 911a634d/r209424 by qsr@chromium.org on 2013-07-01 | 88 // Version 7: 911a634d/r209424 by qsr@chromium.org on 2013-07-01 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 // test-expectation framework that the error was handled. | 262 // test-expectation framework that the error was handled. |
| 261 ignore_result(sql::Connection::IsExpectedSqliteError(extended_error)); | 263 ignore_result(sql::Connection::IsExpectedSqliteError(extended_error)); |
| 262 return; | 264 return; |
| 263 } | 265 } |
| 264 | 266 |
| 265 // The default handling is to assert on debug and to ignore on release. | 267 // The default handling is to assert on debug and to ignore on release. |
| 266 if (!sql::Connection::IsExpectedSqliteError(extended_error)) | 268 if (!sql::Connection::IsExpectedSqliteError(extended_error)) |
| 267 DLOG(FATAL) << db->GetErrorMessage(); | 269 DLOG(FATAL) << db->GetErrorMessage(); |
| 268 } | 270 } |
| 269 | 271 |
| 272 bool SetFaviconBitmapLastRequestedTime(sql::Connection* db, | |
| 273 FaviconBitmapID bitmap_id, | |
| 274 base::Time access_time) { | |
| 275 DCHECK(bitmap_id); | |
| 276 sql::Statement statement(db->GetCachedStatement( | |
| 277 SQL_FROM_HERE, "UPDATE favicon_bitmaps SET last_requested=? WHERE id=?")); | |
| 278 statement.BindInt64(0, access_time.ToInternalValue()); | |
| 279 statement.BindInt64(1, bitmap_id); | |
| 280 return statement.Run(); | |
| 281 } | |
| 282 | |
| 283 void DeleteOrphanagedFaviconBitmaps(sql::Connection* db) { | |
| 284 sql::Statement favicons(db->GetCachedStatement( | |
| 285 SQL_FROM_HERE, | |
| 286 "DELETE FROM favicon_bitmaps WHERE NOT EXISTS (SELECT id FROM favicons " | |
| 287 "WHERE favicon_bitmaps.icon_id = favicons.id)")); | |
| 288 favicons.Run(); | |
| 289 } | |
| 290 | |
| 291 void DeleteOrphanagedMappings(sql::Connection* db) { | |
| 292 sql::Statement mappings(db->GetCachedStatement( | |
| 293 SQL_FROM_HERE, | |
| 294 "DELETE FROM icon_mapping WHERE NOT EXISTS (SELECT id FROM favicons " | |
| 295 "WHERE favicons.id = icon_mapping.icon_id)")); | |
| 296 mappings.Run(); | |
| 297 } | |
| 298 | |
| 270 } // namespace | 299 } // namespace |
| 271 | 300 |
| 272 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { | 301 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { |
| 273 } | 302 } |
| 274 | 303 |
| 275 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() { | 304 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() { |
| 276 } | 305 } |
| 277 | 306 |
| 278 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping( | 307 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping( |
| 279 IconMapping* icon_mapping) { | 308 IconMapping* icon_mapping) { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 void ThumbnailDatabase::Vacuum() { | 430 void ThumbnailDatabase::Vacuum() { |
| 402 DCHECK(db_.transaction_nesting() == 0) << | 431 DCHECK(db_.transaction_nesting() == 0) << |
| 403 "Can not have a transaction when vacuuming."; | 432 "Can not have a transaction when vacuuming."; |
| 404 ignore_result(db_.Execute("VACUUM")); | 433 ignore_result(db_.Execute("VACUUM")); |
| 405 } | 434 } |
| 406 | 435 |
| 407 void ThumbnailDatabase::TrimMemory(bool aggressively) { | 436 void ThumbnailDatabase::TrimMemory(bool aggressively) { |
| 408 db_.TrimMemory(aggressively); | 437 db_.TrimMemory(aggressively); |
| 409 } | 438 } |
| 410 | 439 |
| 440 void ThumbnailDatabase::CleanUnusedFavicons(base::Time expiration_threshold) { | |
| 441 // Select all bitmaps (and their page URLs) that have not been accessed for a | |
| 442 // while. | |
| 443 sql::Statement delete_candidates(db_.GetCachedStatement( | |
| 444 SQL_FROM_HERE, | |
| 445 "SELECT favicon_bitmaps.icon_id, icon_mapping.page_url FROM " | |
| 446 "favicon_bitmaps, icon_mapping WHERE favicon_bitmaps.icon_id = " | |
| 447 "icon_mapping.icon_id AND favicon_bitmaps.last_requested<?;")); | |
|
pkotwicz
2017/05/17 14:56:49
It we end up setting last_requested for only some
| |
| 448 delete_candidates.BindInt64(0, expiration_threshold.ToInternalValue()); | |
| 449 | |
| 450 std::set<FaviconBitmapID> ids_of_bookmarked_favicons; | |
| 451 std::set<FaviconBitmapID> ids_to_delete; | |
| 452 // Multiple page URLs may map to the same favicon. We omit the favicon_bitmap | |
| 453 // from cleaning if at least one of its associated page URLs is bookmarked. | |
| 454 while (delete_candidates.Step()) { | |
| 455 FaviconBitmapID bitmap_id = delete_candidates.ColumnInt64(0); | |
| 456 if (ids_of_bookmarked_favicons.count(bitmap_id)) | |
| 457 continue; | |
| 458 | |
| 459 if (backend_client_ && backend_client_->IsBookmarked( | |
| 460 GURL(delete_candidates.ColumnString(1)))) { | |
| 461 ids_of_bookmarked_favicons.insert(bitmap_id); | |
| 462 ids_to_delete.erase(bitmap_id); | |
| 463 continue; | |
| 464 } | |
| 465 | |
| 466 ids_to_delete.insert(bitmap_id); | |
| 467 } | |
| 468 | |
| 469 for (FaviconBitmapID bitmap_id : ids_to_delete) { | |
| 470 sql::Statement statement(db_.GetCachedStatement( | |
| 471 SQL_FROM_HERE, "DELETE FROM favicons WHERE id=?")); | |
| 472 statement.BindInt64(0, bitmap_id); | |
| 473 statement.Run(); | |
| 474 } | |
| 475 | |
| 476 // The bitmaps and mappings for all deleted favicons are deleted at once. | |
| 477 DeleteOrphanagedFaviconBitmaps(&db_); | |
| 478 DeleteOrphanagedMappings(&db_); | |
| 479 } | |
| 480 | |
| 411 bool ThumbnailDatabase::GetFaviconBitmapIDSizes( | 481 bool ThumbnailDatabase::GetFaviconBitmapIDSizes( |
| 412 favicon_base::FaviconID icon_id, | 482 favicon_base::FaviconID icon_id, |
| 413 std::vector<FaviconBitmapIDSize>* bitmap_id_sizes) { | 483 std::vector<FaviconBitmapIDSize>* bitmap_id_sizes) { |
| 414 DCHECK(icon_id); | 484 DCHECK(icon_id); |
| 415 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 485 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
| 416 "SELECT id, width, height FROM favicon_bitmaps WHERE icon_id=?")); | 486 "SELECT id, width, height FROM favicon_bitmaps WHERE icon_id=?")); |
| 417 statement.BindInt64(0, icon_id); | 487 statement.BindInt64(0, icon_id); |
| 418 | 488 |
| 419 bool result = false; | 489 bool result = false; |
| 420 while (statement.Step()) { | 490 while (statement.Step()) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 460 statement.ColumnInt(4)); | 530 statement.ColumnInt(4)); |
| 461 favicon_bitmap.last_requested = | 531 favicon_bitmap.last_requested = |
| 462 base::Time::FromInternalValue(statement.ColumnInt64(5)); | 532 base::Time::FromInternalValue(statement.ColumnInt64(5)); |
| 463 favicon_bitmaps->push_back(favicon_bitmap); | 533 favicon_bitmaps->push_back(favicon_bitmap); |
| 464 } | 534 } |
| 465 return result; | 535 return result; |
| 466 } | 536 } |
| 467 | 537 |
| 468 bool ThumbnailDatabase::GetFaviconBitmap( | 538 bool ThumbnailDatabase::GetFaviconBitmap( |
| 469 FaviconBitmapID bitmap_id, | 539 FaviconBitmapID bitmap_id, |
| 540 base::Time access_time, | |
| 470 base::Time* last_updated, | 541 base::Time* last_updated, |
| 471 base::Time* last_requested, | |
| 472 scoped_refptr<base::RefCountedMemory>* png_icon_data, | 542 scoped_refptr<base::RefCountedMemory>* png_icon_data, |
| 473 gfx::Size* pixel_size) { | 543 gfx::Size* pixel_size) { |
| 474 DCHECK(bitmap_id); | 544 DCHECK(bitmap_id); |
| 475 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 545 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
| 476 "SELECT last_updated, image_data, width, height, last_requested " | 546 "SELECT last_updated, image_data, width, height, last_requested " |
| 477 "FROM favicon_bitmaps WHERE id=?")); | 547 "FROM favicon_bitmaps WHERE id=?")); |
| 478 statement.BindInt64(0, bitmap_id); | 548 statement.BindInt64(0, bitmap_id); |
| 479 | 549 |
| 480 if (!statement.Step()) | 550 if (!statement.Step()) |
| 481 return false; | 551 return false; |
| 482 | 552 |
| 483 if (last_updated) | 553 if (last_updated) |
| 484 *last_updated = base::Time::FromInternalValue(statement.ColumnInt64(0)); | 554 *last_updated = base::Time::FromInternalValue(statement.ColumnInt64(0)); |
| 485 | 555 |
| 486 if (png_icon_data && statement.ColumnByteLength(1) > 0) { | 556 if (png_icon_data && statement.ColumnByteLength(1) > 0) { |
| 487 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes()); | 557 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes()); |
| 488 statement.ColumnBlobAsVector(1, &data->data()); | 558 statement.ColumnBlobAsVector(1, &data->data()); |
| 489 *png_icon_data = data; | 559 *png_icon_data = data; |
| 490 } | 560 } |
| 491 | 561 |
| 492 if (pixel_size) { | 562 if (pixel_size) { |
| 493 *pixel_size = gfx::Size(statement.ColumnInt(2), | 563 *pixel_size = gfx::Size(statement.ColumnInt(2), |
| 494 statement.ColumnInt(3)); | 564 statement.ColumnInt(3)); |
| 495 } | 565 } |
| 496 | 566 |
| 497 if (last_requested) | 567 base::Time last_requested = |
| 498 *last_requested = base::Time::FromInternalValue(statement.ColumnInt64(4)); | 568 base::Time::FromInternalValue(statement.ColumnInt64(4)); |
| 569 if (access_time - last_requested > | |
| 570 base::TimeDelta::FromDays(kFaviconUpdateLastRequestedAfterDays)) { | |
| 571 SetFaviconBitmapLastRequestedTime(&db_, bitmap_id, access_time); | |
| 572 } | |
| 499 | 573 |
| 500 return true; | 574 return true; |
| 501 } | 575 } |
| 502 | 576 |
| 503 FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap( | 577 FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap( |
| 504 favicon_base::FaviconID icon_id, | 578 favicon_base::FaviconID icon_id, |
| 505 const scoped_refptr<base::RefCountedMemory>& icon_data, | 579 const scoped_refptr<base::RefCountedMemory>& icon_data, |
| 506 base::Time time, | 580 base::Time time, |
| 507 const gfx::Size& pixel_size) { | 581 const gfx::Size& pixel_size) { |
| 508 DCHECK(icon_id); | 582 DCHECK(icon_id); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 548 FaviconBitmapID bitmap_id, | 622 FaviconBitmapID bitmap_id, |
| 549 base::Time time) { | 623 base::Time time) { |
| 550 DCHECK(bitmap_id); | 624 DCHECK(bitmap_id); |
| 551 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 625 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
| 552 "UPDATE favicon_bitmaps SET last_updated=? WHERE id=?")); | 626 "UPDATE favicon_bitmaps SET last_updated=? WHERE id=?")); |
| 553 statement.BindInt64(0, time.ToInternalValue()); | 627 statement.BindInt64(0, time.ToInternalValue()); |
| 554 statement.BindInt64(1, bitmap_id); | 628 statement.BindInt64(1, bitmap_id); |
| 555 return statement.Run(); | 629 return statement.Run(); |
| 556 } | 630 } |
| 557 | 631 |
| 558 bool ThumbnailDatabase::SetFaviconBitmapLastRequestedTime( | |
| 559 FaviconBitmapID bitmap_id, | |
| 560 base::Time time) { | |
| 561 DCHECK(bitmap_id); | |
| 562 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | |
| 563 "UPDATE favicon_bitmaps SET last_requested=? WHERE id=?")); | |
| 564 statement.BindInt64(0, time.ToInternalValue()); | |
| 565 statement.BindInt64(1, bitmap_id); | |
| 566 return statement.Run(); | |
| 567 } | |
| 568 | |
| 569 bool ThumbnailDatabase::DeleteFaviconBitmap(FaviconBitmapID bitmap_id) { | 632 bool ThumbnailDatabase::DeleteFaviconBitmap(FaviconBitmapID bitmap_id) { |
| 570 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 633 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
| 571 "DELETE FROM favicon_bitmaps WHERE id=?")); | 634 "DELETE FROM favicon_bitmaps WHERE id=?")); |
| 572 statement.BindInt64(0, bitmap_id); | 635 statement.BindInt64(0, bitmap_id); |
| 573 return statement.Run(); | 636 return statement.Run(); |
| 574 } | 637 } |
| 575 | 638 |
| 576 bool ThumbnailDatabase::SetFaviconOutOfDate(favicon_base::FaviconID icon_id) { | 639 bool ThumbnailDatabase::SetFaviconOutOfDate(favicon_base::FaviconID icon_id) { |
| 577 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 640 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
| 578 "UPDATE favicon_bitmaps SET last_updated=? WHERE icon_id=?")); | 641 "UPDATE favicon_bitmaps SET last_updated=? WHERE icon_id=?")); |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1063 meta_table_.SetVersionNumber(8); | 1126 meta_table_.SetVersionNumber(8); |
| 1064 meta_table_.SetCompatibleVersionNumber(std::min(8, kCompatibleVersionNumber)); | 1127 meta_table_.SetCompatibleVersionNumber(std::min(8, kCompatibleVersionNumber)); |
| 1065 return true; | 1128 return true; |
| 1066 } | 1129 } |
| 1067 | 1130 |
| 1068 bool ThumbnailDatabase::IsFaviconDBStructureIncorrect() { | 1131 bool ThumbnailDatabase::IsFaviconDBStructureIncorrect() { |
| 1069 return !db_.IsSQLValid("SELECT id, url, icon_type FROM favicons"); | 1132 return !db_.IsSQLValid("SELECT id, url, icon_type FROM favicons"); |
| 1070 } | 1133 } |
| 1071 | 1134 |
| 1072 } // namespace history | 1135 } // namespace history |
| OLD | NEW |