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

Side by Side Diff: chrome/browser/autocomplete/history_url_provider.cc

Issue 7607007: Add confidence to AutocompleteMatch. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 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) 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/history_url_provider.h" 5 #include "chrome/browser/autocomplete/history_url_provider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 if (what_you_typed_match.is_history_what_you_typed_match && 238 if (what_you_typed_match.is_history_what_you_typed_match &&
239 (!backend || !params->dont_suggest_exact_input) && 239 (!backend || !params->dont_suggest_exact_input) &&
240 FixupExactSuggestion(db, params->input, &what_you_typed_match, 240 FixupExactSuggestion(db, params->input, &what_you_typed_match,
241 &history_matches)) { 241 &history_matches)) {
242 // Got an exact match for the user's input. Treat it as the best match 242 // Got an exact match for the user's input. Treat it as the best match
243 // regardless of the input type. 243 // regardless of the input type.
244 exact_suggestion = 1; 244 exact_suggestion = 1;
245 params->matches.push_back(what_you_typed_match); 245 params->matches.push_back(what_you_typed_match);
246 } else if (params->prevent_inline_autocomplete || 246 } else if (params->prevent_inline_autocomplete ||
247 history_matches.empty() || 247 history_matches.empty() ||
248 !PromoteMatchForInlineAutocomplete(params, history_matches.front())) { 248 !PromoteMatchForInlineAutocomplete(params, history_matches.front(),
249 history_matches)) {
249 // Failed to promote any URLs for inline autocompletion. Use the What You 250 // Failed to promote any URLs for inline autocompletion. Use the What You
250 // Typed match, if we have it. 251 // Typed match, if we have it.
251 first_match = 0; 252 first_match = 0;
252 if (have_what_you_typed_match) 253 if (have_what_you_typed_match)
253 params->matches.push_back(what_you_typed_match); 254 params->matches.push_back(what_you_typed_match);
254 } 255 }
255 256
256 // This is the end of the synchronous pass. 257 // This is the end of the synchronous pass.
257 if (!backend) 258 if (!backend)
258 return; 259 return;
259 260
260 // Remove redirects and trim list to size. We want to provide up to 261 // Remove redirects and trim list to size. We want to provide up to
261 // kMaxMatches results plus the What You Typed result, if it was added to 262 // kMaxMatches results plus the What You Typed result, if it was added to
262 // |history_matches| above. 263 // |history_matches| above.
263 CullRedirects(backend, &history_matches, kMaxMatches + exact_suggestion); 264 CullRedirects(backend, &history_matches, kMaxMatches + exact_suggestion);
264 265
265 // Convert the history matches to autocomplete matches. 266 // Convert the history matches to autocomplete matches.
266 for (size_t i = first_match; i < history_matches.size(); ++i) { 267 for (size_t i = first_match; i < history_matches.size(); ++i) {
267 const HistoryMatch& match = history_matches[i]; 268 const HistoryMatch& match = history_matches[i];
268 DCHECK(!have_what_you_typed_match || 269 DCHECK(!have_what_you_typed_match ||
269 (match.url_info.url() != 270 (match.url_info.url() !=
270 GURL(params->matches.front().destination_url))); 271 GURL(params->matches.front().destination_url)));
271 params->matches.push_back(HistoryMatchToACMatch(params, match, NORMAL, 272 AutocompleteMatch ac_match =
272 history_matches.size() - 1 - i)); 273 HistoryMatchToACMatch(params, match, history_matches, NORMAL,
274 history_matches.size() - 1 - i);
275 UMA_HISTOGRAM_COUNTS_100("Autocomplete.Confidence_HistoryUrl",
276 ac_match.confidence * 100);
277 params->matches.push_back(ac_match);
273 } 278 }
274 } 279 }
275 280
276 // Called on the main thread when the query is complete. 281 // Called on the main thread when the query is complete.
277 void HistoryURLProvider::QueryComplete( 282 void HistoryURLProvider::QueryComplete(
278 HistoryURLProviderParams* params_gets_deleted) { 283 HistoryURLProviderParams* params_gets_deleted) {
279 // Ensure |params_gets_deleted| gets deleted on exit. 284 // Ensure |params_gets_deleted| gets deleted on exit.
280 scoped_ptr<HistoryURLProviderParams> params(params_gets_deleted); 285 scoped_ptr<HistoryURLProviderParams> params(params_gets_deleted);
281 286
282 // If the user hasn't already started another query, clear our member pointer 287 // If the user hasn't already started another query, clear our member pointer
(...skipping 12 matching lines...) Expand all
295 UpdateStarredStateOfMatches(); 300 UpdateStarredStateOfMatches();
296 } 301 }
297 302
298 done_ = true; 303 done_ = true;
299 listener_->OnProviderUpdate(true); 304 listener_->OnProviderUpdate(true);
300 } 305 }
301 306
302 AutocompleteMatch HistoryURLProvider::SuggestExactInput( 307 AutocompleteMatch HistoryURLProvider::SuggestExactInput(
303 const AutocompleteInput& input, 308 const AutocompleteInput& input,
304 bool trim_http) { 309 bool trim_http) {
310 // TODO(dominich): Find a confidence measure for this.
305 AutocompleteMatch match(this, 311 AutocompleteMatch match(this,
306 CalculateRelevance(input.type(), WHAT_YOU_TYPED, 0), false, 312 CalculateRelevance(input.type(), WHAT_YOU_TYPED, 0), 0.0f, false,
307 AutocompleteMatch::URL_WHAT_YOU_TYPED); 313 AutocompleteMatch::URL_WHAT_YOU_TYPED);
314 UMA_HISTOGRAM_COUNTS_100("Autocomplete.Confidence_HistoryUrl",
315 match.confidence * 100);
308 316
309 const GURL& url = input.canonicalized_url(); 317 const GURL& url = input.canonicalized_url();
310 if (url.is_valid()) { 318 if (url.is_valid()) {
311 match.destination_url = url; 319 match.destination_url = url;
312 320
313 // Trim off "http://" if the user didn't type it. 321 // Trim off "http://" if the user didn't type it.
314 // NOTE: We use TrimHttpPrefix() here rather than StringForURLDisplay() to 322 // NOTE: We use TrimHttpPrefix() here rather than StringForURLDisplay() to
315 // strip the scheme as we need to know the offset so we can adjust the 323 // strip the scheme as we need to know the offset so we can adjust the
316 // |match_location| below. StringForURLDisplay() and TrimHttpPrefix() have 324 // |match_location| below. StringForURLDisplay() and TrimHttpPrefix() have
317 // slightly different behavior as well (the latter will strip even without 325 // slightly different behavior as well (the latter will strip even without
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 // Promote as an exact match. 412 // Promote as an exact match.
405 match->relevance = CalculateRelevance(input.type(), type, 0); 413 match->relevance = CalculateRelevance(input.type(), type, 0);
406 414
407 // Put it on the front of the HistoryMatches for redirect culling. 415 // Put it on the front of the HistoryMatches for redirect culling.
408 EnsureMatchPresent(info, string16::npos, false, matches, true); 416 EnsureMatchPresent(info, string16::npos, false, matches, true);
409 return true; 417 return true;
410 } 418 }
411 419
412 bool HistoryURLProvider::PromoteMatchForInlineAutocomplete( 420 bool HistoryURLProvider::PromoteMatchForInlineAutocomplete(
413 HistoryURLProviderParams* params, 421 HistoryURLProviderParams* params,
414 const HistoryMatch& match) { 422 const HistoryMatch& match,
423 const HistoryMatches& matches) {
415 // Promote the first match if it's been typed at least n times, where n == 1 424 // Promote the first match if it's been typed at least n times, where n == 1
416 // for "simple" (host-only) URLs and n == 2 for others. We set a higher bar 425 // for "simple" (host-only) URLs and n == 2 for others. We set a higher bar
417 // for these long URLs because it's less likely that users will want to visit 426 // for these long URLs because it's less likely that users will want to visit
418 // them again. Even though we don't increment the typed_count for pasted-in 427 // them again. Even though we don't increment the typed_count for pasted-in
419 // URLs, if the user manually edits the URL or types some long thing in by 428 // URLs, if the user manually edits the URL or types some long thing in by
420 // hand, we wouldn't want to immediately start autocompleting it. 429 // hand, we wouldn't want to immediately start autocompleting it.
421 if (!match.url_info.typed_count() || 430 if (!match.url_info.typed_count() ||
422 ((match.url_info.typed_count() == 1) && 431 ((match.url_info.typed_count() == 1) &&
423 !history::IsHostOnly(match.url_info.url()))) 432 !history::IsHostOnly(match.url_info.url())))
424 return false; 433 return false;
425 434
426 // In the case where the user has typed "foo.com" and visited (but not typed) 435 // In the case where the user has typed "foo.com" and visited (but not typed)
427 // "foo/", and the input is "foo", we can reach here for "foo.com" during the 436 // "foo/", and the input is "foo", we can reach here for "foo.com" during the
428 // first pass but have the second pass suggest the exact input as a better 437 // first pass but have the second pass suggest the exact input as a better
429 // URL. Since we need both passes to agree, and since during the first pass 438 // URL. Since we need both passes to agree, and since during the first pass
430 // there's no way to know about "foo/", make reaching this point prevent any 439 // there's no way to know about "foo/", make reaching this point prevent any
431 // future pass from suggesting the exact input as a better match. 440 // future pass from suggesting the exact input as a better match.
432 params->dont_suggest_exact_input = true; 441 params->dont_suggest_exact_input = true;
433 params->matches.push_back(HistoryMatchToACMatch(params, match, 442 params->matches.push_back(HistoryMatchToACMatch(params, match, matches,
434 INLINE_AUTOCOMPLETE, 0)); 443 INLINE_AUTOCOMPLETE, 0));
435 return true; 444 return true;
436 } 445 }
437 446
438 HistoryURLProvider::~HistoryURLProvider() {} 447 HistoryURLProvider::~HistoryURLProvider() {}
439 448
440 // static 449 // static
441 history::Prefixes HistoryURLProvider::GetPrefixes() { 450 history::Prefixes HistoryURLProvider::GetPrefixes() {
442 // We'll complete text following these prefixes. 451 // We'll complete text following these prefixes.
443 // NOTE: There's no requirement that these be in any particular order. 452 // NOTE: There's no requirement that these be in any particular order.
(...skipping 20 matching lines...) Expand all
464 473
465 case WHAT_YOU_TYPED: 474 case WHAT_YOU_TYPED:
466 return 1200; 475 return 1200;
467 476
468 default: 477 default:
469 return 900 + static_cast<int>(match_number); 478 return 900 + static_cast<int>(match_number);
470 } 479 }
471 } 480 }
472 481
473 // static 482 // static
483 float HistoryURLProvider::CalculateConfidence(
484 const history::HistoryMatch& match,
485 const history::HistoryMatches& matches) {
486 // TODO(dominich): Take into account bookmarked page?
487 // TODO(dominich): See CompareHistoryMatch for more measures to include.
488 // Using typed count in place of visit count as:
489 // - It's a better indicator of what the user wants to open given that they
490 // are typing in the address bar (users tend to open certain URLs by typing
491 // and others by e.g. bookmarks, so visit_count is a good indicator of
492 // overall interest but a bad one for specifically omnibox interest).
493 // - Since the DB query is sorted by typed_count, the results may be
494 // effectively a random selection as far as visit_counts are concerned
495 // (meaning many high-visit_count-URLs may be present in one query and
496 // absent in a similar one), leading to wild swings in confidence for the
497 // same result across distinct queries.
498 float numerator = match.url_info.typed_count();
499 float denominator = 0.0f;
500 for (history::HistoryMatches::const_iterator it = matches.begin();
501 it != matches.end(); ++it) {
502 denominator += it->url_info.typed_count();
503 }
504 if (denominator < 1) {
505 numerator = match.url_info.visit_count();
506 for (history::HistoryMatches::const_iterator it = matches.begin();
507 it != matches.end(); ++it) {
508 denominator += it->url_info.visit_count();
509 }
510 }
511 return (denominator > 0.0f ? numerator / denominator : 0);
512 }
513
514 // static
474 void HistoryURLProvider::PromoteOrCreateShorterSuggestion( 515 void HistoryURLProvider::PromoteOrCreateShorterSuggestion(
475 history::URLDatabase* db, 516 history::URLDatabase* db,
476 const HistoryURLProviderParams& params, 517 const HistoryURLProviderParams& params,
477 bool have_what_you_typed_match, 518 bool have_what_you_typed_match,
478 const AutocompleteMatch& what_you_typed_match, 519 const AutocompleteMatch& what_you_typed_match,
479 HistoryMatches* matches) { 520 HistoryMatches* matches) {
480 if (matches->empty()) 521 if (matches->empty())
481 return; // No matches, nothing to do. 522 return; // No matches, nothing to do.
482 523
483 // Determine the base URL from which to search, and whether that URL could 524 // Determine the base URL from which to search, and whether that URL could
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 next = matches->erase(next); 808 next = matches->erase(next);
768 if (static_cast<size_t>(next - matches->begin()) < next_index) 809 if (static_cast<size_t>(next - matches->begin()) < next_index)
769 next_index--; 810 next_index--;
770 } 811 }
771 return next_index; 812 return next_index;
772 } 813 }
773 814
774 AutocompleteMatch HistoryURLProvider::HistoryMatchToACMatch( 815 AutocompleteMatch HistoryURLProvider::HistoryMatchToACMatch(
775 HistoryURLProviderParams* params, 816 HistoryURLProviderParams* params,
776 const HistoryMatch& history_match, 817 const HistoryMatch& history_match,
818 const HistoryMatches& history_matches,
777 MatchType match_type, 819 MatchType match_type,
778 size_t match_number) { 820 size_t match_number) {
779 const history::URLRow& info = history_match.url_info; 821 const history::URLRow& info = history_match.url_info;
780 AutocompleteMatch match(this, 822 AutocompleteMatch match(this,
781 CalculateRelevance(params->input.type(), match_type, match_number), 823 CalculateRelevance(params->input.type(), match_type, match_number),
824 CalculateConfidence(history_match, history_matches),
782 !!info.visit_count(), AutocompleteMatch::HISTORY_URL); 825 !!info.visit_count(), AutocompleteMatch::HISTORY_URL);
783 match.destination_url = info.url(); 826 match.destination_url = info.url();
784 DCHECK(match.destination_url.is_valid()); 827 DCHECK(match.destination_url.is_valid());
785 size_t inline_autocomplete_offset = 828 size_t inline_autocomplete_offset =
786 history_match.input_location + params->input.text().length(); 829 history_match.input_location + params->input.text().length();
787 std::string languages = (match_type == WHAT_YOU_TYPED) ? 830 std::string languages = (match_type == WHAT_YOU_TYPED) ?
788 std::string() : params->languages; 831 std::string() : params->languages;
789 const net::FormatUrlTypes format_types = net::kFormatUrlOmitAll & 832 const net::FormatUrlTypes format_types = net::kFormatUrlOmitAll &
790 ~((params->trim_http && !history_match.match_in_scheme) ? 833 ~((params->trim_http && !history_match.match_in_scheme) ?
791 0 : net::kFormatUrlOmitHTTP); 834 0 : net::kFormatUrlOmitHTTP);
(...skipping 23 matching lines...) Expand all
815 &match.contents_class); 858 &match.contents_class);
816 } 859 }
817 match.description = info.title(); 860 match.description = info.title();
818 AutocompleteMatch::ClassifyMatchInString(params->input.text(), 861 AutocompleteMatch::ClassifyMatchInString(params->input.text(),
819 info.title(), 862 info.title(),
820 ACMatchClassification::NONE, 863 ACMatchClassification::NONE,
821 &match.description_class); 864 &match.description_class);
822 865
823 return match; 866 return match;
824 } 867 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/history_url_provider.h ('k') | chrome/browser/autocomplete/keyword_provider.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698