| Index: chrome/browser/history/top_sites.cc
|
| diff --git a/chrome/browser/history/top_sites.cc b/chrome/browser/history/top_sites.cc
|
| index 1dacd3b778b8cd881bd9b5953b84274f1f33e604..8bdfe340f55137be2f2306364313fcb213dc564e 100644
|
| --- a/chrome/browser/history/top_sites.cc
|
| +++ b/chrome/browser/history/top_sites.cc
|
| @@ -39,6 +39,11 @@ namespace history {
|
|
|
| // How many top sites to store in the cache.
|
| static const size_t kTopSitesNumber = 20;
|
| +
|
| +// Max number of temporary images we'll cache. See comment above
|
| +// temp_images_ for details.
|
| +static const size_t kMaxTempTopImages = 8;
|
| +
|
| static const size_t kTopSitesShown = 8;
|
| static const int kDaysOfHistory = 90;
|
| // Time from startup to first HistoryService query.
|
| @@ -200,6 +205,9 @@ bool TopSites::SetPageThumbnail(const GURL& url,
|
| return false;
|
|
|
| if (add_temp_thumbnail) {
|
| + // Always remove the existing entry and then add it back. That way if we end
|
| + // up with too many temp thumbnails we'll prune the oldest first.
|
| + RemoveTemporaryThumbnailByURL(url);
|
| AddTemporaryThumbnail(url, thumbnail_data, score);
|
| return true;
|
| }
|
| @@ -487,20 +495,42 @@ bool TopSites::EncodeBitmap(const SkBitmap& bitmap,
|
| scoped_refptr<RefCountedBytes>* bytes) {
|
| *bytes = new RefCountedBytes();
|
| SkAutoLockPixels bitmap_lock(bitmap);
|
| - return gfx::JPEGCodec::Encode(
|
| - reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
|
| - gfx::JPEGCodec::FORMAT_BGRA, bitmap.width(),
|
| - bitmap.height(),
|
| - static_cast<int>(bitmap.rowBytes()), 90,
|
| - &((*bytes)->data));
|
| + std::vector<unsigned char> data;
|
| + if (!gfx::JPEGCodec::Encode(
|
| + reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
|
| + gfx::JPEGCodec::FORMAT_BGRA, bitmap.width(),
|
| + bitmap.height(),
|
| + static_cast<int>(bitmap.rowBytes()), 90,
|
| + &data)) {
|
| + return false;
|
| + }
|
| + // As we're going to cache this data, make sure the vector is only as big as
|
| + // it needs to be.
|
| + (*bytes)->data = data;
|
| + return true;
|
| +}
|
| +
|
| +void TopSites::RemoveTemporaryThumbnailByURL(const GURL& url) {
|
| + for (TempImages::iterator i = temp_images_.begin(); i != temp_images_.end();
|
| + ++i) {
|
| + if (i->first == url) {
|
| + temp_images_.erase(i);
|
| + return;
|
| + }
|
| + }
|
| }
|
|
|
| void TopSites::AddTemporaryThumbnail(const GURL& url,
|
| const RefCountedBytes* thumbnail,
|
| const ThumbnailScore& score) {
|
| - Images& img = temp_thumbnails_map_[url];
|
| - img.thumbnail = const_cast<RefCountedBytes*>(thumbnail);
|
| - img.thumbnail_score = score;
|
| + if (temp_images_.size() == kMaxTempTopImages)
|
| + temp_images_.erase(temp_images_.begin());
|
| +
|
| + TempImage image;
|
| + image.first = url;
|
| + image.second.thumbnail = const_cast<RefCountedBytes*>(thumbnail);
|
| + image.second.thumbnail_score = score;
|
| + temp_images_.push_back(image);
|
| }
|
|
|
| void TopSites::StartQueryForMostVisited() {
|
| @@ -703,10 +733,9 @@ void TopSites::Observe(NotificationType type,
|
| return;
|
| const GURL& url = load_details->entry->url();
|
| if (!cache_->IsKnownURL(url) && HistoryService::CanAddURL(url)) {
|
| - // Ideally we would just invoke StartQueryForMostVisited, but at the
|
| - // time this is invoked history hasn't been updated, which means if we
|
| - // invoked StartQueryForMostVisited now we could get stale data.
|
| - RestartQueryForTopSitesTimer(base::TimeDelta::FromMilliseconds(1));
|
| + // To avoid slamming history we throttle requests when the url updates.
|
| + // To do otherwise negatively impacts perf tests.
|
| + RestartQueryForTopSitesTimer(GetUpdateDelay());
|
| }
|
| }
|
| }
|
| @@ -731,21 +760,19 @@ void TopSites::SetTopSites(const MostVisitedURLList& new_top_sites) {
|
| cache_->SetTopSites(top_sites);
|
|
|
| // See if we have any tmp thumbnails for the new sites.
|
| - if (!temp_thumbnails_map_.empty()) {
|
| + if (!temp_images_.empty()) {
|
| for (size_t i = 0; i < top_sites.size(); ++i) {
|
| const MostVisitedURL& mv = top_sites[i];
|
| GURL canonical_url = cache_->GetCanonicalURL(mv.url);
|
| - for (std::map<GURL, Images>::iterator it = temp_thumbnails_map_.begin();
|
| - it != temp_thumbnails_map_.end(); ++it) {
|
| - // Must map all temp URLs to canonical ones.
|
| - // temp_thumbnails_map_ contains non-canonical URLs, because
|
| - // when we add a temp thumbnail, redirect chain is not known.
|
| - // This is slow, but temp_thumbnails_map_ should have very few URLs.
|
| + // At the time we get the thumbnail redirects aren't known, so we have to
|
| + // iterate through all the images.
|
| + for (TempImages::iterator it = temp_images_.begin();
|
| + it != temp_images_.end(); ++it) {
|
| if (canonical_url == cache_->GetCanonicalURL(it->first)) {
|
| SetPageThumbnailEncoded(mv.url,
|
| it->second.thumbnail,
|
| it->second.thumbnail_score);
|
| - temp_thumbnails_map_.erase(it);
|
| + temp_images_.erase(it);
|
| break;
|
| }
|
| }
|
| @@ -753,7 +780,7 @@ void TopSites::SetTopSites(const MostVisitedURLList& new_top_sites) {
|
| }
|
|
|
| if (top_sites.size() >= kTopSitesNumber)
|
| - temp_thumbnails_map_.clear();
|
| + temp_images_.clear();
|
|
|
| ResetThreadSafeCache();
|
| ResetThreadSafeImageCache();
|
| @@ -810,6 +837,12 @@ void TopSites::ResetThreadSafeImageCache() {
|
| }
|
|
|
| void TopSites::RestartQueryForTopSitesTimer(base::TimeDelta delta) {
|
| + if (timer_.IsRunning() && ((timer_start_time_ + timer_.GetCurrentDelay()) <
|
| + (base::TimeTicks::Now() + delta))) {
|
| + return;
|
| + }
|
| +
|
| + timer_start_time_ = base::TimeTicks::Now();
|
| timer_.Stop();
|
| timer_.Start(delta, this, &TopSites::StartQueryForMostVisited);
|
| }
|
| @@ -858,7 +891,7 @@ void TopSites::OnGotMostVisitedThumbnails(
|
| MoveStateToLoaded();
|
| } else {
|
| top_sites_state_ = TOP_SITES_LOADED_WAITING_FOR_HISTORY;
|
| - // Ask for history just in case it hasn't been load yet. When history
|
| + // Ask for history just in case it hasn't been loaded yet. When history
|
| // finishes loading we'll do migration and/or move to loaded.
|
| profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
|
| }
|
|
|