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

Side by Side Diff: components/omnibox/browser/autocomplete_result.cc

Issue 1877833002: Optimize shortcuts provider (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase on master and minor format fix Created 4 years, 8 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/omnibox/browser/autocomplete_result.h" 5 #include "components/omnibox/browser/autocomplete_result.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "components/metrics/proto/omnibox_event.pb.h" 13 #include "components/metrics/proto/omnibox_event.pb.h"
14 #include "components/metrics/proto/omnibox_input_type.pb.h" 14 #include "components/metrics/proto/omnibox_input_type.pb.h"
15 #include "components/omnibox/browser/autocomplete_input.h" 15 #include "components/omnibox/browser/autocomplete_input.h"
16 #include "components/omnibox/browser/autocomplete_match.h" 16 #include "components/omnibox/browser/autocomplete_match.h"
17 #include "components/omnibox/browser/autocomplete_provider.h" 17 #include "components/omnibox/browser/autocomplete_provider.h"
18 #include "components/omnibox/browser/match_compare.h"
18 #include "components/omnibox/browser/omnibox_field_trial.h" 19 #include "components/omnibox/browser/omnibox_field_trial.h"
19 #include "components/omnibox/browser/omnibox_switches.h" 20 #include "components/omnibox/browser/omnibox_switches.h"
20 #include "components/search/search.h" 21 #include "components/search/search.h"
21 #include "components/url_formatter/url_fixer.h" 22 #include "components/url_formatter/url_fixer.h"
22 23
23 using metrics::OmniboxEventProto;
24
25 namespace {
26
27 // This class implements a special version of AutocompleteMatch::MoreRelevant
28 // that allows matches of particular types to be demoted in AutocompleteResult.
29 class CompareWithDemoteByType {
30 public:
31 CompareWithDemoteByType(
32 OmniboxEventProto::PageClassification current_page_classification);
33
34 // Returns the relevance score of |match| demoted appropriately by
35 // |demotions_by_type_|.
36 int GetDemotedRelevance(const AutocompleteMatch& match);
37
38 // Comparison function.
39 bool operator()(const AutocompleteMatch& elem1,
40 const AutocompleteMatch& elem2);
41
42 private:
43 OmniboxFieldTrial::DemotionMultipliers demotions_;
44 };
45
46 CompareWithDemoteByType::CompareWithDemoteByType(
47 OmniboxEventProto::PageClassification current_page_classification) {
48 OmniboxFieldTrial::GetDemotionsByType(current_page_classification,
49 &demotions_);
50 }
51
52 int CompareWithDemoteByType::GetDemotedRelevance(
53 const AutocompleteMatch& match) {
54 OmniboxFieldTrial::DemotionMultipliers::const_iterator demotion_it =
55 demotions_.find(match.type);
56 return (demotion_it == demotions_.end()) ?
57 match.relevance : (match.relevance * demotion_it->second);
58 }
59
60 bool CompareWithDemoteByType::operator()(const AutocompleteMatch& elem1,
61 const AutocompleteMatch& elem2) {
62 // Compute demoted relevance scores for each match.
63 const int demoted_relevance1 = GetDemotedRelevance(elem1);
64 const int demoted_relevance2 = GetDemotedRelevance(elem2);
65 // For equal-relevance matches, we sort alphabetically, so that providers
66 // who return multiple elements at the same priority get a "stable" sort
67 // across multiple updates.
68 return (demoted_relevance1 == demoted_relevance2) ?
69 (elem1.contents < elem2.contents) :
70 (demoted_relevance1 > demoted_relevance2);
71 }
72
73 class DestinationSort {
74 public:
75 DestinationSort(
76 OmniboxEventProto::PageClassification current_page_classification);
77 bool operator()(const AutocompleteMatch& elem1,
78 const AutocompleteMatch& elem2);
79
80 private:
81 CompareWithDemoteByType demote_by_type_;
82 };
83
84 DestinationSort::DestinationSort(
85 OmniboxEventProto::PageClassification current_page_classification) :
86 demote_by_type_(current_page_classification) {}
87
88 bool DestinationSort::operator()(const AutocompleteMatch& elem1,
89 const AutocompleteMatch& elem2) {
90 // Sort identical destination_urls together. Place the most relevant matches
91 // first, so that when we call std::unique(), these are the ones that get
92 // preserved.
93 if (AutocompleteMatch::DestinationsEqual(elem1, elem2) ||
94 (elem1.stripped_destination_url.is_empty() &&
95 elem2.stripped_destination_url.is_empty())) {
96 return demote_by_type_(elem1, elem2);
97 }
98 return elem1.stripped_destination_url < elem2.stripped_destination_url;
99 }
100
101 }; // namespace
102
103 // static 24 // static
104 const size_t AutocompleteResult::kMaxMatches = 6; 25 const size_t AutocompleteResult::kMaxMatches = 6;
105 26
106 void AutocompleteResult::Selection::Clear() { 27 void AutocompleteResult::Selection::Clear() {
107 destination_url = GURL(); 28 destination_url = GURL();
108 provider_affinity = NULL; 29 provider_affinity = NULL;
109 is_history_what_you_typed_match = false; 30 is_history_what_you_typed_match = false;
110 } 31 }
111 32
112 AutocompleteResult::AutocompleteResult() { 33 AutocompleteResult::AutocompleteResult() {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 default_match_ = end(); 121 default_match_ = end();
201 alternate_nav_url_ = GURL(); 122 alternate_nav_url_ = GURL();
202 } 123 }
203 124
204 void AutocompleteResult::SortAndCull( 125 void AutocompleteResult::SortAndCull(
205 const AutocompleteInput& input, 126 const AutocompleteInput& input,
206 TemplateURLService* template_url_service) { 127 TemplateURLService* template_url_service) {
207 for (ACMatches::iterator i(matches_.begin()); i != matches_.end(); ++i) 128 for (ACMatches::iterator i(matches_.begin()); i != matches_.end(); ++i)
208 i->ComputeStrippedDestinationURL(input, template_url_service); 129 i->ComputeStrippedDestinationURL(input, template_url_service);
209 130
210 DedupMatchesByDestination(input.current_page_classification(), true, 131 SortAndDedupMatches(input.current_page_classification(), &matches_);
211 &matches_);
212 132
213 // Sort and trim to the most relevant kMaxMatches matches. 133 // Sort and trim to the most relevant kMaxMatches matches.
214 size_t max_num_matches = std::min(kMaxMatches, matches_.size()); 134 size_t max_num_matches = std::min(kMaxMatches, matches_.size());
215 CompareWithDemoteByType comparing_object(input.current_page_classification()); 135 CompareWithDemoteByType<AutocompleteMatch> comparing_object(
136 input.current_page_classification());
216 std::sort(matches_.begin(), matches_.end(), comparing_object); 137 std::sort(matches_.begin(), matches_.end(), comparing_object);
217 if (!matches_.empty() && !matches_.begin()->allowed_to_be_default_match) { 138 if (!matches_.empty() && !matches_.begin()->allowed_to_be_default_match) {
218 // Top match is not allowed to be the default match. Find the most 139 // Top match is not allowed to be the default match. Find the most
219 // relevant legal match and shift it to the front. 140 // relevant legal match and shift it to the front.
220 for (AutocompleteResult::iterator it = matches_.begin() + 1; 141 for (AutocompleteResult::iterator it = matches_.begin() + 1;
221 it != matches_.end(); ++it) { 142 it != matches_.end(); ++it) {
222 if (it->allowed_to_be_default_match) { 143 if (it->allowed_to_be_default_match) {
223 std::rotate(matches_.begin(), it, it + 1); 144 std::rotate(matches_.begin(), it, it + 1);
224 break; 145 break;
225 } 146 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 GURL AutocompleteResult::ComputeAlternateNavUrl( 280 GURL AutocompleteResult::ComputeAlternateNavUrl(
360 const AutocompleteInput& input, 281 const AutocompleteInput& input,
361 const AutocompleteMatch& match) { 282 const AutocompleteMatch& match) {
362 return ((input.type() == metrics::OmniboxInputType::UNKNOWN) && 283 return ((input.type() == metrics::OmniboxInputType::UNKNOWN) &&
363 (AutocompleteMatch::IsSearchType(match.type)) && 284 (AutocompleteMatch::IsSearchType(match.type)) &&
364 (match.transition != ui::PAGE_TRANSITION_KEYWORD) && 285 (match.transition != ui::PAGE_TRANSITION_KEYWORD) &&
365 (input.canonicalized_url() != match.destination_url)) ? 286 (input.canonicalized_url() != match.destination_url)) ?
366 input.canonicalized_url() : GURL(); 287 input.canonicalized_url() : GURL();
367 } 288 }
368 289
369 void AutocompleteResult::DedupMatchesByDestination( 290 void AutocompleteResult::SortAndDedupMatches(
370 OmniboxEventProto::PageClassification page_classification, 291 metrics::OmniboxEventProto::PageClassification page_classification,
371 bool set_duplicate_matches, 292 ACMatches* matches) {
372 ACMatches* matches) {
373 DestinationSort destination_sort(page_classification);
374 // Sort matches such that duplicate matches are consecutive. 293 // Sort matches such that duplicate matches are consecutive.
375 std::sort(matches->begin(), matches->end(), destination_sort); 294 std::sort(matches->begin(), matches->end(),
295 DestinationSort<AutocompleteMatch>(page_classification));
376 296
377 if (set_duplicate_matches) { 297 // Set duplicate_matches for the first match before erasing duplicate
378 // Set duplicate_matches for the first match before erasing duplicate 298 // matches.
379 // matches. 299 for (ACMatches::iterator i(matches->begin()); i != matches->end(); ++i) {
380 for (ACMatches::iterator i(matches->begin()); i != matches->end(); ++i) { 300 for (int j = 1; (i + j != matches->end()) &&
381 for (int j = 1; (i + j != matches->end()) && 301 AutocompleteMatch::DestinationsEqual(*i, *(i + j));
382 AutocompleteMatch::DestinationsEqual(*i, *(i + j)); ++j) { 302 ++j) {
383 AutocompleteMatch& dup_match(*(i + j)); 303 AutocompleteMatch& dup_match(*(i + j));
384 i->duplicate_matches.insert(i->duplicate_matches.end(), 304 i->duplicate_matches.insert(i->duplicate_matches.end(),
385 dup_match.duplicate_matches.begin(), 305 dup_match.duplicate_matches.begin(),
386 dup_match.duplicate_matches.end()); 306 dup_match.duplicate_matches.end());
387 dup_match.duplicate_matches.clear(); 307 dup_match.duplicate_matches.clear();
388 i->duplicate_matches.push_back(dup_match); 308 i->duplicate_matches.push_back(dup_match);
389 }
390 } 309 }
391 } 310 }
392 311
393 // Erase duplicate matches. 312 // Erase duplicate matches.
394 matches->erase(std::unique(matches->begin(), matches->end(), 313 matches->erase(std::unique(matches->begin(), matches->end(),
395 &AutocompleteMatch::DestinationsEqual), 314 &AutocompleteMatch::DestinationsEqual),
396 matches->end()); 315 matches->end());
397 } 316 }
398 317
399 void AutocompleteResult::CopyFrom(const AutocompleteResult& rhs) { 318 void AutocompleteResult::CopyFrom(const AutocompleteResult& rhs) {
(...skipping 19 matching lines...) Expand all
419 bool AutocompleteResult::HasMatchByDestination(const AutocompleteMatch& match, 338 bool AutocompleteResult::HasMatchByDestination(const AutocompleteMatch& match,
420 const ACMatches& matches) { 339 const ACMatches& matches) {
421 for (ACMatches::const_iterator i(matches.begin()); i != matches.end(); ++i) { 340 for (ACMatches::const_iterator i(matches.begin()); i != matches.end(); ++i) {
422 if (i->destination_url == match.destination_url) 341 if (i->destination_url == match.destination_url)
423 return true; 342 return true;
424 } 343 }
425 return false; 344 return false;
426 } 345 }
427 346
428 void AutocompleteResult::MergeMatchesByProvider( 347 void AutocompleteResult::MergeMatchesByProvider(
429 OmniboxEventProto::PageClassification page_classification, 348 metrics::OmniboxEventProto::PageClassification page_classification,
430 const ACMatches& old_matches, 349 const ACMatches& old_matches,
431 const ACMatches& new_matches) { 350 const ACMatches& new_matches) {
432 if (new_matches.size() >= old_matches.size()) 351 if (new_matches.size() >= old_matches.size())
433 return; 352 return;
434 353
435 // Prevent old matches from this provider from outranking new ones and 354 // Prevent old matches from this provider from outranking new ones and
436 // becoming the default match by capping old matches' scores to be less than 355 // becoming the default match by capping old matches' scores to be less than
437 // the highest-scoring allowed-to-be-default match from this provider. 356 // the highest-scoring allowed-to-be-default match from this provider.
438 ACMatches::const_iterator i = std::find_if( 357 ACMatches::const_iterator i = std::find_if(
439 new_matches.begin(), new_matches.end(), 358 new_matches.begin(), new_matches.end(),
(...skipping 22 matching lines...) Expand all
462 i != old_matches.rend() && delta > 0; ++i) { 381 i != old_matches.rend() && delta > 0; ++i) {
463 if (!HasMatchByDestination(*i, new_matches)) { 382 if (!HasMatchByDestination(*i, new_matches)) {
464 AutocompleteMatch match = *i; 383 AutocompleteMatch match = *i;
465 match.relevance = std::min(max_relevance, match.relevance); 384 match.relevance = std::min(max_relevance, match.relevance);
466 match.from_previous = true; 385 match.from_previous = true;
467 matches_.push_back(match); 386 matches_.push_back(match);
468 delta--; 387 delta--;
469 } 388 }
470 } 389 }
471 } 390 }
OLDNEW
« no previous file with comments | « components/omnibox/browser/autocomplete_result.h ('k') | components/omnibox/browser/history_url_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698