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

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

Issue 184663002: Omnibox: Make URLs of Bookmarks Searchable (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/bookmarks/bookmark_index.h" 5 #include "chrome/browser/bookmarks/bookmark_index.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <list> 9 #include <list>
10 10
11 #include "base/i18n/case_conversion.h" 11 #include "base/i18n/case_conversion.h"
12 #include "base/strings/string16.h" 12 #include "base/strings/string16.h"
13 #include "chrome/browser/bookmarks/bookmark_match.h"
13 #include "chrome/browser/bookmarks/bookmark_model.h" 14 #include "chrome/browser/bookmarks/bookmark_model.h"
14 #include "chrome/browser/bookmarks/bookmark_title_match.h" 15 #include "chrome/browser/bookmarks/bookmark_utils.h"
15 #include "chrome/browser/history/history_service.h" 16 #include "chrome/browser/history/history_service.h"
16 #include "chrome/browser/history/history_service_factory.h" 17 #include "chrome/browser/history/history_service_factory.h"
17 #include "chrome/browser/history/query_parser.h" 18 #include "chrome/browser/history/query_parser.h"
18 #include "chrome/browser/history/url_database.h" 19 #include "chrome/browser/history/url_database.h"
19 20
20 // Used when finding the set of bookmarks that match a query. Each match 21 // Used when finding the set of bookmarks that match a query. Each match
21 // represents a set of terms (as an interator into the Index) matching the 22 // represents a set of terms (as an interator into the Index) matching the
22 // query as well as the set of nodes that contain those terms in their titles. 23 // query as well as the set of nodes that contain those terms in their titles.
23 struct BookmarkIndex::Match { 24 struct BookmarkIndex::Match {
24 // List of terms matching the query. 25 // List of terms matching the query.
(...skipping 19 matching lines...) Expand all
44 45
45 BookmarkIndex::NodeSet::const_iterator 46 BookmarkIndex::NodeSet::const_iterator
46 BookmarkIndex::Match::nodes_begin() const { 47 BookmarkIndex::Match::nodes_begin() const {
47 return nodes.empty() ? terms.front()->second.begin() : nodes.begin(); 48 return nodes.empty() ? terms.front()->second.begin() : nodes.begin();
48 } 49 }
49 50
50 BookmarkIndex::NodeSet::const_iterator BookmarkIndex::Match::nodes_end() const { 51 BookmarkIndex::NodeSet::const_iterator BookmarkIndex::Match::nodes_end() const {
51 return nodes.empty() ? terms.front()->second.end() : nodes.end(); 52 return nodes.empty() ? terms.front()->second.end() : nodes.end();
52 } 53 }
53 54
54 BookmarkIndex::BookmarkIndex(content::BrowserContext* browser_context) 55 BookmarkIndex::BookmarkIndex(content::BrowserContext* browser_context,
55 : browser_context_(browser_context) { 56 const std::string& languages)
57 : browser_context_(browser_context),
58 languages_(languages) {
56 } 59 }
57 60
58 BookmarkIndex::~BookmarkIndex() { 61 BookmarkIndex::~BookmarkIndex() {
59 } 62 }
60 63
61 void BookmarkIndex::Add(const BookmarkNode* node) { 64 void BookmarkIndex::Add(const BookmarkNode* node) {
62 if (!node->is_url()) 65 if (!node->is_url())
63 return; 66 return;
64 std::vector<base::string16> terms = ExtractQueryWords(node->GetTitle()); 67 std::vector<base::string16> terms = ExtractQueryWords(node->GetTitle());
65 for (size_t i = 0; i < terms.size(); ++i) 68 for (size_t i = 0; i < terms.size(); ++i)
66 RegisterNode(terms[i], node); 69 RegisterNode(terms[i], node);
70 terms = ExtractQueryWords(bookmark_utils::CleanUpUrlForMatching(node->url(),
71 languages_));
72 for (size_t i = 0; i < terms.size(); ++i)
73 RegisterNode(terms[i], node);
67 } 74 }
68 75
69 void BookmarkIndex::Remove(const BookmarkNode* node) { 76 void BookmarkIndex::Remove(const BookmarkNode* node) {
70 if (!node->is_url()) 77 if (!node->is_url())
71 return; 78 return;
72 79
73 std::vector<base::string16> terms = ExtractQueryWords(node->GetTitle()); 80 std::vector<base::string16> terms = ExtractQueryWords(node->GetTitle());
74 for (size_t i = 0; i < terms.size(); ++i) 81 for (size_t i = 0; i < terms.size(); ++i)
75 UnregisterNode(terms[i], node); 82 UnregisterNode(terms[i], node);
83 terms = ExtractQueryWords(bookmark_utils::CleanUpUrlForMatching(node->url(),
84 languages_));
85 for (size_t i = 0; i < terms.size(); ++i)
86 UnregisterNode(terms[i], node);
76 } 87 }
77 88
78 void BookmarkIndex::GetBookmarksWithTitlesMatching( 89 void BookmarkIndex::GetBookmarksMatching(const base::string16& query,
79 const base::string16& query, 90 size_t max_count,
80 size_t max_count, 91 std::vector<BookmarkMatch>* results) {
81 std::vector<BookmarkTitleMatch>* results) {
82 std::vector<base::string16> terms = ExtractQueryWords(query); 92 std::vector<base::string16> terms = ExtractQueryWords(query);
83 if (terms.empty()) 93 if (terms.empty())
84 return; 94 return;
85 95
86 Matches matches; 96 Matches matches;
87 for (size_t i = 0; i < terms.size(); ++i) { 97 for (size_t i = 0; i < terms.size(); ++i) {
88 if (!GetBookmarksWithTitleMatchingTerm(terms[i], i == 0, &matches)) 98 if (!GetBookmarksMatchingTerm(terms[i], i == 0, &matches))
89 return; 99 return;
90 } 100 }
91 101
92 NodeTypedCountPairs node_typed_counts; 102 NodeTypedCountPairs node_typed_counts;
93 SortMatches(matches, &node_typed_counts); 103 SortMatches(matches, &node_typed_counts);
94 104
95 // We use a QueryParser to fill in match positions for us. It's not the most 105 // We use a QueryParser to fill in match positions for us. It's not the most
96 // efficient way to go about this, but by the time we get here we know what 106 // efficient way to go about this, but by the time we get here we know what
97 // matches and so this shouldn't be performance critical. 107 // matches and so this shouldn't be performance critical.
98 QueryParser parser; 108 QueryParser parser;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 url_db->GetRowForURL((*i)->url(), &url); 152 url_db->GetRowForURL((*i)->url(), &url);
143 NodeTypedCountPair pair(*i, url.typed_count()); 153 NodeTypedCountPair pair(*i, url.typed_count());
144 node_typed_counts->push_back(pair); 154 node_typed_counts->push_back(pair);
145 } 155 }
146 } 156 }
147 157
148 void BookmarkIndex::AddMatchToResults( 158 void BookmarkIndex::AddMatchToResults(
149 const BookmarkNode* node, 159 const BookmarkNode* node,
150 QueryParser* parser, 160 QueryParser* parser,
151 const std::vector<QueryNode*>& query_nodes, 161 const std::vector<QueryNode*>& query_nodes,
152 std::vector<BookmarkTitleMatch>* results) { 162 std::vector<BookmarkMatch>* results) {
153 BookmarkTitleMatch title_match; 163 BookmarkMatch match;
154 // Check that the result matches the query. The previous search 164 // Check that the result matches the query. The previous search
155 // was a simple per-word search, while the more complex matching 165 // was a simple per-word search, while the more complex matching
156 // of QueryParser may filter it out. For example, the query 166 // of QueryParser may filter it out. For example, the query
157 // ["thi"] will match the bookmark titled [Thinking], but since 167 // ["thi"] will match the bookmark titled [Thinking], but since
158 // ["thi"] is quoted we don't want to do a prefix match. 168 // ["thi"] is quoted we don't want to do a prefix match.
159 if (parser->DoesQueryMatch(node->GetTitle(), query_nodes, 169 std::vector<QueryWord> title_words, url_words;
160 &(title_match.match_positions))) { 170 parser->ExtractQueryWords(
161 title_match.node = node; 171 base::i18n::ToLower(node->GetTitle()), &title_words);
162 results->push_back(title_match); 172 parser->ExtractQueryWords(
173 bookmark_utils::CleanUpUrlForMatching(node->url(), languages_),
174 &url_words);
175 Snippet::MatchPositions title_matches, url_matches;
176 for (size_t i = 0; i < query_nodes.size(); ++i) {
177 const bool has_title_matches =
178 query_nodes[i]->HasMatchIn(title_words, &title_matches);
179 const bool has_url_matches =
180 query_nodes[i]->HasMatchIn(url_words, &url_matches);
181 if (!has_title_matches && !has_url_matches)
182 return;
183 QueryParser::CoalseAndSortMatchPositions(&title_matches);
184 QueryParser::CoalseAndSortMatchPositions(&url_matches);
163 } 185 }
186 match.title_match_positions.swap(title_matches);
187 match.url_match_positions.swap(url_matches);
188 match.node = node;
189 results->push_back(match);
164 } 190 }
165 191
166 bool BookmarkIndex::GetBookmarksWithTitleMatchingTerm(const base::string16& term , 192 bool BookmarkIndex::GetBookmarksMatchingTerm(const base::string16& term,
167 bool first_term, 193 bool first_term,
168 Matches* matches) { 194 Matches* matches) {
169 Index::const_iterator i = index_.lower_bound(term); 195 Index::const_iterator i = index_.lower_bound(term);
170 if (i == index_.end()) 196 if (i == index_.end())
171 return false; 197 return false;
172 198
173 if (!QueryParser::IsWordLongEnoughForPrefixSearch(term)) { 199 if (!QueryParser::IsWordLongEnoughForPrefixSearch(term)) {
174 // Term is too short for prefix match, compare using exact match. 200 // Term is too short for prefix match, compare using exact match.
175 if (i->first != term) 201 if (i->first != term)
176 return false; // No bookmarks with this term. 202 return false; // No bookmarks with this term.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 Index::iterator i = index_.find(term); 293 Index::iterator i = index_.find(term);
268 if (i == index_.end()) { 294 if (i == index_.end()) {
269 // We can get here if the node has the same term more than once. For 295 // We can get here if the node has the same term more than once. For
270 // example, a bookmark with the title 'foo foo' would end up here. 296 // example, a bookmark with the title 'foo foo' would end up here.
271 return; 297 return;
272 } 298 }
273 i->second.erase(node); 299 i->second.erase(node);
274 if (i->second.empty()) 300 if (i->second.empty())
275 index_.erase(i); 301 index_.erase(i);
276 } 302 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698