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

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

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

Powered by Google App Engine
This is Rietveld 408576698