| 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 |