Chromium Code Reviews| Index: chrome/browser/history/in_memory_url_index.h |
| =================================================================== |
| --- chrome/browser/history/in_memory_url_index.h (revision 117518) |
| +++ chrome/browser/history/in_memory_url_index.h (working copy) |
| @@ -15,30 +15,29 @@ |
| #include "base/basictypes.h" |
| #include "base/file_path.h" |
| #include "base/gtest_prod_util.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" |
| +#include "chrome/browser/cancelable_request.h" |
| +#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 "chrome/browser/history/url_index_private_data.h" |
| -#include "sql/connection.h" |
| +#include "content/public/browser/notification_observer.h" |
| +#include "content/public/browser/notification_registrar.h" |
| +#include "testing/gtest/include/gtest/gtest_prod.h" |
| -namespace base { |
| -class Time; |
| -} |
| +class HistoryQuickProviderTest; |
| +class Profile; |
| -namespace in_memory_url_index { |
| -class InMemoryURLIndexCacheItem; |
| -} |
| - |
| namespace history { |
| -namespace imui = in_memory_url_index; |
| - |
| +class InMemoryURLIndexTest; |
| class URLDatabase; |
| +class URLIndexPrivateData; |
| +struct URLVisitedDetails; |
| +struct URLsModifiedDetails; |
| +struct URLsDeletedDetails; |
| // The URL history source. |
| // Holds portions of the URL database in memory in an indexed form. Used to |
| @@ -59,48 +58,85 @@ |
| // 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 { |
| +class InMemoryURLIndex : public base::RefCountedThreadSafe<InMemoryURLIndex>, |
|
Peter Kasting
2012/01/14 00:12:49
We chatted some in IM about avoiding this by vendi
mrossetti
2012/03/03 05:05:56
Done. Notifications are now employed.
|
| + public content::NotificationObserver { |
| public: |
| - // |history_dir| is a path to the directory containing the history database |
| - // within the profile wherein the cache and transaction journals will be |
| - // stored. |
| - explicit InMemoryURLIndex(const FilePath& history_dir); |
| + // 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. |
| + virtual void OnCacheSaveFinished() = 0; // Is called on the IO thread. |
|
Peter Kasting
2012/01/14 00:12:49
Nit: Since this is subtle, it might make sense to
mrossetti
2012/03/03 05:05:56
This has been postponed to the next CL when the FI
|
| + |
| + // Callback that lets the observer know that the save failed. |
| + virtual void OnCacheSaveFailed() = 0; // Is called on the UI thread. |
| + }; |
| + |
| + // |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 |
| + // journals will be stored. |
| + InMemoryURLIndex(Profile* profile, const FilePath& history_dir); |
| virtual ~InMemoryURLIndex(); |
| - // Opens and indexes the URL history database. If the index private data |
| - // cannot be restored from its cache file then it is rebuilt from the |
| - // |history_db|. |languages| gives a list of language encodings by which URLs |
| - // and omnibox searches are broken down into words and characters. |
| - bool Init(URLDatabase* history_db, const std::string& languages); |
| + // Opens and initializes the index from a cache file. If the cache file is |
| + // not present or empty then the index will eventually be rebuilt from the |
| + // history database associated with the profile. |languages| gives a list of |
| + // language encodings with which the history URLs and omnibox searches are |
| + // interpreted, i.e. when each is broken down into words and each word is |
| + // broken down into characters. |
| + void Init(const std::string& languages); |
| // Signals that any outstanding initialization should be canceled and |
| // flushes the cache to disk. |
| void ShutDown(); |
| - // Reloads the history index from |history_db| ignoring any cache file that |
| - // may be available, clears the cache and saves the cache after reloading. |
| - bool ReloadFromHistory(history::URLDatabase* history_db); |
| - |
| // Scans the history index and returns a vector with all scored, matching |
| // history items. This entry point simply forwards the call on to the |
| // URLIndexPrivateData class. For a complete description of this function |
| // refer to that class. |
| ScoredHistoryMatches HistoryItemsForTerms(const string16& term_string); |
| - // Updates or adds an history item to the index if it meets the minimum |
| - // 'quick' criteria. |
| - void UpdateURL(URLID row_id, const URLRow& row); |
| + // 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; |
| + } |
| - // Deletes indexing data for an history item. The item may not have actually |
| - // been indexed (which is the case if it did not previously meet minimum |
| - // 'quick' criteria). |
| - void DeleteURL(URLID row_id); |
| + // Forwards to the URLIndexPrivateData. For unit testing only. |
| + void UpdateURL(const URLRow& row); |
| + void DeleteURL(const GURL& url); |
| private: |
| - friend class InMemoryURLIndexTest; |
| + friend class HistoryQuickProviderTest; |
| + FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, AddNewRows); |
|
Peter Kasting
2012/01/14 00:12:49
Nit: Does it make sense to build some base class f
mrossetti
2012/03/03 05:05:56
Done.
|
| FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, CacheFilePath); |
| + FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, DeleteRows); |
| FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, CacheSaveRestore); |
| FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, HugeResultSet); |
| + FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, NonUniqueTermCharacterSets); |
| + FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, ProperStringMatching); |
| + FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, Retrieval); |
| + FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, TitleChange); |
| FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, TitleSearch); |
| FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, TypedCharacterCaching); |
| FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, WhitelistedURLs); |
| @@ -109,16 +145,98 @@ |
| // Creating one of me without a history path is not allowed (tests excepted). |
| InMemoryURLIndex(); |
| + // HistoryDBTask used to rebuild our private data from the history database. |
| + class RebuildPrivateDataFromHistoryDBTask : public HistoryDBTask { |
| + public: |
| + // We take ownership of the |private_data|. |
|
Peter Kasting
2012/01/14 00:12:49
Nit: |private_data| is not a variable defined here
mrossetti
2012/03/03 05:05:56
Done.
|
| + explicit RebuildPrivateDataFromHistoryDBTask(InMemoryURLIndex* index); |
| + |
|
Peter Kasting
2012/01/14 00:12:49
Nit: No newline
mrossetti
2012/03/03 05:05:56
Done.
|
| + virtual ~RebuildPrivateDataFromHistoryDBTask(); |
| + |
| + virtual bool RunOnDBThread(HistoryBackend* backend, |
|
Peter Kasting
2012/01/14 00:12:49
Nit: Optional: "// HistoryDBTask"
|
| + history::HistoryDatabase* db) OVERRIDE; |
| + |
|
Peter Kasting
2012/01/14 00:12:49
Nit: Newline unnecessary
mrossetti
2012/03/03 05:05:56
Done.
|
| + virtual void DoneRunOnMainThread() OVERRIDE; |
| + |
| + private: |
| + InMemoryURLIndex* index_; // Call back to this index at completion. |
| + bool succeeded_; // Indicates if the rebuild was successful. |
| + scoped_ptr<URLIndexPrivateData> data_; // The rebuilt private data. |
| + |
| + DISALLOW_COPY_AND_ASSIGN(RebuildPrivateDataFromHistoryDBTask); |
| + }; |
| + |
| // Initializes all index data members in preparation for restoring the index |
| // from the cache or a complete rebuild from the history database. |
| void ClearPrivateData(); |
| + // Utility functions supporting RestoreFromCache and SaveToCache. |
| + |
| // Construct a file path for the cache file within the same directory where |
|
Peter Kasting
2012/01/14 00:12:49
Nit: Construct -> Constructs (while you're here)
mrossetti
2012/03/03 05:05:56
Done.
|
| // the history database is kept and saves that path to |file_path|. Returns |
| // true if |file_path| can be successfully constructed. (This function |
| // provided as a hook for unit testing.) |
| bool GetCacheFilePath(FilePath* file_path); |
| + // Restores the index's private data from the cache file stored in the |
| + // profile directory. |
| + void RestoreFromCacheFile(); |
| + |
| + // Restores private_data_ from the given |path|. Runs on the UI thread. |
|
Peter Kasting
2012/01/14 00:12:49
Nit: You might want an explicit comment here or ab
mrossetti
2012/03/03 05:05:56
Done.
|
| + void DoRestoreFromCacheFile(const FilePath& path); |
| + |
| + // Called by DoRestoreFromCacheFile and retrieves the private data from the |
| + // given |path|. If the restore fails then spawn a task to rebuild the |
| + // private data from the history database. |
| + void ReadPrivateDataFromCacheFile(const FilePath path); |
| + |
| + // Caches the index private data and writes the cache file to the profile |
| + // directory. |
| + void SaveToCacheFile(); |
| + |
| + // Saves private_data_ to the given |path|. Runs on the UI thread. |
| + void DoSaveToCacheFile(const FilePath& path); |
| + |
| + // Called by DoSaveToCacheFile and saves |private_data| to the given |path|. |
|
Peter Kasting
2012/01/14 00:12:49
Nit: and saves -> to save
mrossetti
2012/03/03 05:05:56
Postponed to the FILE/pool change.
|
| + // Runs on the FILE thread. |
| + void WritePrivateDataToCacheFile(const FilePath path, |
| + URLIndexPrivateData* private_data); |
| + |
| + // Called by DoSaveToCacheFile to delete any old cache file at |path| when |
| + // there is no private data to save. Runs on the FILE thread. |
| + static void DeleteCacheFile(const FilePath path); |
| + |
| + // 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. |
|
Peter Kasting
2012/01/14 00:12:49
Nit: Missing space
mrossetti
2012/03/03 05:05:56
Done.
|
| + void DoneRebuidingPrivateDataFromHistoryDB(bool succeeded, |
| + URLIndexPrivateData* data); |
| + |
| + // Callback function that sets the private data from the just-restored-from- |
| + // file |private_data| if |succeeded| otherwise clears the private data. |
| + // Notifies any |restore_cache_observer_| of success status. |
| + void OnCacheRestored(URLIndexPrivateData* private_data, bool succeeded); |
| + |
| + // Notifications ------------------------------------------------------------- |
|
Peter Kasting
2012/01/14 00:12:49
Nit: Kinda weird to have ---- here but not above (
mrossetti
2012/03/03 05:05:56
Done.
|
| + |
| + // Handle notifications of history loading, and all history changes. |
| + virtual void Observe(int notification_type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) OVERRIDE; |
| + |
| + // Notification handlers. |
| + void OnURLVisited(const URLVisitedDetails* details); |
| + void OnURLsModified(const URLsModifiedDetails* details); |
| + void OnURLsDeleted(const URLsDeletedDetails* details); |
| + |
| + // Rebuilds the history index from the history database in |history_db|. |
| + // Used for unit testing only. |
| + void RebuildFromHistory(URLDatabase* history_db); |
| + |
| + // The profile, may be null when testing. |
| + Profile* profile_; |
| + |
| // Directory where cache file resides. This is, except when unit testing, |
| // the same directory in which the profile's history database is found. It |
| // should never be empty. |
| @@ -127,12 +245,25 @@ |
| // The index's durable private data. |
| scoped_ptr<URLIndexPrivateData> private_data_; |
| - // Set to true at shutdown when the cache has been written to disk. Used |
| - // as a temporary safety check to insure that the cache is saved before |
| - // the index has been destructed. |
| + // Observers to notify upon restoral or save of the private data cache. |
|
Peter Kasting
2012/01/14 00:12:49
Nit: restoral or save -> restoration or saving
mrossetti
2012/03/03 05:05:56
Postponed to the FILE/pool change.
|
| + RestoreCacheObserver* restore_cache_observer_; |
| + SaveCacheObserver* save_cache_observer_; |
| + |
| + CancelableRequestConsumer cache_reader_consumer_; |
| + |
| + // Remember to unregister from notifications on destruction. |
|
Peter Kasting
2012/01/14 00:12:49
Nit: Comment unnecessary
mrossetti
2012/03/03 05:05:56
Done.
|
| + 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 |
| + // index has been destructed. |
| // TODO(mrossetti): Eliminate once the transition to SQLite has been done. |
| // http://crbug.com/83659 |
| - bool cached_at_shutdown_; |
| + bool needs_to_be_cached_; |
| DISALLOW_COPY_AND_ASSIGN(InMemoryURLIndex); |
| }; |