OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/autocomplete/network_action_predictor.h" | 5 #include "chrome/browser/autocomplete/network_action_predictor.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 base::Bind(&NetworkActionPredictorDatabase::GetAllRows, db_, rows), | 123 base::Bind(&NetworkActionPredictorDatabase::GetAllRows, db_, rows), |
124 base::Bind(&NetworkActionPredictor::CreateCaches, AsWeakPtr(), | 124 base::Bind(&NetworkActionPredictor::CreateCaches, AsWeakPtr(), |
125 base::Owned(rows))); | 125 base::Owned(rows))); |
126 | 126 |
127 } | 127 } |
128 | 128 |
129 NetworkActionPredictor::~NetworkActionPredictor() { | 129 NetworkActionPredictor::~NetworkActionPredictor() { |
130 db_->OnPredictorDestroyed(); | 130 db_->OnPredictorDestroyed(); |
131 } | 131 } |
132 | 132 |
133 void NetworkActionPredictor::RegisterTransitionalMatches( | |
134 const string16& user_text, | |
135 const AutocompleteResult& result) { | |
136 if (prerender::GetOmniboxHeuristicToUse() != | |
137 prerender::OMNIBOX_HEURISTIC_EXACT_FULL) { | |
138 return; | |
139 } | |
140 if (user_text.length() < kMinimumUserTextLength) | |
141 return; | |
142 const string16 lower_user_text(base::i18n::ToLower(user_text)); | |
143 | |
144 // Don't register if we already saw this |user_text|. | |
Peter Kasting
2011/11/18 21:17:13
Are you sure this is what you want? It's possible
dominich
2011/11/18 23:05:51
I tested this and although I saw OnChanged being c
| |
145 if (std::find(transitional_matches_.begin(), transitional_matches_.end(), | |
146 lower_user_text) != transitional_matches_.end()) | |
147 return; | |
148 | |
149 TransitionalMatch transitional_match; | |
150 transitional_match.user_text = lower_user_text; | |
151 for (AutocompleteResult::const_iterator it = result.begin(); | |
152 it != result.end(); ++it) { | |
153 transitional_match.urls.push_back(it->destination_url); | |
154 } | |
155 transitional_matches_.push_back(transitional_match); | |
156 } | |
157 | |
158 void NetworkActionPredictor::ClearTransitionalMatches() { | |
159 transitional_matches_.clear(); | |
160 } | |
161 | |
133 // Given a match, return a recommended action. | 162 // Given a match, return a recommended action. |
134 NetworkActionPredictor::Action NetworkActionPredictor::RecommendAction( | 163 NetworkActionPredictor::Action NetworkActionPredictor::RecommendAction( |
135 const string16& user_text, | 164 const string16& user_text, |
136 const AutocompleteMatch& match) const { | 165 const AutocompleteMatch& match) const { |
137 double confidence = 0.0; | 166 double confidence = 0.0; |
138 | 167 |
139 switch (prerender::GetOmniboxHeuristicToUse()) { | 168 switch (prerender::GetOmniboxHeuristicToUse()) { |
140 case prerender::OMNIBOX_HEURISTIC_ORIGINAL: { | 169 case prerender::OMNIBOX_HEURISTIC_ORIGINAL: { |
141 history::URLRow url_row; | 170 history::URLRow url_row; |
142 if (GetURLRowForAutocompleteMatch(profile_, match, &url_row)) | 171 if (GetURLRowForAutocompleteMatch(profile_, match, &url_row)) |
143 confidence = OriginalAlgorithm(url_row); | 172 confidence = OriginalAlgorithm(url_row); |
144 break; | 173 break; |
145 } | 174 } |
146 case prerender::OMNIBOX_HEURISTIC_CONSERVATIVE: { | 175 case prerender::OMNIBOX_HEURISTIC_CONSERVATIVE: { |
147 history::URLRow url_row; | 176 history::URLRow url_row; |
148 if (GetURLRowForAutocompleteMatch(profile_, match, &url_row)) | 177 if (GetURLRowForAutocompleteMatch(profile_, match, &url_row)) |
149 confidence = ConservativeAlgorithm(url_row); | 178 confidence = ConservativeAlgorithm(url_row); |
150 break; | 179 break; |
151 } | 180 } |
152 case prerender::OMNIBOX_HEURISTIC_EXACT: | 181 case prerender::OMNIBOX_HEURISTIC_EXACT: |
182 case prerender::OMNIBOX_HEURISTIC_EXACT_FULL: | |
153 confidence = ExactAlgorithm(user_text, match); | 183 confidence = ExactAlgorithm(user_text, match); |
154 break; | 184 break; |
155 default: | 185 default: |
156 NOTREACHED(); | 186 NOTREACHED(); |
157 break; | 187 break; |
158 }; | 188 }; |
159 | 189 |
160 DCHECK(confidence >= 0.0 && confidence <= 1.0); | 190 DCHECK(confidence >= 0.0 && confidence <= 1.0); |
161 | 191 |
162 UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.Confidence_" + | 192 UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.Confidence_" + |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 else | 248 else |
219 DeleteRowsWithURLs(urls_deleted_details->urls); | 249 DeleteRowsWithURLs(urls_deleted_details->urls); |
220 break; | 250 break; |
221 } | 251 } |
222 | 252 |
223 // This notification does not catch all instances of the user navigating | 253 // This notification does not catch all instances of the user navigating |
224 // from the Omnibox, but it does catch the cases where the dropdown is open | 254 // from the Omnibox, but it does catch the cases where the dropdown is open |
225 // and those are the events we're most interested in. | 255 // and those are the events we're most interested in. |
226 case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: { | 256 case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: { |
227 DCHECK(initialized_); | 257 DCHECK(initialized_); |
228 AutocompleteLog* log = content::Details<AutocompleteLog>(details).ptr(); | |
229 if (log->text.length() < kMinimumUserTextLength) | |
230 break; | |
231 | 258 |
232 const string16 lower_user_text(base::i18n::ToLower(log->text)); | 259 // TODO(dominich): This doesn't need to be synchronous. Investigate |
233 | 260 // posting it as a task to be run later. |
234 BeginTransaction(); | 261 OnOmniboxOpenedUrl(*content::Details<AutocompleteLog>(details).ptr()); |
235 for (size_t i = 0; i < log->result.size(); ++i) { | |
236 const AutocompleteMatch& match(log->result.match_at(i)); | |
237 const DBCacheKey key = { lower_user_text, match.destination_url }; | |
238 | |
239 bool is_hit = (i == log->selected_index); | |
240 | |
241 NetworkActionPredictorDatabase::Row row; | |
242 row.user_text = key.user_text; | |
243 row.url = key.url; | |
244 | |
245 DBCacheMap::iterator it = db_cache_.find(key); | |
246 if (it == db_cache_.end()) { | |
247 row.id = guid::GenerateGUID(); | |
248 row.number_of_hits = is_hit ? 1 : 0; | |
249 row.number_of_misses = is_hit ? 0 : 1; | |
250 | |
251 AddRow(key, row); | |
252 } else { | |
253 DCHECK(db_id_cache_.find(key) != db_id_cache_.end()); | |
254 row.id = db_id_cache_.find(key)->second; | |
255 row.number_of_hits = it->second.number_of_hits + (is_hit ? 1 : 0); | |
256 row.number_of_misses = it->second.number_of_misses + (is_hit ? 0 : 1); | |
257 | |
258 UpdateRow(it, row); | |
259 } | |
260 } | |
261 CommitTransaction(); | |
262 break; | 262 break; |
263 } | 263 } |
264 | 264 |
265 case chrome::NOTIFICATION_HISTORY_LOADED: { | 265 case chrome::NOTIFICATION_HISTORY_LOADED: { |
266 DCHECK(!initialized_); | 266 DCHECK(!initialized_); |
267 TryDeleteOldEntries(content::Details<HistoryService>(details).ptr()); | 267 TryDeleteOldEntries(content::Details<HistoryService>(details).ptr()); |
268 | 268 |
269 notification_registrar_.Remove(this, | 269 notification_registrar_.Remove(this, |
270 chrome::NOTIFICATION_HISTORY_LOADED, | 270 chrome::NOTIFICATION_HISTORY_LOADED, |
271 content::Source<Profile>(profile_)); | 271 content::Source<Profile>(profile_)); |
272 break; | 272 break; |
273 } | 273 } |
274 | 274 |
275 default: | 275 default: |
276 NOTREACHED() << "Unexpected notification observed."; | 276 NOTREACHED() << "Unexpected notification observed."; |
277 break; | 277 break; |
278 } | 278 } |
279 } | 279 } |
280 | 280 |
281 void NetworkActionPredictor::OnOmniboxOpenedUrl(const AutocompleteLog& log) { | |
282 if (log.text.length() < kMinimumUserTextLength) | |
283 return; | |
284 | |
285 const GURL& opened_url = | |
286 log.result.match_at(log.selected_index).destination_url; | |
287 | |
288 const string16 lower_user_text(base::i18n::ToLower(log.text)); | |
289 | |
290 // Add the current match as the only transitional match. | |
291 if (prerender::GetOmniboxHeuristicToUse() != | |
292 prerender::OMNIBOX_HEURISTIC_EXACT_FULL) { | |
293 DCHECK(transitional_matches_.empty()); | |
294 TransitionalMatch dummy_match; | |
295 dummy_match.user_text = lower_user_text; | |
296 dummy_match.urls.push_back(opened_url); | |
297 transitional_matches_.push_back(dummy_match); | |
298 } | |
299 | |
300 BeginTransaction(); | |
301 // Traverse transitional matches for those that have a user_text that is a | |
302 // prefix of |lower_user_text|. | |
303 for (std::vector<TransitionalMatch>::const_iterator it = | |
304 transitional_matches_.begin(); it != transitional_matches_.end(); | |
305 ++it) { | |
306 if (!StartsWith(lower_user_text, it->user_text, true)) | |
307 continue; | |
308 | |
309 // Add entries to the database for those matches. | |
310 for (std::vector<GURL>::const_iterator url_it = it->urls.begin(); | |
311 url_it != it->urls.end(); ++url_it) { | |
312 DCHECK(it->user_text.length() >= kMinimumUserTextLength); | |
313 const DBCacheKey key = { it->user_text, *url_it }; | |
314 const bool is_hit = (*url_it == opened_url); | |
315 | |
316 NetworkActionPredictorDatabase::Row row; | |
317 row.user_text = key.user_text; | |
318 row.url = key.url; | |
319 | |
320 DBCacheMap::iterator it = db_cache_.find(key); | |
321 if (it == db_cache_.end()) { | |
322 row.id = guid::GenerateGUID(); | |
323 row.number_of_hits = is_hit ? 1 : 0; | |
324 row.number_of_misses = is_hit ? 0 : 1; | |
Peter Kasting
2011/11/18 21:17:13
Nit: Or "= 1 - row.number_of_hits", dunno which is
dominich
2011/11/18 23:05:51
I like the symmetry of the existing code - it's cl
| |
325 | |
326 AddRow(key, row); | |
327 } else { | |
328 DCHECK(db_id_cache_.find(key) != db_id_cache_.end()); | |
329 row.id = db_id_cache_.find(key)->second; | |
330 row.number_of_hits = it->second.number_of_hits + (is_hit ? 1 : 0); | |
331 row.number_of_misses = it->second.number_of_misses + (is_hit ? 0 : 1); | |
332 | |
333 UpdateRow(it, row); | |
334 } | |
335 } | |
336 } | |
337 CommitTransaction(); | |
338 | |
339 ClearTransitionalMatches(); | |
340 } | |
341 | |
342 | |
281 void NetworkActionPredictor::DeleteOldIdsFromCaches( | 343 void NetworkActionPredictor::DeleteOldIdsFromCaches( |
282 history::URLDatabase* url_db, | 344 history::URLDatabase* url_db, |
283 std::vector<NetworkActionPredictorDatabase::Row::Id>* id_list) { | 345 std::vector<NetworkActionPredictorDatabase::Row::Id>* id_list) { |
284 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 346 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
285 DCHECK(url_db); | 347 DCHECK(url_db); |
286 DCHECK(id_list); | 348 DCHECK(id_list); |
287 id_list->clear(); | 349 id_list->clear(); |
288 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { | 350 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { |
289 history::URLRow url_row; | 351 history::URLRow url_row; |
290 | 352 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
442 base::Bind(&NetworkActionPredictorDatabase::BeginTransaction, db_)); | 504 base::Bind(&NetworkActionPredictorDatabase::BeginTransaction, db_)); |
443 } | 505 } |
444 | 506 |
445 void NetworkActionPredictor::CommitTransaction() { | 507 void NetworkActionPredictor::CommitTransaction() { |
446 if (!initialized_) | 508 if (!initialized_) |
447 return; | 509 return; |
448 | 510 |
449 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 511 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
450 base::Bind(&NetworkActionPredictorDatabase::CommitTransaction, db_)); | 512 base::Bind(&NetworkActionPredictorDatabase::CommitTransaction, db_)); |
451 } | 513 } |
OLD | NEW |