diff options
author | meelapshah@chromium.org <meelapshah@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-28 01:22:25 +0000 |
---|---|---|
committer | meelapshah@chromium.org <meelapshah@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-28 01:22:25 +0000 |
commit | daa82dc7442d26d9a50e342c0d9dcee43f287df8 (patch) | |
tree | be3c211a383852579223f57be9c1ee13b84c1f6d /chrome | |
parent | abaa71c990b2d9dd514e9f2eefb1d2cf7b720562 (diff) | |
download | chromium_src-daa82dc7442d26d9a50e342c0d9dcee43f287df8.zip chromium_src-daa82dc7442d26d9a50e342c0d9dcee43f287df8.tar.gz chromium_src-daa82dc7442d26d9a50e342c0d9dcee43f287df8.tar.bz2 |
Make ThumbnailStore broadcast a notification when it has finished reading thumbnails from disk.
Make DOMUIThumbnailSource wait for this notification if ThumbnailStore isn't ready yet.
Also clean up some of the code.
Review URL: http://codereview.chromium.org/155911
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21785 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/dom_ui/dom_ui_thumbnail_source.cc | 56 | ||||
-rw-r--r-- | chrome/browser/dom_ui/dom_ui_thumbnail_source.h | 21 | ||||
-rw-r--r-- | chrome/browser/history/history.h | 5 | ||||
-rw-r--r-- | chrome/browser/history/history_backend.cc | 10 | ||||
-rw-r--r-- | chrome/browser/profile.cc | 3 | ||||
-rw-r--r-- | chrome/browser/thumbnail_store.cc | 139 | ||||
-rw-r--r-- | chrome/browser/thumbnail_store.h | 39 | ||||
-rw-r--r-- | chrome/browser/thumbnail_store_unittest.cc | 8 | ||||
-rw-r--r-- | chrome/common/chrome_constants.cc | 1 | ||||
-rw-r--r-- | chrome/common/chrome_constants.h | 1 | ||||
-rw-r--r-- | chrome/common/notification_type.h | 6 |
11 files changed, 207 insertions, 82 deletions
diff --git a/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc b/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc index 5a10c7c..230389b 100644 --- a/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc +++ b/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc @@ -10,6 +10,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/thumbnail_store.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/notification_service.h" #include "chrome/common/url_constants.h" #include "googleurl/src/gurl.h" #include "grit/theme_resources.h" @@ -23,20 +24,18 @@ DOMUIThumbnailSource::DOMUIThumbnailSource(Profile* profile) void DOMUIThumbnailSource::StartDataRequest(const std::string& path, int request_id) { if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kThumbnailStore)) { - RefCountedBytes* data = NULL; scoped_refptr<ThumbnailStore> store_ = profile_->GetThumbnailStore(); - if (store_->GetPageThumbnail(GURL(path), &data)) { - // Got the thumbnail. - SendResponse(request_id, data); - } else { - // Don't have the thumbnail so return the default thumbnail. - if (!default_thumbnail_.get()) { - default_thumbnail_ = new RefCountedBytes; - ResourceBundle::GetSharedInstance().LoadImageResourceBytes( - IDR_DEFAULT_THUMBNAIL, &default_thumbnail_->data); + if (!store_->IsReady()) { + // Register to be notified when the ThumbnailStore is ready. + if (registrar_.IsEmpty()) { + registrar_.Add(this, NotificationType::THUMBNAIL_STORE_READY, + Source<ThumbnailStore>(store_.get())); } - SendResponse(request_id, default_thumbnail_); + // Insert into pending_requests. + pending_requests_.push_back(std::make_pair(path, request_id)); + } else { + DoDataRequest(path, request_id); } return; } // end --thumbnail-store switch @@ -55,6 +54,24 @@ void DOMUIThumbnailSource::StartDataRequest(const std::string& path, } } +void DOMUIThumbnailSource::DoDataRequest(const std::string& path, + int request_id) { + RefCountedBytes* data = NULL; + scoped_refptr<ThumbnailStore> store_ = profile_->GetThumbnailStore(); + if (store_->GetPageThumbnail(GURL(path), &data)) { + // Got the thumbnail. + SendResponse(request_id, data); + } else { + // Don't have the thumbnail so return the default thumbnail. + if (!default_thumbnail_.get()) { + default_thumbnail_ = new RefCountedBytes; + ResourceBundle::GetSharedInstance().LoadImageResourceBytes( + IDR_DEFAULT_THUMBNAIL, &default_thumbnail_->data); + } + SendResponse(request_id, default_thumbnail_); + } +} + void DOMUIThumbnailSource::OnThumbnailDataAvailable( HistoryService::Handle request_handle, scoped_refptr<RefCountedBytes> data) { @@ -74,3 +91,20 @@ void DOMUIThumbnailSource::OnThumbnailDataAvailable( SendResponse(request_id, default_thumbnail_); } } + +void DOMUIThumbnailSource::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type.value != NotificationType::THUMBNAIL_STORE_READY) { + NOTREACHED(); + return; + } + + // This notification is sent only once. + registrar_.RemoveAll(); + + for (size_t i = 0; i < pending_requests_.size(); ++i) + DoDataRequest(pending_requests_[i].first, pending_requests_[i].second); + + pending_requests_.clear(); +} diff --git a/chrome/browser/dom_ui/dom_ui_thumbnail_source.h b/chrome/browser/dom_ui/dom_ui_thumbnail_source.h index c94967b..4e1555d 100644 --- a/chrome/browser/dom_ui/dom_ui_thumbnail_source.h +++ b/chrome/browser/dom_ui/dom_ui_thumbnail_source.h @@ -5,20 +5,22 @@ #ifndef CHROME_BROWSER_DOM_UI_DOM_UI_THUMBNAIL_SOURCE_H_ #define CHROME_BROWSER_DOM_UI_DOM_UI_THUMBNAIL_SOURCE_H_ -#include <set> #include <string> +#include <vector> #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/history/history.h" +#include "chrome/common/notification_registrar.h" class Profile; class ThumbnailStore; // ThumbnailSource is the gateway between network-level chrome: // requests for thumbnails and the history backend that serves these. -class DOMUIThumbnailSource : public ChromeURLDataManager::DataSource { +class DOMUIThumbnailSource : public ChromeURLDataManager::DataSource, + public NotificationObserver { public: explicit DOMUIThumbnailSource(Profile* profile); @@ -37,6 +39,14 @@ class DOMUIThumbnailSource : public ChromeURLDataManager::DataSource { scoped_refptr<RefCountedBytes> data); private: + // NotificationObserver implementation + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Fetch the specified resource. + void DoDataRequest(const std::string& path, int request_id); + Profile* profile_; CancelableRequestConsumerT<int, 0> cancelable_consumer_; @@ -44,6 +54,13 @@ class DOMUIThumbnailSource : public ChromeURLDataManager::DataSource { // database doesn't have a thumbnail for a webpage. scoped_refptr<RefCountedBytes> default_thumbnail_; + // Store requests when the ThumbnailStore isn't ready. When a notification is + // received that it is ready, then serve these requests. + std::vector<std::pair<std::string, int> > pending_requests_; + + // To register to be notified when the ThumbnailStore is ready. + NotificationRegistrar registrar_; + DISALLOW_COPY_AND_ASSIGN(DOMUIThumbnailSource); }; diff --git a/chrome/browser/history/history.h b/chrome/browser/history/history.h index 9aec250..0643139 100644 --- a/chrome/browser/history/history.h +++ b/chrome/browser/history/history.h @@ -306,7 +306,10 @@ class HistoryService : public CancelableRequestProvider, // in the map containing redirects from the URL. For example, if we have the // redirect chain A -> B -> C and A is a top visited URL, then A will be in // the vector and "A => {B -> C}" will be in the map. - typedef Callback2<std::vector<GURL>*, history::RedirectMap*>::Type + typedef Callback4<Handle, + bool, // Did we get the top urls and redirects? + std::vector<GURL>*, // List of top URLs. + history::RedirectMap*>::Type // Redirects for top URLs. QueryTopURLsAndRedirectsCallback; // Request the top |result_count| most visited URLs and the chain of redirects diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc index bdf2351..1ccd7cf 100644 --- a/chrome/browser/history/history_backend.cc +++ b/chrome/browser/history/history_backend.cc @@ -1163,7 +1163,7 @@ void HistoryBackend::QueryTopURLsAndRedirects( if (!db_.get()) { request->ForwardResult(QueryTopURLsAndRedirectsRequest::TupleType( - NULL, NULL)); + request->handle(), false, NULL, NULL)); return; } @@ -1176,13 +1176,13 @@ void HistoryBackend::QueryTopURLsAndRedirects( for (size_t i = 0; i < data.size(); ++i) { top_urls->push_back(data[i]->GetURL()); - history::RedirectList list; - GetMostRecentRedirectsFrom(top_urls->back(), &list); - (*redirects)[top_urls->back()] = new RefCountedVector<GURL>(list); + RefCountedVector<GURL>* list = new RefCountedVector<GURL>; + GetMostRecentRedirectsFrom(top_urls->back(), &list->data); + (*redirects)[top_urls->back()] = list; } request->ForwardResult(QueryTopURLsAndRedirectsRequest::TupleType( - top_urls, redirects)); + request->handle(), true, top_urls, redirects)); } void HistoryBackend::GetRedirectsFromSpecificVisit( diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index f32a7bd..5d39188 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -1047,7 +1047,8 @@ TabRestoreService* ProfileImpl::GetTabRestoreService() { ThumbnailStore* ProfileImpl::GetThumbnailStore() { if (!thumbnail_store_.get()) { thumbnail_store_ = new ThumbnailStore; - thumbnail_store_->Init(GetPath().AppendASCII("Top Thumbnails"), this); + thumbnail_store_->Init( + GetPath().Append(chrome::kNewTabThumbnailsFilename), this); } return thumbnail_store_.get(); } diff --git a/chrome/browser/thumbnail_store.cc b/chrome/browser/thumbnail_store.cc index e6f0e99..4f30c62 100644 --- a/chrome/browser/thumbnail_store.cc +++ b/chrome/browser/thumbnail_store.cc @@ -26,7 +26,8 @@ ThumbnailStore::ThumbnailStore() : cache_(NULL), db_(NULL), hs_(NULL), - url_blacklist_(NULL) { + url_blacklist_(NULL), + disk_data_loaded_(false) { } ThumbnailStore::~ThumbnailStore() { @@ -34,8 +35,7 @@ ThumbnailStore::~ThumbnailStore() { DCHECK(hs_ == NULL); } -void ThumbnailStore::Init(const FilePath& db_name, - Profile* profile) { +void ThumbnailStore::Init(const FilePath& db_name, Profile* profile) { // Load thumbnails already in the database. g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &ThumbnailStore::InitializeFromDB, @@ -50,7 +50,9 @@ void ThumbnailStore::Init(const FilePath& db_name, // Get the list of most visited URLs and redirect information from the // HistoryService. - seconds_to_next_update_ = kInitialUpdateIntervalSecs; + most_visited_urls_.reset(new MostVisitedMap); + timer_.Start(base::TimeDelta::FromSeconds(kUpdateIntervalSecs), this, + &ThumbnailStore::UpdateURLData); UpdateURLData(); // Register to get notified when the history is cleared. @@ -139,8 +141,7 @@ void ThumbnailStore::Shutdown() { // for details. hs_ = NULL; - // The source of notifications is the Profile. We may outlive the Profile so - // we unregister for notifications here. + // De-register for notifications. registrar_.RemoveAll(); // Stop the timer to ensure that UpdateURLData is not called during shutdown. @@ -161,6 +162,11 @@ void ThumbnailStore::OnRedirectsForURLAvailable( if (!success) return; + DCHECK(redirect_urls_.get()); + + // If A -> B -> C is a redirect chain, then this function would be called + // with url=C and redirects = {B, A}. This is entered into the RedirectMap as + // A => {B -> C}. if (redirects->empty()) { (*redirect_urls_)[url] = new RefCountedVector<GURL>; } else { @@ -171,9 +177,20 @@ void ThumbnailStore::OnRedirectsForURLAvailable( } } +history::RedirectMap::iterator ThumbnailStore::GetRedirectIteratorForURL( + const GURL& url) const { + for (history::RedirectMap::iterator it = redirect_urls_->begin(); + it != redirect_urls_->end(); ++it) { + if (it->first == url || + (!it->second->data.empty() && it->second->data.back() == url)) + return it; + } + return redirect_urls_->end(); +} + void ThumbnailStore::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { + const NotificationSource& source, + const NotificationDetails& details) { if (type.value != NotificationType::HISTORY_URLS_DELETED) { NOTREACHED(); return; @@ -183,37 +200,58 @@ void ThumbnailStore::Observe(NotificationType type, // If all history was cleared, clear all of our data and reset the update // timer. if (url_details->all_history) { - most_visited_urls_.reset(); - redirect_urls_.reset(); - cache_.reset(); - - timer_.Stop(); - seconds_to_next_update_ = kInitialUpdateIntervalSecs; - timer_.Start(base::TimeDelta::FromSeconds(seconds_to_next_update_), this, - &ThumbnailStore::UpdateURLData); + most_visited_urls_->clear(); + redirect_urls_->clear(); + cache_->clear(); + timer_.Reset(); } } +void ThumbnailStore::NotifyThumbnailStoreReady() { + NotificationService::current()->Notify( + NotificationType::THUMBNAIL_STORE_READY, + Source<ThumbnailStore>(this), + NotificationService::NoDetails()); +} + void ThumbnailStore::UpdateURLData() { + DCHECK(url_blacklist_); + int result_count = ThumbnailStore::kMaxCacheSize + url_blacklist_->GetSize(); hs_->QueryTopURLsAndRedirects(result_count, &consumer_, NewCallback(this, &ThumbnailStore::OnURLDataAvailable)); } -void ThumbnailStore::OnURLDataAvailable(std::vector<GURL>* urls, +void ThumbnailStore::OnURLDataAvailable(HistoryService::Handle handle, + bool success, + std::vector<GURL>* urls, history::RedirectMap* redirects) { + if (!success) + return; + DCHECK(urls); DCHECK(redirects); - most_visited_urls_.reset(new std::vector<GURL>(*urls)); + // Each element of |urls| is the start of a redirect chain. When thumbnails + // are stored from TabContents, the tails of the redirect chains are + // associated with the image. Since SetPageThumbnail is called frequently, we + // look up the tail end of each element in |urls| and insert that into the + // MostVisitedMap. This way SetPageThumbnail can more quickly check if a + // given url is in the most visited list. + most_visited_urls_->clear(); + for (size_t i = 0; i < urls->size(); ++i) { + history::RedirectMap::iterator it = redirects->find(urls->at(i)); + if (it->second->data.empty()) + (*most_visited_urls_)[urls->at(i)] = GURL(); + else + (*most_visited_urls_)[it->second->data.back()] = urls->at(i); + } redirect_urls_.reset(new history::RedirectMap(*redirects)); - CleanCacheData(); - // Schedule the next update. - if (seconds_to_next_update_ < kMaxUpdateIntervalSecs) - seconds_to_next_update_ *= 2; - timer_.Start(base::TimeDelta::FromSeconds(seconds_to_next_update_), this, - &ThumbnailStore::UpdateURLData); + if (IsReady()) + NotifyThumbnailStoreReady(); + + CleanCacheData(); } void ThumbnailStore::CleanCacheData() { @@ -228,26 +266,15 @@ void ThumbnailStore::CleanCacheData() { // be written to disk. for (Cache::iterator cache_it = cache_->begin(); cache_it != cache_->end();) { - const GURL* url = NULL; - // For each URL in the cache, search the RedirectMap for the originating - // URL. - for (history::RedirectMap::iterator it = redirect_urls_->begin(); - it != redirect_urls_->end(); ++it) { - if (cache_it->first == it->first || - (it->second->data.size() && - cache_it->first == it->second->data.back())) { - url = &it->first; - break; - } - } + history::RedirectMap::iterator redirect_it = + GetRedirectIteratorForURL(cache_it->first); + const GURL* url = redirect_it == redirect_urls_->end() ? + NULL : &redirect_it->first; // If this URL is blacklisted or not in the most visited list, mark it for // deletion. Otherwise, if the cache entry is dirty, mark it to be written // to disk. if (url == NULL || IsURLBlacklisted(*url) || !IsPopular(*url)) { - // Note that we don't check whether the cache entry is dirty or not. If - // it is not dirty, then the thumbnail exists on disk and must be - // deleted. If it is dirty, it may exist on disk so we delete it anyways. urls_to_delete->data.push_back(cache_it->first); cache_->erase(cache_it++); } else { @@ -271,6 +298,8 @@ void ThumbnailStore::CommitCacheToDB( if (!db_) return; + base::TimeTicks db_start = base::TimeTicks::Now(); + int rv = sqlite3_exec(db_, "BEGIN TRANSACTION", NULL, NULL, NULL); DCHECK(rv == SQLITE_OK) << "Failed to begin transaction"; @@ -292,7 +321,8 @@ void ThumbnailStore::CommitCacheToDB( it != data_to_save->end(); ++it) { SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_, "INSERT OR REPLACE INTO thumbnails " - "(url, boring_score, good_clipping, at_top, time_taken, data) " + "(url, boring_score, good_clipping, " + "at_top, time_taken, data) " "VALUES (?,?,?,?,?,?)"); statement->bind_string(0, it->first.spec()); statement->bind_double(1, it->second.score_.boring_score); @@ -309,6 +339,9 @@ void ThumbnailStore::CommitCacheToDB( rv = sqlite3_exec(db_, "COMMIT", NULL, NULL, NULL); DCHECK(rv == SQLITE_OK) << "Failed to commit transaction"; + + base::TimeDelta delta = base::TimeTicks::Now() - db_start; + HISTOGRAM_TIMES("ThumbnailStore.WriteDBToDisk", delta); } void ThumbnailStore::InitializeFromDB(const FilePath& db_name, @@ -351,18 +384,23 @@ void ThumbnailStore::InitializeFromDB(const FilePath& db_name, } void ThumbnailStore::GetAllThumbnailsFromDisk(MessageLoop* cb_loop) { - ThumbnailStore::Cache* cache = new ThumbnailStore::Cache; + Cache* cache = new Cache; SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_, "SELECT * FROM thumbnails"); while (statement->step() == SQLITE_ROW) { + // The URL GURL url(statement->column_string(0)); + + // The score. ThumbnailScore score(statement->column_double(1), // Boring score statement->column_bool(2), // Good clipping statement->column_bool(3), // At top base::Time::FromInternalValue( statement->column_int64(4))); // Time taken + + // The image. scoped_refptr<RefCountedBytes> data = new RefCountedBytes; if (statement->column_blob_as_vector(5, &data->data)) (*cache)[url] = CacheEntry(data, score, false); @@ -372,17 +410,23 @@ void ThumbnailStore::GetAllThumbnailsFromDisk(MessageLoop* cb_loop) { NewRunnableMethod(this, &ThumbnailStore::OnDiskDataAvailable, cache)); } -void ThumbnailStore::OnDiskDataAvailable(ThumbnailStore::Cache* cache) { +void ThumbnailStore::OnDiskDataAvailable(Cache* cache) { if (cache) cache_.reset(cache); + + disk_data_loaded_ = true; + if (IsReady()) + NotifyThumbnailStoreReady(); } bool ThumbnailStore::ShouldStoreThumbnailForURL(const GURL& url) const { - if (IsURLBlacklisted(url) || cache_->size() >= ThumbnailStore::kMaxCacheSize) + if (!cache_.get()) + return false; + + if (IsURLBlacklisted(url) || cache_->size() >= kMaxCacheSize) return false; - return most_visited_urls_->size() < ThumbnailStore::kMaxCacheSize || - IsPopular(url); + return IsPopular(url); } bool ThumbnailStore::IsURLBlacklisted(const GURL& url) const { @@ -397,7 +441,6 @@ std::wstring ThumbnailStore::GetDictionaryKeyForURL( } bool ThumbnailStore::IsPopular(const GURL& url) const { - return most_visited_urls_->end() != find(most_visited_urls_->begin(), - most_visited_urls_->end(), - url); + return most_visited_urls_->size() < kMaxCacheSize || + most_visited_urls_->find(url) != most_visited_urls_->end(); } diff --git a/chrome/browser/thumbnail_store.h b/chrome/browser/thumbnail_store.h index 8b5fde8..143cbce 100644 --- a/chrome/browser/thumbnail_store.h +++ b/chrome/browser/thumbnail_store.h @@ -41,9 +41,12 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore>, ThumbnailStore(); ~ThumbnailStore(); - // Must be called after creation but before other methods are called. - void Init(const FilePath& db_name, // The location of the database. - Profile* profile); // To get to the HistoryService. + // Must be called before {Set,Get}PageThumbnail. |db_name| is the location + // of an existing ThumbnailStore database or where to create a new one. + void Init(const FilePath& db_name, Profile* profile); + + // Is the ThumbnailStore ready for GetPageThumbnail requests? + bool IsReady() { return disk_data_loaded_ && redirect_urls_.get(); } // Stores the given thumbnail and score with the associated url in the cache. bool SetPageThumbnail(const GURL& url, @@ -83,11 +86,19 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore>, // Data structure used to store thumbnail data in memory. typedef std::map<GURL, CacheEntry> Cache; + // Data structre used to store the top visited URLs. It maps the end of a + // redirect chain to the beginning. If A -> B -> C is a redirect chain and C + // is a top visited url, then this map will contain an entry C => A. + typedef std::map<GURL, GURL> MostVisitedMap; + // NotificationObserver implementation virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); + // Notify anyone listening that the ThumbnailStore is ready to be used. + void NotifyThumbnailStoreReady(); + // Most visited URLs and their redirect lists ------------------------------- // Query the HistoryService for the most visited URLs and the most recent @@ -96,7 +107,9 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore>, void UpdateURLData(); // The callback for UpdateURLData. - void OnURLDataAvailable(std::vector<GURL>* urls, + void OnURLDataAvailable(HistoryService::Handle handle, + bool success, + std::vector<GURL>* urls, history::RedirectMap* redirects); // The callback for the redirects request to the HistoryService made in @@ -108,6 +121,11 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore>, bool success, history::RedirectList* redirects); + // Search the RedirectMap for a redirect chain ending at |url|. Returns an + // iterator to an entry in redirect_urls_ if found or redirect_urls_->end(). + history::RedirectMap::iterator GetRedirectIteratorForURL( + const GURL& url) const; + // Remove stale data -------------------------------------------------------- // Remove entries from the in memory thumbnail cache cache that have been @@ -165,9 +183,9 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore>, // and redirect information. scoped_refptr<HistoryService> hs_; - // A list of the most_visited_urls_ refreshed every 30mins from the + // The most visited urls refreshed every kUpdateIntervalSecs from the // HistoryService. - scoped_ptr<std::vector<GURL> > most_visited_urls_; + scoped_ptr<MostVisitedMap> most_visited_urls_; // A pointer to the persistent URL blacklist for this profile. const DictionaryValue* url_blacklist_; @@ -178,8 +196,7 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore>, scoped_ptr<history::RedirectMap> redirect_urls_; // Timer on which UpdateURLData runs. - base::OneShotTimer<ThumbnailStore> timer_; - int seconds_to_next_update_; + base::RepeatingTimer<ThumbnailStore> timer_; // Consumer for queries to the HistoryService. CancelableRequestConsumer consumer_; @@ -188,8 +205,10 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore>, NotificationRegistrar registrar_; static const unsigned int kMaxCacheSize = 24; - static const int64 kInitialUpdateIntervalSecs = 180; - static const int64 kMaxUpdateIntervalSecs = 3600; + static const int64 kUpdateIntervalSecs = 360; + + // Has the data from disk been read? + bool disk_data_loaded_; DISALLOW_COPY_AND_ASSIGN(ThumbnailStore); }; diff --git a/chrome/browser/thumbnail_store_unittest.cc b/chrome/browser/thumbnail_store_unittest.cc index 331d5df..cd8f146 100644 --- a/chrome/browser/thumbnail_store_unittest.cc +++ b/chrome/browser/thumbnail_store_unittest.cc @@ -96,8 +96,8 @@ void ThumbnailStoreTest::SetUp() { store_->cache_.reset(new ThumbnailStore::Cache); store_->redirect_urls_.reset(new history::RedirectMap); - store_->most_visited_urls_.reset(new std::vector<GURL>); - store_->most_visited_urls_->push_back(url_); + store_->most_visited_urls_.reset(new ThumbnailStore::MostVisitedMap); + (*store_->most_visited_urls_)[url_] = GURL(); } void ThumbnailStoreTest::PrintPixelDiff(SkBitmap* image_a, SkBitmap* image_b) { @@ -183,7 +183,7 @@ TEST_F(ThumbnailStoreTest, RetrieveFromDisk) { store_->InitializeFromDB(db_name_, NULL); // Write to the DB (dirty bit sould be set) store_->CommitCacheToDB(NULL, new ThumbnailStore::Cache(*store_->cache_)); - store_->cache_->clear(); // Clear it from the cache. + store_->cache_->clear(); // Clear it from the cache. // Read from the DB. SQLITE_UNIQUE_STATEMENT(statement, *store_->statement_cache_, @@ -215,7 +215,7 @@ TEST_F(ThumbnailStoreTest, FollowRedirects) { redirects.push_back(url_); // url_ = http://www.google.com/ (*store_->redirect_urls_)[my_url] = new RefCountedVector<GURL>(redirects); - store_->most_visited_urls_->push_back(my_url); + (*store_->most_visited_urls_)[url_] = my_url; EXPECT_TRUE(store_->SetPageThumbnail(GURL("google.com"), *google_, score_, false)); diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc index fbedb7c..2b32993 100644 --- a/chrome/common/chrome_constants.cc +++ b/chrome/common/chrome_constants.cc @@ -68,6 +68,7 @@ const FilePath::CharType kSafeBrowsingFilename[] = FPL("Safe Browsing"); // chrome_process_util_linux would be broken. const FilePath::CharType kSingletonSocketFilename[] = FPL("SingletonSocket"); const FilePath::CharType kThumbnailsFilename[] = FPL("Thumbnails"); +const FilePath::CharType kNewTabThumbnailsFilename[] = FPL("Top Thumbnails"); const wchar_t kUserDataDirname[] = L"User Data"; const FilePath::CharType kUserScriptsDirname[] = FPL("User Scripts"); const FilePath::CharType kWebDataFilename[] = FPL("Web Data"); diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h index 4f9f4a1..350c835 100644 --- a/chrome/common/chrome_constants.h +++ b/chrome/common/chrome_constants.h @@ -37,6 +37,7 @@ extern const FilePath::CharType kPreferencesFilename[]; extern const FilePath::CharType kSafeBrowsingFilename[]; extern const FilePath::CharType kSingletonSocketFilename[]; extern const FilePath::CharType kThumbnailsFilename[]; +extern const FilePath::CharType kNewTabThumbnailsFilename[]; extern const wchar_t kUserDataDirname[]; extern const FilePath::CharType kUserScriptsDirname[]; extern const FilePath::CharType kWebDataFilename[]; diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index 221bf32..04fc94f 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -471,6 +471,12 @@ class NotificationType { // history_notifications.h). FAVICON_CHANGED, + // Thumbnails--------------------------------------------------------------- + + // Set by ThumbnailStore when it was finished loading data from disk on + // startup. + THUMBNAIL_STORE_READY, + // Bookmarks --------------------------------------------------------------- // Sent when the starred state of a URL changes. A URL is starred if there |