| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "ui/app_list/search/mixer.h" | 5 #include "ui/app_list/search/mixer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "ui/app_list/search_provider.h" | 13 #include "ui/app_list/search_provider.h" |
| 14 #include "ui/app_list/search_result.h" | 14 #include "ui/app_list/search_result.h" |
| 15 | 15 |
| 16 namespace app_list { | 16 namespace app_list { |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 // Maximum number of results to show. | 20 // Maximum number of results to show. |
| 21 const size_t kMaxResults = 6; | 21 const size_t kMaxResults = 6; |
| 22 | 22 |
| 23 // A value to indicate no max number of results limit. | |
| 24 const size_t kNoMaxResultsLimit = 0; | |
| 25 | |
| 26 void UpdateResult(const SearchResult& source, SearchResult* target) { | 23 void UpdateResult(const SearchResult& source, SearchResult* target) { |
| 27 target->set_display_type(source.display_type()); | 24 target->set_display_type(source.display_type()); |
| 28 target->set_title(source.title()); | 25 target->set_title(source.title()); |
| 29 target->set_title_tags(source.title_tags()); | 26 target->set_title_tags(source.title_tags()); |
| 30 target->set_details(source.details()); | 27 target->set_details(source.details()); |
| 31 target->set_details_tags(source.details_tags()); | 28 target->set_details_tags(source.details_tags()); |
| 32 } | 29 } |
| 33 | 30 |
| 34 } // namespace | 31 } // namespace |
| 35 | 32 |
| 36 Mixer::SortData::SortData() : result(NULL), score(0.0) { | 33 Mixer::SortData::SortData() : result(NULL), score(0.0) { |
| 37 } | 34 } |
| 38 | 35 |
| 39 Mixer::SortData::SortData(SearchResult* result, double score) | 36 Mixer::SortData::SortData(SearchResult* result, double score) |
| 40 : result(result), score(score) { | 37 : result(result), score(score) { |
| 41 } | 38 } |
| 42 | 39 |
| 43 bool Mixer::SortData::operator<(const SortData& other) const { | 40 bool Mixer::SortData::operator<(const SortData& other) const { |
| 44 // This data precedes (less than) |other| if it has higher score. | 41 // This data precedes (less than) |other| if it has higher score. |
| 45 return score > other.score; | 42 return score > other.score; |
| 46 } | 43 } |
| 47 | 44 |
| 48 // Used to group relevant providers together fox mixing their results. | 45 // Used to group relevant providers together for mixing their results. |
| 49 class Mixer::Group { | 46 class Mixer::Group { |
| 50 public: | 47 public: |
| 51 Group(size_t max_results, double boost) | 48 Group(size_t max_results, double boost) |
| 52 : max_results_(max_results), boost_(boost) {} | 49 : max_results_(max_results), boost_(boost) {} |
| 53 ~Group() {} | 50 ~Group() {} |
| 54 | 51 |
| 55 void AddProvider(SearchProvider* provider) { providers_.push_back(provider); } | 52 void AddProvider(SearchProvider* provider) { providers_.push_back(provider); } |
| 56 | 53 |
| 57 void FetchResults(bool is_voice_query, const KnownResults& known_results) { | 54 void FetchResults(bool is_voice_query, const KnownResults& known_results) { |
| 58 results_.clear(); | 55 results_.clear(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 | 88 |
| 92 // If this is a voice query, voice results receive a massive boost. | 89 // If this is a voice query, voice results receive a massive boost. |
| 93 if (is_voice_query && result->voice_result()) | 90 if (is_voice_query && result->voice_result()) |
| 94 boost += 4.0; | 91 boost += 4.0; |
| 95 | 92 |
| 96 results_.push_back(SortData(result, relevance + boost)); | 93 results_.push_back(SortData(result, relevance + boost)); |
| 97 } | 94 } |
| 98 } | 95 } |
| 99 | 96 |
| 100 std::sort(results_.begin(), results_.end()); | 97 std::sort(results_.begin(), results_.end()); |
| 101 if (max_results_ != kNoMaxResultsLimit && results_.size() > max_results_) | |
| 102 results_.resize(max_results_); | |
| 103 } | 98 } |
| 104 | 99 |
| 105 const SortedResults& results() const { return results_; } | 100 const SortedResults& results() const { return results_; } |
| 106 | 101 |
| 102 size_t max_results() const { return max_results_; } |
| 103 |
| 107 private: | 104 private: |
| 108 typedef std::vector<SearchProvider*> Providers; | 105 typedef std::vector<SearchProvider*> Providers; |
| 109 const size_t max_results_; | 106 const size_t max_results_; |
| 110 const double boost_; | 107 const double boost_; |
| 111 | 108 |
| 112 Providers providers_; // Not owned. | 109 Providers providers_; // Not owned. |
| 113 SortedResults results_; | 110 SortedResults results_; |
| 114 | 111 |
| 115 DISALLOW_COPY_AND_ASSIGN(Group); | 112 DISALLOW_COPY_AND_ASSIGN(Group); |
| 116 }; | 113 }; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 139 groups_[group_id]->AddProvider(provider); | 136 groups_[group_id]->AddProvider(provider); |
| 140 } | 137 } |
| 141 | 138 |
| 142 void Mixer::MixAndPublish(bool is_voice_query, | 139 void Mixer::MixAndPublish(bool is_voice_query, |
| 143 const KnownResults& known_results) { | 140 const KnownResults& known_results) { |
| 144 FetchResults(is_voice_query, known_results); | 141 FetchResults(is_voice_query, known_results); |
| 145 | 142 |
| 146 SortedResults results; | 143 SortedResults results; |
| 147 results.reserve(kMaxResults); | 144 results.reserve(kMaxResults); |
| 148 | 145 |
| 149 // Add results from non-omnibox groups first. | 146 // Add results from non-omnibox groups first. Limit to the maximum number of |
| 147 // results in each group. |
| 150 for (size_t i = 0; i < groups_.size(); ++i) { | 148 for (size_t i = 0; i < groups_.size(); ++i) { |
| 151 if (!has_omnibox_group_ || i != omnibox_group_) { | 149 if (!has_omnibox_group_ || i != omnibox_group_) { |
| 152 const Group& group = *groups_[i]; | 150 const Group& group = *groups_[i]; |
| 151 size_t num_results = |
| 152 std::min(group.results().size(), group.max_results()); |
| 153 results.insert(results.end(), group.results().begin(), | 153 results.insert(results.end(), group.results().begin(), |
| 154 group.results().end()); | 154 group.results().begin() + num_results); |
| 155 } | 155 } |
| 156 } | 156 } |
| 157 | 157 |
| 158 // Collapse duplicate apps from local and web store. | 158 // Collapse duplicate apps from local and web store. |
| 159 RemoveDuplicates(&results); | 159 RemoveDuplicates(&results); |
| 160 | 160 |
| 161 // Fill the remaining slots with omnibox results. Always add at least one | 161 // Fill the remaining slots with omnibox results. Always add at least one |
| 162 // omnibox result (even if there are no more slots; if we over-fill the | 162 // omnibox result (even if there are no more slots; if we over-fill the |
| 163 // vector, the web store and people results will be removed in a later step). | 163 // vector, the web store and people results will be removed in a later step). |
| 164 // Note: max_results() is ignored for the omnibox group. |
| 164 if (has_omnibox_group_) { | 165 if (has_omnibox_group_) { |
| 165 CHECK_LT(omnibox_group_, groups_.size()); | 166 CHECK_LT(omnibox_group_, groups_.size()); |
| 166 const Group& omnibox_group = *groups_[omnibox_group_]; | 167 const Group& omnibox_group = *groups_[omnibox_group_]; |
| 167 const size_t omnibox_results = std::min( | 168 const size_t omnibox_results = std::min( |
| 168 omnibox_group.results().size(), | 169 omnibox_group.results().size(), |
| 169 results.size() < kMaxResults ? kMaxResults - results.size() : 1); | 170 results.size() < kMaxResults ? kMaxResults - results.size() : 1); |
| 170 results.insert(results.end(), omnibox_group.results().begin(), | 171 results.insert(results.end(), omnibox_group.results().begin(), |
| 171 omnibox_group.results().begin() + omnibox_results); | 172 omnibox_group.results().begin() + omnibox_results); |
| 172 } | 173 } |
| 173 | 174 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 results->swap(final); | 248 results->swap(final); |
| 248 } | 249 } |
| 249 | 250 |
| 250 void Mixer::FetchResults(bool is_voice_query, | 251 void Mixer::FetchResults(bool is_voice_query, |
| 251 const KnownResults& known_results) { | 252 const KnownResults& known_results) { |
| 252 for (auto* group : groups_) | 253 for (auto* group : groups_) |
| 253 group->FetchResults(is_voice_query, known_results); | 254 group->FetchResults(is_voice_query, known_results); |
| 254 } | 255 } |
| 255 | 256 |
| 256 } // namespace app_list | 257 } // namespace app_list |
| OLD | NEW |