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

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

Issue 9030031: Move InMemoryURLIndex Caching Operations to FILE Thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Missed a private data swap. Try to fix update phase failure. Created 8 years, 11 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/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/history/history_database.h"
10 #include "chrome/browser/history/history_notifications.h"
8 #include "chrome/browser/history/url_database.h" 11 #include "chrome/browser/history/url_database.h"
12 #include "chrome/browser/history/url_index_private_data.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/chrome_notification_types.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/notification_details.h"
17 #include "content/public/browser/notification_source.h"
9 18
10 using in_memory_url_index::InMemoryURLIndexCacheItem; 19 using content::BrowserThread;
11 20
12 namespace history { 21 namespace history {
13 22
14 InMemoryURLIndex::InMemoryURLIndex(const FilePath& history_dir) 23 InMemoryURLIndex::RestoreCacheObserver::~RestoreCacheObserver() {}
15 : history_dir_(history_dir), 24
25 InMemoryURLIndex::SaveCacheObserver::~SaveCacheObserver() {}
26
27 InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
28 RebuildPrivateDataFromHistoryDBTask(InMemoryURLIndex* index)
29 : index_(index),
30 succeeded_(false) {}
31
32 InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
33 ~RebuildPrivateDataFromHistoryDBTask() {}
34
35 bool InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::RunOnDBThread(
36 HistoryBackend* backend,
37 HistoryDatabase* db) {
38 data_.reset(URLIndexPrivateData::RebuildFromHistory(db));
39 succeeded_ = data_.get() && !data_->history_info_map_.empty();
40 if (!succeeded_)
41 data_.reset();
42 return true;
Peter Kasting 2012/01/14 00:12:49 Idle curiosity... what would be the consequences o
mrossetti 2012/03/03 05:05:56 The index data would still have been cleared so th
43 }
44
45 void InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
46 DoneRunOnMainThread() {
47 index_->DoneRebuidingPrivateDataFromHistoryDB(succeeded_, data_.release());
48 }
49
50 InMemoryURLIndex::InMemoryURLIndex(Profile* profile,
51 const FilePath& history_dir)
52 : profile_(profile),
53 history_dir_(history_dir),
16 private_data_(new URLIndexPrivateData), 54 private_data_(new URLIndexPrivateData),
17 cached_at_shutdown_(false) { 55 restore_cache_observer_(NULL),
56 save_cache_observer_(NULL),
57 shutdown_(false),
58 needs_to_be_cached_(false) {
59 if (profile) {
60 // TODO(mrossetti): Register for profile/language change notifications.
Peter Kasting 2012/01/14 00:12:49 What is a profile change notification? We don't e
mrossetti 2012/03/03 05:05:56 Comment changes to only refer to language changes.
61 content::Source<Profile> source(profile);
62 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED, source);
63 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, source);
64 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_TYPED_URLS_MODIFIED,
65 source);
66 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, source);
67 }
18 } 68 }
19 69
20 // Called only by unit tests. 70 // Called only by unit tests.
21 InMemoryURLIndex::InMemoryURLIndex() 71 InMemoryURLIndex::InMemoryURLIndex()
22 : private_data_(new URLIndexPrivateData), 72 : profile_(NULL),
23 cached_at_shutdown_(false) { 73 private_data_(new URLIndexPrivateData),
74 restore_cache_observer_(NULL),
75 save_cache_observer_(NULL),
76 shutdown_(false),
77 needs_to_be_cached_(false) {
24 } 78 }
25 79
26 InMemoryURLIndex::~InMemoryURLIndex() { 80 InMemoryURLIndex::~InMemoryURLIndex() {
27 // If there was a history directory (which there won't be for some unit tests) 81 // If there was a history directory (which there won't be for some unit tests)
28 // then insure that the cache has already been saved. 82 // then insure that the cache has already been saved.
29 DCHECK(history_dir_.empty() || cached_at_shutdown_); 83 DCHECK(history_dir_.empty() || !needs_to_be_cached_);
30 } 84 }
31 85
32 bool InMemoryURLIndex::Init(URLDatabase* history_db, 86 void InMemoryURLIndex::Init(const std::string& languages) {
33 const std::string& languages) {
34 // TODO(mrossetti): Register for profile/language change notifications.
35 private_data_->set_languages(languages); 87 private_data_->set_languages(languages);
36 FilePath cache_file_path; 88 RestoreFromCacheFile();
37 return (GetCacheFilePath(&cache_file_path) &&
38 private_data_->RestoreFromFile(cache_file_path)) ||
39 ReloadFromHistory(history_db);
40 }
41
42 bool InMemoryURLIndex::ReloadFromHistory(history::URLDatabase* history_db) {
43 if (!private_data_->ReloadFromHistory(history_db))
44 return false;
45 FilePath cache_file_path;
46 if (GetCacheFilePath(&cache_file_path))
47 private_data_->SaveToFile(cache_file_path);
48 return true;
49 } 89 }
50 90
51 void InMemoryURLIndex::ShutDown() { 91 void InMemoryURLIndex::ShutDown() {
52 // Write our cache. 92 registrar_.RemoveAll();
53 FilePath cache_file_path; 93 cache_reader_consumer_.CancelAllRequests();
54 if (!GetCacheFilePath(&cache_file_path)) 94 shutdown_ = true;
55 return; 95 SaveToCacheFile();
56 private_data_->SaveToFile(cache_file_path); 96 needs_to_be_cached_ = false;
57 cached_at_shutdown_ = true;
58 }
59
60 void InMemoryURLIndex::ClearPrivateData() {
61 private_data_->Clear();
62 } 97 }
63 98
64 bool InMemoryURLIndex::GetCacheFilePath(FilePath* file_path) { 99 bool InMemoryURLIndex::GetCacheFilePath(FilePath* file_path) {
65 if (history_dir_.empty()) 100 if (history_dir_.empty())
66 return false; 101 return false;
67 *file_path = history_dir_.Append(FILE_PATH_LITERAL("History Provider Cache")); 102 *file_path = history_dir_.Append(FILE_PATH_LITERAL("History Provider Cache"));
68 return true; 103 return true;
69 } 104 }
70 105
71 // Querying and Updating ------------------------------------------------------- 106 void InMemoryURLIndex::ClearPrivateData() {
107 private_data_->Clear();
108 }
109
110 // Saving to Cache -------------------------------------------------------------
111
112 void InMemoryURLIndex::SaveToCacheFile() {
113 FilePath path;
114 if (GetCacheFilePath(&path))
115 DoSaveToCacheFile(path);
116 }
117
118 void InMemoryURLIndex::DoSaveToCacheFile(const FilePath& path) {
119 URLIndexPrivateData* private_data = private_data_.get();
120 // If there is anything in our private data then make a copy of it and tell
121 // it to save itself to a file.
122 if (private_data && private_data->word_list_.size()) {
123 URLIndexPrivateData* private_data_copy(
124 new URLIndexPrivateData(*(private_data)));
125 BrowserThread::PostTask(
126 BrowserThread::FILE, FROM_HERE,
Peter Kasting 2012/01/14 00:12:49 Nit: You could put these on the above line if you
mrossetti 2012/03/03 05:05:56 This part of the change has been postponed. I'll a
brettw 2012/03/05 22:13:05 It's not clear what you mean here? What part has b
127 base::Bind(&InMemoryURLIndex::WritePrivateDataToCacheFile, this,
128 path, private_data_copy));
129 } else {
130 // If there is no data in our index then delete any existing cache file.
131 BrowserThread::PostTask(
132 BrowserThread::FILE, FROM_HERE,
133 base::Bind(InMemoryURLIndex::DeleteCacheFile, path));
134 }
135 }
136
137 void InMemoryURLIndex::WritePrivateDataToCacheFile(
138 const FilePath path,
139 URLIndexPrivateData* private_data) {
140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
141 scoped_ptr<history::URLIndexPrivateData> data(private_data);
142 data->SaveToFile(path);
143 if (save_cache_observer_)
144 save_cache_observer_->OnCacheSaveFinished();
145 }
146
147 // static
148 void InMemoryURLIndex::DeleteCacheFile(const FilePath path) {
149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
150 file_util::Delete(path, false);
151 }
152
153 // Restoring from Cache --------------------------------------------------------
154
155 void InMemoryURLIndex::RestoreFromCacheFile() {
156 FilePath path;
157 if (GetCacheFilePath(&path) && !shutdown_)
158 DoRestoreFromCacheFile(path);
159 }
160
161 void InMemoryURLIndex::DoRestoreFromCacheFile(const FilePath& path) {
162 BrowserThread::PostTask(
163 BrowserThread::FILE, FROM_HERE,
164 base::Bind(&InMemoryURLIndex::ReadPrivateDataFromCacheFile, this, path));
165 }
166
167 void InMemoryURLIndex::ReadPrivateDataFromCacheFile(const FilePath path) {
168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
169 history::URLIndexPrivateData* data(
170 history::URLIndexPrivateData::RestoreFromFile(path));
171 if (!profile_ || (data && !data->history_info_map_.empty())) {
172 BrowserThread::PostTask(
173 BrowserThread::UI, FROM_HERE,
174 base::Bind(&history::InMemoryURLIndex::OnCacheRestored, this, data,
175 profile_ != NULL));
176 } else if (profile_) {
177 profile_->GetHistoryServiceWithoutCreating()->ScheduleDBTask(
178 new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask(this),
179 &cache_reader_consumer_);
180 }
181 }
182
183 void InMemoryURLIndex::OnCacheRestored(URLIndexPrivateData* private_data,
184 bool succeeded) {
185 if (succeeded)
186 private_data_.reset(private_data);
187 else
188 private_data_->Clear();
Peter Kasting 2012/01/14 00:12:49 Nit: Would it make sense to allow |private_data_|
mrossetti 2012/03/03 05:05:56 I've been thinking about this actually. The approa
189 if (restore_cache_observer_)
190 restore_cache_observer_->OnCacheRestoreFinished(succeeded);
191 }
192
193 // Restoring from the History DB -----------------------------------------------
194
195 void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB(
Peter Kasting 2012/01/14 00:12:49 This function seems basically identical to OnCache
mrossetti 2012/03/03 05:05:56 Possibly. I'll consider this for the next change a
196 bool succeeded,
197 URLIndexPrivateData* data) {
198 scoped_ptr<URLIndexPrivateData> private_data(data);
199 if (succeeded)
200 private_data_.swap(private_data);
201 else
202 private_data_->Clear(); // Dump the old private data.
203 if (restore_cache_observer_)
204 restore_cache_observer_->OnCacheRestoreFinished(succeeded);
205 }
206
207 void InMemoryURLIndex::RebuildFromHistory(URLDatabase* history_db) {
208 private_data_.reset(URLIndexPrivateData::RebuildFromHistory(history_db));
209 }
210
211 // Querying --------------------------------------------------------------------
72 212
73 ScoredHistoryMatches InMemoryURLIndex::HistoryItemsForTerms( 213 ScoredHistoryMatches InMemoryURLIndex::HistoryItemsForTerms(
74 const string16& term_string) { 214 const string16& term_string) {
75 return private_data_->HistoryItemsForTerms(term_string); 215 return private_data_->HistoryItemsForTerms(term_string);
76 } 216 }
77 217
78 void InMemoryURLIndex::UpdateURL(URLID row_id, const URLRow& row) { 218
79 private_data_->UpdateURL(row_id, row); 219 // Updating --------------------------------------------------------------------
220
221 void InMemoryURLIndex::Observe(int notification_type,
222 const content::NotificationSource& source,
223 const content::NotificationDetails& details) {
224 switch (notification_type) {
225 case chrome::NOTIFICATION_HISTORY_URL_VISITED:
226 OnURLVisited(content::Details<URLVisitedDetails>(details).ptr());
227 break;
228 case chrome::NOTIFICATION_HISTORY_TYPED_URLS_MODIFIED:
229 OnURLsModified(
230 content::Details<history::URLsModifiedDetails>(details).ptr());
231 break;
232 case chrome::NOTIFICATION_HISTORY_URLS_DELETED:
233 OnURLsDeleted(
234 content::Details<history::URLsDeletedDetails>(details).ptr());
235 break;
236 default:
237 // For simplicity, the unit tests send us all notifications, even when
238 // we haven't registered for them, so don't assert here.
239 break;
240 }
80 } 241 }
81 242
82 void InMemoryURLIndex::DeleteURL(URLID row_id) { 243 void InMemoryURLIndex::OnURLVisited(const URLVisitedDetails* details) {
83 private_data_->DeleteURL(row_id); 244 private_data_->UpdateURL(details->row);
Peter Kasting 2012/01/14 00:12:49 Nit: Should we be calling IMUI::UpdateURL() or Del
mrossetti 2012/03/03 05:05:56 Done.
245 needs_to_be_cached_ = true;
Peter Kasting 2012/01/14 00:12:49 Nit: Does this need to be after the above line? D
mrossetti 2012/03/03 05:05:56 I'll move them to the bottom for now for consisten
246 }
247
248 void InMemoryURLIndex::OnURLsModified(const URLsModifiedDetails* details) {
249 needs_to_be_cached_ = true;
250 for (std::vector<history::URLRow>::const_iterator row =
Peter Kasting 2012/01/14 00:12:49 Nit: Is there a typedef somewhere (history.h? I d
mrossetti 2012/03/03 05:05:56 Done. Added 'URLRows' to history_types.h. Will fil
251 details->changed_urls.begin();
252 row != details->changed_urls.end(); ++row)
253 private_data_->UpdateURL(*row);
254 }
255
256 void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) {
257 needs_to_be_cached_ = true;
258 if (details->all_history) {
259 ClearPrivateData();
260 } else {
261 for (std::vector<URLRow>::const_iterator row = details->rows.begin();
262 row != details->rows.end(); ++row)
263 private_data_->DeleteURL(row->url());
264 }
265 }
266
267 void InMemoryURLIndex::UpdateURL(const URLRow& row) {
268 private_data_->UpdateURL(row);
269 }
270
271 void InMemoryURLIndex::DeleteURL(const GURL& url) {
272 private_data_->DeleteURL(url);
84 } 273 }
85 274
86 } // namespace history 275 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698