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 60445eb48f0dc66b6f7bc4dd12dedc3898a0327a..c8b430f4f71d8dd70f0111995c5ce74297cec7d9 100644 |
--- a/components/history/core/browser/thumbnail_database.cc |
+++ b/components/history/core/browser/thumbnail_database.cc |
@@ -64,13 +64,17 @@ namespace history { |
// icon_id The ID of the favicon that the bitmap is associated to. |
// last_updated The time at which this favicon was inserted into the |
// table. This is used to determine if it needs to be |
-// redownloaded from the web. |
+// redownloaded from the web. Value 0 denotes that the bitmap |
+// has been explicitly expired. |
// image_data PNG encoded data of the favicon. |
// width Pixel width of |image_data|. |
// height Pixel height of |image_data|. |
-// last_requested The time at which this bitmap was last requested. This is |
-// used to determine the priority with which the bitmap |
-// should be retained on cleanup. |
+// last_requested The time at which this bitmap was last requested. This |
+// entry is non-zero iff the bitmap is of type ON_DEMAND. |
+// This info is used for clearing old ON_DEMAND bitmaps. |
+// (On-demand bitmaps cannot get cleared along with expired |
+// visits in history DB because there is no corresponding |
+// visit.) |
namespace { |
@@ -503,12 +507,16 @@ bool ThumbnailDatabase::GetFaviconBitmap( |
FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap( |
favicon_base::FaviconID icon_id, |
const scoped_refptr<base::RefCountedMemory>& icon_data, |
+ FaviconBitmapType type, |
base::Time time, |
const gfx::Size& pixel_size) { |
DCHECK(icon_id); |
- sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
- "INSERT INTO favicon_bitmaps (icon_id, image_data, last_updated, width, " |
- "height) VALUES (?, ?, ?, ?, ?)")); |
+ |
+ sql::Statement statement(db_.GetCachedStatement( |
+ SQL_FROM_HERE, |
+ "INSERT INTO favicon_bitmaps (icon_id, image_data, last_updated, " |
+ "last_requested, width, height) VALUES (?, ?, ?, ?, ?, ?)")); |
+ |
statement.BindInt64(0, icon_id); |
if (icon_data.get() && icon_data->size()) { |
statement.BindBlob(1, icon_data->front(), |
@@ -516,9 +524,19 @@ FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap( |
} else { |
statement.BindNull(1); |
} |
- statement.BindInt64(2, time.ToInternalValue()); |
- statement.BindInt(3, pixel_size.width()); |
- statement.BindInt(4, pixel_size.height()); |
+ |
+ // On-visit bitmaps: |
+ // - keep track of last_updated: last write time is used for expiration; |
+ // - always have last_requested==0: no need to keep track of last read time. |
+ statement.BindInt64(2, type == ON_VISIT ? time.ToInternalValue() : 0); |
+ // On-demand bitmaps: |
+ // - always have last_updated==0: last write time is not stored as they are |
+ // always expired and thus ready to be replaced by ON_VISIT icons; |
+ // - keep track of last_requested: last read time is used for cache eviction. |
+ statement.BindInt64(3, type == ON_DEMAND ? time.ToInternalValue() : 0); |
+ |
+ statement.BindInt(4, pixel_size.width()); |
+ statement.BindInt(5, pixel_size.height()); |
if (!statement.Run()) |
return 0; |
@@ -530,8 +548,13 @@ bool ThumbnailDatabase::SetFaviconBitmap( |
scoped_refptr<base::RefCountedMemory> bitmap_data, |
base::Time time) { |
DCHECK(bitmap_id); |
- sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
- "UPDATE favicon_bitmaps SET image_data=?, last_updated=? WHERE id=?")); |
+ // By updating last_updated timestamp, we assume the icon is of type ON_VISIT. |
+ // If it is ON_DEMAND, reset last_requested to 0 and thus silently change the |
+ // type to ON_VISIT. |
+ sql::Statement statement( |
+ db_.GetCachedStatement(SQL_FROM_HERE, |
+ "UPDATE favicon_bitmaps SET image_data=?, " |
+ "last_updated=?, last_requested=? WHERE id=?")); |
if (bitmap_data.get() && bitmap_data->size()) { |
statement.BindBlob(0, bitmap_data->front(), |
static_cast<int>(bitmap_data->size())); |
@@ -539,7 +562,8 @@ bool ThumbnailDatabase::SetFaviconBitmap( |
statement.BindNull(0); |
} |
statement.BindInt64(1, time.ToInternalValue()); |
- statement.BindInt64(2, bitmap_id); |
+ statement.BindInt64(2, 0); |
+ statement.BindInt64(3, bitmap_id); |
return statement.Run(); |
} |
@@ -548,22 +572,47 @@ bool ThumbnailDatabase::SetFaviconBitmapLastUpdateTime( |
FaviconBitmapID bitmap_id, |
base::Time time) { |
DCHECK(bitmap_id); |
- sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
- "UPDATE favicon_bitmaps SET last_updated=? WHERE id=?")); |
+ // By updating last_updated timestamp, we assume the icon is of type ON_VISIT. |
+ // If it is ON_DEMAND, reset last_requested to 0 and thus silently change the |
+ // type to ON_VISIT. |
+ sql::Statement statement( |
+ db_.GetCachedStatement(SQL_FROM_HERE, |
+ "UPDATE favicon_bitmaps SET last_updated=?, " |
+ "last_requested=? WHERE id=?")); |
statement.BindInt64(0, time.ToInternalValue()); |
- statement.BindInt64(1, bitmap_id); |
+ statement.BindInt64(1, 0); |
+ statement.BindInt64(2, bitmap_id); |
return statement.Run(); |
} |
-bool ThumbnailDatabase::SetFaviconBitmapLastRequestedTime( |
- FaviconBitmapID bitmap_id, |
- base::Time time) { |
- DCHECK(bitmap_id); |
- sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
- "UPDATE favicon_bitmaps SET last_requested=? WHERE id=?")); |
- statement.BindInt64(0, time.ToInternalValue()); |
- statement.BindInt64(1, bitmap_id); |
- return statement.Run(); |
+bool ThumbnailDatabase::TouchOnDemandFavicon(const GURL& icon_url, |
+ base::Time time) { |
+ // Look up the icon ids for the url. |
+ sql::Statement id_statement(db_.GetCachedStatement( |
+ SQL_FROM_HERE, "SELECT id FROM favicons WHERE url=?")); |
+ id_statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); |
+ |
+ base::Time max_time = |
+ time - base::TimeDelta::FromDays(kFaviconUpdateLastRequestedAfterDays); |
+ |
+ while (id_statement.Step()) { |
+ favicon_base::FaviconID icon_id = id_statement.ColumnInt64(0); |
+ |
+ // Update the time only for ON_DEMAND bitmaps (i.e. with last_requested > |
+ // 0). For performance reasons, update the time only if the currently stored |
+ // time is old enough (UPDATEs where the WHERE condition does not match any |
+ // entries are way faster than UPDATEs that really change some data). |
+ sql::Statement statement(db_.GetCachedStatement( |
+ SQL_FROM_HERE, |
+ "UPDATE favicon_bitmaps SET last_requested=? WHERE icon_id=? AND " |
+ "last_requested>0 AND last_requested<=?")); |
+ statement.BindInt64(0, time.ToInternalValue()); |
+ statement.BindInt64(1, icon_id); |
+ statement.BindInt64(2, max_time.ToInternalValue()); |
+ if (!statement.Run()) |
+ return false; |
+ } |
+ return true; |
} |
bool ThumbnailDatabase::DeleteFaviconBitmap(FaviconBitmapID bitmap_id) { |
@@ -634,10 +683,11 @@ favicon_base::FaviconID ThumbnailDatabase::AddFavicon( |
const GURL& icon_url, |
favicon_base::IconType icon_type, |
const scoped_refptr<base::RefCountedMemory>& icon_data, |
+ FaviconBitmapType type, |
base::Time time, |
const gfx::Size& pixel_size) { |
favicon_base::FaviconID icon_id = AddFavicon(icon_url, icon_type); |
- if (!icon_id || !AddFaviconBitmap(icon_id, icon_data, time, pixel_size)) |
+ if (!icon_id || !AddFaviconBitmap(icon_id, icon_data, type, time, pixel_size)) |
return 0; |
return icon_id; |