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 // Merge this in to an existing match if we already saw |user_text| |
| 145 std::vector<TransitionalMatch>::iterator match_it = |
| 146 std::find(transitional_matches_.begin(), transitional_matches_.end(), |
| 147 lower_user_text); |
| 148 |
| 149 if (match_it == transitional_matches_.end()) { |
| 150 TransitionalMatch transitional_match; |
| 151 transitional_match.user_text = lower_user_text; |
| 152 match_it = transitional_matches_.insert(transitional_matches_.end(), |
| 153 transitional_match); |
| 154 } |
| 155 |
| 156 for (AutocompleteResult::const_iterator it = result.begin(); |
| 157 it != result.end(); ++it) { |
| 158 if (std::find(match_it->urls.begin(), match_it->urls.end(), |
| 159 it->destination_url) == match_it->urls.end()) { |
| 160 match_it->urls.push_back(it->destination_url); |
| 161 } |
| 162 } |
| 163 } |
| 164 |
| 165 void NetworkActionPredictor::ClearTransitionalMatches() { |
| 166 transitional_matches_.clear(); |
| 167 } |
| 168 |
133 // Given a match, return a recommended action. | 169 // Given a match, return a recommended action. |
134 NetworkActionPredictor::Action NetworkActionPredictor::RecommendAction( | 170 NetworkActionPredictor::Action NetworkActionPredictor::RecommendAction( |
135 const string16& user_text, | 171 const string16& user_text, |
136 const AutocompleteMatch& match) const { | 172 const AutocompleteMatch& match) const { |
137 double confidence = 0.0; | 173 double confidence = 0.0; |
138 | 174 |
139 switch (prerender::GetOmniboxHeuristicToUse()) { | 175 switch (prerender::GetOmniboxHeuristicToUse()) { |
140 case prerender::OMNIBOX_HEURISTIC_ORIGINAL: { | 176 case prerender::OMNIBOX_HEURISTIC_ORIGINAL: { |
141 history::URLRow url_row; | 177 history::URLRow url_row; |
142 if (GetURLRowForAutocompleteMatch(profile_, match, &url_row)) | 178 if (GetURLRowForAutocompleteMatch(profile_, match, &url_row)) |
143 confidence = OriginalAlgorithm(url_row); | 179 confidence = OriginalAlgorithm(url_row); |
144 break; | 180 break; |
145 } | 181 } |
146 case prerender::OMNIBOX_HEURISTIC_CONSERVATIVE: { | 182 case prerender::OMNIBOX_HEURISTIC_CONSERVATIVE: { |
147 history::URLRow url_row; | 183 history::URLRow url_row; |
148 if (GetURLRowForAutocompleteMatch(profile_, match, &url_row)) | 184 if (GetURLRowForAutocompleteMatch(profile_, match, &url_row)) |
149 confidence = ConservativeAlgorithm(url_row); | 185 confidence = ConservativeAlgorithm(url_row); |
150 break; | 186 break; |
151 } | 187 } |
152 case prerender::OMNIBOX_HEURISTIC_EXACT: | 188 case prerender::OMNIBOX_HEURISTIC_EXACT: |
| 189 case prerender::OMNIBOX_HEURISTIC_EXACT_FULL: |
153 confidence = ExactAlgorithm(user_text, match); | 190 confidence = ExactAlgorithm(user_text, match); |
154 break; | 191 break; |
155 default: | 192 default: |
156 NOTREACHED(); | 193 NOTREACHED(); |
157 break; | 194 break; |
158 }; | 195 }; |
159 | 196 |
160 DCHECK(confidence >= 0.0 && confidence <= 1.0); | 197 DCHECK(confidence >= 0.0 && confidence <= 1.0); |
161 | 198 |
162 UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.Confidence_" + | 199 UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.Confidence_" + |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 else | 255 else |
219 DeleteRowsWithURLs(urls_deleted_details->urls); | 256 DeleteRowsWithURLs(urls_deleted_details->urls); |
220 break; | 257 break; |
221 } | 258 } |
222 | 259 |
223 // This notification does not catch all instances of the user navigating | 260 // 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 | 261 // 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. | 262 // and those are the events we're most interested in. |
226 case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: { | 263 case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: { |
227 DCHECK(initialized_); | 264 DCHECK(initialized_); |
228 AutocompleteLog* log = content::Details<AutocompleteLog>(details).ptr(); | |
229 if (log->text.length() < kMinimumUserTextLength) | |
230 break; | |
231 | 265 |
232 const string16 lower_user_text(base::i18n::ToLower(log->text)); | 266 // TODO(dominich): This doesn't need to be synchronous. Investigate |
233 | 267 // posting it as a task to be run later. |
234 BeginTransaction(); | 268 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; | 269 break; |
263 } | 270 } |
264 | 271 |
265 case chrome::NOTIFICATION_HISTORY_LOADED: { | 272 case chrome::NOTIFICATION_HISTORY_LOADED: { |
266 DCHECK(!initialized_); | 273 DCHECK(!initialized_); |
267 TryDeleteOldEntries(content::Details<HistoryService>(details).ptr()); | 274 TryDeleteOldEntries(content::Details<HistoryService>(details).ptr()); |
268 | 275 |
269 notification_registrar_.Remove(this, | 276 notification_registrar_.Remove(this, |
270 chrome::NOTIFICATION_HISTORY_LOADED, | 277 chrome::NOTIFICATION_HISTORY_LOADED, |
271 content::Source<Profile>(profile_)); | 278 content::Source<Profile>(profile_)); |
272 break; | 279 break; |
273 } | 280 } |
274 | 281 |
275 default: | 282 default: |
276 NOTREACHED() << "Unexpected notification observed."; | 283 NOTREACHED() << "Unexpected notification observed."; |
277 break; | 284 break; |
278 } | 285 } |
279 } | 286 } |
280 | 287 |
| 288 void NetworkActionPredictor::OnOmniboxOpenedUrl(const AutocompleteLog& log) { |
| 289 if (log.text.length() < kMinimumUserTextLength) |
| 290 return; |
| 291 |
| 292 const GURL& opened_url = |
| 293 log.result.match_at(log.selected_index).destination_url; |
| 294 |
| 295 const string16 lower_user_text(base::i18n::ToLower(log.text)); |
| 296 |
| 297 // Add the current match as the only transitional match. |
| 298 if (prerender::GetOmniboxHeuristicToUse() != |
| 299 prerender::OMNIBOX_HEURISTIC_EXACT_FULL) { |
| 300 DCHECK(transitional_matches_.empty()); |
| 301 TransitionalMatch dummy_match; |
| 302 dummy_match.user_text = lower_user_text; |
| 303 dummy_match.urls.push_back(opened_url); |
| 304 transitional_matches_.push_back(dummy_match); |
| 305 } |
| 306 |
| 307 BeginTransaction(); |
| 308 // Traverse transitional matches for those that have a user_text that is a |
| 309 // prefix of |lower_user_text|. |
| 310 for (std::vector<TransitionalMatch>::const_iterator it = |
| 311 transitional_matches_.begin(); it != transitional_matches_.end(); |
| 312 ++it) { |
| 313 if (!StartsWith(lower_user_text, it->user_text, true)) |
| 314 continue; |
| 315 |
| 316 // Add entries to the database for those matches. |
| 317 for (std::vector<GURL>::const_iterator url_it = it->urls.begin(); |
| 318 url_it != it->urls.end(); ++url_it) { |
| 319 DCHECK(it->user_text.length() >= kMinimumUserTextLength); |
| 320 const DBCacheKey key = { it->user_text, *url_it }; |
| 321 const bool is_hit = (*url_it == opened_url); |
| 322 |
| 323 NetworkActionPredictorDatabase::Row row; |
| 324 row.user_text = key.user_text; |
| 325 row.url = key.url; |
| 326 |
| 327 DBCacheMap::iterator it = db_cache_.find(key); |
| 328 if (it == db_cache_.end()) { |
| 329 row.id = guid::GenerateGUID(); |
| 330 row.number_of_hits = is_hit ? 1 : 0; |
| 331 row.number_of_misses = is_hit ? 0 : 1; |
| 332 |
| 333 AddRow(key, row); |
| 334 } else { |
| 335 DCHECK(db_id_cache_.find(key) != db_id_cache_.end()); |
| 336 row.id = db_id_cache_.find(key)->second; |
| 337 row.number_of_hits = it->second.number_of_hits + (is_hit ? 1 : 0); |
| 338 row.number_of_misses = it->second.number_of_misses + (is_hit ? 0 : 1); |
| 339 |
| 340 UpdateRow(it, row); |
| 341 } |
| 342 } |
| 343 } |
| 344 CommitTransaction(); |
| 345 |
| 346 ClearTransitionalMatches(); |
| 347 } |
| 348 |
| 349 |
281 void NetworkActionPredictor::DeleteOldIdsFromCaches( | 350 void NetworkActionPredictor::DeleteOldIdsFromCaches( |
282 history::URLDatabase* url_db, | 351 history::URLDatabase* url_db, |
283 std::vector<NetworkActionPredictorDatabase::Row::Id>* id_list) { | 352 std::vector<NetworkActionPredictorDatabase::Row::Id>* id_list) { |
284 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 353 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
285 DCHECK(url_db); | 354 DCHECK(url_db); |
286 DCHECK(id_list); | 355 DCHECK(id_list); |
287 id_list->clear(); | 356 id_list->clear(); |
288 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { | 357 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { |
289 history::URLRow url_row; | 358 history::URLRow url_row; |
290 | 359 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 base::Bind(&NetworkActionPredictorDatabase::BeginTransaction, db_)); | 511 base::Bind(&NetworkActionPredictorDatabase::BeginTransaction, db_)); |
443 } | 512 } |
444 | 513 |
445 void NetworkActionPredictor::CommitTransaction() { | 514 void NetworkActionPredictor::CommitTransaction() { |
446 if (!initialized_) | 515 if (!initialized_) |
447 return; | 516 return; |
448 | 517 |
449 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 518 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
450 base::Bind(&NetworkActionPredictorDatabase::CommitTransaction, db_)); | 519 base::Bind(&NetworkActionPredictorDatabase::CommitTransaction, db_)); |
451 } | 520 } |
| 521 |
| 522 NetworkActionPredictor::TransitionalMatch::TransitionalMatch() { |
| 523 } |
| 524 |
| 525 NetworkActionPredictor::TransitionalMatch::~TransitionalMatch() { |
| 526 } |
OLD | NEW |