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

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: Syncing with hopes of pleasing trybot update Created 8 years, 9 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 126922)
+++ chrome/browser/history/in_memory_url_index.cc (working copy)
@@ -4,23 +4,52 @@
#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_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 "chrome/common/url_constants.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
using in_memory_url_index::InMemoryURLIndexCacheItem;
namespace history {
+// Called by DoSaveToCacheFile to delete any old cache file at |path| when
+// there is no private data to save. Runs on the FILE thread.
+void DeleteCacheFile(const FilePath& path) {
+ DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ file_util::Delete(path, false);
+}
+
+// RefCountedBool --------------------------------------------------------------
+
+RefCountedBool::~RefCountedBool() {}
+
+// Restore/SaveCacheObserver ---------------------------------------------------
+
+InMemoryURLIndex::RestoreCacheObserver::~RestoreCacheObserver() {}
+
+InMemoryURLIndex::SaveCacheObserver::~SaveCacheObserver() {}
+
+// RebuildPrivateDataFromHistoryDBTask -----------------------------------------
+
InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
- RebuildPrivateDataFromHistoryDBTask(InMemoryURLIndex* index)
+ RebuildPrivateDataFromHistoryDBTask(
+ InMemoryURLIndex* index,
+ const std::string& languages,
+ const std::set<std::string>& scheme_whitelist)
: index_(index),
- succeeded_(false) {}
+ languages_(languages),
+ scheme_whitelist_(scheme_whitelist),
+ succeeded_(false) {
+}
InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
~RebuildPrivateDataFromHistoryDBTask() {}
@@ -28,28 +57,33 @@
bool InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::RunOnDBThread(
HistoryBackend* backend,
HistoryDatabase* db) {
- data_.reset(URLIndexPrivateData::RebuildFromHistory(db));
- succeeded_ = data_.get() && !data_->history_info_map_.empty();
+ data_ = URLIndexPrivateData::RebuildFromHistory(db, languages_,
+ scheme_whitelist_);
+ succeeded_ = data_.get() && !data_->Empty();
if (!succeeded_)
- data_.reset();
+ data_->Clear();
return true;
}
void InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
DoneRunOnMainThread() {
- if (succeeded_)
- index_->DoneRebuidingPrivateDataFromHistoryDB(data_.release());
+ index_->DoneRebuidingPrivateDataFromHistoryDB(succeeded_, data_.release());
}
+// InMemoryURLIndex ------------------------------------------------------------
+
InMemoryURLIndex::InMemoryURLIndex(Profile* profile,
const FilePath& history_dir,
const std::string& languages)
: profile_(profile),
history_dir_(history_dir),
+ languages_(languages),
private_data_(new URLIndexPrivateData),
+ restore_cache_observer_(NULL),
+ save_cache_observer_(NULL),
shutdown_(false),
needs_to_be_cached_(false) {
- private_data_->set_languages(languages);
+ InMemoryURLIndex::InitializeSchemeWhitelist(&scheme_whitelist_);
if (profile) {
// TODO(mrossetti): Register for language change notifications.
content::Source<Profile> source(profile);
@@ -64,8 +98,11 @@
InMemoryURLIndex::InMemoryURLIndex()
: profile_(NULL),
private_data_(new URLIndexPrivateData),
+ restore_cache_observer_(NULL),
+ save_cache_observer_(NULL),
shutdown_(false),
needs_to_be_cached_(false) {
+ InMemoryURLIndex::InitializeSchemeWhitelist(&scheme_whitelist_);
}
InMemoryURLIndex::~InMemoryURLIndex() {
@@ -75,14 +112,14 @@
}
void InMemoryURLIndex::Init() {
- RestoreFromCacheFile();
+ PostRestoreFromCacheFileTask();
}
void InMemoryURLIndex::ShutDown() {
registrar_.RemoveAll();
cache_reader_consumer_.CancelAllRequests();
shutdown_ = true;
- SaveToCacheFile();
+ PostSaveToCacheFileTask();
needs_to_be_cached_ = false;
}
@@ -121,12 +158,11 @@
OnURLsDeleted(
content::Details<history::URLsDeletedDetails>(details).ptr());
break;
- case chrome::NOTIFICATION_HISTORY_LOADED: {
+ case chrome::NOTIFICATION_HISTORY_LOADED:
registrar_.Remove(this, chrome::NOTIFICATION_HISTORY_LOADED,
content::Source<Profile>(profile_));
ScheduleRebuildFromHistory();
break;
- }
default:
// For simplicity, the unit tests send us all notifications, even when
// we haven't registered for them, so don't assert here.
@@ -135,13 +171,15 @@
}
void InMemoryURLIndex::OnURLVisited(const URLVisitedDetails* details) {
- needs_to_be_cached_ |= private_data_->UpdateURL(details->row);
+ needs_to_be_cached_ |=
+ private_data_->UpdateURL(details->row, languages_, scheme_whitelist_);
}
void InMemoryURLIndex::OnURLsModified(const URLsModifiedDetails* details) {
for (URLRows::const_iterator row = details->changed_urls.begin();
row != details->changed_urls.end(); ++row)
- needs_to_be_cached_ |= private_data_->UpdateURL(*row);
+ needs_to_be_cached_ |=
+ private_data_->UpdateURL(*row, languages_, scheme_whitelist_);
}
void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) {
@@ -157,24 +195,43 @@
// Restoring from Cache --------------------------------------------------------
-void InMemoryURLIndex::RestoreFromCacheFile() {
+void InMemoryURLIndex::PostRestoreFromCacheFileTask() {
FilePath path;
- if (GetCacheFilePath(&path) && !shutdown_)
- DoRestoreFromCacheFile(path);
+ if (!GetCacheFilePath(&path) || shutdown_)
+ return;
+ scoped_refptr<URLIndexPrivateData> restored_private_data =
+ new URLIndexPrivateData;
+ content::BrowserThread::PostTaskAndReply(
+ content::BrowserThread::FILE, FROM_HERE,
+ base::Bind(&URLIndexPrivateData::RestoreFromFileTask, path,
+ restored_private_data, languages_),
+ base::Bind(&InMemoryURLIndex::OnCacheLoadDone, AsWeakPtr(),
+ restored_private_data));
}
-void InMemoryURLIndex::DoRestoreFromCacheFile(const FilePath& path) {
- if (private_data_->RestoreFromFile(path))
- return;
-
- // When unable to restore from the cache file we must rebuild from the
- // history database.
- HistoryService* service = profile_->GetHistoryServiceWithoutCreating();
- if (service && service->backend_loaded())
- ScheduleRebuildFromHistory();
- // We must wait to rebuild until the history backend has been loaded.
- registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED,
- content::Source<Profile>(profile_));
+void InMemoryURLIndex::OnCacheLoadDone(
+ scoped_refptr<URLIndexPrivateData> private_data) {
+ if (private_data.get() && !private_data->Empty()) {
+ private_data_ = private_data;
+ if (restore_cache_observer_)
+ restore_cache_observer_->OnCacheRestoreFinished(true);
+ } else if (profile_) {
+ // When unable to restore from the cache file delete the cache file, if
+ // it exists, and then rebuild from the history database if it's available,
+ // otherwise wait until the history database loaded and then rebuild.
+ FilePath path;
+ if (!GetCacheFilePath(&path) || shutdown_)
+ return;
+ content::BrowserThread::PostBlockingPoolTask(
+ FROM_HERE, base::Bind(DeleteCacheFile, path));
+ HistoryService* service = profile_->GetHistoryServiceWithoutCreating();
+ if (service && service->backend_loaded()) {
+ ScheduleRebuildFromHistory();
+ } else {
+ registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED,
+ content::Source<Profile>(profile_));
+ }
+ }
}
// Restoring from the History DB -----------------------------------------------
@@ -183,34 +240,79 @@
HistoryService* service =
profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
service->ScheduleDBTask(
- new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask(this),
+ new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask(
+ this, languages_, scheme_whitelist_),
&cache_reader_consumer_);
}
void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB(
+ bool succeeded,
URLIndexPrivateData* data) {
- scoped_ptr<URLIndexPrivateData> private_data(data);
- private_data_.swap(private_data);
- // Cache the newly rebuilt index.
- FilePath cache_file_path;
- if (GetCacheFilePath(&cache_file_path))
- private_data_->SaveToFile(cache_file_path);
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ scoped_refptr<URLIndexPrivateData> private_data(data);
+ if (succeeded) {
+ private_data_ = private_data;
+ PostSaveToCacheFileTask(); // Cache the newly rebuilt index.
+ } else {
+ private_data_->Clear(); // Dump the old private data.
+ // There is no need to do anything with the cache file as it was deleted
+ // when the rebuild from the history operation was kicked off.
+ }
+ if (restore_cache_observer_)
+ restore_cache_observer_->OnCacheRestoreFinished(succeeded);
}
void InMemoryURLIndex::RebuildFromHistory(HistoryDatabase* history_db) {
- private_data_.reset(URLIndexPrivateData::RebuildFromHistory(history_db));
+ private_data_ = URLIndexPrivateData::RebuildFromHistory(history_db,
+ languages_,
+ scheme_whitelist_);
}
// Saving to Cache -------------------------------------------------------------
-void InMemoryURLIndex::SaveToCacheFile() {
+void InMemoryURLIndex::PostSaveToCacheFileTask() {
FilePath path;
- if (GetCacheFilePath(&path))
- DoSaveToCacheFile(path);
+ if (!GetCacheFilePath(&path))
+ return;
+ // If there is anything in our private data then make a copy of it and tell
+ // it to save itself to a file.
+ URLIndexPrivateData* private_data = private_data_.get();
+ if (private_data && !private_data->Empty()) {
+ // Note that ownership of the copy of our private data is passed to the
+ // completion closure below.
+ scoped_refptr<URLIndexPrivateData> private_data_copy =
+ private_data->Duplicate();
+ scoped_refptr<RefCountedBool> succeeded(new RefCountedBool(false));
+ content::BrowserThread::PostTaskAndReply(
+ content::BrowserThread::FILE, FROM_HERE,
+ base::Bind(&URLIndexPrivateData::WritePrivateDataToCacheFileTask,
+ private_data_copy, path, succeeded),
+ base::Bind(&InMemoryURLIndex::OnCacheSaveDone, AsWeakPtr(), succeeded));
+ } else {
+ // If there is no data in our index then delete any existing cache file.
+ content::BrowserThread::PostBlockingPoolTask(
+ FROM_HERE,
+ base::Bind(DeleteCacheFile, path));
+ }
}
-void InMemoryURLIndex::DoSaveToCacheFile(const FilePath& path) {
- private_data_->SaveToFile(path);
+void InMemoryURLIndex::OnCacheSaveDone(
+ scoped_refptr<RefCountedBool> succeeded) {
+ if (save_cache_observer_)
+ save_cache_observer_->OnCacheSaveFinished(succeeded->value());
}
+// static
+void InMemoryURLIndex::InitializeSchemeWhitelist(
+ std::set<std::string>* whitelist) {
+ DCHECK(whitelist);
+ whitelist->insert(std::string(chrome::kAboutScheme));
+ whitelist->insert(std::string(chrome::kChromeUIScheme));
+ whitelist->insert(std::string(chrome::kFileScheme));
+ whitelist->insert(std::string(chrome::kFtpScheme));
+ whitelist->insert(std::string(chrome::kHttpScheme));
+ whitelist->insert(std::string(chrome::kHttpsScheme));
+ whitelist->insert(std::string(chrome::kMailToScheme));
+}
+
} // namespace history
« no previous file with comments | « chrome/browser/history/in_memory_url_index.h ('k') | chrome/browser/history/in_memory_url_index_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698