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

Unified Diff: components/query_parser/query_parser.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 side-by-side diff with in-line comments
Download patch
Index: components/query_parser/query_parser.cc
diff --git a/components/query_parser/query_parser.cc b/components/query_parser/query_parser.cc
index 96c73c2de5e9f719366cc98952b669c350ce54b5..dc8471e76a1c6ed6b634f8293a8fb06a8f1a45a5 100644
--- a/components/query_parser/query_parser.cc
+++ b/components/query_parser/query_parser.cc
@@ -71,6 +71,7 @@ class QueryNodeWord : public QueryNode {
const base::string16& word() const { return word_; }
+ bool literal() const { return literal_; };
void set_literal(bool literal) { literal_ = literal; }
// QueryNode:
@@ -142,6 +143,44 @@ void QueryNodeWord::AppendWords(std::vector<base::string16>* words) const {
words->push_back(word_);
}
+// A QueryNodePrefixWord is a single word in the query that can always be used
+// in a prefix search. By comparison, short words as QueryNodeWord are only
+// checked for exact matches.
+class QueryNodePrefixWord : public QueryNodeWord {
Kibeom Kim (inactive) 2014/11/03 18:41:32 It looks like this class is identical to QueryNode
sky 2014/11/03 21:44:05 Why bother with a template and not a field, always
Kibeom Kim (inactive) 2014/11/04 01:28:19 Done. Since the class is local to this file and n
+ public:
+ explicit QueryNodePrefixWord(const base::string16& word);
+ ~QueryNodePrefixWord() override;
+
+ // QueryNodeWord:
+ int AppendToSQLiteQuery(base::string16* query) const override;
+ bool Matches(const base::string16& word, bool exact) const override;
+
+ DISALLOW_COPY_AND_ASSIGN(QueryNodePrefixWord);
+};
+
+QueryNodePrefixWord::QueryNodePrefixWord(const base::string16& word)
+ : QueryNodeWord(word) {}
+
+QueryNodePrefixWord::~QueryNodePrefixWord() {}
+
+int QueryNodePrefixWord::AppendToSQLiteQuery(base::string16* query) const {
+ query->append(this->word());
+
+ // Use prefix search if we're not literal and long enough.
+ if (!this->literal())
+ *query += L'*';
+ return 1;
+}
+
+bool QueryNodePrefixWord::Matches(const base::string16& word,
+ bool exact) const {
+ if (exact)
+ return word == this->word();
+ return word.size() >= this->word().size() &&
+ (this->word().compare(
+ 0, this->word().size(), word, 0, this->word().size()) == 0);
+}
+
// A QueryNodeList has a collection of QueryNodes which are deleted in the end.
class QueryNodeList : public QueryNode {
public:
@@ -327,25 +366,28 @@ bool QueryParser::IsWordLongEnoughForPrefixSearch(const base::string16& word) {
}
int QueryParser::ParseQuery(const base::string16& query,
+ bool always_prefix_search,
base::string16* sqlite_query) {
QueryNodeList root;
- if (!ParseQueryImpl(query, &root))
+ if (!ParseQueryImpl(query, always_prefix_search, &root))
return 0;
return root.AppendToSQLiteQuery(sqlite_query);
}
void QueryParser::ParseQueryWords(const base::string16& query,
+ bool always_prefix_search,
std::vector<base::string16>* words) {
QueryNodeList root;
- if (!ParseQueryImpl(query, &root))
+ if (!ParseQueryImpl(query, always_prefix_search, &root))
return;
root.AppendWords(words);
}
void QueryParser::ParseQueryNodes(const base::string16& query,
+ bool always_prefix_search,
QueryNodeStarVector* nodes) {
QueryNodeList root;
- if (ParseQueryImpl(base::i18n::ToLower(query), &root))
+ if (ParseQueryImpl(base::i18n::ToLower(query), always_prefix_search, &root))
nodes->swap(*root.children());
}
@@ -393,6 +435,7 @@ bool QueryParser::DoesQueryMatch(const QueryWordVector& query_words,
}
bool QueryParser::ParseQueryImpl(const base::string16& query,
+ bool always_prefix_search,
QueryNodeList* root) {
base::i18n::BreakIterator iter(query, base::i18n::BreakIterator::BREAK_WORD);
// TODO(evanm): support a locale here
@@ -410,7 +453,9 @@ bool QueryParser::ParseQueryImpl(const base::string16& query,
// is not necessarily a word, but could also be a sequence of punctuation
// or whitespace.
if (iter.IsWord()) {
- QueryNodeWord* word_node = new QueryNodeWord(iter.GetString());
+ QueryNodeWord* word_node = (always_prefix_search)
+ ? new QueryNodePrefixWord(iter.GetString())
+ : new QueryNodeWord(iter.GetString());
if (in_quotes)
word_node->set_literal(true);
query_stack.back()->AddChild(word_node);

Powered by Google App Engine
This is Rietveld 408576698