OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CHROME_BROWSER_HISTORY_IN_MEMORY_URL_INDEX_H_ | |
6 #define CHROME_BROWSER_HISTORY_IN_MEMORY_URL_INDEX_H_ | |
7 | |
8 #include <functional> | |
9 #include <map> | |
10 #include <set> | |
11 #include <string> | |
12 #include <vector> | |
13 | |
14 #include "base/basictypes.h" | |
15 #include "base/files/file_path.h" | |
16 #include "base/gtest_prod_util.h" | |
17 #include "base/memory/ref_counted.h" | |
18 #include "base/memory/weak_ptr.h" | |
19 #include "base/strings/string16.h" | |
20 #include "base/task/cancelable_task_tracker.h" | |
21 #include "components/history/core/browser/history_db_task.h" | |
22 #include "components/history/core/browser/history_service_observer.h" | |
23 #include "components/history/core/browser/history_types.h" | |
24 #include "components/history/core/browser/scored_history_match.h" | |
25 #include "sql/connection.h" | |
26 | |
27 class HistoryService; | |
28 class HistoryQuickProviderTest; | |
29 | |
30 namespace base { | |
31 class Time; | |
32 } | |
33 | |
34 namespace in_memory_url_index { | |
35 class InMemoryURLIndexCacheItem; | |
36 } | |
37 | |
38 namespace history { | |
39 | |
40 namespace imui = in_memory_url_index; | |
41 | |
42 class HistoryDatabase; | |
43 class URLIndexPrivateData; | |
44 | |
45 // The URL history source. | |
46 // Holds portions of the URL database in memory in an indexed form. Used to | |
47 // quickly look up matching URLs for a given query string. Used by | |
48 // the HistoryURLProvider for inline autocomplete and to provide URL | |
49 // matches to the omnibox. | |
50 // | |
51 // Note about multi-byte codepoints and the data structures in the | |
52 // InMemoryURLIndex class: One will quickly notice that no effort is made to | |
53 // insure that multi-byte character boundaries are detected when indexing the | |
54 // words and characters in the URL history database except when converting | |
55 // URL strings to lowercase. Multi-byte-edness makes no difference when | |
56 // indexing or when searching the index as the final filtering of results | |
57 // is dependent on the comparison of a string of bytes, not individual | |
58 // characters. While the lookup of those bytes during a search in the | |
59 // |char_word_map_| could serve up words in which the individual char16 | |
60 // occurs as a portion of a composite character the next filtering step | |
61 // will eliminate such words except in the case where a single character | |
62 // is being searched on and which character occurs as the second char16 of a | |
63 // multi-char16 instance. | |
64 class InMemoryURLIndex : public HistoryServiceObserver, | |
65 public base::SupportsWeakPtr<InMemoryURLIndex> { | |
66 public: | |
67 // Defines an abstract class which is notified upon completion of restoring | |
68 // the index's private data either by reading from the cache file or by | |
69 // rebuilding from the history database. | |
70 class RestoreCacheObserver { | |
71 public: | |
72 virtual ~RestoreCacheObserver(); | |
73 | |
74 // Callback that lets the observer know that the restore operation has | |
75 // completed. |succeeded| indicates if the restore was successful. This is | |
76 // called on the UI thread. | |
77 virtual void OnCacheRestoreFinished(bool succeeded) = 0; | |
78 }; | |
79 | |
80 // Defines an abstract class which is notified upon completion of saving | |
81 // the index's private data to the cache file. | |
82 class SaveCacheObserver { | |
83 public: | |
84 virtual ~SaveCacheObserver(); | |
85 | |
86 // Callback that lets the observer know that the save succeeded. | |
87 // This is called on the UI thread. | |
88 virtual void OnCacheSaveFinished(bool succeeded) = 0; | |
89 }; | |
90 | |
91 // |history_service| which may be null during unit testing is used to register | |
92 // |as an HistoryServiceObserver. |history_dir| is a path to the directory | |
93 // containing the history database within the profile wherein the cache and | |
94 // transaction journals will be stored. |languages| gives a list of language | |
95 // encodings by which URLs and omnibox searches are broken down into words and | |
96 // characters. | |
97 InMemoryURLIndex(HistoryService* history_service, | |
98 const base::FilePath& history_dir, | |
99 const std::string& languages); | |
100 ~InMemoryURLIndex() override; | |
101 | |
102 // Opens and prepares the index of historical URL visits. If the index private | |
103 // data cannot be restored from its cache file then it is rebuilt from the | |
104 // history database. | |
105 void Init(); | |
106 | |
107 // Signals that any outstanding initialization should be canceled and | |
108 // flushes the cache to disk. | |
109 void ShutDown(); | |
110 | |
111 // Scans the history index and returns a vector with all scored, matching | |
112 // history items. This entry point simply forwards the call on to the | |
113 // URLIndexPrivateData class. For a complete description of this function | |
114 // refer to that class. If |cursor_position| is base::string16::npos, the | |
115 // function doesn't do anything special with the cursor; this is equivalent | |
116 // to the cursor being at the end. In total, |max_matches| of items will be | |
117 // returned in the |ScoredHistoryMatches| vector. | |
118 ScoredHistoryMatches HistoryItemsForTerms( | |
119 const base::string16& term_string, | |
120 size_t cursor_position, | |
121 size_t max_matches, | |
122 const ScoredHistoryMatch::Builder& builder); | |
123 | |
124 // Deletes the index entry, if any, for the given |url|. | |
125 void DeleteURL(const GURL& url); | |
126 | |
127 // Sets the optional observers for completion of restoral and saving of the | |
128 // index's private data. | |
129 void set_restore_cache_observer( | |
130 RestoreCacheObserver* restore_cache_observer) { | |
131 restore_cache_observer_ = restore_cache_observer; | |
132 } | |
133 void set_save_cache_observer(SaveCacheObserver* save_cache_observer) { | |
134 save_cache_observer_ = save_cache_observer; | |
135 } | |
136 | |
137 // Indicates that the index restoration is complete. | |
138 bool restored() const { | |
139 return restored_; | |
140 } | |
141 | |
142 private: | |
143 friend class ::HistoryQuickProviderTest; | |
144 friend class InMemoryURLIndexTest; | |
145 friend class InMemoryURLIndexCacheTest; | |
146 FRIEND_TEST_ALL_PREFIXES(InMemoryURLIndexTest, ExpireRow); | |
147 FRIEND_TEST_ALL_PREFIXES(LimitedInMemoryURLIndexTest, Initialization); | |
148 | |
149 // HistoryDBTask used to rebuild our private data from the history database. | |
150 class RebuildPrivateDataFromHistoryDBTask : public HistoryDBTask { | |
151 public: | |
152 explicit RebuildPrivateDataFromHistoryDBTask( | |
153 InMemoryURLIndex* index, | |
154 const std::string& languages, | |
155 const std::set<std::string>& scheme_whitelist); | |
156 | |
157 bool RunOnDBThread(HistoryBackend* backend, | |
158 history::HistoryDatabase* db) override; | |
159 void DoneRunOnMainThread() override; | |
160 | |
161 private: | |
162 ~RebuildPrivateDataFromHistoryDBTask() override; | |
163 | |
164 InMemoryURLIndex* index_; // Call back to this index at completion. | |
165 std::string languages_; // Languages for word-breaking. | |
166 std::set<std::string> scheme_whitelist_; // Schemes to be indexed. | |
167 bool succeeded_; // Indicates if the rebuild was successful. | |
168 scoped_refptr<URLIndexPrivateData> data_; // The rebuilt private data. | |
169 | |
170 DISALLOW_COPY_AND_ASSIGN(RebuildPrivateDataFromHistoryDBTask); | |
171 }; | |
172 | |
173 // Initializes all index data members in preparation for restoring the index | |
174 // from the cache or a complete rebuild from the history database. | |
175 void ClearPrivateData(); | |
176 | |
177 // Constructs a file path for the cache file within the same directory where | |
178 // the history database is kept and saves that path to |file_path|. Returns | |
179 // true if |file_path| can be successfully constructed. (This function | |
180 // provided as a hook for unit testing.) | |
181 bool GetCacheFilePath(base::FilePath* file_path); | |
182 | |
183 // Restores the index's private data from the cache file stored in the history | |
184 // directory. | |
185 void PostRestoreFromCacheFileTask(); | |
186 | |
187 // Schedules a history task to rebuild our private data from the history | |
188 // database. | |
189 void ScheduleRebuildFromHistory(); | |
190 | |
191 // Callback used by RebuildPrivateDataFromHistoryDBTask to signal completion | |
192 // or rebuilding our private data from the history database. |succeeded| | |
193 // will be true if the rebuild was successful. |data| will point to a new | |
194 // instanceof the private data just rebuilt. | |
195 void DoneRebuidingPrivateDataFromHistoryDB( | |
196 bool succeeded, | |
197 scoped_refptr<URLIndexPrivateData> private_data); | |
198 | |
199 // Rebuilds the history index from the history database in |history_db|. | |
200 // Used for unit testing only. | |
201 void RebuildFromHistory(HistoryDatabase* history_db); | |
202 | |
203 // Determines if the private data was successfully reloaded from the cache | |
204 // file or if the private data must be rebuilt from the history database. | |
205 // |private_data_ptr|'s data will be NULL if the cache file load failed. If | |
206 // successful, sets the private data and notifies any | |
207 // |restore_cache_observer_|. Otherwise, kicks off a rebuild from the history | |
208 // database. | |
209 void OnCacheLoadDone(scoped_refptr<URLIndexPrivateData> private_data_ptr); | |
210 | |
211 // Callback function that sets the private data from the just-restored-from- | |
212 // file |private_data|. Notifies any |restore_cache_observer_| that the | |
213 // restore has succeeded. | |
214 void OnCacheRestored(URLIndexPrivateData* private_data); | |
215 | |
216 // Posts a task to cache the index private data and write the cache file to | |
217 // the history directory. | |
218 void PostSaveToCacheFileTask(); | |
219 | |
220 // Saves private_data_ to the given |path|. Runs on the UI thread. | |
221 // Provided for unit testing so that a test cache file can be used. | |
222 void DoSaveToCacheFile(const base::FilePath& path); | |
223 | |
224 // Notifies the observer, if any, of the success of the private data caching. | |
225 // |succeeded| is true on a successful save. | |
226 void OnCacheSaveDone(bool succeeded); | |
227 | |
228 // HistoryServiceObserver: | |
229 void OnURLVisited(HistoryService* history_service, | |
230 ui::PageTransition transition, | |
231 const URLRow& row, | |
232 const RedirectList& redirects, | |
233 base::Time visit_time) override; | |
234 void OnURLsModified(HistoryService* history_service, | |
235 const URLRows& changed_urls) override; | |
236 void OnURLsDeleted(HistoryService* history_service, | |
237 bool all_history, | |
238 bool expired, | |
239 const URLRows& deleted_rows, | |
240 const std::set<GURL>& favicon_urls) override; | |
241 void OnHistoryServiceLoaded(HistoryService* history_service) override; | |
242 | |
243 // Sets the directory wherein the cache file will be maintained. | |
244 // For unit test usage only. | |
245 void set_history_dir(const base::FilePath& dir_path) { | |
246 history_dir_ = dir_path; | |
247 } | |
248 | |
249 // Returns a pointer to our private data. For unit testing only. | |
250 URLIndexPrivateData* private_data() { return private_data_.get(); } | |
251 | |
252 // Returns a pointer to our private data cancelable request tracker. For | |
253 // unit testing only. | |
254 base::CancelableTaskTracker* private_data_tracker() { | |
255 return &private_data_tracker_; | |
256 } | |
257 | |
258 // Returns the set of whitelisted schemes. For unit testing only. | |
259 const std::set<std::string>& scheme_whitelist() { return scheme_whitelist_; } | |
260 | |
261 // The HistoryService; may be null when testing. | |
262 HistoryService* history_service_; | |
263 | |
264 // Directory where cache file resides. This is, except when unit testing, | |
265 // the same directory in which the history database is found. It should never | |
266 // be empty. | |
267 base::FilePath history_dir_; | |
268 | |
269 // Languages used during the word-breaking process during indexing. | |
270 std::string languages_; | |
271 | |
272 // Only URLs with a whitelisted scheme are indexed. | |
273 std::set<std::string> scheme_whitelist_; | |
274 | |
275 // The index's durable private data. | |
276 scoped_refptr<URLIndexPrivateData> private_data_; | |
277 | |
278 // Observers to notify upon restoral or save of the private data cache. | |
279 RestoreCacheObserver* restore_cache_observer_; | |
280 SaveCacheObserver* save_cache_observer_; | |
281 | |
282 base::CancelableTaskTracker private_data_tracker_; | |
283 base::CancelableTaskTracker cache_reader_tracker_; | |
284 | |
285 // Set to true once the shutdown process has begun. | |
286 bool shutdown_; | |
287 | |
288 // Set to true once the index restoration is complete. | |
289 bool restored_; | |
290 | |
291 // Set to true when changes to the index have been made and the index needs | |
292 // to be cached. Set to false when the index has been cached. Used as a | |
293 // temporary safety check to insure that the cache is saved before the | |
294 // index has been destructed. | |
295 bool needs_to_be_cached_; | |
296 | |
297 // This flag is set to true,if we want to listen to the | |
298 // HistoryServiceLoaded Notification. | |
299 bool listen_to_history_service_loaded_; | |
300 | |
301 DISALLOW_COPY_AND_ASSIGN(InMemoryURLIndex); | |
302 }; | |
303 | |
304 } // namespace history | |
305 | |
306 #endif // CHROME_BROWSER_HISTORY_IN_MEMORY_URL_INDEX_H_ | |
OLD | NEW |