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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 BookmarkIndex::NodeSet::const_iterator | 90 BookmarkIndex::NodeSet::const_iterator |
91 BookmarkIndex::Match::nodes_begin() const { | 91 BookmarkIndex::Match::nodes_begin() const { |
92 return nodes.empty() ? terms.front()->second.begin() : nodes.begin(); | 92 return nodes.empty() ? terms.front()->second.begin() : nodes.begin(); |
93 } | 93 } |
94 | 94 |
95 BookmarkIndex::NodeSet::const_iterator BookmarkIndex::Match::nodes_end() const { | 95 BookmarkIndex::NodeSet::const_iterator BookmarkIndex::Match::nodes_end() const { |
96 return nodes.empty() ? terms.front()->second.end() : nodes.end(); | 96 return nodes.empty() ? terms.front()->second.end() : nodes.end(); |
97 } | 97 } |
98 | 98 |
99 BookmarkIndex::BookmarkIndex(BookmarkClient* client, | 99 BookmarkIndex::BookmarkIndex(BookmarkClient* client, |
100 bool index_urls, | |
101 const std::string& languages) | 100 const std::string& languages) |
102 : client_(client), | 101 : client_(client), |
103 languages_(languages), | 102 languages_(languages) { |
104 index_urls_(index_urls) { | |
105 DCHECK(client_); | 103 DCHECK(client_); |
106 } | 104 } |
107 | 105 |
108 BookmarkIndex::~BookmarkIndex() { | 106 BookmarkIndex::~BookmarkIndex() { |
109 } | 107 } |
110 | 108 |
111 void BookmarkIndex::Add(const BookmarkNode* node) { | 109 void BookmarkIndex::Add(const BookmarkNode* node) { |
112 if (!node->is_url()) | 110 if (!node->is_url()) |
113 return; | 111 return; |
114 std::vector<base::string16> terms = | 112 std::vector<base::string16> terms = |
115 ExtractQueryWords(Normalize(node->GetTitle())); | 113 ExtractQueryWords(Normalize(node->GetTitle())); |
116 for (size_t i = 0; i < terms.size(); ++i) | 114 for (size_t i = 0; i < terms.size(); ++i) |
117 RegisterNode(terms[i], node); | 115 RegisterNode(terms[i], node); |
118 if (index_urls_) { | 116 terms = |
119 terms = | 117 ExtractQueryWords(CleanUpUrlForMatching(node->url(), languages_, NULL)); |
120 ExtractQueryWords(CleanUpUrlForMatching(node->url(), languages_, NULL)); | 118 for (size_t i = 0; i < terms.size(); ++i) |
121 for (size_t i = 0; i < terms.size(); ++i) | 119 RegisterNode(terms[i], node); |
122 RegisterNode(terms[i], node); | |
123 } | |
124 } | 120 } |
125 | 121 |
126 void BookmarkIndex::Remove(const BookmarkNode* node) { | 122 void BookmarkIndex::Remove(const BookmarkNode* node) { |
127 if (!node->is_url()) | 123 if (!node->is_url()) |
128 return; | 124 return; |
129 | 125 |
130 std::vector<base::string16> terms = | 126 std::vector<base::string16> terms = |
131 ExtractQueryWords(Normalize(node->GetTitle())); | 127 ExtractQueryWords(Normalize(node->GetTitle())); |
132 for (size_t i = 0; i < terms.size(); ++i) | 128 for (size_t i = 0; i < terms.size(); ++i) |
133 UnregisterNode(terms[i], node); | 129 UnregisterNode(terms[i], node); |
134 if (index_urls_) { | 130 terms = |
135 terms = | 131 ExtractQueryWords(CleanUpUrlForMatching(node->url(), languages_, NULL)); |
136 ExtractQueryWords(CleanUpUrlForMatching(node->url(), languages_, NULL)); | 132 for (size_t i = 0; i < terms.size(); ++i) |
137 for (size_t i = 0; i < terms.size(); ++i) | 133 UnregisterNode(terms[i], node); |
138 UnregisterNode(terms[i], node); | |
139 } | |
140 } | 134 } |
141 | 135 |
142 void BookmarkIndex::GetBookmarksMatching(const base::string16& input_query, | 136 void BookmarkIndex::GetBookmarksMatching(const base::string16& input_query, |
143 size_t max_count, | 137 size_t max_count, |
144 std::vector<BookmarkMatch>* results) { | 138 std::vector<BookmarkMatch>* results) { |
145 const base::string16 query = Normalize(input_query); | 139 const base::string16 query = Normalize(input_query); |
146 std::vector<base::string16> terms = ExtractQueryWords(query); | 140 std::vector<base::string16> terms = ExtractQueryWords(query); |
147 if (terms.empty()) | 141 if (terms.empty()) |
148 return; | 142 return; |
149 | 143 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 // Check that the result matches the query. The previous search | 205 // Check that the result matches the query. The previous search |
212 // was a simple per-word search, while the more complex matching | 206 // was a simple per-word search, while the more complex matching |
213 // of QueryParser may filter it out. For example, the query | 207 // of QueryParser may filter it out. For example, the query |
214 // ["thi"] will match the bookmark titled [Thinking], but since | 208 // ["thi"] will match the bookmark titled [Thinking], but since |
215 // ["thi"] is quoted we don't want to do a prefix match. | 209 // ["thi"] is quoted we don't want to do a prefix match. |
216 query_parser::QueryWordVector title_words, url_words; | 210 query_parser::QueryWordVector title_words, url_words; |
217 const base::string16 lower_title = | 211 const base::string16 lower_title = |
218 base::i18n::ToLower(Normalize(node->GetTitle())); | 212 base::i18n::ToLower(Normalize(node->GetTitle())); |
219 parser->ExtractQueryWords(lower_title, &title_words); | 213 parser->ExtractQueryWords(lower_title, &title_words); |
220 base::OffsetAdjuster::Adjustments adjustments; | 214 base::OffsetAdjuster::Adjustments adjustments; |
221 if (index_urls_) { | 215 parser->ExtractQueryWords( |
222 parser->ExtractQueryWords( | 216 CleanUpUrlForMatching(node->url(), languages_, &adjustments), |
223 CleanUpUrlForMatching(node->url(), languages_, &adjustments), | 217 &url_words); |
224 &url_words); | |
225 } | |
226 query_parser::Snippet::MatchPositions title_matches, url_matches; | 218 query_parser::Snippet::MatchPositions title_matches, url_matches; |
227 for (size_t i = 0; i < query_nodes.size(); ++i) { | 219 for (size_t i = 0; i < query_nodes.size(); ++i) { |
228 const bool has_title_matches = | 220 const bool has_title_matches = |
229 query_nodes[i]->HasMatchIn(title_words, &title_matches); | 221 query_nodes[i]->HasMatchIn(title_words, &title_matches); |
230 const bool has_url_matches = index_urls_ && | 222 const bool has_url_matches = |
231 query_nodes[i]->HasMatchIn(url_words, &url_matches); | 223 query_nodes[i]->HasMatchIn(url_words, &url_matches); |
232 if (!has_title_matches && !has_url_matches) | 224 if (!has_title_matches && !has_url_matches) |
233 return; | 225 return; |
234 query_parser::QueryParser::SortAndCoalesceMatchPositions(&title_matches); | 226 query_parser::QueryParser::SortAndCoalesceMatchPositions(&title_matches); |
235 if (index_urls_) | 227 query_parser::QueryParser::SortAndCoalesceMatchPositions(&url_matches); |
236 query_parser::QueryParser::SortAndCoalesceMatchPositions(&url_matches); | |
237 } | 228 } |
238 BookmarkMatch match; | 229 BookmarkMatch match; |
239 if (lower_title.length() == node->GetTitle().length()) { | 230 if (lower_title.length() == node->GetTitle().length()) { |
240 // Only use title matches if the lowercase string is the same length | 231 // Only use title matches if the lowercase string is the same length |
241 // as the original string, otherwise the matches are meaningless. | 232 // as the original string, otherwise the matches are meaningless. |
242 // TODO(mpearson): revise match positions appropriately. | 233 // TODO(mpearson): revise match positions appropriately. |
243 match.title_match_positions.swap(title_matches); | 234 match.title_match_positions.swap(title_matches); |
244 } | 235 } |
245 if (index_urls_) { | 236 // Now that we're done processing this entry, correct the offsets of the |
246 // Now that we're done processing this entry, correct the offsets of the | 237 // matches in |url_matches| so they point to offsets in the original URL |
247 // matches in |url_matches| so they point to offsets in the original URL | 238 // spec, not the cleaned-up URL string that we used for matching. |
248 // spec, not the cleaned-up URL string that we used for matching. | 239 std::vector<size_t> offsets = |
249 std::vector<size_t> offsets = | 240 BookmarkMatch::OffsetsFromMatchPositions(url_matches); |
250 BookmarkMatch::OffsetsFromMatchPositions(url_matches); | 241 base::OffsetAdjuster::UnadjustOffsets(adjustments, &offsets); |
251 base::OffsetAdjuster::UnadjustOffsets(adjustments, &offsets); | 242 url_matches = |
252 url_matches = | 243 BookmarkMatch::ReplaceOffsetsInMatchPositions(url_matches, offsets); |
253 BookmarkMatch::ReplaceOffsetsInMatchPositions(url_matches, offsets); | 244 match.url_match_positions.swap(url_matches); |
254 match.url_match_positions.swap(url_matches); | |
255 } | |
256 match.node = node; | 245 match.node = node; |
257 results->push_back(match); | 246 results->push_back(match); |
258 } | 247 } |
259 | 248 |
260 bool BookmarkIndex::GetBookmarksMatchingTerm(const base::string16& term, | 249 bool BookmarkIndex::GetBookmarksMatchingTerm(const base::string16& term, |
261 bool first_term, | 250 bool first_term, |
262 Matches* matches) { | 251 Matches* matches) { |
263 Index::const_iterator i = index_.lower_bound(term); | 252 Index::const_iterator i = index_.lower_bound(term); |
264 if (i == index_.end()) | 253 if (i == index_.end()) |
265 return false; | 254 return false; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 // We can get here if the node has the same term more than once. For | 350 // We can get here if the node has the same term more than once. For |
362 // example, a bookmark with the title 'foo foo' would end up here. | 351 // example, a bookmark with the title 'foo foo' would end up here. |
363 return; | 352 return; |
364 } | 353 } |
365 i->second.erase(node); | 354 i->second.erase(node); |
366 if (i->second.empty()) | 355 if (i->second.empty()) |
367 index_.erase(i); | 356 index_.erase(i); |
368 } | 357 } |
369 | 358 |
370 } // namespace bookmarks | 359 } // namespace bookmarks |
OLD | NEW |