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.cc

Issue 10830297: Revert 151419 - 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 #include "chrome/browser/history/in_memory_url_index.h" 5 #include "chrome/browser/history/in_memory_url_index.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/history/history_notifications.h" 9 #include "chrome/browser/history/history_notifications.h"
10 #include "chrome/browser/history/history_service_factory.h" 10 #include "chrome/browser/history/history_service_factory.h"
11 #include "chrome/browser/history/in_memory_url_cache_database.h"
12 #include "chrome/browser/history/url_database.h" 11 #include "chrome/browser/history/url_database.h"
13 #include "chrome/browser/history/url_index_private_data.h" 12 #include "chrome/browser/history/url_index_private_data.h"
14 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/chrome_notification_types.h" 14 #include "chrome/common/chrome_notification_types.h"
15 #include "chrome/common/url_constants.h"
16 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/notification_details.h" 17 #include "content/public/browser/notification_details.h"
18 #include "content/public/browser/notification_service.h" 18 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/notification_source.h" 19 #include "content/public/browser/notification_source.h"
20 20
21 using content::BrowserThread; 21 using in_memory_url_index::InMemoryURLIndexCacheItem;
22 22
23 namespace history { 23 namespace history {
24 24
25 // InMemoryURLIndex::Observer -------------------------------------------------- 25 // Called by DoSaveToCacheFile to delete any old cache file at |path| when
26 26 // there is no private data to save. Runs on the FILE thread.
27 InMemoryURLIndex::Observer::Observer(InMemoryURLIndex* index) 27 void DeleteCacheFile(const FilePath& path) {
28 : index_(index) { 28 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
29 DCHECK(index); 29 file_util::Delete(path, false);
30 index_->AddObserver(this);
31 } 30 }
32 31
33 InMemoryURLIndex::Observer::~Observer() { 32 // Initializes a whitelist of URL schemes.
34 index_->RemoveObserver(this); 33 void InitializeSchemeWhitelist(std::set<std::string>* whitelist) {
34 DCHECK(whitelist);
35 if (!whitelist->empty())
36 return; // Nothing to do, already initialized.
37 whitelist->insert(std::string(chrome::kAboutScheme));
38 whitelist->insert(std::string(chrome::kChromeUIScheme));
39 whitelist->insert(std::string(chrome::kFileScheme));
40 whitelist->insert(std::string(chrome::kFtpScheme));
41 whitelist->insert(std::string(chrome::kHttpScheme));
42 whitelist->insert(std::string(chrome::kHttpsScheme));
43 whitelist->insert(std::string(chrome::kMailToScheme));
35 } 44 }
36 45
37 void InMemoryURLIndex::Observer::Loaded() { 46 // RefCountedBool --------------------------------------------------------------
38 MessageLoop::current()->QuitNow(); 47
39 } 48 RefCountedBool::~RefCountedBool() {}
49
50 // Restore/SaveCacheObserver ---------------------------------------------------
51
52 InMemoryURLIndex::RestoreCacheObserver::~RestoreCacheObserver() {}
53
54 InMemoryURLIndex::SaveCacheObserver::~SaveCacheObserver() {}
40 55
41 // RebuildPrivateDataFromHistoryDBTask ----------------------------------------- 56 // RebuildPrivateDataFromHistoryDBTask -----------------------------------------
42 57
43 InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask:: 58 InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
44 RebuildPrivateDataFromHistoryDBTask(InMemoryURLIndex* index) 59 RebuildPrivateDataFromHistoryDBTask(
60 InMemoryURLIndex* index,
61 const std::string& languages,
62 const std::set<std::string>& scheme_whitelist)
45 : index_(index), 63 : index_(index),
64 languages_(languages),
65 scheme_whitelist_(scheme_whitelist),
46 succeeded_(false) { 66 succeeded_(false) {
47 } 67 }
48 68
49 InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
50 ~RebuildPrivateDataFromHistoryDBTask() {
51 }
52
53 bool InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::RunOnDBThread( 69 bool InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::RunOnDBThread(
54 HistoryBackend* backend, 70 HistoryBackend* backend,
55 HistoryDatabase* db) { 71 HistoryDatabase* db) {
56 data_ = URLIndexPrivateData::RebuildFromHistory(db, index_->private_data()); 72 data_ = URLIndexPrivateData::RebuildFromHistory(db, languages_,
73 scheme_whitelist_);
57 succeeded_ = data_.get() && !data_->Empty(); 74 succeeded_ = data_.get() && !data_->Empty();
75 if (!succeeded_ && data_.get())
76 data_->Clear();
58 return true; 77 return true;
59 } 78 }
60 79
61 void InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask:: 80 void InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
62 DoneRunOnMainThread() { 81 DoneRunOnMainThread() {
63 index_->DoneRebuidingPrivateDataFromHistoryDB(succeeded_, data_); 82 index_->DoneRebuidingPrivateDataFromHistoryDB(succeeded_, data_);
64 } 83 }
65 84
66 // IndexUpdateItem ------------------------------------------------------------- 85 InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
67 86 ~RebuildPrivateDataFromHistoryDBTask() {
68 InMemoryURLIndex::IndexUpdateItem::IndexUpdateItem(UpdateType update_type,
69 URLRow row)
70 : update_type(update_type),
71 row(row) {
72 } 87 }
73 88
74 InMemoryURLIndex::IndexUpdateItem::~IndexUpdateItem() {}
75
76 // InMemoryURLIndex ------------------------------------------------------------ 89 // InMemoryURLIndex ------------------------------------------------------------
77 90
78 InMemoryURLIndex::InMemoryURLIndex(Profile* profile, 91 InMemoryURLIndex::InMemoryURLIndex(Profile* profile,
79 const FilePath& history_dir, 92 const FilePath& history_dir,
80 const std::string& languages) 93 const std::string& languages)
81 : profile_(profile), 94 : profile_(profile),
95 history_dir_(history_dir),
82 languages_(languages), 96 languages_(languages),
83 history_dir_(history_dir), 97 private_data_(new URLIndexPrivateData),
84 private_data_(new URLIndexPrivateData(history_dir, languages)), 98 restore_cache_observer_(NULL),
85 sequence_token_(BrowserThread::GetBlockingPool()->GetSequenceToken()), 99 save_cache_observer_(NULL),
86 index_available_(false), 100 shutdown_(false),
87 shutdown_(false) { 101 needs_to_be_cached_(false) {
102 InitializeSchemeWhitelist(&scheme_whitelist_);
88 if (profile) { 103 if (profile) {
104 // TODO(mrossetti): Register for language change notifications.
89 content::Source<Profile> source(profile); 105 content::Source<Profile> source(profile);
90 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, source); 106 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, source);
91 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, 107 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED,
92 source); 108 source);
93 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, source); 109 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, source);
94 } 110 }
95 // Note: private_data_ will be reset after rebuilding from the history
96 // database but the ownership of the database passes to the new
97 // private_data_ instance so there is no need to re-register for the
98 // following notification at that time.
99 registrar_.Add(this,
100 chrome::NOTIFICATION_IN_MEMORY_URL_CACHE_DATABASE_FAILURE,
101 content::Source<InMemoryURLCacheDatabase>(
102 private_data_->cache_db()));
103 // TODO(mrossetti): Register for language change notifications.
104 } 111 }
105 112
106 // Called only by unit tests. 113 // Called only by unit tests.
107 InMemoryURLIndex::InMemoryURLIndex(const FilePath& history_dir, 114 InMemoryURLIndex::InMemoryURLIndex()
108 const std::string& languages)
109 : profile_(NULL), 115 : profile_(NULL),
110 languages_(languages), 116 private_data_(new URLIndexPrivateData),
111 history_dir_(history_dir), 117 restore_cache_observer_(NULL),
112 index_available_(false), 118 save_cache_observer_(NULL),
113 shutdown_(false) { 119 shutdown_(false),
120 needs_to_be_cached_(false) {
121 InitializeSchemeWhitelist(&scheme_whitelist_);
114 } 122 }
115 123
116 InMemoryURLIndex::~InMemoryURLIndex() {} 124 InMemoryURLIndex::~InMemoryURLIndex() {
117 125 // If there was a history directory (which there won't be for some unit tests)
118 void InMemoryURLIndex::Init(bool disable_cache) { 126 // then insure that the cache has already been saved.
119 if (disable_cache) { 127 DCHECK(history_dir_.empty() || !needs_to_be_cached_);
120 RebuildFromHistoryIfLoaded();
121 } else {
122 // It's safe to initialize the private data and the cache database without
123 // using the sequenced worker pool as no other database operations will be
124 // going on at the same time.
125 BrowserThread::PostTaskAndReplyWithResult<bool>(
126 BrowserThread::DB, FROM_HERE,
127 base::Bind(&URLIndexPrivateData::Init, private_data_, sequence_token_),
128 base::Bind(&InMemoryURLIndex::OnPrivateDataInitDone, AsWeakPtr()));
129 }
130 } 128 }
131 129
132 void InMemoryURLIndex::OnPrivateDataInitDone(bool succeeded) { 130 void InMemoryURLIndex::Init() {
133 if (shutdown_) 131 PostRestoreFromCacheFileTask();
134 return;
135 if (succeeded)
136 PostRestoreFromCacheTask();
137 else
138 RebuildFromHistoryIfLoaded();
139 } 132 }
140 133
141 void InMemoryURLIndex::Shutdown() { 134 void InMemoryURLIndex::ShutDown() {
142 // Close down the cache database as quickly as possible. Any pending cache DB
143 // transactions will detect that the database is no longer there and give up.
144 registrar_.RemoveAll(); 135 registrar_.RemoveAll();
145 cache_reader_consumer_.CancelAllRequests(); 136 cache_reader_consumer_.CancelAllRequests();
146 shutdown_ = true; 137 shutdown_ = true;
147 private_data_->Shutdown(); 138 FilePath path;
139 if (!GetCacheFilePath(&path))
140 return;
141 scoped_refptr<RefCountedBool> succeeded(new RefCountedBool(false));
142 URLIndexPrivateData::WritePrivateDataToCacheFileTask(
143 private_data_, path, succeeded);
144 needs_to_be_cached_ = false;
148 } 145 }
149 146
150 void InMemoryURLIndex::AddObserver(InMemoryURLIndex::Observer* observer) { 147 void InMemoryURLIndex::ClearPrivateData() {
151 observers_.AddObserver(observer); 148 private_data_->Clear();
152 } 149 }
153 150
154 void InMemoryURLIndex::RemoveObserver(InMemoryURLIndex::Observer* observer) { 151 bool InMemoryURLIndex::GetCacheFilePath(FilePath* file_path) {
155 observers_.RemoveObserver(observer); 152 if (history_dir_.empty())
153 return false;
154 *file_path = history_dir_.Append(FILE_PATH_LITERAL("History Provider Cache"));
155 return true;
156 } 156 }
157 157
158 // Querying -------------------------------------------------------------------- 158 // Querying --------------------------------------------------------------------
159 159
160 ScoredHistoryMatches InMemoryURLIndex::HistoryItemsForTerms( 160 ScoredHistoryMatches InMemoryURLIndex::HistoryItemsForTerms(
161 const string16& term_string) { 161 const string16& term_string) {
162 return private_data_->HistoryItemsForTerms(term_string); 162 return private_data_->HistoryItemsForTerms(term_string);
163 } 163 }
164 164
165 // Updating -------------------------------------------------------------------- 165 // Updating --------------------------------------------------------------------
166 166
167 void InMemoryURLIndex::DeleteURL(const GURL& url) {
168 private_data_->DeleteURL(url);
169 }
170
171 void InMemoryURLIndex::Observe(int notification_type, 167 void InMemoryURLIndex::Observe(int notification_type,
172 const content::NotificationSource& source, 168 const content::NotificationSource& source,
173 const content::NotificationDetails& details) { 169 const content::NotificationDetails& details) {
174 switch (notification_type) { 170 switch (notification_type) {
175 case chrome::NOTIFICATION_HISTORY_URL_VISITED: 171 case chrome::NOTIFICATION_HISTORY_URL_VISITED:
176 OnURLVisited(content::Details<URLVisitedDetails>(details).ptr()); 172 OnURLVisited(content::Details<URLVisitedDetails>(details).ptr());
177 break; 173 break;
178 case chrome::NOTIFICATION_HISTORY_URLS_MODIFIED: 174 case chrome::NOTIFICATION_HISTORY_URLS_MODIFIED:
179 OnURLsModified( 175 OnURLsModified(
180 content::Details<history::URLsModifiedDetails>(details).ptr()); 176 content::Details<history::URLsModifiedDetails>(details).ptr());
181 break; 177 break;
182 case chrome::NOTIFICATION_HISTORY_URLS_DELETED: 178 case chrome::NOTIFICATION_HISTORY_URLS_DELETED:
183 OnURLsDeleted( 179 OnURLsDeleted(
184 content::Details<history::URLsDeletedDetails>(details).ptr()); 180 content::Details<history::URLsDeletedDetails>(details).ptr());
185 break; 181 break;
186 case chrome::NOTIFICATION_HISTORY_LOADED: 182 case chrome::NOTIFICATION_HISTORY_LOADED:
187 registrar_.Remove(this, chrome::NOTIFICATION_HISTORY_LOADED, 183 registrar_.Remove(this, chrome::NOTIFICATION_HISTORY_LOADED,
188 content::Source<Profile>(profile_)); 184 content::Source<Profile>(profile_));
189 ScheduleRebuildFromHistory(); 185 ScheduleRebuildFromHistory();
190 break; 186 break;
191 case chrome::NOTIFICATION_IN_MEMORY_URL_CACHE_DATABASE_FAILURE:
192 RepairCacheDatabase();
193 break;
194 default: 187 default:
195 // For simplicity, the unit tests send us all notifications, even when 188 // For simplicity, the unit tests send us all notifications, even when
196 // we haven't registered for them, so don't assert here. 189 // we haven't registered for them, so don't assert here.
197 break; 190 break;
198 } 191 }
199 } 192 }
200 193
201 void InMemoryURLIndex::OnURLVisited(const URLVisitedDetails* details) { 194 void InMemoryURLIndex::OnURLVisited(const URLVisitedDetails* details) {
202 if (index_available_) 195 needs_to_be_cached_ |=
203 private_data_->UpdateURL(details->row); 196 private_data_->UpdateURL(details->row, languages_, scheme_whitelist_);
204 else
205 pending_updates_.push_back(IndexUpdateItem(UPDATE_VISIT, details->row));
206 } 197 }
207 198
208 void InMemoryURLIndex::OnURLsModified(const URLsModifiedDetails* details) { 199 void InMemoryURLIndex::OnURLsModified(const URLsModifiedDetails* details) {
209 for (URLRows::const_iterator row = details->changed_urls.begin(); 200 for (URLRows::const_iterator row = details->changed_urls.begin();
210 row != details->changed_urls.end(); ++row) { 201 row != details->changed_urls.end(); ++row)
211 if (index_available_) 202 needs_to_be_cached_ |=
212 private_data_->UpdateURL(*row); 203 private_data_->UpdateURL(*row, languages_, scheme_whitelist_);
213 else
214 pending_updates_.push_back(IndexUpdateItem(UPDATE_VISIT, *row));
215 }
216 } 204 }
217 205
218 void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) { 206 void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) {
219 if (details->all_history) { 207 if (details->all_history) {
220 PostResetPrivateDataTask(); 208 ClearPrivateData();
209 needs_to_be_cached_ = true;
221 } else { 210 } else {
222 for (URLRows::const_iterator row = details->rows.begin(); 211 for (URLRows::const_iterator row = details->rows.begin();
223 row != details->rows.end(); ++row) { 212 row != details->rows.end(); ++row)
224 if (index_available_) 213 needs_to_be_cached_ |= private_data_->DeleteURL(row->url());
225 DeleteURL(row->url()); 214 }
226 else 215 }
227 pending_updates_.push_back(IndexUpdateItem(DELETE_VISIT, *row)); 216
217 // Restoring from Cache --------------------------------------------------------
218
219 void InMemoryURLIndex::PostRestoreFromCacheFileTask() {
220 FilePath path;
221 if (!GetCacheFilePath(&path) || shutdown_)
222 return;
223 scoped_refptr<URLIndexPrivateData> restored_private_data =
224 new URLIndexPrivateData;
225 content::BrowserThread::PostTaskAndReply(
226 content::BrowserThread::FILE, FROM_HERE,
227 base::Bind(&URLIndexPrivateData::RestoreFromFileTask, path,
228 restored_private_data, languages_),
229 base::Bind(&InMemoryURLIndex::OnCacheLoadDone, AsWeakPtr(),
230 restored_private_data));
231 }
232
233 void InMemoryURLIndex::OnCacheLoadDone(
234 scoped_refptr<URLIndexPrivateData> private_data) {
235 if (private_data.get() && !private_data->Empty()) {
236 private_data_ = private_data;
237 if (restore_cache_observer_)
238 restore_cache_observer_->OnCacheRestoreFinished(true);
239 } else if (profile_) {
240 // When unable to restore from the cache file delete the cache file, if
241 // it exists, and then rebuild from the history database if it's available,
242 // otherwise wait until the history database loaded and then rebuild.
243 FilePath path;
244 if (!GetCacheFilePath(&path) || shutdown_)
245 return;
246 content::BrowserThread::PostBlockingPoolTask(
247 FROM_HERE, base::Bind(DeleteCacheFile, path));
248 HistoryService* service =
249 HistoryServiceFactory::GetForProfileWithoutCreating(profile_);
250 if (service && service->backend_loaded()) {
251 ScheduleRebuildFromHistory();
252 } else {
253 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED,
254 content::Source<Profile>(profile_));
228 } 255 }
229 } 256 }
230 } 257 }
231 258
232 void InMemoryURLIndex::FlushPendingUpdates() {
233 for (PendingUpdates::iterator i = pending_updates_.begin();
234 i != pending_updates_.end(); ++i) {
235 if (i->update_type == UPDATE_VISIT)
236 private_data_->UpdateURL(i->row);
237 else if (i->update_type == DELETE_VISIT)
238 DeleteURL(i->row.url());
239 }
240 pending_updates_.clear();
241 }
242
243 // Restoring from Cache --------------------------------------------------------
244
245 void InMemoryURLIndex::PostRestoreFromCacheTask() {
246 // It's safe to restore from the cache database without using the sequenced
247 // worker pool as no other database operations will be going on at the same
248 // time.
249 BrowserThread::PostTaskAndReplyWithResult<bool>(
250 BrowserThread::DB, FROM_HERE,
251 base::Bind(&URLIndexPrivateData::RestoreFromCacheTask, private_data_),
252 base::Bind(&InMemoryURLIndex::OnCacheRestoreDone, AsWeakPtr()));
253 }
254
255 void InMemoryURLIndex::OnCacheRestoreDone(bool succeeded) {
256 if (shutdown_) {
257 NotifyHasLoaded();
258 return;
259 }
260 if (succeeded) {
261 FlushPendingUpdates();
262 index_available_ = true;
263 NotifyHasLoaded();
264 } else if (profile_) {
265 RebuildFromHistoryIfLoaded();
266 }
267 }
268
269 void InMemoryURLIndex::NotifyHasLoaded() {
270 FOR_EACH_OBSERVER(InMemoryURLIndex::Observer, observers_, Loaded());
271 }
272
273 // Restoring from the History DB ----------------------------------------------- 259 // Restoring from the History DB -----------------------------------------------
274 260
275 void InMemoryURLIndex::RebuildFromHistoryIfLoaded() {
276 // When unable to restore from the cache database, rebuild from the history
277 // database, if it's available, otherwise wait until the history database
278 // has loaded and then rebuild the index.
279 HistoryService* service =
280 HistoryServiceFactory::GetForProfileIfExists(profile_,
281 Profile::EXPLICIT_ACCESS);
282 if (service && service->backend_loaded()) {
283 ScheduleRebuildFromHistory();
284 } else {
285 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED,
286 content::Source<Profile>(profile_));
287 }
288 }
289
290 void InMemoryURLIndex::ScheduleRebuildFromHistory() { 261 void InMemoryURLIndex::ScheduleRebuildFromHistory() {
291 // It's possible that we were waiting on history to finish loading when
292 // the profile was told to shut down.
293 if (shutdown_)
294 return;
295 // Reset availability here as this function is called directly by unit tests.
296 index_available_ = false;
297 HistoryService* service = 262 HistoryService* service =
298 HistoryServiceFactory::GetForProfile(profile_, 263 HistoryServiceFactory::GetForProfile(profile_,
299 Profile::EXPLICIT_ACCESS); 264 Profile::EXPLICIT_ACCESS);
300 // Do not update the cache database while rebuilding.
301 private_data_->set_cache_enabled(false);
302 service->ScheduleDBTask( 265 service->ScheduleDBTask(
303 new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask(this), 266 new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask(
267 this, languages_, scheme_whitelist_),
304 &cache_reader_consumer_); 268 &cache_reader_consumer_);
305 } 269 }
306 270
307 void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB( 271 void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB(
308 bool succeeded, 272 bool succeeded,
309 scoped_refptr<URLIndexPrivateData> private_data) { 273 scoped_refptr<URLIndexPrivateData> private_data) {
310 DCHECK(!BrowserThread::IsWellKnownThread(BrowserThread::UI) || 274 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
311 BrowserThread::CurrentlyOn(BrowserThread::UI));
312 if (shutdown_)
313 return;
314 if (succeeded) { 275 if (succeeded) {
315 private_data_ = private_data; 276 private_data_ = private_data;
316 private_data_->set_cache_enabled(true); 277 PostSaveToCacheFileTask(); // Cache the newly rebuilt index.
317 PostRefreshCacheTask(); // Cache the newly rebuilt index.
318 } else { 278 } else {
319 private_data_->set_cache_enabled(true); 279 private_data_->Clear(); // Dump the old private data.
320 PostResetPrivateDataTask(); 280 // There is no need to do anything with the cache file as it was deleted
281 // when the rebuild from the history operation was kicked off.
282 }
283 if (restore_cache_observer_)
284 restore_cache_observer_->OnCacheRestoreFinished(succeeded);
285 }
286
287 void InMemoryURLIndex::RebuildFromHistory(HistoryDatabase* history_db) {
288 private_data_ = URLIndexPrivateData::RebuildFromHistory(history_db,
289 languages_,
290 scheme_whitelist_);
291 }
292
293 // Saving to Cache -------------------------------------------------------------
294
295 void InMemoryURLIndex::PostSaveToCacheFileTask() {
296 FilePath path;
297 if (!GetCacheFilePath(&path))
298 return;
299 // If there is anything in our private data then make a copy of it and tell
300 // it to save itself to a file.
301 if (private_data_.get() && !private_data_->Empty()) {
302 // Note that ownership of the copy of our private data is passed to the
303 // completion closure below.
304 scoped_refptr<URLIndexPrivateData> private_data_copy =
305 private_data_->Duplicate();
306 scoped_refptr<RefCountedBool> succeeded(new RefCountedBool(false));
307 content::BrowserThread::PostTaskAndReply(
308 content::BrowserThread::FILE, FROM_HERE,
309 base::Bind(&URLIndexPrivateData::WritePrivateDataToCacheFileTask,
310 private_data_copy, path, succeeded),
311 base::Bind(&InMemoryURLIndex::OnCacheSaveDone, AsWeakPtr(), succeeded));
312 } else {
313 // If there is no data in our index then delete any existing cache file.
314 content::BrowserThread::PostBlockingPoolTask(
315 FROM_HERE,
316 base::Bind(DeleteCacheFile, path));
321 } 317 }
322 } 318 }
323 319
324 // Reset Cache ----------------------------------------------------------------- 320 void InMemoryURLIndex::OnCacheSaveDone(
325 321 scoped_refptr<RefCountedBool> succeeded) {
326 void InMemoryURLIndex::PostResetPrivateDataTask() { 322 if (save_cache_observer_)
327 index_available_ = false; 323 save_cache_observer_->OnCacheSaveFinished(succeeded->value());
328 scoped_refptr<base::SequencedTaskRunner> runner =
329 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(sequence_token_);
330 DCHECK(runner.get());
331 runner->PostTaskAndReply(FROM_HERE,
332 base::Bind(&URLIndexPrivateData::Reset, private_data_),
333 base::Bind(&InMemoryURLIndex::OnCacheRefreshOrResetDone, AsWeakPtr()));
334 }
335
336 // Refresh Cache ---------------------------------------------------------------
337
338 void InMemoryURLIndex::PostRefreshCacheTask() {
339 scoped_refptr<base::SequencedTaskRunner> runner =
340 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(sequence_token_);
341 DCHECK(runner.get());
342 runner->PostTaskAndReply(FROM_HERE,
343 base::Bind(&URLIndexPrivateData::RefreshCacheTask, private_data_),
344 base::Bind(&InMemoryURLIndex::OnCacheRefreshOrResetDone, AsWeakPtr()));
345 }
346
347 void InMemoryURLIndex::OnCacheRefreshOrResetDone() {
348 if (shutdown_) {
349 NotifyHasLoaded();
350 return;
351 }
352 FlushPendingUpdates();
353 index_available_ = true;
354 NotifyHasLoaded();
355 }
356
357 // Repair Cache ----------------------------------------------------------------
358
359 void InMemoryURLIndex::RepairCacheDatabase() {
360 // The database will disable itself when it detects an error so re-enable the
361 // database and try to refresh it from scratch. If that fails then the
362 // database will be left in a disabled state and will be rebuilt from the
363 // history database the next time the profile is opened.
364 private_data_->set_cache_enabled(true);
365 PostRefreshCacheTask(); // Cache the newly rebuilt index.
366 } 324 }
367 325
368 } // namespace history 326 } // namespace history
OLDNEW
« no previous file with comments | « chrome/browser/history/in_memory_url_index.h ('k') | chrome/browser/history/in_memory_url_index_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698