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