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

Unified Diff: components/history/core/browser/thumbnail_database.cc

Issue 2903573002: [Thumbnails DB] Add functionality to clear unused on-demand favicons. (Closed)
Patch Set: Implementation variants + unit-tests Created 3 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: components/history/core/browser/thumbnail_database.cc
diff --git a/components/history/core/browser/thumbnail_database.cc b/components/history/core/browser/thumbnail_database.cc
index c8b430f4f71d8dd70f0111995c5ce74297cec7d9..06d7176e5d31be142791c11f866b998e1c1e1db5 100644
--- a/components/history/core/browser/thumbnail_database.cc
+++ b/components/history/core/browser/thumbnail_database.cc
@@ -271,6 +271,22 @@ void DatabaseErrorCallback(sql::Connection* db,
DLOG(FATAL) << db->GetErrorMessage();
}
+void DeleteOrphanagedFaviconBitmaps(sql::Connection* db) {
+ sql::Statement favicons(db->GetCachedStatement(
+ SQL_FROM_HERE,
+ "DELETE FROM favicon_bitmaps WHERE NOT EXISTS (SELECT id FROM favicons "
+ "WHERE favicon_bitmaps.icon_id = favicons.id)"));
+ favicons.Run();
+}
+
+void DeleteOrphanagedMappings(sql::Connection* db) {
+ sql::Statement mappings(db->GetCachedStatement(
+ SQL_FROM_HERE,
+ "DELETE FROM icon_mapping WHERE NOT EXISTS (SELECT id FROM favicons "
+ "WHERE favicons.id = icon_mapping.icon_id)"));
+ mappings.Run();
+}
+
} // namespace
ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() {
@@ -412,6 +428,151 @@ void ThumbnailDatabase::TrimMemory(bool aggressively) {
db_.TrimMemory(aggressively);
}
+void ThumbnailDatabase::ClearOldOnDemandFavicons(
+ base::Time deletion_threshold) {
+ // Select all bitmaps (and their page URLs) that have not been accessed for a
+ // while. Restrict to on-demand bitmaps (i.e. with last_requested != 0).
+ sql::Statement delete_candidates(db_.GetCachedStatement(
+ SQL_FROM_HERE,
+ "SELECT favicon_bitmaps.icon_id, icon_mapping.page_url FROM "
+ "favicon_bitmaps, icon_mapping WHERE favicon_bitmaps.icon_id = "
+ "icon_mapping.icon_id AND favicon_bitmaps.last_requested>0 AND "
+ "favicon_bitmaps.last_requested<?;"));
+ delete_candidates.BindInt64(0, deletion_threshold.ToInternalValue());
+
+ // Multiple page URLs may map to the same favicon. We omit the favicon from
+ // cleaning if at least one of its associated page URLs is bookmarked.
+ std::set<favicon_base::FaviconID> ids_of_icons_with_some_bookmarked_page;
+ std::set<favicon_base::FaviconID> ids_of_icons_with_no_bookmarked_page;
+ while (delete_candidates.Step()) {
+ favicon_base::FaviconID icon_id = delete_candidates.ColumnInt64(0);
+ if (ids_of_icons_with_some_bookmarked_page.count(icon_id))
+ continue;
+
+ GURL page_url = GURL(delete_candidates.ColumnString(1));
+ if (backend_client_ && backend_client_->IsBookmarked(page_url)) {
+ ids_of_icons_with_some_bookmarked_page.insert(icon_id);
+ ids_of_icons_with_no_bookmarked_page.erase(icon_id);
+ continue;
+ }
+
+ ids_of_icons_with_no_bookmarked_page.insert(icon_id);
+ }
+
+ for (favicon_base::FaviconID icon_id : ids_of_icons_with_no_bookmarked_page) {
+ sql::Statement statement(db_.GetCachedStatement(
+ SQL_FROM_HERE, "DELETE FROM favicons WHERE id=?"));
+ statement.BindInt64(0, icon_id);
+ statement.Run();
+ }
+
+ // The bitmaps and mappings for all deleted favicons are deleted at once.
+ DeleteOrphanagedFaviconBitmaps(&db_);
+ DeleteOrphanagedMappings(&db_);
+}
+
+void ThumbnailDatabase::ClearOldOnDemandFaviconsOneByOne(
+ base::Time deletion_threshold) {
+ // Select all bitmaps (and their page URLs) that have not been accessed for a
+ // while. Restrict to on-demand bitmaps (i.e. with last_requested != 0).
+ sql::Statement delete_candidates(db_.GetCachedStatement(
+ SQL_FROM_HERE,
+ "SELECT favicon_bitmaps.icon_id, icon_mapping.page_url FROM "
+ "favicon_bitmaps, icon_mapping WHERE favicon_bitmaps.icon_id = "
+ "icon_mapping.icon_id AND favicon_bitmaps.last_requested>0 AND "
+ "favicon_bitmaps.last_requested<?;"));
+ delete_candidates.BindInt64(0, deletion_threshold.ToInternalValue());
+
+ // Multiple page URLs may map to the same favicon. We omit the favicon from
+ // cleaning if at least one of its associated page URLs is bookmarked.
+ std::set<favicon_base::FaviconID> ids_of_icons_with_some_bookmarked_page;
+ std::set<favicon_base::FaviconID> ids_of_icons_with_no_bookmarked_page;
+ while (delete_candidates.Step()) {
+ favicon_base::FaviconID icon_id = delete_candidates.ColumnInt64(0);
+ if (ids_of_icons_with_some_bookmarked_page.count(icon_id))
+ continue;
+
+ GURL page_url = GURL(delete_candidates.ColumnString(1));
+ if (backend_client_ && backend_client_->IsBookmarked(page_url)) {
+ ids_of_icons_with_some_bookmarked_page.insert(icon_id);
+ ids_of_icons_with_no_bookmarked_page.erase(icon_id);
+ continue;
+ }
+
+ ids_of_icons_with_no_bookmarked_page.insert(icon_id);
+ }
+
+ for (favicon_base::FaviconID icon_id : ids_of_icons_with_no_bookmarked_page) {
+ sql::Statement statement(db_.GetCachedStatement(
+ SQL_FROM_HERE, "DELETE FROM favicons WHERE id=?"));
+ statement.BindInt64(0, icon_id);
+ statement.Run();
+
+ sql::Statement statement2(db_.GetCachedStatement(
+ SQL_FROM_HERE, "DELETE FROM favicon_bitmaps WHERE icon_id=?"));
+ statement2.BindInt64(0, icon_id);
+ statement2.Run();
+
+ sql::Statement statement3(db_.GetCachedStatement(
+ SQL_FROM_HERE, "DELETE FROM icon_mapping WHERE icon_id=?"));
+ statement3.BindInt64(0, icon_id);
+ statement3.Run();
+ }
+}
+
+void ThumbnailDatabase::ClearOldOnDemandFaviconsNoJoin(
+ base::Time deletion_threshold) {
+ // Select all bitmaps (and their page URLs) that have not been accessed for a
+ // while. Restrict to on-demand bitmaps (i.e. with last_requested != 0).
+ sql::Statement delete_candidates(
+ db_.GetCachedStatement(SQL_FROM_HERE,
+ "SELECT icon_id FROM favicon_bitmaps WHERE "
+ "favicon_bitmaps.last_requested>0 AND "
+ "favicon_bitmaps.last_requested<?;"));
+ delete_candidates.BindInt64(0, deletion_threshold.ToInternalValue());
+
+ // Multiple page URLs may map to the same favicon. We omit the favicon from
+ // cleaning if at least one of its associated page URLs is bookmarked.
+ std::set<favicon_base::FaviconID> ids_of_icons_with_some_bookmarked_page;
+ std::set<favicon_base::FaviconID> ids_of_icons_with_no_bookmarked_page;
+ while (delete_candidates.Step()) {
+ favicon_base::FaviconID icon_id = delete_candidates.ColumnInt64(0);
+ if (ids_of_icons_with_some_bookmarked_page.count(icon_id))
+ continue;
+
+ ids_of_icons_with_no_bookmarked_page.insert(icon_id);
+
+ if (!backend_client_)
+ continue;
+
+ sql::Statement delete_candidate_urls(db_.GetCachedStatement(
+ SQL_FROM_HERE,
+ "SELECT page_url FROM icon_mapping WHERE icon_mapping.icon_id=?;"));
+ delete_candidate_urls.BindInt64(0, icon_id);
+
+ while (delete_candidate_urls.Step()) {
+ GURL page_url = GURL(delete_candidate_urls.ColumnString(0));
+ if (!backend_client_->IsBookmarked(page_url))
+ continue;
+
+ ids_of_icons_with_some_bookmarked_page.insert(icon_id);
+ ids_of_icons_with_no_bookmarked_page.erase(icon_id);
+ break;
+ }
+ }
+
+ for (favicon_base::FaviconID icon_id : ids_of_icons_with_no_bookmarked_page) {
+ sql::Statement statement(db_.GetCachedStatement(
+ SQL_FROM_HERE, "DELETE FROM favicons WHERE id=?"));
+ statement.BindInt64(0, icon_id);
+ statement.Run();
+ }
+
+ // The bitmaps and mappings for all deleted favicons are deleted at once.
+ DeleteOrphanagedFaviconBitmaps(&db_);
+ DeleteOrphanagedMappings(&db_);
+}
+
bool ThumbnailDatabase::GetFaviconBitmapIDSizes(
favicon_base::FaviconID icon_id,
std::vector<FaviconBitmapIDSize>* bitmap_id_sizes) {

Powered by Google App Engine
This is Rietveld 408576698