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

Side by Side Diff: components/bookmarks/browser/bookmark_index.cc

Issue 2559633003: Factor out bookmark-specific sorting logic from BookmarkIndex (Closed)
Patch Set: comments, virtual destructor, explicit Created 4 years 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/bookmarks/browser/bookmark_index.h" 5 #include "components/bookmarks/browser/bookmark_index.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include "base/i18n/case_conversion.h" 9 #include "base/i18n/case_conversion.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/strings/utf_offset_string_conversions.h" 12 #include "base/strings/utf_offset_string_conversions.h"
13 #include "build/build_config.h" 13 #include "build/build_config.h"
14 #include "components/bookmarks/browser/bookmark_client.h"
15 #include "components/bookmarks/browser/bookmark_match.h" 14 #include "components/bookmarks/browser/bookmark_match.h"
16 #include "components/bookmarks/browser/bookmark_utils.h" 15 #include "components/bookmarks/browser/bookmark_utils.h"
17 #include "components/bookmarks/browser/titled_url_node.h" 16 #include "components/bookmarks/browser/titled_url_node.h"
17 #include "components/bookmarks/browser/titled_url_node_sorter.h"
18 #include "components/query_parser/snippet.h" 18 #include "components/query_parser/snippet.h"
19 #include "third_party/icu/source/common/unicode/normalizer2.h" 19 #include "third_party/icu/source/common/unicode/normalizer2.h"
20 #include "third_party/icu/source/common/unicode/utypes.h" 20 #include "third_party/icu/source/common/unicode/utypes.h"
21 21
22 namespace bookmarks { 22 namespace bookmarks {
23 23
24 using UrlTypedCountMap = BookmarkClient::UrlTypedCountMap;
25
26 namespace { 24 namespace {
27 25
28 using UrlNodeMap = std::unordered_map<const GURL*, const TitledUrlNode*>;
29 using UrlTypedCountPair = std::pair<const GURL*, int>;
30 using UrlTypedCountPairs = std::vector<UrlTypedCountPair>;
31
32 // Returns a normalized version of the UTF16 string |text|. If it fails to 26 // Returns a normalized version of the UTF16 string |text|. If it fails to
33 // normalize the string, returns |text| itself as a best-effort. 27 // normalize the string, returns |text| itself as a best-effort.
34 base::string16 Normalize(const base::string16& text) { 28 base::string16 Normalize(const base::string16& text) {
35 UErrorCode status = U_ZERO_ERROR; 29 UErrorCode status = U_ZERO_ERROR;
36 const icu::Normalizer2* normalizer2 = 30 const icu::Normalizer2* normalizer2 =
37 icu::Normalizer2::getInstance(nullptr, "nfkc", UNORM2_COMPOSE, status); 31 icu::Normalizer2::getInstance(nullptr, "nfkc", UNORM2_COMPOSE, status);
38 if (U_FAILURE(status)) { 32 if (U_FAILURE(status)) {
39 // Log and crash right away to capture the error code in the crash report. 33 // Log and crash right away to capture the error code in the crash report.
40 LOG(FATAL) << "failed to create a normalizer: " << u_errorName(status); 34 LOG(FATAL) << "failed to create a normalizer: " << u_errorName(status);
41 } 35 }
42 icu::UnicodeString unicode_text( 36 icu::UnicodeString unicode_text(
43 text.data(), static_cast<int32_t>(text.length())); 37 text.data(), static_cast<int32_t>(text.length()));
44 icu::UnicodeString unicode_normalized_text; 38 icu::UnicodeString unicode_normalized_text;
45 normalizer2->normalize(unicode_text, unicode_normalized_text, status); 39 normalizer2->normalize(unicode_text, unicode_normalized_text, status);
46 if (U_FAILURE(status)) { 40 if (U_FAILURE(status)) {
47 // This should not happen. Log the error and fall back. 41 // This should not happen. Log the error and fall back.
48 LOG(ERROR) << "normalization failed: " << u_errorName(status); 42 LOG(ERROR) << "normalization failed: " << u_errorName(status);
49 return text; 43 return text;
50 } 44 }
51 return base::string16(unicode_normalized_text.getBuffer(), 45 return base::string16(unicode_normalized_text.getBuffer(),
52 unicode_normalized_text.length()); 46 unicode_normalized_text.length());
53 } 47 }
54 48
55 // Sort functor for UrlTypedCountPairs. We sort in decreasing order of typed
56 // count so that the best matches will always be added to the results.
57 struct UrlTypedCountPairSortFunctor {
58 bool operator()(const UrlTypedCountPair& a,
59 const UrlTypedCountPair& b) const {
60 return a.second > b.second;
61 }
62 };
63
64 // Extract the GURL stored in an UrlTypedCountPair and use it to look up the
65 // corresponding TitledUrlNode.
66 class UrlTypedCountPairNodeLookupFunctor {
67 public:
68 explicit UrlTypedCountPairNodeLookupFunctor(UrlNodeMap& url_node_map)
69 : url_node_map_(url_node_map) {
70 }
71
72 const TitledUrlNode* operator()(const UrlTypedCountPair& pair) const {
73 return url_node_map_[pair.first];
74 }
75
76 private:
77 UrlNodeMap& url_node_map_;
78 };
79
80 } // namespace 49 } // namespace
81 50
82 BookmarkIndex::BookmarkIndex(BookmarkClient* client) 51 BookmarkIndex::BookmarkIndex(std::unique_ptr<TitledUrlNodeSorter> sorter)
83 : client_(client) { 52 : sorter_(std::move(sorter)) {
84 DCHECK(client_);
85 } 53 }
86 54
87 BookmarkIndex::~BookmarkIndex() { 55 BookmarkIndex::~BookmarkIndex() {
88 } 56 }
89 57
90 void BookmarkIndex::Add(const TitledUrlNode* node) { 58 void BookmarkIndex::Add(const TitledUrlNode* node) {
91 std::vector<base::string16> terms = 59 std::vector<base::string16> terms =
92 ExtractQueryWords(Normalize(node->GetTitledUrlNodeTitle())); 60 ExtractQueryWords(Normalize(node->GetTitledUrlNodeTitle()));
93 for (size_t i = 0; i < terms.size(); ++i) 61 for (size_t i = 0; i < terms.size(); ++i)
94 RegisterNode(terms[i], node); 62 RegisterNode(terms[i], node);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // will run backwards to assure higher relevance will be attributed to the 111 // will run backwards to assure higher relevance will be attributed to the
144 // best matches. 112 // best matches.
145 for (TitledUrlNodes::const_iterator i = sorted_nodes.begin(); 113 for (TitledUrlNodes::const_iterator i = sorted_nodes.begin();
146 i != sorted_nodes.end() && results->size() < max_count; 114 i != sorted_nodes.end() && results->size() < max_count;
147 ++i) 115 ++i)
148 AddMatchToResults(*i, &parser, query_nodes, results); 116 AddMatchToResults(*i, &parser, query_nodes, results);
149 } 117 }
150 118
151 void BookmarkIndex::SortMatches(const TitledUrlNodeSet& matches, 119 void BookmarkIndex::SortMatches(const TitledUrlNodeSet& matches,
152 TitledUrlNodes* sorted_nodes) const { 120 TitledUrlNodes* sorted_nodes) const {
153 sorted_nodes->reserve(matches.size()); 121 if (sorter_) {
154 if (client_->SupportsTypedCountForUrls()) { 122 sorter_->SortMatches(matches, sorted_nodes);
155 UrlNodeMap url_node_map;
156 UrlTypedCountMap url_typed_count_map;
157 for (auto node : matches) {
158 const GURL& url = node->GetTitledUrlNodeUrl();
159 url_node_map.insert(std::make_pair(&url, node));
160 url_typed_count_map.insert(std::make_pair(&url, 0));
161 }
162
163 client_->GetTypedCountForUrls(&url_typed_count_map);
164
165 UrlTypedCountPairs url_typed_counts;
166 std::copy(url_typed_count_map.begin(),
167 url_typed_count_map.end(),
168 std::back_inserter(url_typed_counts));
169 std::sort(url_typed_counts.begin(),
170 url_typed_counts.end(),
171 UrlTypedCountPairSortFunctor());
172 std::transform(url_typed_counts.begin(),
173 url_typed_counts.end(),
174 std::back_inserter(*sorted_nodes),
175 UrlTypedCountPairNodeLookupFunctor(url_node_map));
176 } else { 123 } else {
177 sorted_nodes->insert(sorted_nodes->end(), matches.begin(), matches.end()); 124 sorted_nodes->insert(sorted_nodes->end(), matches.begin(), matches.end());
178 } 125 }
179 } 126 }
180 127
181 void BookmarkIndex::AddMatchToResults( 128 void BookmarkIndex::AddMatchToResults(
182 const TitledUrlNode* node, 129 const TitledUrlNode* node,
183 query_parser::QueryParser* parser, 130 query_parser::QueryParser* parser,
184 const query_parser::QueryNodeVector& query_nodes, 131 const query_parser::QueryNodeVector& query_nodes,
185 std::vector<BookmarkMatch>* results) { 132 std::vector<BookmarkMatch>* results) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 // We can get here if the node has the same term more than once. For 251 // We can get here if the node has the same term more than once. For
305 // example, a node with the title 'foo foo' would end up here. 252 // example, a node with the title 'foo foo' would end up here.
306 return; 253 return;
307 } 254 }
308 i->second.erase(node); 255 i->second.erase(node);
309 if (i->second.empty()) 256 if (i->second.empty())
310 index_.erase(i); 257 index_.erase(i);
311 } 258 }
312 259
313 } // namespace bookmarks 260 } // namespace bookmarks
OLDNEW
« no previous file with comments | « components/bookmarks/browser/bookmark_index.h ('k') | components/bookmarks/browser/bookmark_model.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698