Chromium Code Reviews| Index: chrome/browser/ui/app_list/search/mixer.cc |
| diff --git a/chrome/browser/ui/app_list/search/mixer.cc b/chrome/browser/ui/app_list/search/mixer.cc |
| index 6a737713492183c446f450610d0811731f52e34c..8e3801cce5653b2aed21d35a748552d11dbdd712 100644 |
| --- a/chrome/browser/ui/app_list/search/mixer.cc |
| +++ b/chrome/browser/ui/app_list/search/mixer.cc |
| @@ -66,30 +66,63 @@ void RemoveDuplicates(SortedResults* results) { |
| results->swap(final); |
| } |
| -// Publishes the given |results| to |ui_results|. Reuse existing ones to avoid |
| -// flickering. |
| -void Publish(const SortedResults& results, |
| +// Publishes the given |new_results| to |ui_results|. Reuse existing ones to |
|
Matt Giuca
2014/07/04 08:21:21
I'm a little skeptical of the name |new_results|,
calamity
2014/07/08 09:47:20
Done. Also changed the second sentence to better d
|
| +// avoid flickering. |
| +void Publish(const SortedResults& new_results, |
|
Matt Giuca
2014/07/04 08:21:21
I think there should be unit tests for this functi
calamity
2014/07/08 09:47:21
Done.
|
| AppListModel::SearchResults* ui_results) { |
|
Matt Giuca
2014/07/04 08:21:22
It might be nice to give a high-level overview of
calamity
2014/07/08 09:47:20
Done. Changed for new algorithm.
|
| - for (size_t i = 0; i < results.size(); ++i) { |
| - ChromeSearchResult* result = results[i].result; |
| - |
| - ChromeSearchResult* ui_result = i < ui_results->item_count() ? |
| - static_cast<ChromeSearchResult*>(ui_results->GetItemAt(i)) : NULL; |
| - if (ui_result && ui_result->id() == result->id()) { |
| - ui_result->set_title(result->title()); |
| - ui_result->set_title_tags(result->title_tags()); |
| - ui_result->set_details(result->details()); |
| - ui_result->set_details_tags(result->details_tags()); |
| - ui_results->NotifyItemsChanged(i, 1); |
| + typedef std::map<std::string, ChromeSearchResult*> IdToResultMap; |
| + |
| + IdToResultMap new_results_map; |
| + for (size_t i = 0; i < new_results.size(); ++i) |
|
Matt Giuca
2014/07/04 08:21:21
Use an iterator.
calamity
2014/07/08 09:47:21
Done.
|
| + new_results_map[new_results[i].result->id()] = new_results[i].result; |
| + |
| + // A map of the items in |ui_results| that takes ownership of the items. |
| + IdToResultMap ui_results_map; |
| + for (size_t i = 0; i < ui_results->item_count(); ++i) { |
| + ChromeSearchResult* ui_result = |
| + static_cast<ChromeSearchResult*>(ui_results->GetItemAt(i)); |
| + ui_results_map[ui_result->id()] = ui_result; |
| + } |
| + // We have to erase all results at once so that observers are notified with |
| + // meaningful indexes. |
|
Matt Giuca
2014/07/04 08:21:22
Does this mean observers will see a "remove" of a
calamity
2014/07/08 09:47:21
Yes. The alternative is to use a Move(), but the o
|
| + ui_results->RemoveAll(); |
| + |
| + // For each ui result, update its properties if it is in the new results, |
| + // otherwise delete it. |
| + std::vector<std::string> ids_to_delete; |
| + for (IdToResultMap::const_iterator ui_result_it = ui_results_map.begin(); |
| + ui_result_it != ui_results_map.end(); |
| + ++ui_result_it) { |
| + ChromeSearchResult* ui_result = ui_result_it->second; |
| + IdToResultMap::const_iterator result_it = |
| + new_results_map.find(ui_result->id()); |
| + if (result_it != new_results_map.end()) { |
| + ChromeSearchResult* new_result = result_it->second; |
|
Matt Giuca
2014/07/04 08:21:22
Can I suggest (the original code could have used t
calamity
2014/07/08 09:47:21
Done.
|
| + ui_result->set_title(new_result->title()); |
| + ui_result->set_title_tags(new_result->title_tags()); |
| + ui_result->set_details(new_result->details()); |
| + ui_result->set_details_tags(new_result->details_tags()); |
| + new_results_map.erase(result_it); |
|
Matt Giuca
2014/07/04 08:21:21
Is there a reason you need to erase results from n
|
| } else { |
| - if (ui_result) |
| - ui_results->DeleteAt(i); |
| - ui_results->AddAt(i, result->Duplicate().release()); |
| + ids_to_delete.push_back(ui_result->id()); |
| } |
| } |
| - while (ui_results->item_count() > results.size()) |
| - ui_results->DeleteAt(ui_results->item_count() - 1); |
| + for (size_t i = 0; i < ids_to_delete.size(); ++i) { |
| + delete ui_results_map[ids_to_delete[i]]; |
| + ui_results_map.erase(ids_to_delete[i]); |
| + } |
| + |
| + // Insert results in the order of |new_results|. |
|
Matt Giuca
2014/07/04 08:21:21
Before this comment, say:
// Now, ui_results_map c
calamity
2014/07/08 09:47:21
Done.
|
| + for (size_t i = 0; i < new_results.size(); ++i) { |
| + ChromeSearchResult* new_result = new_results[i].result; |
| + IdToResultMap::const_iterator ui_result_it = |
| + ui_results_map.find(new_result->id()); |
| + // |ui_results| takes ownership here. |
| + ui_results->Add(ui_result_it != ui_results_map.end() |
| + ? ui_result_it->second |
| + : new_result->Duplicate().release()); |
|
Matt Giuca
2014/07/04 08:21:21
Should you be calling NotifyItemsChanged here? The
calamity
2014/07/08 09:47:21
Not necessary as the add and remove are used to no
|
| + } |
| } |
| } // namespace |