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

Unified Diff: chrome/browser/history/in_memory_url_index.cc

Issue 9030031: Move InMemoryURLIndex Caching Operations to FILE Thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Missed a private data swap. Try to fix update phase failure. Created 8 years, 11 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: chrome/browser/history/in_memory_url_index.cc
===================================================================
--- chrome/browser/history/in_memory_url_index.cc (revision 117518)
+++ chrome/browser/history/in_memory_url_index.cc (working copy)
@@ -4,63 +4,98 @@
#include "chrome/browser/history/in_memory_url_index.h"
+#include "base/file_util.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/history/history_database.h"
+#include "chrome/browser/history/history_notifications.h"
#include "chrome/browser/history/url_database.h"
+#include "chrome/browser/history/url_index_private_data.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
-using in_memory_url_index::InMemoryURLIndexCacheItem;
+using content::BrowserThread;
namespace history {
-InMemoryURLIndex::InMemoryURLIndex(const FilePath& history_dir)
- : history_dir_(history_dir),
+InMemoryURLIndex::RestoreCacheObserver::~RestoreCacheObserver() {}
+
+InMemoryURLIndex::SaveCacheObserver::~SaveCacheObserver() {}
+
+InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
+ RebuildPrivateDataFromHistoryDBTask(InMemoryURLIndex* index)
+ : index_(index),
+ succeeded_(false) {}
+
+InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
+ ~RebuildPrivateDataFromHistoryDBTask() {}
+
+bool InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::RunOnDBThread(
+ HistoryBackend* backend,
+ HistoryDatabase* db) {
+ data_.reset(URLIndexPrivateData::RebuildFromHistory(db));
+ succeeded_ = data_.get() && !data_->history_info_map_.empty();
+ if (!succeeded_)
+ data_.reset();
+ return true;
Peter Kasting 2012/01/14 00:12:49 Idle curiosity... what would be the consequences o
mrossetti 2012/03/03 05:05:56 The index data would still have been cleared so th
+}
+
+void InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
+ DoneRunOnMainThread() {
+ index_->DoneRebuidingPrivateDataFromHistoryDB(succeeded_, data_.release());
+}
+
+InMemoryURLIndex::InMemoryURLIndex(Profile* profile,
+ const FilePath& history_dir)
+ : profile_(profile),
+ history_dir_(history_dir),
private_data_(new URLIndexPrivateData),
- cached_at_shutdown_(false) {
+ restore_cache_observer_(NULL),
+ save_cache_observer_(NULL),
+ shutdown_(false),
+ needs_to_be_cached_(false) {
+ if (profile) {
+ // TODO(mrossetti): Register for profile/language change notifications.
Peter Kasting 2012/01/14 00:12:49 What is a profile change notification? We don't e
mrossetti 2012/03/03 05:05:56 Comment changes to only refer to language changes.
+ content::Source<Profile> source(profile);
+ registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED, source);
+ registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, source);
+ registrar_.Add(this, chrome::NOTIFICATION_HISTORY_TYPED_URLS_MODIFIED,
+ source);
+ registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, source);
+ }
}
// Called only by unit tests.
InMemoryURLIndex::InMemoryURLIndex()
- : private_data_(new URLIndexPrivateData),
- cached_at_shutdown_(false) {
+ : profile_(NULL),
+ private_data_(new URLIndexPrivateData),
+ restore_cache_observer_(NULL),
+ save_cache_observer_(NULL),
+ shutdown_(false),
+ needs_to_be_cached_(false) {
}
InMemoryURLIndex::~InMemoryURLIndex() {
// If there was a history directory (which there won't be for some unit tests)
// then insure that the cache has already been saved.
- DCHECK(history_dir_.empty() || cached_at_shutdown_);
+ DCHECK(history_dir_.empty() || !needs_to_be_cached_);
}
-bool InMemoryURLIndex::Init(URLDatabase* history_db,
- const std::string& languages) {
- // TODO(mrossetti): Register for profile/language change notifications.
+void InMemoryURLIndex::Init(const std::string& languages) {
private_data_->set_languages(languages);
- FilePath cache_file_path;
- return (GetCacheFilePath(&cache_file_path) &&
- private_data_->RestoreFromFile(cache_file_path)) ||
- ReloadFromHistory(history_db);
+ RestoreFromCacheFile();
}
-bool InMemoryURLIndex::ReloadFromHistory(history::URLDatabase* history_db) {
- if (!private_data_->ReloadFromHistory(history_db))
- return false;
- FilePath cache_file_path;
- if (GetCacheFilePath(&cache_file_path))
- private_data_->SaveToFile(cache_file_path);
- return true;
-}
-
void InMemoryURLIndex::ShutDown() {
- // Write our cache.
- FilePath cache_file_path;
- if (!GetCacheFilePath(&cache_file_path))
- return;
- private_data_->SaveToFile(cache_file_path);
- cached_at_shutdown_ = true;
+ registrar_.RemoveAll();
+ cache_reader_consumer_.CancelAllRequests();
+ shutdown_ = true;
+ SaveToCacheFile();
+ needs_to_be_cached_ = false;
}
-void InMemoryURLIndex::ClearPrivateData() {
- private_data_->Clear();
-}
-
bool InMemoryURLIndex::GetCacheFilePath(FilePath* file_path) {
if (history_dir_.empty())
return false;
@@ -68,19 +103,173 @@
return true;
}
-// Querying and Updating -------------------------------------------------------
+void InMemoryURLIndex::ClearPrivateData() {
+ private_data_->Clear();
+}
+// Saving to Cache -------------------------------------------------------------
+
+void InMemoryURLIndex::SaveToCacheFile() {
+ FilePath path;
+ if (GetCacheFilePath(&path))
+ DoSaveToCacheFile(path);
+}
+
+void InMemoryURLIndex::DoSaveToCacheFile(const FilePath& path) {
+ URLIndexPrivateData* private_data = private_data_.get();
+ // If there is anything in our private data then make a copy of it and tell
+ // it to save itself to a file.
+ if (private_data && private_data->word_list_.size()) {
+ URLIndexPrivateData* private_data_copy(
+ new URLIndexPrivateData(*(private_data)));
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
Peter Kasting 2012/01/14 00:12:49 Nit: You could put these on the above line if you
mrossetti 2012/03/03 05:05:56 This part of the change has been postponed. I'll a
brettw 2012/03/05 22:13:05 It's not clear what you mean here? What part has b
+ base::Bind(&InMemoryURLIndex::WritePrivateDataToCacheFile, this,
+ path, private_data_copy));
+ } else {
+ // If there is no data in our index then delete any existing cache file.
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(InMemoryURLIndex::DeleteCacheFile, path));
+ }
+}
+
+void InMemoryURLIndex::WritePrivateDataToCacheFile(
+ const FilePath path,
+ URLIndexPrivateData* private_data) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ scoped_ptr<history::URLIndexPrivateData> data(private_data);
+ data->SaveToFile(path);
+ if (save_cache_observer_)
+ save_cache_observer_->OnCacheSaveFinished();
+}
+
+// static
+void InMemoryURLIndex::DeleteCacheFile(const FilePath path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ file_util::Delete(path, false);
+}
+
+// Restoring from Cache --------------------------------------------------------
+
+void InMemoryURLIndex::RestoreFromCacheFile() {
+ FilePath path;
+ if (GetCacheFilePath(&path) && !shutdown_)
+ DoRestoreFromCacheFile(path);
+}
+
+void InMemoryURLIndex::DoRestoreFromCacheFile(const FilePath& path) {
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&InMemoryURLIndex::ReadPrivateDataFromCacheFile, this, path));
+}
+
+void InMemoryURLIndex::ReadPrivateDataFromCacheFile(const FilePath path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ history::URLIndexPrivateData* data(
+ history::URLIndexPrivateData::RestoreFromFile(path));
+ if (!profile_ || (data && !data->history_info_map_.empty())) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&history::InMemoryURLIndex::OnCacheRestored, this, data,
+ profile_ != NULL));
+ } else if (profile_) {
+ profile_->GetHistoryServiceWithoutCreating()->ScheduleDBTask(
+ new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask(this),
+ &cache_reader_consumer_);
+ }
+}
+
+void InMemoryURLIndex::OnCacheRestored(URLIndexPrivateData* private_data,
+ bool succeeded) {
+ if (succeeded)
+ private_data_.reset(private_data);
+ else
+ private_data_->Clear();
Peter Kasting 2012/01/14 00:12:49 Nit: Would it make sense to allow |private_data_|
mrossetti 2012/03/03 05:05:56 I've been thinking about this actually. The approa
+ if (restore_cache_observer_)
+ restore_cache_observer_->OnCacheRestoreFinished(succeeded);
+}
+
+// Restoring from the History DB -----------------------------------------------
+
+void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB(
Peter Kasting 2012/01/14 00:12:49 This function seems basically identical to OnCache
mrossetti 2012/03/03 05:05:56 Possibly. I'll consider this for the next change a
+ bool succeeded,
+ URLIndexPrivateData* data) {
+ scoped_ptr<URLIndexPrivateData> private_data(data);
+ if (succeeded)
+ private_data_.swap(private_data);
+ else
+ private_data_->Clear(); // Dump the old private data.
+ if (restore_cache_observer_)
+ restore_cache_observer_->OnCacheRestoreFinished(succeeded);
+}
+
+void InMemoryURLIndex::RebuildFromHistory(URLDatabase* history_db) {
+ private_data_.reset(URLIndexPrivateData::RebuildFromHistory(history_db));
+}
+
+// Querying --------------------------------------------------------------------
+
ScoredHistoryMatches InMemoryURLIndex::HistoryItemsForTerms(
const string16& term_string) {
return private_data_->HistoryItemsForTerms(term_string);
}
-void InMemoryURLIndex::UpdateURL(URLID row_id, const URLRow& row) {
- private_data_->UpdateURL(row_id, row);
+
+// Updating --------------------------------------------------------------------
+
+void InMemoryURLIndex::Observe(int notification_type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (notification_type) {
+ case chrome::NOTIFICATION_HISTORY_URL_VISITED:
+ OnURLVisited(content::Details<URLVisitedDetails>(details).ptr());
+ break;
+ case chrome::NOTIFICATION_HISTORY_TYPED_URLS_MODIFIED:
+ OnURLsModified(
+ content::Details<history::URLsModifiedDetails>(details).ptr());
+ break;
+ case chrome::NOTIFICATION_HISTORY_URLS_DELETED:
+ OnURLsDeleted(
+ content::Details<history::URLsDeletedDetails>(details).ptr());
+ break;
+ default:
+ // For simplicity, the unit tests send us all notifications, even when
+ // we haven't registered for them, so don't assert here.
+ break;
+ }
}
-void InMemoryURLIndex::DeleteURL(URLID row_id) {
- private_data_->DeleteURL(row_id);
+void InMemoryURLIndex::OnURLVisited(const URLVisitedDetails* details) {
+ private_data_->UpdateURL(details->row);
Peter Kasting 2012/01/14 00:12:49 Nit: Should we be calling IMUI::UpdateURL() or Del
mrossetti 2012/03/03 05:05:56 Done.
+ needs_to_be_cached_ = true;
Peter Kasting 2012/01/14 00:12:49 Nit: Does this need to be after the above line? D
mrossetti 2012/03/03 05:05:56 I'll move them to the bottom for now for consisten
}
+void InMemoryURLIndex::OnURLsModified(const URLsModifiedDetails* details) {
+ needs_to_be_cached_ = true;
+ for (std::vector<history::URLRow>::const_iterator row =
Peter Kasting 2012/01/14 00:12:49 Nit: Is there a typedef somewhere (history.h? I d
mrossetti 2012/03/03 05:05:56 Done. Added 'URLRows' to history_types.h. Will fil
+ details->changed_urls.begin();
+ row != details->changed_urls.end(); ++row)
+ private_data_->UpdateURL(*row);
+}
+
+void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) {
+ needs_to_be_cached_ = true;
+ if (details->all_history) {
+ ClearPrivateData();
+ } else {
+ for (std::vector<URLRow>::const_iterator row = details->rows.begin();
+ row != details->rows.end(); ++row)
+ private_data_->DeleteURL(row->url());
+ }
+}
+
+void InMemoryURLIndex::UpdateURL(const URLRow& row) {
+ private_data_->UpdateURL(row);
+}
+
+void InMemoryURLIndex::DeleteURL(const GURL& url) {
+ private_data_->DeleteURL(url);
+}
+
} // namespace history

Powered by Google App Engine
This is Rietveld 408576698