Chromium Code Reviews| Index: chrome/browser/history/history_backend.cc |
| diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc |
| index d53f6727cce8a948986b5fc2438928be4e2bb419..bf2f6abc5a0e6bca536b28acdceece66fcbf8701 100644 |
| --- a/chrome/browser/history/history_backend.cc |
| +++ b/chrome/browser/history/history_backend.cc |
| @@ -1930,6 +1930,13 @@ void HistoryBackend::MergeFavicon( |
| bool replaced_bitmap = false; |
| for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { |
| if (bitmap_id_sizes[i].pixel_size == pixel_size) { |
| + if (IsFaviconBitmapDataEqual(bitmap_id_sizes[i].bitmap_id, bitmap_data)) { |
| + thumbnail_db_->SetFaviconBitmapLastUpdateTime( |
| + bitmap_id_sizes[i].bitmap_id, base::Time::Now()); |
| + // Return early as merging did not alter the bitmap data. |
| + ScheduleCommit(); |
| + return; |
| + } |
| thumbnail_db_->SetFaviconBitmap(bitmap_id_sizes[i].bitmap_id, bitmap_data, |
| base::Time::Now()); |
| replaced_bitmap = true; |
| @@ -2059,31 +2066,51 @@ void HistoryBackend::SetFavicons( |
| grouped_by_icon_url[icon_url].push_back(favicon_bitmap_data[i]); |
| } |
| + // Track whether the method modifies or creates any favicon bitmaps, favicons |
| + // or icon mappings. |
| + bool data_modified = false; |
| + |
| std::vector<FaviconID> icon_ids; |
| for (IconURLSizesMap::const_iterator it = icon_url_sizes.begin(); |
| it != icon_url_sizes.end(); ++it) { |
| const GURL& icon_url = it->first; |
| FaviconID icon_id = |
| thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, NULL); |
| - if (icon_id) |
| - SetFaviconSizes(icon_id, it->second); |
| - else |
| + if (icon_id) { |
| + bool favicon_bitmaps_deleted = false; |
| + SetFaviconSizes(icon_id, it->second, &favicon_bitmaps_deleted); |
| + data_modified |= favicon_bitmaps_deleted; |
| + } else { |
| icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type, it->second); |
| + data_modified = true; |
| + } |
| icon_ids.push_back(icon_id); |
| BitmapDataByIconURL::iterator grouped_by_icon_url_it = |
| grouped_by_icon_url.find(icon_url); |
| - if (grouped_by_icon_url_it != grouped_by_icon_url.end()) |
| - SetFaviconBitmaps(icon_id, grouped_by_icon_url_it->second); |
| + if (grouped_by_icon_url_it != grouped_by_icon_url.end()) { |
| + if (!data_modified) { |
| + bool favicon_bitmaps_changed = false; |
| + SetFaviconBitmaps(icon_id, |
| + grouped_by_icon_url_it->second, |
| + &favicon_bitmaps_changed); |
| + data_modified |= favicon_bitmaps_changed; |
| + } else { |
| + SetFaviconBitmaps(icon_id, |
| + grouped_by_icon_url_it->second, |
| + NULL); |
| + } |
| + } |
| } |
| - SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); |
| + data_modified |= |
| + SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); |
| - // Send notification to the UI as an icon mapping, favicon, or favicon bitmap |
| - // almost certainly was changed by this function. The situations where no |
| - // data was changed, notably when |favicon_bitmap_data| is empty do not occur |
| - // in practice. |
| - SendFaviconChangedNotificationForPageAndRedirects(page_url); |
| + if (data_modified) { |
| + // Send notification to the UI as an icon mapping, favicon, or favicon |
| + // bitmap was changed by this function. |
| + SendFaviconChangedNotificationForPageAndRedirects(page_url); |
| + } |
| ScheduleCommit(); |
| } |
| @@ -2243,7 +2270,11 @@ void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( |
| void HistoryBackend::SetFaviconBitmaps( |
| FaviconID icon_id, |
| - const std::vector<FaviconBitmapData>& favicon_bitmap_data) { |
| + const std::vector<FaviconBitmapData>& favicon_bitmap_data, |
| + bool* favicon_bitmaps_changed) { |
| + if (favicon_bitmaps_changed) |
| + *favicon_bitmaps_changed = false; |
| + |
| std::vector<FaviconBitmapIDSize> bitmap_id_sizes; |
| thumbnail_db_->GetFaviconBitmapIDSizes(icon_id, &bitmap_id_sizes); |
| @@ -2259,11 +2290,23 @@ void HistoryBackend::SetFaviconBitmaps( |
| } |
| } |
| if (bitmap_id) { |
| - thumbnail_db_->SetFaviconBitmap(bitmap_id, |
| - bitmap_data_element.bitmap_data, base::Time::Now()); |
| + if (favicon_bitmaps_changed && |
| + !*favicon_bitmaps_changed && |
| + IsFaviconBitmapDataEqual(bitmap_id, |
| + bitmap_data_element.bitmap_data)) { |
| + thumbnail_db_->SetFaviconBitmapLastUpdateTime( |
| + bitmap_id, base::Time::Now()); |
| + } else { |
| + thumbnail_db_->SetFaviconBitmap(bitmap_id, |
| + bitmap_data_element.bitmap_data, base::Time::Now()); |
| + if (favicon_bitmaps_changed) |
| + *favicon_bitmaps_changed = true; |
| + } |
| } else { |
| thumbnail_db_->AddFaviconBitmap(icon_id, bitmap_data_element.bitmap_data, |
| base::Time::Now(), bitmap_data_element.pixel_size); |
| + if (favicon_bitmaps_changed) |
| + *favicon_bitmaps_changed = true; |
| } |
| } |
| } |
| @@ -2299,7 +2342,10 @@ bool HistoryBackend::ValidateSetFaviconsParams( |
| } |
| void HistoryBackend::SetFaviconSizes(FaviconID icon_id, |
| - const FaviconSizes& favicon_sizes) { |
| + const FaviconSizes& favicon_sizes, |
| + bool* favicon_bitmaps_deleted) { |
| + *favicon_bitmaps_deleted = false; |
| + |
| std::vector<FaviconBitmapIDSize> bitmap_id_sizes; |
| thumbnail_db_->GetFaviconBitmapIDSizes(icon_id, &bitmap_id_sizes); |
| @@ -2308,13 +2354,32 @@ void HistoryBackend::SetFaviconSizes(FaviconID icon_id, |
| const gfx::Size& pixel_size = bitmap_id_sizes[i].pixel_size; |
| FaviconSizes::const_iterator sizes_it = std::find(favicon_sizes.begin(), |
| favicon_sizes.end(), pixel_size); |
| - if (sizes_it == favicon_sizes.end()) |
| + if (sizes_it == favicon_sizes.end()) { |
| thumbnail_db_->DeleteFaviconBitmap(bitmap_id_sizes[i].bitmap_id); |
| + *favicon_bitmaps_deleted = true; |
| + } |
| } |
| thumbnail_db_->SetFaviconSizes(icon_id, favicon_sizes); |
| } |
| +bool HistoryBackend::IsFaviconBitmapDataEqual( |
| + FaviconBitmapID bitmap_id, |
| + const scoped_refptr<base::RefCountedMemory>& new_bitmap_data) { |
| + if (!new_bitmap_data.get()) |
| + return false; |
| + |
| + scoped_refptr<base::RefCountedMemory> original_bitmap_data; |
| + thumbnail_db_->GetFaviconBitmap(bitmap_id, |
| + NULL, |
| + &original_bitmap_data, |
| + NULL); |
| + return original_bitmap_data.get() && |
|
sky
2013/01/09 17:55:25
Should this be on RefCountedMemory? Specfically an
|
| + original_bitmap_data->size() == new_bitmap_data->size() && |
| + (memcmp(new_bitmap_data->front(), original_bitmap_data->front(), |
| + new_bitmap_data->size()) == 0); |
| +} |
| + |
| bool HistoryBackend::GetFaviconsFromDB( |
| const GURL& page_url, |
| int icon_types, |