summaryrefslogtreecommitdiffstats
path: root/chrome/browser/history
diff options
context:
space:
mode:
authorzmo@google.com <zmo@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-15 21:26:19 +0000
committerzmo@google.com <zmo@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-15 21:26:19 +0000
commit103e385c881d7f83bd0aeecdcf618a746f47e9be (patch)
tree20e17071327fc810a73418c2aa15861d3172b607 /chrome/browser/history
parent55f4ef8487fb2a9fa3e556a17ebd315847e34dbb (diff)
downloadchromium_src-103e385c881d7f83bd0aeecdcf618a746f47e9be.zip
chromium_src-103e385c881d7f83bd0aeecdcf618a746f47e9be.tar.gz
chromium_src-103e385c881d7f83bd0aeecdcf618a746f47e9be.tar.bz2
Revert 126982 - Move InMemoryURLIndex Caching Operations to FILE Thread
Reading and writing of the InMemoryURLIndex (IMUI) cache is now peformed on the FILE thread and, when required, rebuilding of the index is performed on the history thread. Reading and rebuilding of the index from the cache file or history database are now performed as atomic operations rather than by restoring/rebuilding in-place, i.e. a new private data object is created and populated then swapped in for the live private data object. BUG=83659,118486 TEST=Unit tests updated/enhanced. Review URL: https://chromiumcodereview.appspot.com/9030031 TBR=mrossetti@chromium.org Review URL: https://chromiumcodereview.appspot.com/9705075 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126998 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/history')
-rw-r--r--chrome/browser/history/in_memory_url_index.cc186
-rw-r--r--chrome/browser/history/in_memory_url_index.h140
-rw-r--r--chrome/browser/history/in_memory_url_index_unittest.cc247
-rw-r--r--chrome/browser/history/url_index_private_data.cc161
-rw-r--r--chrome/browser/history/url_index_private_data.h108
5 files changed, 231 insertions, 611 deletions
diff --git a/chrome/browser/history/in_memory_url_index.cc b/chrome/browser/history/in_memory_url_index.cc
index 6990b6c..d6495c8 100644
--- a/chrome/browser/history/in_memory_url_index.cc
+++ b/chrome/browser/history/in_memory_url_index.cc
@@ -4,52 +4,23 @@
#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,
- const std::string& languages,
- const std::set<std::string>& scheme_whitelist)
+ RebuildPrivateDataFromHistoryDBTask(InMemoryURLIndex* index)
: index_(index),
- languages_(languages),
- scheme_whitelist_(scheme_whitelist),
- succeeded_(false) {
-}
+ succeeded_(false) {}
InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
~RebuildPrivateDataFromHistoryDBTask() {}
@@ -57,33 +28,28 @@ InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
bool InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::RunOnDBThread(
HistoryBackend* backend,
HistoryDatabase* db) {
- data_ = URLIndexPrivateData::RebuildFromHistory(db, languages_,
- scheme_whitelist_);
- succeeded_ = data_.get() && !data_->Empty();
+ data_.reset(URLIndexPrivateData::RebuildFromHistory(db));
+ succeeded_ = data_.get() && !data_->history_info_map_.empty();
if (!succeeded_)
- data_->Clear();
+ data_.reset();
return true;
}
void InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
DoneRunOnMainThread() {
- index_->DoneRebuidingPrivateDataFromHistoryDB(succeeded_, data_.release());
+ if (succeeded_)
+ index_->DoneRebuidingPrivateDataFromHistoryDB(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) {
- InMemoryURLIndex::InitializeSchemeWhitelist(&scheme_whitelist_);
+ private_data_->set_languages(languages);
if (profile) {
// TODO(mrossetti): Register for language change notifications.
content::Source<Profile> source(profile);
@@ -98,11 +64,8 @@ InMemoryURLIndex::InMemoryURLIndex(Profile* profile,
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() {
@@ -112,14 +75,14 @@ InMemoryURLIndex::~InMemoryURLIndex() {
}
void InMemoryURLIndex::Init() {
- PostRestoreFromCacheFileTask();
+ RestoreFromCacheFile();
}
void InMemoryURLIndex::ShutDown() {
registrar_.RemoveAll();
cache_reader_consumer_.CancelAllRequests();
shutdown_ = true;
- PostSaveToCacheFileTask();
+ SaveToCacheFile();
needs_to_be_cached_ = false;
}
@@ -158,11 +121,12 @@ void InMemoryURLIndex::Observe(int notification_type,
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.
@@ -171,15 +135,13 @@ void InMemoryURLIndex::Observe(int notification_type,
}
void InMemoryURLIndex::OnURLVisited(const URLVisitedDetails* details) {
- needs_to_be_cached_ |=
- private_data_->UpdateURL(details->row, languages_, scheme_whitelist_);
+ needs_to_be_cached_ |= private_data_->UpdateURL(details->row);
}
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, languages_, scheme_whitelist_);
+ needs_to_be_cached_ |= private_data_->UpdateURL(*row);
}
void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) {
@@ -195,43 +157,24 @@ void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) {
// Restoring from Cache --------------------------------------------------------
-void InMemoryURLIndex::PostRestoreFromCacheFileTask() {
+void InMemoryURLIndex::RestoreFromCacheFile() {
FilePath 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));
+ if (GetCacheFilePath(&path) && !shutdown_)
+ DoRestoreFromCacheFile(path);
}
-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_));
- }
- }
+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_));
}
// Restoring from the History DB -----------------------------------------------
@@ -240,79 +183,34 @@ void InMemoryURLIndex::ScheduleRebuildFromHistory() {
HistoryService* service =
profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
service->ScheduleDBTask(
- new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask(
- this, languages_, scheme_whitelist_),
+ new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask(this),
&cache_reader_consumer_);
}
void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB(
- bool succeeded,
URLIndexPrivateData* data) {
- 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);
+ 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);
}
void InMemoryURLIndex::RebuildFromHistory(HistoryDatabase* history_db) {
- private_data_ = URLIndexPrivateData::RebuildFromHistory(history_db,
- languages_,
- scheme_whitelist_);
+ private_data_.reset(URLIndexPrivateData::RebuildFromHistory(history_db));
}
// Saving to Cache -------------------------------------------------------------
-void InMemoryURLIndex::PostSaveToCacheFileTask() {
+void InMemoryURLIndex::SaveToCacheFile() {
FilePath 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::OnCacheSaveDone(
- scoped_refptr<RefCountedBool> succeeded) {
- if (save_cache_observer_)
- save_cache_observer_->OnCacheSaveFinished(succeeded->value());
+ if (GetCacheFilePath(&path))
+ DoSaveToCacheFile(path);
}
-// 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));
+void InMemoryURLIndex::DoSaveToCacheFile(const FilePath& path) {
+ private_data_->SaveToFile(path);
}
} // namespace history
diff --git a/chrome/browser/history/in_memory_url_index.h b/chrome/browser/history/in_memory_url_index.h
index 30f0c8f..665f7de 100644
--- a/chrome/browser/history/in_memory_url_index.h
+++ b/chrome/browser/history/in_memory_url_index.h
@@ -15,8 +15,8 @@
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "chrome/browser/autocomplete/history_provider_util.h"
@@ -24,6 +24,7 @@
#include "chrome/browser/history/history.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/history/in_memory_url_index_types.h"
+#include "chrome/browser/history/in_memory_url_index_cache.pb.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "sql/connection.h"
@@ -49,24 +50,6 @@ struct URLVisitedDetails;
struct URLsModifiedDetails;
struct URLsDeletedDetails;
-// A RefCountedThreadSafe class that manages a bool used for passing around
-// success when saving the persistent data for the InMemoryURLIndex in a cache.
-class RefCountedBool : public base::RefCountedThreadSafe<RefCountedBool> {
- public:
- explicit RefCountedBool(bool value) : value_(value) {}
-
- bool value() const { return value_; }
- void set_value(bool value) { value_ = value; }
-
- private:
- friend class base::RefCountedThreadSafe<RefCountedBool>;
- virtual ~RefCountedBool();
-
- bool value_;
-
- DISALLOW_COPY_AND_ASSIGN(RefCountedBool);
-};
-
// The URL history source.
// Holds portions of the URL database in memory in an indexed form. Used to
// quickly look up matching URLs for a given query string. Used by
@@ -86,33 +69,8 @@ class RefCountedBool : public base::RefCountedThreadSafe<RefCountedBool> {
// will eliminate such words except in the case where a single character
// is being searched on and which character occurs as the second char16 of a
// multi-char16 instance.
-class InMemoryURLIndex : public content::NotificationObserver,
- public base::SupportsWeakPtr<InMemoryURLIndex> {
+class InMemoryURLIndex : public content::NotificationObserver {
public:
- // Defines an abstract class which is notified upon completion of restoring
- // the index's private data either by reading from the cache file or by
- // rebuilding from the history database.
- class RestoreCacheObserver {
- public:
- virtual ~RestoreCacheObserver();
-
- // Callback that lets the observer know that the restore operation has
- // completed. |succeeded| indicates if the restore was successful. This is
- // called on the UI thread.
- virtual void OnCacheRestoreFinished(bool succeeded) = 0;
- };
-
- // Defines an abstract class which is notified upon completion of saving
- // the index's private data to the cache file.
- class SaveCacheObserver {
- public:
- virtual ~SaveCacheObserver();
-
- // Callback that lets the observer know that the save succeeded.
- // This is called on the UI thread.
- virtual void OnCacheSaveFinished(bool succeeded) = 0;
- };
-
// |profile|, which may be NULL during unit testing, is used to register for
// history changes. |history_dir| is a path to the directory containing the
// history database within the profile wherein the cache and transaction
@@ -138,21 +96,11 @@ class InMemoryURLIndex : public content::NotificationObserver,
// refer to that class.
ScoredHistoryMatches HistoryItemsForTerms(const string16& term_string);
- // Sets the optional observers for completion of restoral and saving of the
- // index's private data.
- void set_restore_cache_observer(
- RestoreCacheObserver* restore_cache_observer) {
- restore_cache_observer_ = restore_cache_observer;
- }
- void set_save_cache_observer(SaveCacheObserver* save_cache_observer) {
- save_cache_observer_ = save_cache_observer;
- }
-
private:
friend class ::HistoryQuickProviderTest;
friend class InMemoryURLIndexTest;
- friend class InMemoryURLIndexCacheTest;
FRIEND_TEST_ALL_PREFIXES(LimitedInMemoryURLIndexTest, Initialization);
+ FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexCacheTest, CacheFilePath);
// Creating one of me without a history path is not allowed (tests excepted).
InMemoryURLIndex();
@@ -160,10 +108,7 @@ class InMemoryURLIndex : public content::NotificationObserver,
// HistoryDBTask used to rebuild our private data from the history database.
class RebuildPrivateDataFromHistoryDBTask : public HistoryDBTask {
public:
- explicit RebuildPrivateDataFromHistoryDBTask(
- InMemoryURLIndex* index,
- const std::string& languages,
- const std::set<std::string>& scheme_whitelist);
+ explicit RebuildPrivateDataFromHistoryDBTask(InMemoryURLIndex* index);
virtual ~RebuildPrivateDataFromHistoryDBTask();
virtual bool RunOnDBThread(HistoryBackend* backend,
@@ -172,10 +117,8 @@ class InMemoryURLIndex : public content::NotificationObserver,
private:
InMemoryURLIndex* index_; // Call back to this index at completion.
- std::string languages_; // Languages for word-breaking.
- std::set<std::string> scheme_whitelist_; // Schemes to be indexed.
bool succeeded_; // Indicates if the rebuild was successful.
- scoped_refptr<URLIndexPrivateData> data_; // The rebuilt private data.
+ scoped_ptr<URLIndexPrivateData> data_; // The rebuilt private data.
DISALLOW_COPY_AND_ASSIGN(RebuildPrivateDataFromHistoryDBTask);
};
@@ -192,7 +135,11 @@ class InMemoryURLIndex : public content::NotificationObserver,
// Restores the index's private data from the cache file stored in the
// profile directory.
- void PostRestoreFromCacheFileTask();
+ void RestoreFromCacheFile();
+
+ // Restores private_data_ from the given |path|. Runs on the UI thread.
+ // Provided for unit testing so that a test cache file can be used.
+ void DoRestoreFromCacheFile(const FilePath& path);
// Schedules a history task to rebuild our private data from the history
// database.
@@ -204,42 +151,17 @@ class InMemoryURLIndex : public content::NotificationObserver,
// called upon a successful restore from the history database.
void DoneRebuidingPrivateDataFromHistoryDB(URLIndexPrivateData* data);
- // Posts a task to cache the index private data and write the cache file to
- // the profile directory.
- void PostSaveToCacheFileTask();
-
- // Saves private_data_ to the given |path|. Runs on the UI thread.
- // Provided for unit testing so that a test cache file can be used.
- void DoSaveToCacheFile(const FilePath& path);
-
- // Notifies the observer, if any, of the success of the private data caching.
- // |succeeded| is true on a successful save.
- void OnCacheSaveDone(scoped_refptr<RefCountedBool> succeeded);
-
- // Callback used by RebuildPrivateDataFromHistoryDBTask to signal completion
- // or rebuilding our private data from the history database. |succeeded|
- // will be true if the rebuild was successful. |data| will point to a new
- // instanceof the private data just rebuilt.
- void DoneRebuidingPrivateDataFromHistoryDB(bool succeeded,
- URLIndexPrivateData* data);
-
// Rebuilds the history index from the history database in |history_db|.
// Used for unit testing only.
void RebuildFromHistory(HistoryDatabase* history_db);
- // Determines if the private data was successfully reloaded from the cache
- // file or if the private data must be rebuilt from the history database.
- // |private_data_ptr|'s data will be NULL if the cache file load failed. If
- // successful, sets the private data and notifies any
- // |restore_cache_observer_|. Otherwise, kicks off a rebuild from the history
- // database.
- void OnCacheLoadDone(
- scoped_refptr<URLIndexPrivateData> private_data_ptr);
+ // Caches the index private data and writes the cache file to the profile
+ // directory.
+ void SaveToCacheFile();
- // Callback function that sets the private data from the just-restored-from-
- // file |private_data|. Notifies any |restore_cache_observer_| that the
- // restore has succeeded.
- void OnCacheRestored(URLIndexPrivateData* private_data);
+ // Saves private_data_ to the given |path|. Runs on the UI thread.
+ // Provided for unit testing so that a test cache file can be used.
+ void DoSaveToCacheFile(const FilePath& path);
// Handles notifications of history changes.
virtual void Observe(int notification_type,
@@ -251,19 +173,9 @@ class InMemoryURLIndex : public content::NotificationObserver,
void OnURLsModified(const URLsModifiedDetails* details);
void OnURLsDeleted(const URLsDeletedDetails* details);
- // Sets the directory wherein the cache file will be maintained.
- // For unit test usage only.
- void set_history_dir(const FilePath& dir_path) { history_dir_ = dir_path; }
-
- // Initializes the whitelist of URL schemes.
- static void InitializeSchemeWhitelist(std::set<std::string>* whitelist);
-
// Returns a pointer to our private data. For unit testing only.
URLIndexPrivateData* private_data() { return private_data_.get(); }
- // Returns the set of whitelisted schemes. For unit testing only.
- const std::set<std::string>& scheme_whitelist() { return scheme_whitelist_; }
-
// The profile, may be null when testing.
Profile* profile_;
@@ -272,25 +184,15 @@ class InMemoryURLIndex : public content::NotificationObserver,
// should never be empty.
FilePath history_dir_;
- // Languages used during the word-breaking process during indexing.
- std::string languages_;
-
- // Only URLs with a whitelisted scheme are indexed.
- std::set<std::string> scheme_whitelist_;
-
// The index's durable private data.
- scoped_refptr<URLIndexPrivateData> private_data_;
+ scoped_ptr<URLIndexPrivateData> private_data_;
- // Observers to notify upon restoral or save of the private data cache.
- RestoreCacheObserver* restore_cache_observer_;
- SaveCacheObserver* save_cache_observer_;
+ // Set to true once the shutdown process has begun.
+ bool shutdown_;
CancelableRequestConsumer cache_reader_consumer_;
content::NotificationRegistrar registrar_;
- // Set to true once the shutdown process has begun.
- bool shutdown_;
-
// Set to true when changes to the index have been made and the index needs
// to be cached. Set to false when the index has been cached. Used as a
// temporary safety check to insure that the cache is saved before the
diff --git a/chrome/browser/history/in_memory_url_index_unittest.cc b/chrome/browser/history/in_memory_url_index_unittest.cc
index bbc7bf1..8796cc2 100644
--- a/chrome/browser/history/in_memory_url_index_unittest.cc
+++ b/chrome/browser/history/in_memory_url_index_unittest.cc
@@ -9,7 +9,6 @@
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/path_service.h"
-#include "base/scoped_temp_dir.h"
#include "base/string_util.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
@@ -26,8 +25,6 @@
#include "sql/transaction.h"
#include "testing/gtest/include/gtest/gtest.h"
-using content::BrowserThread;
-
// The test version of the history url database table ('url') is contained in
// a database file created from a text file('url_history_provider_test.db.txt').
// The only difference between this table and a live 'urls' table from a
@@ -41,54 +38,6 @@ using content::BrowserThread;
namespace history {
-// -----------------------------------------------------------------------------
-
-// Observer class so the unit tests can wait while the cache is being saved.
-class CacheFileSaverObserver : public InMemoryURLIndex::SaveCacheObserver {
- public:
- explicit CacheFileSaverObserver(MessageLoop* loop);
- virtual void OnCacheSaveFinished(bool succeeded) OVERRIDE;
-
- MessageLoop* loop_;
- bool succeeded_;
- DISALLOW_COPY_AND_ASSIGN(CacheFileSaverObserver);
-};
-
-CacheFileSaverObserver::CacheFileSaverObserver(MessageLoop* loop)
- : loop_(loop),
- succeeded_(false) {
- DCHECK(loop);
-}
-
-void CacheFileSaverObserver::OnCacheSaveFinished(bool succeeded) {
- succeeded_ = succeeded;
- loop_->Quit();
-}
-
-// Observer class so the unit tests can wait while the cache is being restored.
-class CacheFileReaderObserver : public InMemoryURLIndex::RestoreCacheObserver {
- public:
- explicit CacheFileReaderObserver(MessageLoop* loop);
- virtual void OnCacheRestoreFinished(bool succeeded) OVERRIDE;
-
- MessageLoop* loop_;
- bool succeeded_;
- DISALLOW_COPY_AND_ASSIGN(CacheFileReaderObserver);
-};
-
-CacheFileReaderObserver::CacheFileReaderObserver(MessageLoop* loop)
- : loop_(loop),
- succeeded_(false) {
- DCHECK(loop);
-}
-
-void CacheFileReaderObserver::OnCacheRestoreFinished(bool succeeded) {
- succeeded_ = succeeded;
- loop_->Quit();
-}
-
-// -----------------------------------------------------------------------------
-
class InMemoryURLIndexTest : public testing::Test {
public:
InMemoryURLIndexTest();
@@ -124,13 +73,8 @@ class InMemoryURLIndexTest : public testing::Test {
// Pass-through functions to simplify our friendship with InMemoryURLIndex.
URLIndexPrivateData* GetPrivateData() const;
- void ClearPrivateData();
- void set_history_dir(const FilePath& dir_path);
bool GetCacheFilePath(FilePath* file_path) const;
- void PostRestoreFromCacheFileTask();
- void PostSaveToCacheFileTask();
- const std::set<std::string>& scheme_whitelist();
-
+ void ClearHistoryDir() const;
// Pass-through functions to simplify our friendship with URLIndexPrivateData.
bool UpdateURL(const URLRow& row);
@@ -161,16 +105,8 @@ sql::Connection& InMemoryURLIndexTest::GetDB() {
}
URLIndexPrivateData* InMemoryURLIndexTest::GetPrivateData() const {
- DCHECK(url_index_->private_data());
- return url_index_->private_data();
-}
-
-void InMemoryURLIndexTest::ClearPrivateData() {
- return url_index_->ClearPrivateData();
-}
-
-void InMemoryURLIndexTest::set_history_dir(const FilePath& dir_path) {
- return url_index_->set_history_dir(dir_path);
+ DCHECK(url_index_->private_data_.get());
+ return url_index_->private_data_.get();
}
bool InMemoryURLIndexTest::GetCacheFilePath(FilePath* file_path) const {
@@ -178,25 +114,16 @@ bool InMemoryURLIndexTest::GetCacheFilePath(FilePath* file_path) const {
return url_index_->GetCacheFilePath(file_path);
}
-void InMemoryURLIndexTest::PostRestoreFromCacheFileTask() {
- url_index_->PostRestoreFromCacheFileTask();
-}
-
-void InMemoryURLIndexTest::PostSaveToCacheFileTask() {
- url_index_->PostSaveToCacheFileTask();
-}
-
-const std::set<std::string>& InMemoryURLIndexTest::scheme_whitelist() {
- return url_index_->scheme_whitelist();
+void InMemoryURLIndexTest::ClearHistoryDir() const {
+ url_index_->history_dir_.clear();
}
bool InMemoryURLIndexTest::UpdateURL(const URLRow& row) {
- return GetPrivateData()->UpdateURL(row, url_index_->languages_,
- url_index_->scheme_whitelist_);
+ return url_index_->private_data_->UpdateURL(row);
}
bool InMemoryURLIndexTest::DeleteURL(const GURL& url) {
- return GetPrivateData()->DeleteURL(url);
+ return url_index_->private_data_->DeleteURL(url);
}
void InMemoryURLIndexTest::SetUp() {
@@ -432,7 +359,8 @@ FilePath::StringType LimitedInMemoryURLIndexTest::TestDBName() const {
TEST_F(LimitedInMemoryURLIndexTest, Initialization) {
// Verify that the database contains the expected number of items, which
// is the pre-filtered count, i.e. all of the items.
- sql::Statement statement(GetDB().GetUniqueStatement("SELECT * FROM urls;"));
+ sql::Connection& db(GetDB());
+ sql::Statement statement(db.GetUniqueStatement("SELECT * FROM urls;"));
ASSERT_TRUE(statement.is_valid());
uint64 row_count = 0;
while (statement.Step()) ++row_count;
@@ -441,7 +369,7 @@ TEST_F(LimitedInMemoryURLIndexTest, Initialization) {
new InMemoryURLIndex(&profile_, FilePath(), "en,ja,hi,zh"));
url_index_->Init();
url_index_->RebuildFromHistory(history_database_);
- URLIndexPrivateData& private_data(*GetPrivateData());
+ URLIndexPrivateData& private_data(*(url_index_->private_data_));
// history_info_map_ should have the same number of items as were filtered.
EXPECT_EQ(1U, private_data.history_info_map_.size());
@@ -910,95 +838,73 @@ TEST_F(InMemoryURLIndexTest, WhitelistedURLs) {
};
URLIndexPrivateData& private_data(*GetPrivateData());
- const std::set<std::string>& whitelist(scheme_whitelist());
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
GURL url(data[i].url_spec);
EXPECT_EQ(data[i].expected_is_whitelisted,
- private_data.URLSchemeIsWhitelisted(url, whitelist));
+ private_data.URLSchemeIsWhitelisted(url));
}
}
TEST_F(InMemoryURLIndexTest, CacheSaveRestore) {
- ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
- set_history_dir(temp_directory.path());
+ // Part 1: Save the cache to a protobuf, restore it, and compare the results.
+ in_memory_url_index::InMemoryURLIndexCacheItem index_cache;
+ URLIndexPrivateData& expected(*GetPrivateData());
- URLIndexPrivateData& private_data(*GetPrivateData());
+ // Capture our private data so we can later compare for equality.
+ URLIndexPrivateData actual(expected);
- // Ensure that there is really something there to be saved.
- EXPECT_FALSE(private_data.word_list_.empty());
- // available_words_ will already be empty since we have freshly built the
- // data set for this test.
- EXPECT_TRUE(private_data.available_words_.empty());
- EXPECT_FALSE(private_data.word_map_.empty());
- EXPECT_FALSE(private_data.char_word_map_.empty());
- EXPECT_FALSE(private_data.word_id_history_map_.empty());
- EXPECT_FALSE(private_data.history_id_word_map_.empty());
- EXPECT_FALSE(private_data.history_info_map_.empty());
-
- // Capture the current private data for later comparison to restored data.
- scoped_refptr<URLIndexPrivateData> old_data(private_data.Duplicate());
-
- // Save then restore our private data.
- CacheFileSaverObserver save_observer(&message_loop_);
- url_index_->set_save_cache_observer(&save_observer);
- PostSaveToCacheFileTask();
- message_loop_.Run();
- EXPECT_TRUE(save_observer.succeeded_);
-
- // Clear and then prove it's clear before restoring.
- ClearPrivateData();
- EXPECT_TRUE(private_data.word_list_.empty());
- EXPECT_TRUE(private_data.available_words_.empty());
- EXPECT_TRUE(private_data.word_map_.empty());
- EXPECT_TRUE(private_data.char_word_map_.empty());
- EXPECT_TRUE(private_data.word_id_history_map_.empty());
- EXPECT_TRUE(private_data.history_id_word_map_.empty());
- EXPECT_TRUE(private_data.history_info_map_.empty());
-
- CacheFileReaderObserver read_observer(&message_loop_);
- url_index_->set_restore_cache_observer(&read_observer);
- PostRestoreFromCacheFileTask();
- message_loop_.Run();
- EXPECT_TRUE(read_observer.succeeded_);
-
- URLIndexPrivateData& new_data(*GetPrivateData());
-
- // Compare the captured and restored for equality.
- EXPECT_EQ(old_data->word_list_.size(), new_data.word_list_.size());
- EXPECT_EQ(old_data->word_map_.size(), new_data.word_map_.size());
- EXPECT_EQ(old_data->char_word_map_.size(), new_data.char_word_map_.size());
- EXPECT_EQ(old_data->word_id_history_map_.size(),
- new_data.word_id_history_map_.size());
- EXPECT_EQ(old_data->history_id_word_map_.size(),
- new_data.history_id_word_map_.size());
- EXPECT_EQ(old_data->history_info_map_.size(),
- new_data.history_info_map_.size());
- // WordList must be index-by-index equal.
- size_t count = old_data->word_list_.size();
- for (size_t i = 0; i < count; ++i)
- EXPECT_EQ(old_data->word_list_[i], new_data.word_list_[i]);
-
- ExpectMapOfContainersIdentical(old_data->char_word_map_,
- new_data.char_word_map_);
- ExpectMapOfContainersIdentical(old_data->word_id_history_map_,
- new_data.word_id_history_map_);
- ExpectMapOfContainersIdentical(old_data->history_id_word_map_,
- new_data.history_id_word_map_);
-
- for (HistoryInfoMap::const_iterator expected =
- old_data->history_info_map_.begin();
- expected != old_data->history_info_map_.end(); ++expected) {
- HistoryInfoMap::const_iterator actual =
- new_data.history_info_map_.find(expected->first);
- ASSERT_FALSE(new_data.history_info_map_.end() == actual);
- const URLRow& expected_row(expected->second);
- const URLRow& actual_row(actual->second);
- EXPECT_EQ(expected_row.visit_count(), actual_row.visit_count());
- EXPECT_EQ(expected_row.typed_count(), actual_row.typed_count());
- EXPECT_EQ(expected_row.last_visit(), actual_row.last_visit());
- EXPECT_EQ(expected_row.url(), actual_row.url());
- }
+ actual.SavePrivateData(&index_cache);
+
+ // Version check: Make sure this version actually has the word starts.
+ EXPECT_TRUE(index_cache.has_word_starts_map());
+
+ // Save the size of the resulting cache for later versioning comparison.
+ std::string data;
+ EXPECT_TRUE(index_cache.SerializeToString(&data));
+ size_t current_version_cache_size = data.size();
+
+ // Prove that there is really something there.
+ ExpectPrivateDataNotEmpty(actual);
+
+ // Clear and then prove it's clear.
+ actual.Clear();
+ ExpectPrivateDataEmpty(actual);
+
+ // Restore the cache.
+ EXPECT_TRUE(actual.RestorePrivateData(index_cache));
+ EXPECT_EQ(kCurrentCacheFileVersion, actual.restored_cache_version_);
+
+ // Compare the restored and expected for equality.
+ ExpectPrivateDataEqual(expected, actual);
+
+ // Part 2: Save an older version of the cache, restore it, and verify that the
+ // reversioned portions are as expected.
+ URLIndexPrivateData older(expected);
+ in_memory_url_index::InMemoryURLIndexCacheItem older_cache;
+ older.set_saved_cache_version(0);
+ older.SavePrivateData(&older_cache);
+
+ // Version check: Make sure this version does not have the word starts.
+ EXPECT_FALSE(older_cache.has_word_starts_map());
+
+ // Since we shouldn't have saved the word starts information for the version
+ // 0 save immediately above, the cache should be a bit smaller.
+ std::string older_data;
+ EXPECT_TRUE(older_cache.SerializeToString(&older_data));
+ size_t old_version_file_size = older_data.size();
+ EXPECT_LT(old_version_file_size, current_version_cache_size);
+ EXPECT_NE(data, older_data);
+
+ // Clear and then prove it's clear.
+ older.Clear();
+ ExpectPrivateDataEmpty(older);
+
+ // Restore the cache.
+ EXPECT_TRUE(older.RestorePrivateData(older_cache));
+ EXPECT_EQ(0, older.restored_cache_version_);
+
+ // Compare the restored and expected for equality.
+ ExpectPrivateDataEqual(expected, older);
}
class InMemoryURLIndexCacheTest : public testing::Test {
@@ -1008,10 +914,6 @@ class InMemoryURLIndexCacheTest : public testing::Test {
protected:
virtual void SetUp() OVERRIDE;
- // Pass-through functions to simplify our friendship with InMemoryURLIndex.
- void set_history_dir(const FilePath& dir_path);
- bool GetCacheFilePath(FilePath* file_path) const;
-
ScopedTempDir temp_dir_;
scoped_ptr<InMemoryURLIndex> url_index_;
};
@@ -1023,22 +925,13 @@ void InMemoryURLIndexCacheTest::SetUp() {
new InMemoryURLIndex(NULL, path, "en,ja,hi,zh"));
}
-void InMemoryURLIndexCacheTest::set_history_dir(const FilePath& dir_path) {
- return url_index_->set_history_dir(dir_path);
-}
-
-bool InMemoryURLIndexCacheTest::GetCacheFilePath(FilePath* file_path) const {
- DCHECK(file_path);
- return url_index_->GetCacheFilePath(file_path);
-}
-
TEST_F(InMemoryURLIndexCacheTest, CacheFilePath) {
FilePath expectedPath =
temp_dir_.path().Append(FILE_PATH_LITERAL("History Provider Cache"));
std::vector<FilePath::StringType> expected_parts;
expectedPath.GetComponents(&expected_parts);
FilePath full_file_path;
- ASSERT_TRUE(GetCacheFilePath(&full_file_path));
+ ASSERT_TRUE(url_index_->GetCacheFilePath(&full_file_path));
std::vector<FilePath::StringType> actual_parts;
full_file_path.GetComponents(&actual_parts);
ASSERT_EQ(expected_parts.size(), actual_parts.size());
@@ -1046,7 +939,7 @@ TEST_F(InMemoryURLIndexCacheTest, CacheFilePath) {
for (size_t i = 0; i < count; ++i)
EXPECT_EQ(expected_parts[i], actual_parts[i]);
// Must clear the history_dir_ to satisfy the dtor's DCHECK.
- set_history_dir(FilePath());
+ url_index_->history_dir_.clear();
}
} // namespace history
diff --git a/chrome/browser/history/url_index_private_data.cc b/chrome/browser/history/url_index_private_data.cc
index 522bf51..de779f4 100644
--- a/chrome/browser/history/url_index_private_data.cc
+++ b/chrome/browser/history/url_index_private_data.cc
@@ -14,14 +14,11 @@
#include "base/i18n/case_conversion.h"
#include "base/metrics/histogram.h"
#include "base/string_util.h"
-#include "base/time.h"
+#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/history/history_database.h"
-#include "chrome/browser/history/in_memory_url_index.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_source.h"
+#include "chrome/common/url_constants.h"
#include "net/base/net_util.h"
#include "third_party/protobuf/src/google/protobuf/repeated_field.h"
@@ -126,6 +123,7 @@ URLIndexPrivateData::URLIndexPrivateData()
pre_filter_item_count_(0),
post_filter_item_count_(0),
post_scoring_item_count_(0) {
+ URLIndexPrivateData::InitializeSchemeWhitelist(&scheme_whitelist_);
}
URLIndexPrivateData::~URLIndexPrivateData() {}
@@ -141,42 +139,18 @@ void URLIndexPrivateData::Clear() {
word_starts_map_.clear();
}
-bool URLIndexPrivateData::Empty() const {
- return history_info_map_.empty();
-}
-
-scoped_refptr<URLIndexPrivateData> URLIndexPrivateData::Duplicate() const {
- scoped_refptr<URLIndexPrivateData> data_copy = new URLIndexPrivateData;
- data_copy->word_list_ = word_list_;
- data_copy->available_words_ = available_words_;
- data_copy->word_map_ = word_map_;
- data_copy->char_word_map_ = char_word_map_;
- data_copy->word_id_history_map_ = word_id_history_map_;
- data_copy->history_id_word_map_ = history_id_word_map_;
- data_copy->history_info_map_ = history_info_map_;
- return data_copy;
- // Not copied:
- // search_term_cache_
- // pre_filter_item_count_
- // post_filter_item_count_
- // post_scoring_item_count_
-};
-
// Cache Updating --------------------------------------------------------------
-bool URLIndexPrivateData::IndexRow(
- const URLRow& row,
- const std::string& languages,
- const std::set<std::string>& scheme_whitelist) {
+bool URLIndexPrivateData::IndexRow(const URLRow& row) {
const GURL& gurl(row.url());
// Index only URLs with a whitelisted scheme.
- if (!URLSchemeIsWhitelisted(gurl, scheme_whitelist))
+ if (!URLIndexPrivateData::URLSchemeIsWhitelisted(gurl))
return false;
URLID row_id = row.id();
// Strip out username and password before saving and indexing.
- string16 url(net::FormatUrl(gurl, languages,
+ string16 url(net::FormatUrl(gurl, languages_,
net::kFormatUrlOmitUsernamePassword,
net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS,
NULL, NULL, NULL));
@@ -194,18 +168,17 @@ bool URLIndexPrivateData::IndexRow(
// Index the words contained in the URL and title of the row.
RowWordStarts word_starts;
- AddRowWordsToIndex(new_row, &word_starts, languages);
+ AddRowWordsToIndex(new_row, &word_starts);
word_starts_map_[history_id] = word_starts;
return true;
}
void URLIndexPrivateData::AddRowWordsToIndex(const URLRow& row,
- RowWordStarts* word_starts,
- const std::string& languages) {
+ RowWordStarts* word_starts) {
HistoryID history_id = static_cast<HistoryID>(row.id());
// Split URL into individual, unique words then add in the title words.
const GURL& gurl(row.url());
- string16 url(net::FormatUrl(gurl, languages,
+ string16 url(net::FormatUrl(gurl, languages_,
net::kFormatUrlOmitUsernamePassword,
net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS,
NULL, NULL, NULL));
@@ -334,10 +307,7 @@ void URLIndexPrivateData::AddToHistoryIDWordMap(HistoryID history_id,
}
}
-bool URLIndexPrivateData::UpdateURL(
- const URLRow& row,
- const std::string& languages,
- const std::set<std::string>& scheme_whitelist) {
+bool URLIndexPrivateData::UpdateURL(const URLRow& row) {
// The row may or may not already be in our index. If it is not already
// indexed and it qualifies then it gets indexed. If it is already
// indexed and still qualifies then it gets updated, otherwise it
@@ -349,8 +319,8 @@ bool URLIndexPrivateData::UpdateURL(
// This new row should be indexed if it qualifies.
URLRow new_row(row);
new_row.set_id(row_id);
- row_was_updated = RowQualifiesAsSignificant(new_row, base::Time()) &&
- IndexRow(new_row, languages, scheme_whitelist);
+ row_was_updated =
+ RowQualifiesAsSignificant(new_row, base::Time()) && IndexRow(new_row);
} else if (RowQualifiesAsSignificant(row, base::Time())) {
// This indexed row still qualifies and will be re-indexed.
// The url won't have changed but the title, visit count, etc.
@@ -371,7 +341,7 @@ bool URLIndexPrivateData::UpdateURL(
RemoveRowWordsFromIndex(row_to_update);
row_to_update.set_title(row.title());
RowWordStarts word_starts;
- AddRowWordsToIndex(row_to_update, &word_starts, languages);
+ AddRowWordsToIndex(row_to_update, &word_starts);
word_starts_map_[row_id] = word_starts;
}
row_was_updated = true;
@@ -413,6 +383,10 @@ bool URLIndexPrivateData::DeleteURL(const GURL& url) {
return true;
}
+bool URLIndexPrivateData::URLSchemeIsWhitelisted(const GURL& gurl) const {
+ return scheme_whitelist_.find(gurl.scheme()) != scheme_whitelist_.end();
+}
+
// URLIndexPrivateData::HistoryItemFactorGreater -------------------------------
URLIndexPrivateData::HistoryItemFactorGreater::HistoryItemFactorGreater(
@@ -931,19 +905,24 @@ WordIDSet URLIndexPrivateData::WordIDSetForTermChars(
return word_id_set;
}
-// Cache Saving ----------------------------------------------------------------
-
// static
-void URLIndexPrivateData::WritePrivateDataToCacheFileTask(
- scoped_refptr<URLIndexPrivateData> private_data,
- const FilePath& file_path,
- scoped_refptr<RefCountedBool> succeeded) {
- DCHECK(private_data.get());
- DCHECK(!file_path.empty());
- succeeded->set_value(private_data->SaveToFile(file_path));
+void URLIndexPrivateData::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));
}
+// Cache Saving ----------------------------------------------------------------
+
bool URLIndexPrivateData::SaveToFile(const FilePath& file_path) {
+ // TODO(mrossetti): Move File IO to another thread.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
base::TimeTicks beginning_time = base::TimeTicks::Now();
InMemoryURLIndexCacheItem index_cache;
SavePrivateData(&index_cache);
@@ -1051,7 +1030,8 @@ void URLIndexPrivateData::SaveHistoryInfoMap(
map_entry->set_history_id(iter->first);
const URLRow& url_row(iter->second);
// Note: We only save information that contributes to the index so there
- // is no need to save search_term_cache_ (not persistent).
+ // is no need to save search_term_cache_ (not persistent),
+ // languages_, etc.
map_entry->set_visit_count(url_row.visit_count());
map_entry->set_typed_count(url_row.typed_count());
map_entry->set_last_visit(url_row.last_visit().ToInternalValue());
@@ -1090,68 +1070,60 @@ void URLIndexPrivateData::SaveWordStartsMap(
// Cache Restoring -------------------------------------------------------------
-// static
-void URLIndexPrivateData::RestoreFromFileTask(
- const FilePath& file_path,
- scoped_refptr<URLIndexPrivateData> private_data,
- std::string languages) {
- private_data = URLIndexPrivateData::RestoreFromFile(file_path, languages);
-}
+bool URLIndexPrivateData::RestoreFromFile(const FilePath& file_path) {
+ // TODO(mrossetti): Figure out how to determine if the cache is up-to-date.
+ // That is: ensure that the database has not been modified since the cache
+ // was last saved. DB file modification date is inadequate. There are no
+ // SQLite table checksums automatically stored.
+ Clear(); // Start with a clean slate.
-// static
-scoped_refptr<URLIndexPrivateData> URLIndexPrivateData::RestoreFromFile(
- const FilePath& file_path,
- const std::string& languages) {
+ // FIXME(mrossetti): Move File IO to another thread.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
base::TimeTicks beginning_time = base::TimeTicks::Now();
if (!file_util::PathExists(file_path))
- return NULL;
+ return false;
std::string data;
// If there is no cache file then simply give up. This will cause us to
// attempt to rebuild from the history database.
if (!file_util::ReadFileToString(file_path, &data))
- return NULL;
+ return false;
- scoped_refptr<URLIndexPrivateData> restored_data(new URLIndexPrivateData);
InMemoryURLIndexCacheItem index_cache;
if (!index_cache.ParseFromArray(data.c_str(), data.size())) {
- LOG(WARNING) << "Failed to parse URLIndexPrivateData cache data read from "
+ LOG(WARNING) << "Failed to parse InMemoryURLIndex cache data read from "
<< file_path.value();
- return restored_data;
+ return false;
}
- if (!restored_data->RestorePrivateData(index_cache, languages))
- return NULL;
+ if (!RestorePrivateData(index_cache)) {
+ Clear(); // Back to square one -- must build from scratch.
+ return false;
+ }
UMA_HISTOGRAM_TIMES("History.InMemoryURLIndexRestoreCacheTime",
base::TimeTicks::Now() - beginning_time);
UMA_HISTOGRAM_COUNTS("History.InMemoryURLHistoryItems",
- restored_data->history_id_word_map_.size());
+ history_id_word_map_.size());
UMA_HISTOGRAM_COUNTS("History.InMemoryURLCacheSize", data.size());
- UMA_HISTOGRAM_COUNTS_10000("History.InMemoryURLWords",
- restored_data->word_map_.size());
- UMA_HISTOGRAM_COUNTS_10000("History.InMemoryURLChars",
- restored_data->char_word_map_.size());
- if (restored_data->Empty())
- return NULL; // 'No data' is the same as a failed reload.
- return restored_data;
+ UMA_HISTOGRAM_COUNTS_10000("History.InMemoryURLWords", word_map_.size());
+ UMA_HISTOGRAM_COUNTS_10000("History.InMemoryURLChars", char_word_map_.size());
+ return true;
}
// static
-scoped_refptr<URLIndexPrivateData> URLIndexPrivateData::RebuildFromHistory(
- HistoryDatabase* history_db,
- const std::string& languages,
- const std::set<std::string>& scheme_whitelist) {
+URLIndexPrivateData* URLIndexPrivateData::RebuildFromHistory(
+ HistoryDatabase* history_db) {
if (!history_db)
return NULL;
base::TimeTicks beginning_time = base::TimeTicks::Now();
- scoped_refptr<URLIndexPrivateData> rebuilt_data(new URLIndexPrivateData);
+ scoped_ptr<URLIndexPrivateData> rebuilt_data(new URLIndexPrivateData);
URLDatabase::URLEnumerator history_enum;
if (!history_db->InitURLEnumeratorForSignificant(&history_enum))
return NULL;
for (URLRow row; history_enum.GetNextURL(&row); )
- rebuilt_data->IndexRow(row, languages, scheme_whitelist);
+ rebuilt_data->IndexRow(row);
UMA_HISTOGRAM_TIMES("History.InMemoryURLIndexingTime",
base::TimeTicks::Now() - beginning_time);
@@ -1161,17 +1133,16 @@ scoped_refptr<URLIndexPrivateData> URLIndexPrivateData::RebuildFromHistory(
rebuilt_data->word_map_.size());
UMA_HISTOGRAM_COUNTS_10000("History.InMemoryURLChars",
rebuilt_data->char_word_map_.size());
- return rebuilt_data;
+ return rebuilt_data.release();
}
bool URLIndexPrivateData::RestorePrivateData(
- const InMemoryURLIndexCacheItem& cache,
- const std::string& languages) {
+ const InMemoryURLIndexCacheItem& cache) {
if (cache.has_version())
restored_cache_version_ = cache.version();
return RestoreWordList(cache) && RestoreWordMap(cache) &&
RestoreCharWordMap(cache) && RestoreWordIDHistoryMap(cache) &&
- RestoreHistoryInfoMap(cache) && RestoreWordStartsMap(cache, languages);
+ RestoreHistoryInfoMap(cache) && RestoreWordStartsMap(cache);
}
bool URLIndexPrivateData::RestoreWordList(
@@ -1293,8 +1264,7 @@ bool URLIndexPrivateData::RestoreHistoryInfoMap(
}
bool URLIndexPrivateData::RestoreWordStartsMap(
- const InMemoryURLIndexCacheItem& cache,
- const std::string& languages) {
+ const InMemoryURLIndexCacheItem& cache) {
// Note that this function must be called after RestoreHistoryInfoMap() has
// been run as the word starts may have to be recalculated from the urls and
// page titles.
@@ -1329,7 +1299,7 @@ bool URLIndexPrivateData::RestoreWordStartsMap(
iter != history_info_map_.end(); ++iter) {
RowWordStarts word_starts;
const URLRow& row(iter->second);
- string16 url(net::FormatUrl(row.url(), languages,
+ string16 url(net::FormatUrl(row.url(), languages_,
net::kFormatUrlOmitUsernamePassword,
net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS,
NULL, NULL, NULL));
@@ -1343,11 +1313,4 @@ bool URLIndexPrivateData::RestoreWordStartsMap(
return true;
}
-// static
-bool URLIndexPrivateData::URLSchemeIsWhitelisted(
- const GURL& gurl,
- const std::set<std::string>& whitelist) {
- return whitelist.find(gurl.scheme()) != whitelist.end();
-}
-
} // namespace history
diff --git a/chrome/browser/history/url_index_private_data.h b/chrome/browser/history/url_index_private_data.h
index 96669f2..92d4731 100644
--- a/chrome/browser/history/url_index_private_data.h
+++ b/chrome/browser/history/url_index_private_data.h
@@ -8,10 +8,8 @@
#include "base/file_path.h"
#include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
#include "chrome/browser/history/in_memory_url_index_types.h"
#include "chrome/browser/history/in_memory_url_index_cache.pb.h"
-#include "content/public/browser/notification_details.h"
class HistoryQuickProviderTest;
@@ -24,23 +22,18 @@ namespace history {
namespace imui = in_memory_url_index;
class HistoryDatabase;
-class InMemoryURLIndex;
-class RefCountedBool;
// Current version of the cache file.
static const int kCurrentCacheFileVersion = 1;
// A structure describing the InMemoryURLIndex's internal data and providing for
// restoring, rebuilding and updating that internal data.
-class URLIndexPrivateData
- : public base::RefCountedThreadSafe<URLIndexPrivateData> {
+class URLIndexPrivateData {
public:
URLIndexPrivateData();
-
- private:
- friend class base::RefCountedThreadSafe<URLIndexPrivateData>;
~URLIndexPrivateData();
+ private:
friend class AddHistoryMatch;
friend class ::HistoryQuickProviderTest;
friend class InMemoryURLIndex;
@@ -136,54 +129,28 @@ class URLIndexPrivateData
// to this function.
ScoredHistoryMatches HistoryItemsForTerms(const string16& term_string);
- // Creates a new URLIndexPrivateData object, populates it from the contents
- // of the cache file stored in |file_path|, and assigns it to |private_data|.
- // |languages| will be used to break URLs and page titles into words and is
- // deliberately passed by value.
- static void RestoreFromFileTask(
- const FilePath& file_path,
- scoped_refptr<URLIndexPrivateData> private_data,
- std::string languages);
-
- // Constructs a new object by restoring its contents from the file at |path|.
- // Returns the new URLIndexPrivateData which on success will contain the
- // restored data but upon failure will be empty. |languages| will be used to
- // break URLs and page titles into words
- static scoped_refptr<URLIndexPrivateData> RestoreFromFile(
- const FilePath& path,
- const std::string& languages);
+ // Sets the |languages| to a list of language encodings with which the history
+ // URLs and omnibox searches are interpreted, i.e. how each is broken
+ // down into words and each word is broken down into characters.
+ void set_languages(const std::string& languages) { languages_ = languages; }
+
+ // Restores the index's private data from the cache file stored in the
+ // profile directory and returns true if successful.
+ bool RestoreFromFile(const FilePath& file_path);
// Constructs a new object by rebuilding its contents from the history
// database in |history_db|. Returns the new URLIndexPrivateData which on
// success will contain the rebuilt data but upon failure will be empty.
- // |languages| gives a list of language encodings by which the URLs and page
- // titles are broken down into words and characters.
- static scoped_refptr<URLIndexPrivateData> RebuildFromHistory(
- HistoryDatabase* history_db,
- const std::string& languages,
- const std::set<std::string>& scheme_whitelist);
-
- // Writes |private_data| as a cache file to |file_path| and returns success
- // via |succeeded|.
- static void WritePrivateDataToCacheFileTask(
- scoped_refptr<URLIndexPrivateData> private_data,
- const FilePath& file_path,
- scoped_refptr<RefCountedBool> succeeded);
+ static URLIndexPrivateData* RebuildFromHistory(HistoryDatabase* history_db);
// Caches the index private data and writes the cache file to the profile
- // directory. Called by WritePrivateDataToCacheFileTask.
+ // directory.
bool SaveToFile(const FilePath& file_path);
// Initializes all index data members in preparation for restoring the index
// from the cache or a complete rebuild from the history database.
void Clear();
- // Returns true if there is no data in the index.
- bool Empty() const;
-
- // Creates a copy of ourself.
- scoped_refptr<URLIndexPrivateData> Duplicate() const;
-
// Adds |word_id| to |history_id|'s entry in the history/word map,
// creating a new entry if one does not already exist.
void AddToHistoryIDWordMap(HistoryID history_id, WordID word_id);
@@ -191,26 +158,21 @@ class URLIndexPrivateData
// Given a set of Char16s, finds words containing those characters.
WordIDSet WordIDSetForTermChars(const Char16Set& term_chars);
+ // Initializes the whitelist of URL schemes.
+ static void InitializeSchemeWhitelist(std::set<std::string>* whitelist);
+
// URL History indexing support functions.
// Indexes one URL history item as described by |row|. Returns true if the
- // row was actually indexed. |languages| gives a list of language encodings by
- // which the URLs and page titles are broken down into words and characters.
- // |scheme_whitelist| is used to filter non-qualifying schemes.
- bool IndexRow(const URLRow& row,
- const std::string& languages,
- const std::set<std::string>& scheme_whitelist);
+ // row was actually indexed.
+ bool IndexRow(const URLRow& row);
// Adds the history item in |row| to the index if it does not already already
// exist and it meets the minimum 'quick' criteria. If the row already exists
// in the index then the index will be updated if the row still meets the
// criteria, otherwise the row will be removed from the index. Returns true
- // if the index was actually updated. |languages| gives a list of language
- // encodings by which the URLs and page titles are broken down into words and
- // characters. |scheme_whitelist| is used to filter non-qualifying schemes.
- bool UpdateURL(const URLRow& row,
- const std::string& languages,
- const std::set<std::string>& scheme_whitelist);
+ // if the index was actually updated.
+ bool UpdateURL(const URLRow& row);
// Deletes indexing data for the history item with the URL given in |url|.
// The item may not have actually been indexed, which is the case if it did
@@ -220,11 +182,7 @@ class URLIndexPrivateData
// Parses and indexes the words in the URL and page title of |row| and
// calculate the word starts in each, saving the starts in |word_starts|.
- // |languages| gives a list of language encodings by which the URLs and page
- // titles are broken down into words and characters.
- void AddRowWordsToIndex(const URLRow& row,
- RowWordStarts* word_starts,
- const std::string& languages);
+ void AddRowWordsToIndex(const URLRow& row, RowWordStarts* word_starts);
// Removes |row| and all associated words and characters from the index.
void RemoveRowFromIndex(const URLRow& row);
@@ -277,6 +235,13 @@ class URLIndexPrivateData
static int ScoreComponentForMatches(const TermMatches& matches,
size_t max_length);
+ // Determines if |gurl| has a whitelisted scheme and returns true if so.
+ bool URLSchemeIsWhitelisted(const GURL& gurl) const;
+
+ // Sets the version of the cache file that will be saved when calling
+ // SavePrivateData(). For unit testing only.
+ void set_saved_cache_version(int version) { saved_cache_version_ = version; }
+
// Encode a data structure into the protobuf |cache|.
void SavePrivateData(imui::InMemoryURLIndexCacheItem* cache) const;
void SaveWordList(imui::InMemoryURLIndexCacheItem* cache) const;
@@ -287,25 +252,24 @@ class URLIndexPrivateData
void SaveWordStartsMap(imui::InMemoryURLIndexCacheItem* cache) const;
// Decode a data structure from the protobuf |cache|. Return false if there
- // is any kind of failure. |languages| will be used to break URLs and page
- // titles into words
- bool RestorePrivateData(const imui::InMemoryURLIndexCacheItem& cache,
- const std::string& languages);
+ // is any kind of failure.
+ bool RestorePrivateData(const imui::InMemoryURLIndexCacheItem& cache);
bool RestoreWordList(const imui::InMemoryURLIndexCacheItem& cache);
bool RestoreWordMap(const imui::InMemoryURLIndexCacheItem& cache);
bool RestoreCharWordMap(const imui::InMemoryURLIndexCacheItem& cache);
bool RestoreWordIDHistoryMap(const imui::InMemoryURLIndexCacheItem& cache);
bool RestoreHistoryInfoMap(const imui::InMemoryURLIndexCacheItem& cache);
- bool RestoreWordStartsMap(const imui::InMemoryURLIndexCacheItem& cache,
- const std::string& languages);
-
- // Determines if |gurl| has a whitelisted scheme and returns true if so.
- static bool URLSchemeIsWhitelisted(const GURL& gurl,
- const std::set<std::string>& whitelist);
+ bool RestoreWordStartsMap(const imui::InMemoryURLIndexCacheItem& cache);
// Cache of search terms.
SearchTermCacheMap search_term_cache_;
+ // Languages used during the word-breaking process during indexing.
+ std::string languages_;
+
+ // Only URLs with a whitelisted scheme are indexed.
+ std::set<std::string> scheme_whitelist_;
+
// Start of data members that are cached -------------------------------------
// The version of the cache file most recently used to restore this instance