Chromium Code Reviews| 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 "chrome/browser/ui/app_list/search/mixer.h" | 5 #include "chrome/browser/ui/app_list/search/mixer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "chrome/browser/ui/app_list/search/chrome_search_result.h" | 12 #include "chrome/browser/ui/app_list/search/chrome_search_result.h" |
| 13 #include "ui/app_list/search_provider.h" | 13 #include "ui/app_list/search_provider.h" |
| 14 | 14 |
| 15 namespace app_list { | 15 namespace app_list { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 // Maximum number of results to show. | 19 // Maximum number of results to show. |
| 20 const size_t kMaxResults = 6; | 20 const size_t kMaxResults = 6; |
| 21 const size_t kMaxMainGroupResults = 4; | 21 const size_t kMaxMainGroupResults = 4; |
| 22 const size_t kMaxWebstoreResults = 2; | 22 const size_t kMaxWebstoreResults = 2; |
| 23 const size_t kMaxPeopleResults = 2; | 23 const size_t kMaxPeopleResults = 2; |
| 24 | 24 |
| 25 // A value to indicate no max number of results limit. | 25 // A value to indicate no max number of results limit. |
| 26 const size_t kNoMaxResultsLimit = 0; | 26 const size_t kNoMaxResultsLimit = 0; |
| 27 | 27 |
| 28 void UpdateResult(const ChromeSearchResult& source, | |
| 29 ChromeSearchResult* target) { | |
| 30 target->set_title(source.title()); | |
| 31 target->set_title_tags(source.title_tags()); | |
| 32 target->set_details(source.details()); | |
| 33 target->set_details_tags(source.details_tags()); | |
| 34 } | |
| 35 | |
| 28 } // namespace | 36 } // namespace |
| 29 | 37 |
| 30 Mixer::SortData::SortData() : result(NULL), score(0.0) { | 38 Mixer::SortData::SortData() : result(NULL), score(0.0) { |
| 31 } | 39 } |
| 32 | 40 |
| 33 Mixer::SortData::SortData(ChromeSearchResult* result, double score) | 41 Mixer::SortData::SortData(ChromeSearchResult* result, double score) |
| 34 : result(result), score(score) { | 42 : result(result), score(score) { |
| 35 } | 43 } |
| 36 | 44 |
| 37 bool Mixer::SortData::operator<(const SortData& other) const { | 45 bool Mixer::SortData::operator<(const SortData& other) const { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 groups_[OMNIBOX_GROUP]->results().begin() + remaining_slots); | 172 groups_[OMNIBOX_GROUP]->results().begin() + remaining_slots); |
| 165 | 173 |
| 166 std::sort(results.begin(), results.end()); | 174 std::sort(results.begin(), results.end()); |
| 167 RemoveDuplicates(&results); | 175 RemoveDuplicates(&results); |
| 168 if (results.size() > kMaxResults) | 176 if (results.size() > kMaxResults) |
| 169 results.resize(kMaxResults); | 177 results.resize(kMaxResults); |
| 170 | 178 |
| 171 Publish(results, ui_results_); | 179 Publish(results, ui_results_); |
| 172 } | 180 } |
| 173 | 181 |
| 174 void Mixer::Publish(const SortedResults& results, | 182 // The following algorithm is used: |
|
Matt Giuca
2014/07/09 01:30:54
nit: Move this comment inside the function braces
calamity
2014/07/09 03:03:48
Done.
| |
| 183 // 1. Transform the |ui_results| list into an unordered map from result ID | |
| 184 // to item. | |
| 185 // 2. Use the order of items in |new_results| to build an ordered list. If the | |
| 186 // result IDs exist in the map, update and use the item in the map and delete | |
| 187 // it from the map afterwards. Otherwise, clone new items from |new_results|. | |
| 188 // 3. Delete the objects remaining in the map as they are unused. | |
| 189 void Mixer::Publish(const SortedResults& new_results, | |
| 175 AppListModel::SearchResults* ui_results) { | 190 AppListModel::SearchResults* ui_results) { |
| 176 for (size_t i = 0; i < results.size(); ++i) { | 191 typedef std::map<std::string, ChromeSearchResult*> IdToResultMap; |
| 177 ChromeSearchResult* result = results[i].result; | |
| 178 | 192 |
| 193 // A map of the items in |ui_results| that takes ownership of the items. | |
| 194 IdToResultMap ui_results_map; | |
| 195 for (size_t i = 0; i < ui_results->item_count(); ++i) { | |
| 179 ChromeSearchResult* ui_result = | 196 ChromeSearchResult* ui_result = |
| 180 i < ui_results->item_count() | 197 static_cast<ChromeSearchResult*>(ui_results->GetItemAt(i)); |
| 181 ? static_cast<ChromeSearchResult*>(ui_results->GetItemAt(i)) | 198 ui_results_map[ui_result->id()] = ui_result; |
| 182 : NULL; | 199 } |
| 183 if (ui_result && ui_result->id() == result->id()) { | 200 // We have to erase all results at once so that observers are notified with |
| 184 ui_result->set_title(result->title()); | 201 // meaningful indexes. |
| 185 ui_result->set_title_tags(result->title_tags()); | 202 ui_results->RemoveAll(); |
| 186 ui_result->set_details(result->details()); | 203 |
| 187 ui_result->set_details_tags(result->details_tags()); | 204 // Add items back to |ui_results| in the order of |new_results|. |
| 188 ui_results->NotifyItemsChanged(i, 1); | 205 for (size_t i = 0; i < new_results.size(); ++i) { |
| 206 ChromeSearchResult* new_result = new_results[i].result; | |
| 207 IdToResultMap::const_iterator ui_result_it = | |
| 208 ui_results_map.find(new_result->id()); | |
| 209 if (ui_result_it != ui_results_map.end()) { | |
| 210 // Update and use the old result if it exists. | |
| 211 ChromeSearchResult* ui_result = ui_result_it->second; | |
| 212 UpdateResult(*new_result, ui_result); | |
| 213 | |
| 214 // |ui_results| takes back ownership from |ui_results_map| here. | |
| 215 ui_results->Add(ui_result); | |
| 216 | |
| 217 // Remove the item from the map so that it ends up only with unused | |
| 218 // results. | |
| 219 ui_results_map.erase(ui_result_it); | |
| 189 } else { | 220 } else { |
| 190 if (ui_result) | 221 // Copy the result from |new_results| otherwise. |
| 191 ui_results->DeleteAt(i); | 222 ui_results->Add(new_result->Duplicate().release()); |
| 192 ui_results->AddAt(i, result->Duplicate().release()); | |
| 193 } | 223 } |
| 194 } | 224 } |
| 195 | 225 |
| 196 while (ui_results->item_count() > results.size()) | 226 // Delete the results remaining in the map as they are not in the new results. |
| 197 ui_results->DeleteAt(ui_results->item_count() - 1); | 227 for (IdToResultMap::const_iterator ui_result_it = ui_results_map.begin(); |
| 228 ui_result_it != ui_results_map.end(); | |
| 229 ++ui_result_it) { | |
| 230 delete ui_result_it->second; | |
| 231 } | |
| 198 } | 232 } |
| 199 | 233 |
| 200 void Mixer::RemoveDuplicates(SortedResults* results) { | 234 void Mixer::RemoveDuplicates(SortedResults* results) { |
| 201 SortedResults final; | 235 SortedResults final; |
| 202 final.reserve(results->size()); | 236 final.reserve(results->size()); |
| 203 | 237 |
| 204 std::set<std::string> id_set; | 238 std::set<std::string> id_set; |
| 205 for (SortedResults::iterator it = results->begin(); it != results->end(); | 239 for (SortedResults::iterator it = results->begin(); it != results->end(); |
| 206 ++it) { | 240 ++it) { |
| 207 const std::string& id = it->result->id(); | 241 const std::string& id = it->result->id(); |
| 208 if (id_set.find(id) != id_set.end()) | 242 if (id_set.find(id) != id_set.end()) |
| 209 continue; | 243 continue; |
| 210 | 244 |
| 211 id_set.insert(id); | 245 id_set.insert(id); |
| 212 final.push_back(*it); | 246 final.push_back(*it); |
| 213 } | 247 } |
| 214 | 248 |
| 215 results->swap(final); | 249 results->swap(final); |
| 216 } | 250 } |
| 217 | 251 |
| 218 void Mixer::FetchResults(const KnownResults& known_results) { | 252 void Mixer::FetchResults(const KnownResults& known_results) { |
| 219 for (Groups::iterator group_it = groups_.begin(); | 253 for (Groups::iterator group_it = groups_.begin(); |
| 220 group_it != groups_.end(); | 254 group_it != groups_.end(); |
| 221 ++group_it) { | 255 ++group_it) { |
| 222 (*group_it)->FetchResults(known_results); | 256 (*group_it)->FetchResults(known_results); |
| 223 } | 257 } |
| 224 } | 258 } |
| 225 | 259 |
| 226 } // namespace app_list | 260 } // namespace app_list |
| OLD | NEW |