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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 // test-expectation framework that the error was handled. | 264 // test-expectation framework that the error was handled. |
265 ignore_result(sql::Connection::IsExpectedSqliteError(extended_error)); | 265 ignore_result(sql::Connection::IsExpectedSqliteError(extended_error)); |
266 return; | 266 return; |
267 } | 267 } |
268 | 268 |
269 // The default handling is to assert on debug and to ignore on release. | 269 // The default handling is to assert on debug and to ignore on release. |
270 if (!sql::Connection::IsExpectedSqliteError(extended_error)) | 270 if (!sql::Connection::IsExpectedSqliteError(extended_error)) |
271 DLOG(FATAL) << db->GetErrorMessage(); | 271 DLOG(FATAL) << db->GetErrorMessage(); |
272 } | 272 } |
273 | 273 |
| 274 void DeleteOrphanagedFaviconBitmaps(sql::Connection* db) { |
| 275 sql::Statement favicons(db->GetCachedStatement( |
| 276 SQL_FROM_HERE, |
| 277 "DELETE FROM favicon_bitmaps WHERE NOT EXISTS (SELECT id FROM favicons " |
| 278 "WHERE favicon_bitmaps.icon_id = favicons.id)")); |
| 279 favicons.Run(); |
| 280 } |
| 281 |
| 282 void DeleteOrphanagedMappings(sql::Connection* db) { |
| 283 sql::Statement mappings(db->GetCachedStatement( |
| 284 SQL_FROM_HERE, |
| 285 "DELETE FROM icon_mapping WHERE NOT EXISTS (SELECT id FROM favicons " |
| 286 "WHERE favicons.id = icon_mapping.icon_id)")); |
| 287 mappings.Run(); |
| 288 } |
| 289 |
274 } // namespace | 290 } // namespace |
275 | 291 |
276 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { | 292 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { |
277 } | 293 } |
278 | 294 |
279 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() { | 295 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() { |
280 } | 296 } |
281 | 297 |
282 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping( | 298 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping( |
283 IconMapping* icon_mapping) { | 299 IconMapping* icon_mapping) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 void ThumbnailDatabase::Vacuum() { | 421 void ThumbnailDatabase::Vacuum() { |
406 DCHECK(db_.transaction_nesting() == 0) << | 422 DCHECK(db_.transaction_nesting() == 0) << |
407 "Can not have a transaction when vacuuming."; | 423 "Can not have a transaction when vacuuming."; |
408 ignore_result(db_.Execute("VACUUM")); | 424 ignore_result(db_.Execute("VACUUM")); |
409 } | 425 } |
410 | 426 |
411 void ThumbnailDatabase::TrimMemory(bool aggressively) { | 427 void ThumbnailDatabase::TrimMemory(bool aggressively) { |
412 db_.TrimMemory(aggressively); | 428 db_.TrimMemory(aggressively); |
413 } | 429 } |
414 | 430 |
| 431 void ThumbnailDatabase::ClearOldOnDemandFavicons( |
| 432 base::Time deletion_threshold) { |
| 433 // Select all bitmaps (and their page URLs) that have not been accessed for a |
| 434 // while. Restrict to on-demand bitmaps (i.e. with last_requested != 0). |
| 435 sql::Statement delete_candidates(db_.GetCachedStatement( |
| 436 SQL_FROM_HERE, |
| 437 "SELECT favicon_bitmaps.icon_id, icon_mapping.page_url FROM " |
| 438 "favicon_bitmaps, icon_mapping WHERE favicon_bitmaps.icon_id = " |
| 439 "icon_mapping.icon_id AND favicon_bitmaps.last_requested>0 AND " |
| 440 "favicon_bitmaps.last_requested<?;")); |
| 441 delete_candidates.BindInt64(0, deletion_threshold.ToInternalValue()); |
| 442 |
| 443 // Multiple page URLs may map to the same favicon. We omit the favicon from |
| 444 // cleaning if at least one of its associated page URLs is bookmarked. |
| 445 std::set<favicon_base::FaviconID> ids_of_icons_with_some_bookmarked_page; |
| 446 std::set<favicon_base::FaviconID> ids_of_icons_with_no_bookmarked_page; |
| 447 while (delete_candidates.Step()) { |
| 448 favicon_base::FaviconID icon_id = delete_candidates.ColumnInt64(0); |
| 449 if (ids_of_icons_with_some_bookmarked_page.count(icon_id)) |
| 450 continue; |
| 451 |
| 452 GURL page_url = GURL(delete_candidates.ColumnString(1)); |
| 453 if (backend_client_ && backend_client_->IsBookmarked(page_url)) { |
| 454 ids_of_icons_with_some_bookmarked_page.insert(icon_id); |
| 455 ids_of_icons_with_no_bookmarked_page.erase(icon_id); |
| 456 continue; |
| 457 } |
| 458 |
| 459 ids_of_icons_with_no_bookmarked_page.insert(icon_id); |
| 460 } |
| 461 |
| 462 for (favicon_base::FaviconID icon_id : ids_of_icons_with_no_bookmarked_page) { |
| 463 sql::Statement statement(db_.GetCachedStatement( |
| 464 SQL_FROM_HERE, "DELETE FROM favicons WHERE id=?")); |
| 465 statement.BindInt64(0, icon_id); |
| 466 statement.Run(); |
| 467 } |
| 468 |
| 469 // The bitmaps and mappings for all deleted favicons are deleted at once. |
| 470 DeleteOrphanagedFaviconBitmaps(&db_); |
| 471 DeleteOrphanagedMappings(&db_); |
| 472 } |
| 473 |
| 474 void ThumbnailDatabase::ClearOldOnDemandFaviconsOneByOne( |
| 475 base::Time deletion_threshold) { |
| 476 // Select all bitmaps (and their page URLs) that have not been accessed for a |
| 477 // while. Restrict to on-demand bitmaps (i.e. with last_requested != 0). |
| 478 sql::Statement delete_candidates(db_.GetCachedStatement( |
| 479 SQL_FROM_HERE, |
| 480 "SELECT favicon_bitmaps.icon_id, icon_mapping.page_url FROM " |
| 481 "favicon_bitmaps, icon_mapping WHERE favicon_bitmaps.icon_id = " |
| 482 "icon_mapping.icon_id AND favicon_bitmaps.last_requested>0 AND " |
| 483 "favicon_bitmaps.last_requested<?;")); |
| 484 delete_candidates.BindInt64(0, deletion_threshold.ToInternalValue()); |
| 485 |
| 486 // Multiple page URLs may map to the same favicon. We omit the favicon from |
| 487 // cleaning if at least one of its associated page URLs is bookmarked. |
| 488 std::set<favicon_base::FaviconID> ids_of_icons_with_some_bookmarked_page; |
| 489 std::set<favicon_base::FaviconID> ids_of_icons_with_no_bookmarked_page; |
| 490 while (delete_candidates.Step()) { |
| 491 favicon_base::FaviconID icon_id = delete_candidates.ColumnInt64(0); |
| 492 if (ids_of_icons_with_some_bookmarked_page.count(icon_id)) |
| 493 continue; |
| 494 |
| 495 GURL page_url = GURL(delete_candidates.ColumnString(1)); |
| 496 if (backend_client_ && backend_client_->IsBookmarked(page_url)) { |
| 497 ids_of_icons_with_some_bookmarked_page.insert(icon_id); |
| 498 ids_of_icons_with_no_bookmarked_page.erase(icon_id); |
| 499 continue; |
| 500 } |
| 501 |
| 502 ids_of_icons_with_no_bookmarked_page.insert(icon_id); |
| 503 } |
| 504 |
| 505 for (favicon_base::FaviconID icon_id : ids_of_icons_with_no_bookmarked_page) { |
| 506 sql::Statement statement(db_.GetCachedStatement( |
| 507 SQL_FROM_HERE, "DELETE FROM favicons WHERE id=?")); |
| 508 statement.BindInt64(0, icon_id); |
| 509 statement.Run(); |
| 510 |
| 511 sql::Statement statement2(db_.GetCachedStatement( |
| 512 SQL_FROM_HERE, "DELETE FROM favicon_bitmaps WHERE icon_id=?")); |
| 513 statement2.BindInt64(0, icon_id); |
| 514 statement2.Run(); |
| 515 |
| 516 sql::Statement statement3(db_.GetCachedStatement( |
| 517 SQL_FROM_HERE, "DELETE FROM icon_mapping WHERE icon_id=?")); |
| 518 statement3.BindInt64(0, icon_id); |
| 519 statement3.Run(); |
| 520 } |
| 521 } |
| 522 |
| 523 void ThumbnailDatabase::ClearOldOnDemandFaviconsNoJoin( |
| 524 base::Time deletion_threshold) { |
| 525 // Select all bitmaps (and their page URLs) that have not been accessed for a |
| 526 // while. Restrict to on-demand bitmaps (i.e. with last_requested != 0). |
| 527 sql::Statement delete_candidates( |
| 528 db_.GetCachedStatement(SQL_FROM_HERE, |
| 529 "SELECT icon_id FROM favicon_bitmaps WHERE " |
| 530 "favicon_bitmaps.last_requested>0 AND " |
| 531 "favicon_bitmaps.last_requested<?;")); |
| 532 delete_candidates.BindInt64(0, deletion_threshold.ToInternalValue()); |
| 533 |
| 534 // Multiple page URLs may map to the same favicon. We omit the favicon from |
| 535 // cleaning if at least one of its associated page URLs is bookmarked. |
| 536 std::set<favicon_base::FaviconID> ids_of_icons_with_some_bookmarked_page; |
| 537 std::set<favicon_base::FaviconID> ids_of_icons_with_no_bookmarked_page; |
| 538 while (delete_candidates.Step()) { |
| 539 favicon_base::FaviconID icon_id = delete_candidates.ColumnInt64(0); |
| 540 if (ids_of_icons_with_some_bookmarked_page.count(icon_id)) |
| 541 continue; |
| 542 |
| 543 ids_of_icons_with_no_bookmarked_page.insert(icon_id); |
| 544 |
| 545 if (!backend_client_) |
| 546 continue; |
| 547 |
| 548 sql::Statement delete_candidate_urls(db_.GetCachedStatement( |
| 549 SQL_FROM_HERE, |
| 550 "SELECT page_url FROM icon_mapping WHERE icon_mapping.icon_id=?;")); |
| 551 delete_candidate_urls.BindInt64(0, icon_id); |
| 552 |
| 553 while (delete_candidate_urls.Step()) { |
| 554 GURL page_url = GURL(delete_candidate_urls.ColumnString(0)); |
| 555 if (!backend_client_->IsBookmarked(page_url)) |
| 556 continue; |
| 557 |
| 558 ids_of_icons_with_some_bookmarked_page.insert(icon_id); |
| 559 ids_of_icons_with_no_bookmarked_page.erase(icon_id); |
| 560 break; |
| 561 } |
| 562 } |
| 563 |
| 564 for (favicon_base::FaviconID icon_id : ids_of_icons_with_no_bookmarked_page) { |
| 565 sql::Statement statement(db_.GetCachedStatement( |
| 566 SQL_FROM_HERE, "DELETE FROM favicons WHERE id=?")); |
| 567 statement.BindInt64(0, icon_id); |
| 568 statement.Run(); |
| 569 } |
| 570 |
| 571 // The bitmaps and mappings for all deleted favicons are deleted at once. |
| 572 DeleteOrphanagedFaviconBitmaps(&db_); |
| 573 DeleteOrphanagedMappings(&db_); |
| 574 } |
| 575 |
415 bool ThumbnailDatabase::GetFaviconBitmapIDSizes( | 576 bool ThumbnailDatabase::GetFaviconBitmapIDSizes( |
416 favicon_base::FaviconID icon_id, | 577 favicon_base::FaviconID icon_id, |
417 std::vector<FaviconBitmapIDSize>* bitmap_id_sizes) { | 578 std::vector<FaviconBitmapIDSize>* bitmap_id_sizes) { |
418 DCHECK(icon_id); | 579 DCHECK(icon_id); |
419 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 580 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
420 "SELECT id, width, height FROM favicon_bitmaps WHERE icon_id=?")); | 581 "SELECT id, width, height FROM favicon_bitmaps WHERE icon_id=?")); |
421 statement.BindInt64(0, icon_id); | 582 statement.BindInt64(0, icon_id); |
422 | 583 |
423 bool result = false; | 584 bool result = false; |
424 while (statement.Step()) { | 585 while (statement.Step()) { |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 meta_table_.SetVersionNumber(8); | 1269 meta_table_.SetVersionNumber(8); |
1109 meta_table_.SetCompatibleVersionNumber(std::min(8, kCompatibleVersionNumber)); | 1270 meta_table_.SetCompatibleVersionNumber(std::min(8, kCompatibleVersionNumber)); |
1110 return true; | 1271 return true; |
1111 } | 1272 } |
1112 | 1273 |
1113 bool ThumbnailDatabase::IsFaviconDBStructureIncorrect() { | 1274 bool ThumbnailDatabase::IsFaviconDBStructureIncorrect() { |
1114 return !db_.IsSQLValid("SELECT id, url, icon_type FROM favicons"); | 1275 return !db_.IsSQLValid("SELECT id, url, icon_type FROM favicons"); |
1115 } | 1276 } |
1116 | 1277 |
1117 } // namespace history | 1278 } // namespace history |
OLD | NEW |