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

Side by Side Diff: ui/app_list/search/mixer.cc

Issue 2379863002: Fix object ownership in ui/base/models. (Closed)
Patch Set: fix Created 4 years, 2 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 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>
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 // group has a soft maximum of 4 results. (Otherwise, the People result 173 // group has a soft maximum of 4 results. (Otherwise, the People result
174 // would not be seen at all once the result list is truncated.) 174 // would not be seen at all once the result list is truncated.)
175 std::sort(results.begin() + original_size, results.end()); 175 std::sort(results.begin() + original_size, results.end());
176 } 176 }
177 177
178 Publish(results, ui_results_); 178 Publish(results, ui_results_);
179 } 179 }
180 180
181 void Mixer::Publish(const SortedResults& new_results, 181 void Mixer::Publish(const SortedResults& new_results,
182 AppListModel::SearchResults* ui_results) { 182 AppListModel::SearchResults* ui_results) {
183 typedef std::map<std::string, SearchResult*> IdToResultMap;
184
185 // The following algorithm is used: 183 // The following algorithm is used:
186 // 1. Transform the |ui_results| list into an unordered map from result ID 184 // 1. Transform the |ui_results| list into an unordered map from result ID
187 // to item. 185 // to item.
188 // 2. Use the order of items in |new_results| to build an ordered list. If the 186 // 2. Use the order of items in |new_results| to build an ordered list. If the
189 // result IDs exist in the map, update and use the item in the map and delete 187 // result IDs exist in the map, update and use the item in the map and delete
190 // it from the map afterwards. Otherwise, clone new items from |new_results|. 188 // it from the map afterwards. Otherwise, clone new items from |new_results|.
191 // 3. Delete the objects remaining in the map as they are unused. 189 // 3. Delete the objects remaining in the map as they are unused.
192 190
193 // A map of the items in |ui_results| that takes ownership of the items.
194 IdToResultMap ui_results_map;
195 for (SearchResult* ui_result : *ui_results)
196 ui_results_map[ui_result->id()] = ui_result;
197 // We have to erase all results at once so that observers are notified with 191 // We have to erase all results at once so that observers are notified with
198 // meaningful indexes. 192 // meaningful indexes.
199 ui_results->RemoveAll(); 193 auto current_results = ui_results->RemoveAll();
194 std::map<std::string, std::unique_ptr<SearchResult>> ui_results_map;
195 for (std::unique_ptr<SearchResult>& ui_result : current_results)
196 ui_results_map[ui_result->id()] = std::move(ui_result);
200 197
201 // Add items back to |ui_results| in the order of |new_results|. 198 // Add items back to |ui_results| in the order of |new_results|.
202 for (const SortData& sort_data : new_results) { 199 for (const SortData& sort_data : new_results) {
203 const SearchResult& new_result = *sort_data.result; 200 const SearchResult& new_result = *sort_data.result;
204 IdToResultMap::const_iterator ui_result_it = 201 auto ui_result_it = ui_results_map.find(new_result.id());
205 ui_results_map.find(new_result.id());
206 if (ui_result_it != ui_results_map.end()) { 202 if (ui_result_it != ui_results_map.end()) {
207 // Update and use the old result if it exists. 203 // Update and use the old result if it exists.
208 SearchResult* ui_result = ui_result_it->second; 204 std::unique_ptr<SearchResult> ui_result = std::move(ui_result_it->second);
209 UpdateResult(new_result, ui_result); 205 UpdateResult(new_result, ui_result.get());
210 ui_result->set_relevance(sort_data.score); 206 ui_result->set_relevance(sort_data.score);
211 207
212 // |ui_results| takes back ownership from |ui_results_map| here. 208 ui_results->Add(std::move(ui_result));
213 ui_results->Add(ui_result);
214 209
215 // Remove the item from the map so that it ends up only with unused 210 // Remove the item from the map so that it ends up only with unused
216 // results. 211 // results.
217 ui_results_map.erase(ui_result->id()); 212 ui_results_map.erase(ui_result_it);
218 } else { 213 } else {
219 std::unique_ptr<SearchResult> result_copy = new_result.Duplicate(); 214 std::unique_ptr<SearchResult> result_copy = new_result.Duplicate();
220 result_copy->set_relevance(sort_data.score); 215 result_copy->set_relevance(sort_data.score);
221 // Copy the result from |new_results| otherwise. 216 // Copy the result from |new_results| otherwise.
222 ui_results->Add(result_copy.release()); 217 ui_results->Add(std::move(result_copy));
223 } 218 }
224 } 219 }
225 220
226 // Delete the results remaining in the map as they are not in the new results. 221 // Any remaining results in |ui_results_map| will be automatically deleted.
227 for (const auto& ui_result : ui_results_map) {
228 delete ui_result.second;
229 }
230 } 222 }
231 223
232 void Mixer::RemoveDuplicates(SortedResults* results) { 224 void Mixer::RemoveDuplicates(SortedResults* results) {
233 SortedResults final; 225 SortedResults final;
234 final.reserve(results->size()); 226 final.reserve(results->size());
235 227
236 std::set<std::string> id_set; 228 std::set<std::string> id_set;
237 for (const SortData& sort_data : *results) { 229 for (const SortData& sort_data : *results) {
238 const std::string& id = sort_data.result->id(); 230 const std::string& id = sort_data.result->id();
239 if (id_set.find(id) != id_set.end()) 231 if (id_set.find(id) != id_set.end())
240 continue; 232 continue;
241 233
242 id_set.insert(id); 234 id_set.insert(id);
243 final.push_back(sort_data); 235 final.push_back(sort_data);
244 } 236 }
245 237
246 results->swap(final); 238 results->swap(final);
247 } 239 }
248 240
249 void Mixer::FetchResults(bool is_voice_query, 241 void Mixer::FetchResults(bool is_voice_query,
250 const KnownResults& known_results) { 242 const KnownResults& known_results) {
251 for (auto* group : groups_) 243 for (auto* group : groups_)
252 group->FetchResults(is_voice_query, known_results); 244 group->FetchResults(is_voice_query, known_results);
253 } 245 }
254 246
255 } // namespace app_list 247 } // namespace app_list
OLDNEW
« no previous file with comments | « components/bookmarks/test/test_bookmark_client.cc ('k') | ui/app_list/views/app_list_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698