OLD | NEW |
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 <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <iterator> | 9 #include <iterator> |
10 #include <list> | 10 #include <list> |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 std::vector<base::string16> terms = | 126 std::vector<base::string16> terms = |
127 ExtractQueryWords(Normalize(node->GetTitle())); | 127 ExtractQueryWords(Normalize(node->GetTitle())); |
128 for (size_t i = 0; i < terms.size(); ++i) | 128 for (size_t i = 0; i < terms.size(); ++i) |
129 UnregisterNode(terms[i], node); | 129 UnregisterNode(terms[i], node); |
130 terms = | 130 terms = |
131 ExtractQueryWords(CleanUpUrlForMatching(node->url(), languages_, NULL)); | 131 ExtractQueryWords(CleanUpUrlForMatching(node->url(), languages_, NULL)); |
132 for (size_t i = 0; i < terms.size(); ++i) | 132 for (size_t i = 0; i < terms.size(); ++i) |
133 UnregisterNode(terms[i], node); | 133 UnregisterNode(terms[i], node); |
134 } | 134 } |
135 | 135 |
136 void BookmarkIndex::GetBookmarksMatching(const base::string16& input_query, | 136 void BookmarkIndex::GetBookmarksMatching( |
137 size_t max_count, | 137 const base::string16& input_query, |
138 std::vector<BookmarkMatch>* results) { | 138 size_t max_count, |
| 139 query_parser::MatchingAlgorithm matching_algorithm, |
| 140 std::vector<BookmarkMatch>* results) { |
139 const base::string16 query = Normalize(input_query); | 141 const base::string16 query = Normalize(input_query); |
140 std::vector<base::string16> terms = ExtractQueryWords(query); | 142 std::vector<base::string16> terms = ExtractQueryWords(query); |
141 if (terms.empty()) | 143 if (terms.empty()) |
142 return; | 144 return; |
143 | 145 |
144 Matches matches; | 146 Matches matches; |
145 for (size_t i = 0; i < terms.size(); ++i) { | 147 for (size_t i = 0; i < terms.size(); ++i) { |
146 if (!GetBookmarksMatchingTerm(terms[i], i == 0, &matches)) | 148 if (!GetBookmarksMatchingTerm( |
| 149 terms[i], i == 0, matching_algorithm, &matches)) { |
147 return; | 150 return; |
| 151 } |
148 } | 152 } |
149 | 153 |
150 Nodes sorted_nodes; | 154 Nodes sorted_nodes; |
151 SortMatches(matches, &sorted_nodes); | 155 SortMatches(matches, &sorted_nodes); |
152 | 156 |
153 // We use a QueryParser to fill in match positions for us. It's not the most | 157 // We use a QueryParser to fill in match positions for us. It's not the most |
154 // efficient way to go about this, but by the time we get here we know what | 158 // efficient way to go about this, but by the time we get here we know what |
155 // matches and so this shouldn't be performance critical. | 159 // matches and so this shouldn't be performance critical. |
156 query_parser::QueryParser parser; | 160 query_parser::QueryParser parser; |
157 ScopedVector<query_parser::QueryNode> query_nodes; | 161 ScopedVector<query_parser::QueryNode> query_nodes; |
158 parser.ParseQueryNodes(query, &query_nodes.get()); | 162 parser.ParseQueryNodes(query, matching_algorithm, &query_nodes.get()); |
159 | 163 |
160 // The highest typed counts should be at the beginning of the results vector | 164 // The highest typed counts should be at the beginning of the results vector |
161 // so that the best matches will always be included in the results. The loop | 165 // so that the best matches will always be included in the results. The loop |
162 // that calculates result relevance in HistoryContentsProvider::ConvertResults | 166 // that calculates result relevance in HistoryContentsProvider::ConvertResults |
163 // will run backwards to assure higher relevance will be attributed to the | 167 // will run backwards to assure higher relevance will be attributed to the |
164 // best matches. | 168 // best matches. |
165 for (Nodes::const_iterator i = sorted_nodes.begin(); | 169 for (Nodes::const_iterator i = sorted_nodes.begin(); |
166 i != sorted_nodes.end() && results->size() < max_count; | 170 i != sorted_nodes.end() && results->size() < max_count; |
167 ++i) | 171 ++i) |
168 AddMatchToResults(*i, &parser, query_nodes.get(), results); | 172 AddMatchToResults(*i, &parser, query_nodes.get(), results); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 std::vector<size_t> offsets = | 243 std::vector<size_t> offsets = |
240 BookmarkMatch::OffsetsFromMatchPositions(url_matches); | 244 BookmarkMatch::OffsetsFromMatchPositions(url_matches); |
241 base::OffsetAdjuster::UnadjustOffsets(adjustments, &offsets); | 245 base::OffsetAdjuster::UnadjustOffsets(adjustments, &offsets); |
242 url_matches = | 246 url_matches = |
243 BookmarkMatch::ReplaceOffsetsInMatchPositions(url_matches, offsets); | 247 BookmarkMatch::ReplaceOffsetsInMatchPositions(url_matches, offsets); |
244 match.url_match_positions.swap(url_matches); | 248 match.url_match_positions.swap(url_matches); |
245 match.node = node; | 249 match.node = node; |
246 results->push_back(match); | 250 results->push_back(match); |
247 } | 251 } |
248 | 252 |
249 bool BookmarkIndex::GetBookmarksMatchingTerm(const base::string16& term, | 253 bool BookmarkIndex::GetBookmarksMatchingTerm( |
250 bool first_term, | 254 const base::string16& term, |
251 Matches* matches) { | 255 bool first_term, |
| 256 query_parser::MatchingAlgorithm matching_algorithm, |
| 257 Matches* matches) { |
252 Index::const_iterator i = index_.lower_bound(term); | 258 Index::const_iterator i = index_.lower_bound(term); |
253 if (i == index_.end()) | 259 if (i == index_.end()) |
254 return false; | 260 return false; |
255 | 261 |
256 if (!query_parser::QueryParser::IsWordLongEnoughForPrefixSearch(term)) { | 262 if (!query_parser::QueryParser::IsWordLongEnoughForPrefixSearch( |
| 263 term, matching_algorithm)) { |
257 // Term is too short for prefix match, compare using exact match. | 264 // Term is too short for prefix match, compare using exact match. |
258 if (i->first != term) | 265 if (i->first != term) |
259 return false; // No bookmarks with this term. | 266 return false; // No bookmarks with this term. |
260 | 267 |
261 if (first_term) { | 268 if (first_term) { |
262 Match match; | 269 Match match; |
263 match.terms.push_back(i); | 270 match.terms.push_back(i); |
264 matches->push_back(match); | 271 matches->push_back(match); |
265 return true; | 272 return true; |
266 } | 273 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 } | 334 } |
328 } | 335 } |
329 } | 336 } |
330 | 337 |
331 std::vector<base::string16> BookmarkIndex::ExtractQueryWords( | 338 std::vector<base::string16> BookmarkIndex::ExtractQueryWords( |
332 const base::string16& query) { | 339 const base::string16& query) { |
333 std::vector<base::string16> terms; | 340 std::vector<base::string16> terms; |
334 if (query.empty()) | 341 if (query.empty()) |
335 return std::vector<base::string16>(); | 342 return std::vector<base::string16>(); |
336 query_parser::QueryParser parser; | 343 query_parser::QueryParser parser; |
337 parser.ParseQueryWords(base::i18n::ToLower(query), &terms); | 344 parser.ParseQueryWords(base::i18n::ToLower(query), |
| 345 query_parser::MatchingAlgorithm::DEFAULT, |
| 346 &terms); |
338 return terms; | 347 return terms; |
339 } | 348 } |
340 | 349 |
341 void BookmarkIndex::RegisterNode(const base::string16& term, | 350 void BookmarkIndex::RegisterNode(const base::string16& term, |
342 const BookmarkNode* node) { | 351 const BookmarkNode* node) { |
343 index_[term].insert(node); | 352 index_[term].insert(node); |
344 } | 353 } |
345 | 354 |
346 void BookmarkIndex::UnregisterNode(const base::string16& term, | 355 void BookmarkIndex::UnregisterNode(const base::string16& term, |
347 const BookmarkNode* node) { | 356 const BookmarkNode* node) { |
348 Index::iterator i = index_.find(term); | 357 Index::iterator i = index_.find(term); |
349 if (i == index_.end()) { | 358 if (i == index_.end()) { |
350 // We can get here if the node has the same term more than once. For | 359 // We can get here if the node has the same term more than once. For |
351 // example, a bookmark with the title 'foo foo' would end up here. | 360 // example, a bookmark with the title 'foo foo' would end up here. |
352 return; | 361 return; |
353 } | 362 } |
354 i->second.erase(node); | 363 i->second.erase(node); |
355 if (i->second.empty()) | 364 if (i->second.empty()) |
356 index_.erase(i); | 365 index_.erase(i); |
357 } | 366 } |
358 | 367 |
359 } // namespace bookmarks | 368 } // namespace bookmarks |
OLD | NEW |