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

Side by Side Diff: chrome/browser/history/in_memory_url_index.h

Issue 10872032: Revert 152946 - Replace HistoryQuickProvider protobuf-based caching with an SQLite-based database. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CHROME_BROWSER_HISTORY_IN_MEMORY_URL_INDEX_H_ 5 #ifndef CHROME_BROWSER_HISTORY_IN_MEMORY_URL_INDEX_H_
6 #define CHROME_BROWSER_HISTORY_IN_MEMORY_URL_INDEX_H_ 6 #define CHROME_BROWSER_HISTORY_IN_MEMORY_URL_INDEX_H_
7 7
8 #include <functional> 8 #include <functional>
9 #include <map> 9 #include <map>
10 #include <set> 10 #include <set>
11 #include <string> 11 #include <string>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/basictypes.h" 14 #include "base/basictypes.h"
15 #include "base/file_path.h" 15 #include "base/file_path.h"
16 #include "base/gtest_prod_util.h" 16 #include "base/gtest_prod_util.h"
17 #include "base/memory/ref_counted.h" 17 #include "base/memory/ref_counted.h"
18 #include "base/memory/weak_ptr.h" 18 #include "base/memory/weak_ptr.h"
19 #include "base/observer_list.h"
20 #include "base/string16.h" 19 #include "base/string16.h"
21 #include "base/threading/sequenced_worker_pool.h"
22 #include "chrome/browser/autocomplete/autocomplete_match.h" 20 #include "chrome/browser/autocomplete/autocomplete_match.h"
23 #include "chrome/browser/autocomplete/history_provider_util.h" 21 #include "chrome/browser/autocomplete/history_provider_util.h"
24 #include "chrome/browser/cancelable_request.h" 22 #include "chrome/browser/cancelable_request.h"
25 #include "chrome/browser/history/history.h" 23 #include "chrome/browser/history/history.h"
26 #include "chrome/browser/history/history_types.h" 24 #include "chrome/browser/history/history_types.h"
27 #include "chrome/browser/history/in_memory_url_index_types.h" 25 #include "chrome/browser/history/in_memory_url_index_types.h"
28 #include "chrome/browser/history/scored_history_match.h" 26 #include "chrome/browser/history/scored_history_match.h"
29 #include "chrome/browser/history/url_index_private_data.h"
30 #include "content/public/browser/notification_observer.h" 27 #include "content/public/browser/notification_observer.h"
31 #include "content/public/browser/notification_registrar.h" 28 #include "content/public/browser/notification_registrar.h"
32 #include "sql/connection.h" 29 #include "sql/connection.h"
33 30
34 class HistoryQuickProviderTest; 31 class HistoryQuickProviderTest;
35 class Profile; 32 class Profile;
36 33
37 namespace base { 34 namespace base {
38 class Time; 35 class Time;
39 } 36 }
40 37
38 namespace in_memory_url_index {
39 class InMemoryURLIndexCacheItem;
40 }
41
41 namespace history { 42 namespace history {
42 43
43 class InMemoryURLIndexObserver; 44 namespace imui = in_memory_url_index;
44 class URLDatabase; 45
46 class HistoryDatabase;
47 class URLIndexPrivateData;
48 struct URLVisitedDetails;
49 struct URLsModifiedDetails;
45 struct URLsDeletedDetails; 50 struct URLsDeletedDetails;
46 struct URLsModifiedDetails;
47 struct URLVisitedDetails;
48 51
49 // The URL history source. 52 // The URL history source.
50 // Holds portions of the URL database in memory in an indexed form. Used to 53 // Holds portions of the URL database in memory in an indexed form. Used to
51 // quickly look up matching URLs for a given query string. Used by 54 // quickly look up matching URLs for a given query string. Used by
52 // the HistoryURLProvider for inline autocomplete and to provide URL 55 // the HistoryURLProvider for inline autocomplete and to provide URL
53 // matches to the omnibox. 56 // matches to the omnibox.
54 // 57 //
55 // Note about multi-byte codepoints and the data structures in the 58 // Note about multi-byte codepoints and the data structures in the
56 // InMemoryURLIndex class: One will quickly notice that no effort is made to 59 // InMemoryURLIndex class: One will quickly notice that no effort is made to
57 // insure that multi-byte character boundaries are detected when indexing the 60 // insure that multi-byte character boundaries are detected when indexing the
58 // words and characters in the URL history database except when converting 61 // words and characters in the URL history database except when converting
59 // URL strings to lowercase. Multi-byte-edness makes no difference when 62 // URL strings to lowercase. Multi-byte-edness makes no difference when
60 // indexing or when searching the index as the final filtering of results 63 // indexing or when searching the index as the final filtering of results
61 // is dependent on the comparison of a string of bytes, not individual 64 // is dependent on the comparison of a string of bytes, not individual
62 // characters. While the lookup of those bytes during a search in the 65 // characters. While the lookup of those bytes during a search in the
63 // |char_word_map_| could serve up words in which the individual char16 66 // |char_word_map_| could serve up words in which the individual char16
64 // occurs as a portion of a composite character the next filtering step 67 // occurs as a portion of a composite character the next filtering step
65 // will eliminate such words except in the case where a single character 68 // will eliminate such words except in the case where a single character
66 // is being searched on and which character occurs as the second char16 of a 69 // is being searched on and which character occurs as the second char16 of a
67 // multi-char16 instance. 70 // multi-char16 instance.
68 class InMemoryURLIndex : public content::NotificationObserver { 71 class InMemoryURLIndex : public content::NotificationObserver,
72 public base::SupportsWeakPtr<InMemoryURLIndex> {
69 public: 73 public:
70 // Observer is used for blocking until the InMemoryURLIndex has finished 74 // Defines an abstract class which is notified upon completion of restoring
71 // loading. Usage typically follows this pattern: 75 // the index's private data either by reading from the cache file or by
72 // InMemoryURLIndex::Observer observer(index); // Create observer. 76 // rebuilding from the history database.
73 // MessageLoop::current()->Run(); // Blocks until loaded. 77 class RestoreCacheObserver {
74 //
75 class Observer {
76 public: 78 public:
77 explicit Observer(InMemoryURLIndex* index); 79 virtual ~RestoreCacheObserver();
78 80
79 // Called when the InMemoryURLIndex has completed loading. 81 // Callback that lets the observer know that the restore operation has
80 virtual void Loaded(); 82 // completed. |succeeded| indicates if the restore was successful. This is
83 // called on the UI thread.
84 virtual void OnCacheRestoreFinished(bool succeeded) = 0;
85 };
81 86
82 private: 87 // Defines an abstract class which is notified upon completion of saving
83 friend class InMemoryURLIndexBaseTest; 88 // the index's private data to the cache file.
84 virtual ~Observer(); 89 class SaveCacheObserver {
90 public:
91 virtual ~SaveCacheObserver();
85 92
86 InMemoryURLIndex* index_; 93 // Callback that lets the observer know that the save succeeded.
87 94 // This is called on the UI thread.
88 DISALLOW_COPY_AND_ASSIGN(Observer); 95 virtual void OnCacheSaveFinished(bool succeeded) = 0;
89 }; 96 };
90 97
91 // |profile|, which may be NULL during unit testing, is used to register for 98 // |profile|, which may be NULL during unit testing, is used to register for
92 // history changes. |history_dir| is a path to the directory containing the 99 // history changes. |history_dir| is a path to the directory containing the
93 // history database within the profile wherein the cache and transaction 100 // history database within the profile wherein the cache and transaction
94 // journals will be stored. |languages| gives a list of language encodings by 101 // journals will be stored. |languages| gives a list of language encodings by
95 // which URLs and omnibox searches are broken down into words and characters. 102 // which URLs and omnibox searches are broken down into words and characters.
96 InMemoryURLIndex(Profile* profile, 103 InMemoryURLIndex(Profile* profile,
97 const FilePath& history_dir, 104 const FilePath& history_dir,
98 const std::string& languages); 105 const std::string& languages);
99 virtual ~InMemoryURLIndex(); 106 virtual ~InMemoryURLIndex();
100 107
101 // Opens and prepares the index of historical URL visits. If the index private 108 // Opens and prepares the index of historical URL visits. If the index private
102 // data cannot be restored from its cache database then it is rebuilt from the 109 // data cannot be restored from its cache file then it is rebuilt from the
103 // history database. |disable_cache| causes the InMemoryURLIndex to not create 110 // history database.
104 // or use its cache database. 111 void Init();
105 void Init(bool disable_cache);
106 112
107 // Signals that any outstanding initialization should be canceled. 113 // Signals that any outstanding initialization should be canceled and
108 void Shutdown(); 114 // flushes the cache to disk.
109 115 void ShutDown();
110 // Returns true if the index has been loaded or rebuilt and so is available
111 // for use.
112 bool index_available() const { return index_available_; }
113 116
114 // Scans the history index and returns a vector with all scored, matching 117 // Scans the history index and returns a vector with all scored, matching
115 // history items. This entry point simply forwards the call on to the 118 // history items. This entry point simply forwards the call on to the
116 // URLIndexPrivateData class. For a complete description of this function 119 // URLIndexPrivateData class. For a complete description of this function
117 // refer to that class. 120 // refer to that class.
118 ScoredHistoryMatches HistoryItemsForTerms(const string16& term_string); 121 ScoredHistoryMatches HistoryItemsForTerms(const string16& term_string);
119 122
120 // Deletes the index entry, if any, for the given |url|. 123 // Sets the optional observers for completion of restoral and saving of the
121 void DeleteURL(const GURL& url); 124 // index's private data.
125 void set_restore_cache_observer(
126 RestoreCacheObserver* restore_cache_observer) {
127 restore_cache_observer_ = restore_cache_observer;
128 }
129 void set_save_cache_observer(SaveCacheObserver* save_cache_observer) {
130 save_cache_observer_ = save_cache_observer;
131 }
122 132
123 private: 133 private:
124 friend class ::HistoryQuickProviderTest; 134 friend class ::HistoryQuickProviderTest;
125 friend class InMemoryURLIndex::Observer; 135 friend class InMemoryURLIndexTest;
126 friend class InMemoryURLIndexCacheTest; 136 friend class InMemoryURLIndexCacheTest;
127 friend class InMemoryURLIndexTest;
128 friend class InMemoryURLIndexBaseTest;
129 friend class IntercessionaryIndexTest;
130 FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, ExpireRow);
131 FRIEND_TEST_ALL_PREFIXES(IntercessionaryIndexTest, CacheDatabaseFailure);
132 FRIEND_TEST_ALL_PREFIXES(IntercessionaryIndexTest,
133 ShutdownDuringCacheRefresh);
134 FRIEND_TEST_ALL_PREFIXES(LimitedInMemoryURLIndexTest, Initialization); 137 FRIEND_TEST_ALL_PREFIXES(LimitedInMemoryURLIndexTest, Initialization);
135 138
139 // Creating one of me without a history path is not allowed (tests excepted).
140 InMemoryURLIndex();
141
136 // HistoryDBTask used to rebuild our private data from the history database. 142 // HistoryDBTask used to rebuild our private data from the history database.
137 class RebuildPrivateDataFromHistoryDBTask : public HistoryDBTask { 143 class RebuildPrivateDataFromHistoryDBTask : public HistoryDBTask {
138 public: 144 public:
139 explicit RebuildPrivateDataFromHistoryDBTask(InMemoryURLIndex* index); 145 explicit RebuildPrivateDataFromHistoryDBTask(
146 InMemoryURLIndex* index,
147 const std::string& languages,
148 const std::set<std::string>& scheme_whitelist);
140 149
141 virtual bool RunOnDBThread(HistoryBackend* backend, 150 virtual bool RunOnDBThread(HistoryBackend* backend,
142 history::HistoryDatabase* db) OVERRIDE; 151 history::HistoryDatabase* db) OVERRIDE;
143 virtual void DoneRunOnMainThread() OVERRIDE; 152 virtual void DoneRunOnMainThread() OVERRIDE;
144 153
145 private: 154 private:
146 virtual ~RebuildPrivateDataFromHistoryDBTask(); 155 virtual ~RebuildPrivateDataFromHistoryDBTask();
147 156
148 InMemoryURLIndex* index_; // Call back to this index at completion. 157 InMemoryURLIndex* index_; // Call back to this index at completion.
158 std::string languages_; // Languages for word-breaking.
159 std::set<std::string> scheme_whitelist_; // Schemes to be indexed.
149 bool succeeded_; // Indicates if the rebuild was successful. 160 bool succeeded_; // Indicates if the rebuild was successful.
150 scoped_refptr<URLIndexPrivateData> data_; // The rebuilt private data. 161 scoped_refptr<URLIndexPrivateData> data_; // The rebuilt private data.
151 162
152 DISALLOW_COPY_AND_ASSIGN(RebuildPrivateDataFromHistoryDBTask); 163 DISALLOW_COPY_AND_ASSIGN(RebuildPrivateDataFromHistoryDBTask);
153 }; 164 };
154 165
155 // For unit testing only. 166 // Initializes all index data members in preparation for restoring the index
156 InMemoryURLIndex(const FilePath& history_dir, const std::string& languages); 167 // from the cache or a complete rebuild from the history database.
168 void ClearPrivateData();
157 169
158 // Completes index initialization once the cache DB has been initialized. 170 // Constructs a file path for the cache file within the same directory where
159 void OnPrivateDataInitDone(bool succeeded); 171 // the history database is kept and saves that path to |file_path|. Returns
172 // true if |file_path| can be successfully constructed. (This function
173 // provided as a hook for unit testing.)
174 bool GetCacheFilePath(FilePath* file_path);
160 175
161 // Adds or removes an observer that is notified when the index has been 176 // Restores the index's private data from the cache file stored in the
162 // loaded. 177 // profile directory.
163 void AddObserver(InMemoryURLIndex::Observer* observer); 178 void PostRestoreFromCacheFileTask();
164 void RemoveObserver(InMemoryURLIndex::Observer* observer);
165
166 // Handles notifications of history changes.
167 virtual void Observe(int notification_type,
168 const content::NotificationSource& source,
169 const content::NotificationDetails& details) OVERRIDE;
170
171 // Notification handlers.
172 void OnURLVisited(const URLVisitedDetails* details);
173 void OnURLsModified(const URLsModifiedDetails* details);
174 void OnURLsDeleted(const URLsDeletedDetails* details);
175
176 // Posts any outstanding updates to the index which were queued while the
177 // index was being initialized.
178 void FlushPendingUpdates();
179
180 // Restores the index's private data from the cache database stored in the
181 // profile directory. If no database is found or can be restored then look
182 // for an old version protobuf-based cache file.
183 void PostRestoreFromCacheTask();
184
185 // Determines if the private data was successfully restored from the cache
186 // database, as indicated by |succeeded|, or if the private data must be
187 // rebuilt from the history database. If successful, notifies any
188 // |restore_cache_observer_|. Otherwise, kicks off a rebuild from the history
189 // database.
190 void OnCacheRestoreDone(bool succeeded);
191
192 // Notifies all observers that the index has been loaded or rebuilt.
193 void NotifyHasLoaded();
194
195 // Rebuilds the index from the history database if the history database has
196 // been loaded, otherwise registers for the history loaded notification so
197 // that the rebuild can take place at a later time.
198 void RebuildFromHistoryIfLoaded();
199 179
200 // Schedules a history task to rebuild our private data from the history 180 // Schedules a history task to rebuild our private data from the history
201 // database. 181 // database.
202 void ScheduleRebuildFromHistory(); 182 void ScheduleRebuildFromHistory();
203 183
204 // Callback used by RebuildPrivateDataFromHistoryDBTask to signal completion 184 // Callback used by RebuildPrivateDataFromHistoryDBTask to signal completion
205 // or rebuilding our private data from the history database. |succeeded| 185 // or rebuilding our private data from the history database. |succeeded|
206 // will be true if the rebuild was successful. |data| will point to a new 186 // will be true if the rebuild was successful. |data| will point to a new
207 // instanceof the private data just rebuilt. 187 // instanceof the private data just rebuilt.
208 void DoneRebuidingPrivateDataFromHistoryDB( 188 void DoneRebuidingPrivateDataFromHistoryDB(
209 bool succeeded, 189 bool succeeded,
210 scoped_refptr<URLIndexPrivateData> private_data); 190 scoped_refptr<URLIndexPrivateData> private_data);
211 191
212 // Posts a task to completely reset the private data and the backing cache. 192 // Rebuilds the history index from the history database in |history_db|.
213 void PostResetPrivateDataTask(); 193 // Used for unit testing only.
194 void RebuildFromHistory(HistoryDatabase* history_db);
214 195
215 // Posts a task to completely replace the cache database with a current 196 // Determines if the private data was successfully reloaded from the cache
216 // image of the index private data. 197 // file or if the private data must be rebuilt from the history database.
217 void PostRefreshCacheTask(); 198 // |private_data_ptr|'s data will be NULL if the cache file load failed. If
199 // successful, sets the private data and notifies any
200 // |restore_cache_observer_|. Otherwise, kicks off a rebuild from the history
201 // database.
202 void OnCacheLoadDone(
203 scoped_refptr<URLIndexPrivateData> private_data_ptr);
218 204
219 // Callback used by PostRefreshCacheTask and PostResetPrivateDataTask to 205 // Callback function that sets the private data from the just-restored-from-
220 // notify observers that the cache database contents have been refreshed or 206 // file |private_data|. Notifies any |restore_cache_observer_| that the
221 // reset and that the loading of the index is complete. 207 // restore has succeeded.
222 void OnCacheRefreshOrResetDone(); 208 void OnCacheRestored(URLIndexPrivateData* private_data);
223 209
224 // Attempts to refresh the cache database in response to a notification that 210 // Posts a task to cache the index private data and write the cache file to
225 // an update transaction has failed. If the refresh fails then the cache 211 // the profile directory.
226 // database is ignored and an attempt will be made to rebuild the cache 212 void PostSaveToCacheFileTask();
227 // the next time the associated profile is opened.
228 void RepairCacheDatabase();
229 213
230 // Returns a pointer to our private data. 214 // Saves private_data_ to the given |path|. Runs on the UI thread.
231 scoped_refptr<URLIndexPrivateData> private_data() { return private_data_; } 215 // Provided for unit testing so that a test cache file can be used.
216 void DoSaveToCacheFile(const FilePath& path);
232 217
233 // Returns the blocking pool sequence token. 218 // Notifies the observer, if any, of the success of the private data caching.
234 base::SequencedWorkerPool::SequenceToken sequence_token_for_testing() { 219 // |succeeded| is true on a successful save.
235 return sequence_token_; 220 void OnCacheSaveDone(scoped_refptr<RefCountedBool> succeeded);
236 } 221
222 // Handles notifications of history changes.
223 virtual void Observe(int notification_type,
224 const content::NotificationSource& source,
225 const content::NotificationDetails& details) OVERRIDE;
226
227 // Notification handlers.
228 void OnURLVisited(const URLVisitedDetails* details);
229 void OnURLsModified(const URLsModifiedDetails* details);
230 void OnURLsDeleted(const URLsDeletedDetails* details);
231
232 // Sets the directory wherein the cache file will be maintained.
233 // For unit test usage only.
234 void set_history_dir(const FilePath& dir_path) { history_dir_ = dir_path; }
235
236 // Returns a pointer to our private data. For unit testing only.
237 URLIndexPrivateData* private_data() { return private_data_.get(); }
238
239 // Returns the set of whitelisted schemes. For unit testing only.
240 const std::set<std::string>& scheme_whitelist() { return scheme_whitelist_; }
237 241
238 // The profile, may be null when testing. 242 // The profile, may be null when testing.
239 Profile* profile_; 243 Profile* profile_;
240 244
245 // Directory where cache file resides. This is, except when unit testing,
246 // the same directory in which the profile's history database is found. It
247 // should never be empty.
248 FilePath history_dir_;
249
241 // Languages used during the word-breaking process during indexing. 250 // Languages used during the word-breaking process during indexing.
242 std::string languages_; 251 std::string languages_;
243 252
244 // Directory where cache database or protobuf-based cache file resides. 253 // Only URLs with a whitelisted scheme are indexed.
245 // This is, except when unit testing, the same directory in which the 254 std::set<std::string> scheme_whitelist_;
246 // profile's history database is found.
247 FilePath history_dir_;
248 255
249 // The index's durable private data. 256 // The index's durable private data.
250 scoped_refptr<URLIndexPrivateData> private_data_; 257 scoped_refptr<URLIndexPrivateData> private_data_;
251 258
252 // Sequence token for coordinating database tasks. This is shared with 259 // Observers to notify upon restoral or save of the private data cache.
253 // our private data and its cache database. 260 RestoreCacheObserver* restore_cache_observer_;
254 const base::SequencedWorkerPool::SequenceToken sequence_token_; 261 SaveCacheObserver* save_cache_observer_;
255
256 bool index_available_; // True when index is available for updating.
257
258 // Contains index updates queued up while the index is unavailable. This
259 // usually during profile startup.
260 enum UpdateType { UPDATE_VISIT, DELETE_VISIT };
261
262 struct IndexUpdateItem {
263 IndexUpdateItem(UpdateType update_type, URLRow row);
264 ~IndexUpdateItem();
265
266 UpdateType update_type;
267 URLRow row; // The row to be updated or deleted.
268 };
269 typedef std::vector<IndexUpdateItem> PendingUpdates;
270 PendingUpdates pending_updates_;
271
272 ObserverList<InMemoryURLIndex::Observer> observers_;
273 262
274 CancelableRequestConsumer cache_reader_consumer_; 263 CancelableRequestConsumer cache_reader_consumer_;
275 content::NotificationRegistrar registrar_; 264 content::NotificationRegistrar registrar_;
276 265
277 // Set to true once the shutdown process has begun. 266 // Set to true once the shutdown process has begun.
278 bool shutdown_; 267 bool shutdown_;
279 268
280 // Note: This should remain the last member so it'll be destroyed and 269 // Set to true when changes to the index have been made and the index needs
281 // invalidate its weak pointers before any other members are destroyed. 270 // to be cached. Set to false when the index has been cached. Used as a
282 base::WeakPtrFactory<InMemoryURLIndex> weak_ptr_factory_; 271 // temporary safety check to insure that the cache is saved before the
272 // index has been destructed.
273 // TODO(mrossetti): Eliminate once the transition to SQLite has been done.
274 // http://crbug.com/83659
275 bool needs_to_be_cached_;
283 276
284 DISALLOW_COPY_AND_ASSIGN(InMemoryURLIndex); 277 DISALLOW_COPY_AND_ASSIGN(InMemoryURLIndex);
285 }; 278 };
286 279
287 } // namespace history 280 } // namespace history
288 281
289 #endif // CHROME_BROWSER_HISTORY_IN_MEMORY_URL_INDEX_H_ 282 #endif // CHROME_BROWSER_HISTORY_IN_MEMORY_URL_INDEX_H_
OLDNEW
« no previous file with comments | « chrome/browser/history/in_memory_url_cache_database.cc ('k') | chrome/browser/history/in_memory_url_index.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698