| Index: chrome/browser/history/in_memory_url_index.h
|
| ===================================================================
|
| --- chrome/browser/history/in_memory_url_index.h (revision 151481)
|
| +++ chrome/browser/history/in_memory_url_index.h (working copy)
|
| @@ -16,7 +16,9 @@
|
| #include "base/gtest_prod_util.h"
|
| #include "base/memory/ref_counted.h"
|
| #include "base/memory/weak_ptr.h"
|
| +#include "base/observer_list.h"
|
| #include "base/string16.h"
|
| +#include "base/threading/sequenced_worker_pool.h"
|
| #include "chrome/browser/autocomplete/autocomplete_match.h"
|
| #include "chrome/browser/autocomplete/history_provider_util.h"
|
| #include "chrome/browser/cancelable_request.h"
|
| @@ -24,6 +26,7 @@
|
| #include "chrome/browser/history/history_types.h"
|
| #include "chrome/browser/history/in_memory_url_index_types.h"
|
| #include "chrome/browser/history/scored_history_match.h"
|
| +#include "chrome/browser/history/url_index_private_data.h"
|
| #include "content/public/browser/notification_observer.h"
|
| #include "content/public/browser/notification_registrar.h"
|
| #include "sql/connection.h"
|
| @@ -35,19 +38,13 @@
|
| class Time;
|
| }
|
|
|
| -namespace in_memory_url_index {
|
| -class InMemoryURLIndexCacheItem;
|
| -}
|
| -
|
| namespace history {
|
|
|
| -namespace imui = in_memory_url_index;
|
| -
|
| -class HistoryDatabase;
|
| -class URLIndexPrivateData;
|
| +class InMemoryURLIndexObserver;
|
| +class URLDatabase;
|
| +struct URLsDeletedDetails;
|
| +struct URLsModifiedDetails;
|
| struct URLVisitedDetails;
|
| -struct URLsModifiedDetails;
|
| -struct URLsDeletedDetails;
|
|
|
| // The URL history source.
|
| // Holds portions of the URL database in memory in an indexed form. Used to
|
| @@ -68,31 +65,27 @@
|
| // 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 {
|
| + // Observer is used for blocking until the InMemoryURLIndex has finished
|
| + // loading. Usage typically follows this pattern:
|
| + // InMemoryURLIndex::Observer observer(index); // Create observer.
|
| + // MessageLoop::current()->Run(); // Blocks until loaded.
|
| + //
|
| + class Observer {
|
| public:
|
| - virtual ~RestoreCacheObserver();
|
| + explicit Observer(InMemoryURLIndex* index);
|
|
|
| - // 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;
|
| - };
|
| + // Called when the InMemoryURLIndex has completed loading.
|
| + virtual void Loaded();
|
|
|
| - // 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();
|
| + private:
|
| + friend class InMemoryURLIndexBaseTest;
|
| + virtual ~Observer();
|
|
|
| - // Callback that lets the observer know that the save succeeded.
|
| - // This is called on the UI thread.
|
| - virtual void OnCacheSaveFinished(bool succeeded) = 0;
|
| + InMemoryURLIndex* index_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Observer);
|
| };
|
|
|
| // |profile|, which may be NULL during unit testing, is used to register for
|
| @@ -106,46 +99,44 @@
|
| virtual ~InMemoryURLIndex();
|
|
|
| // Opens and prepares the index of historical URL visits. If the index private
|
| - // data cannot be restored from its cache file then it is rebuilt from the
|
| - // history database.
|
| - void Init();
|
| + // data cannot be restored from its cache database then it is rebuilt from the
|
| + // history database. |disable_cache| causes the InMemoryURLIndex to not create
|
| + // or use its cache database.
|
| + void Init(bool disable_cache);
|
|
|
| - // Signals that any outstanding initialization should be canceled and
|
| - // flushes the cache to disk.
|
| - void ShutDown();
|
| + // Signals that any outstanding initialization should be canceled.
|
| + void Shutdown();
|
|
|
| + // Returns true if the index has been loaded or rebuilt and so is available
|
| + // for use.
|
| + bool index_available() const { return index_available_; }
|
| +
|
| // 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);
|
|
|
| - // 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 the index entry, if any, for the given |url|.
|
| + void DeleteURL(const GURL& url);
|
|
|
| private:
|
| friend class ::HistoryQuickProviderTest;
|
| + friend class InMemoryURLIndex::Observer;
|
| + friend class InMemoryURLIndexCacheTest;
|
| friend class InMemoryURLIndexTest;
|
| - friend class InMemoryURLIndexCacheTest;
|
| + friend class InMemoryURLIndexBaseTest;
|
| + friend class IntercessionaryIndexTest;
|
| + FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, ExpireRow);
|
| + FRIEND_TEST_ALL_PREFIXES(IntercessionaryIndexTest, CacheDatabaseFailure);
|
| + FRIEND_TEST_ALL_PREFIXES(IntercessionaryIndexTest,
|
| + ShutdownDuringCacheRefresh);
|
| FRIEND_TEST_ALL_PREFIXES(LimitedInMemoryURLIndexTest, Initialization);
|
|
|
| - // 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:
|
| - explicit RebuildPrivateDataFromHistoryDBTask(
|
| - InMemoryURLIndex* index,
|
| - const std::string& languages,
|
| - const std::set<std::string>& scheme_whitelist);
|
| + explicit RebuildPrivateDataFromHistoryDBTask(InMemoryURLIndex* index);
|
|
|
| virtual bool RunOnDBThread(HistoryBackend* backend,
|
| history::HistoryDatabase* db) OVERRIDE;
|
| @@ -155,28 +146,57 @@
|
| virtual ~RebuildPrivateDataFromHistoryDBTask();
|
|
|
| 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.
|
|
|
| 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();
|
| + // For unit testing only.
|
| + InMemoryURLIndex(const FilePath& history_dir, const std::string& languages);
|
|
|
| - // Constructs a file path for the cache file within the same directory where
|
| - // 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);
|
| + // Completes index initialization once the cache DB has been initialized.
|
| + void OnPrivateDataInitDone(bool succeeded);
|
|
|
| - // Restores the index's private data from the cache file stored in the
|
| - // profile directory.
|
| - void PostRestoreFromCacheFileTask();
|
| + // Adds or removes an observer that is notified when the index has been
|
| + // loaded.
|
| + void AddObserver(InMemoryURLIndex::Observer* observer);
|
| + void RemoveObserver(InMemoryURLIndex::Observer* observer);
|
|
|
| + // Handles notifications of 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);
|
| +
|
| + // Posts any outstanding updates to the index which were queued while the
|
| + // index was being initialized.
|
| + void FlushPendingUpdates();
|
| +
|
| + // Restores the index's private data from the cache database stored in the
|
| + // profile directory. If no database is found or can be restored then look
|
| + // for an old version protobuf-based cache file.
|
| + void PostRestoreFromCacheTask();
|
| +
|
| + // Determines if the private data was successfully restored from the cache
|
| + // database, as indicated by |succeeded|, or if the private data must be
|
| + // rebuilt from the history database. If successful, notifies any
|
| + // |restore_cache_observer_|. Otherwise, kicks off a rebuild from the history
|
| + // database.
|
| + void OnCacheRestoreDone(bool succeeded);
|
| +
|
| + // Notifies all observers that the index has been loaded or rebuilt.
|
| + void NotifyHasLoaded();
|
| +
|
| + // Rebuilds the index from the history database if the history database has
|
| + // been loaded, otherwise registers for the history loaded notification so
|
| + // that the rebuild can take place at a later time.
|
| + void RebuildFromHistoryIfLoaded();
|
| +
|
| // Schedules a history task to rebuild our private data from the history
|
| // database.
|
| void ScheduleRebuildFromHistory();
|
| @@ -189,90 +209,77 @@
|
| bool succeeded,
|
| scoped_refptr<URLIndexPrivateData> private_data);
|
|
|
| - // Rebuilds the history index from the history database in |history_db|.
|
| - // Used for unit testing only.
|
| - void RebuildFromHistory(HistoryDatabase* history_db);
|
| + // Posts a task to completely reset the private data and the backing cache.
|
| + void PostResetPrivateDataTask();
|
|
|
| - // 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);
|
| + // Posts a task to completely replace the cache database with a current
|
| + // image of the index private data.
|
| + void PostRefreshCacheTask();
|
|
|
| - // 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);
|
| + // Callback used by PostRefreshCacheTask and PostResetPrivateDataTask to
|
| + // notify observers that the cache database contents have been refreshed or
|
| + // reset and that the loading of the index is complete.
|
| + void OnCacheRefreshOrResetDone();
|
|
|
| - // Posts a task to cache the index private data and write the cache file to
|
| - // the profile directory.
|
| - void PostSaveToCacheFileTask();
|
| + // Attempts to refresh the cache database in response to a notification that
|
| + // an update transaction has failed. If the refresh fails then the cache
|
| + // database is ignored and an attempt will be made to rebuild the cache
|
| + // the next time the associated profile is opened.
|
| + void RepairCacheDatabase();
|
|
|
| - // 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);
|
| + // Returns a pointer to our private data.
|
| + scoped_refptr<URLIndexPrivateData> private_data() { return private_data_; }
|
|
|
| - // 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);
|
| + // Returns the blocking pool sequence token.
|
| + base::SequencedWorkerPool::SequenceToken sequence_token_for_testing() {
|
| + return sequence_token_;
|
| + }
|
|
|
| - // Handles notifications of 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);
|
| -
|
| - // 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; }
|
| -
|
| - // 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_;
|
|
|
| - // 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.
|
| - 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_;
|
| + // Directory where cache database or protobuf-based cache file resides.
|
| + // This is, except when unit testing, the same directory in which the
|
| + // profile's history database is found.
|
| + FilePath history_dir_;
|
|
|
| // The index's durable private data.
|
| scoped_refptr<URLIndexPrivateData> private_data_;
|
|
|
| - // Observers to notify upon restoral or save of the private data cache.
|
| - RestoreCacheObserver* restore_cache_observer_;
|
| - SaveCacheObserver* save_cache_observer_;
|
| + // Sequence token for coordinating database tasks. This is shared with
|
| + // our private data and its cache database.
|
| + const base::SequencedWorkerPool::SequenceToken sequence_token_;
|
|
|
| + bool index_available_; // True when index is available for updating.
|
| +
|
| + // Contains index updates queued up while the index is unavailable. This
|
| + // usually during profile startup.
|
| + enum UpdateType { UPDATE_VISIT, DELETE_VISIT };
|
| +
|
| + struct IndexUpdateItem {
|
| + IndexUpdateItem(UpdateType update_type, URLRow row);
|
| + ~IndexUpdateItem();
|
| +
|
| + UpdateType update_type;
|
| + URLRow row; // The row to be updated or deleted.
|
| + };
|
| + typedef std::vector<IndexUpdateItem> PendingUpdates;
|
| + PendingUpdates pending_updates_;
|
| +
|
| + ObserverList<InMemoryURLIndex::Observer> observers_;
|
| +
|
| 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
|
| - // index has been destructed.
|
| - // TODO(mrossetti): Eliminate once the transition to SQLite has been done.
|
| - // http://crbug.com/83659
|
| - bool needs_to_be_cached_;
|
| + // Note: This should remain the last member so it'll be destroyed and
|
| + // invalidate its weak pointers before any other members are destroyed.
|
| + base::WeakPtrFactory<InMemoryURLIndex> weak_ptr_factory_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(InMemoryURLIndex);
|
| };
|
|
|