OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/history/query_parser.h" | 5 #include "chrome/browser/history/query_parser.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/i18n/break_iterator.h" | 10 #include "base/i18n/break_iterator.h" |
11 #include "base/i18n/case_conversion.h" | 11 #include "base/i18n/case_conversion.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 // Returns true if |mp1.first| is less than |mp2.first|. This is used to | 17 // Returns true if |mp1.first| is less than |mp2.first|. This is used to |
18 // sort match positions. | 18 // sort match positions. |
19 int CompareMatchPosition(const Snippet::MatchPosition& mp1, | 19 int CompareMatchPosition(const Snippet::MatchPosition& mp1, |
20 const Snippet::MatchPosition& mp2) { | 20 const Snippet::MatchPosition& mp2) { |
21 return mp1.first < mp2.first; | 21 return mp1.first < mp2.first; |
22 } | 22 } |
23 | 23 |
24 // Returns true if |mp2| intersects |mp1|. This is intended for use by | 24 // Returns true if |mp2| intersects |mp1|. This is intended for use by |
25 // CoalesceMatchesFrom and isn't meant as a general intersectpion comparison | 25 // CoalesceMatchesFrom and isn't meant as a general intersection comparison |
26 // function. | 26 // function. |
27 bool SnippetIntersects(const Snippet::MatchPosition& mp1, | 27 bool SnippetIntersects(const Snippet::MatchPosition& mp1, |
28 const Snippet::MatchPosition& mp2) { | 28 const Snippet::MatchPosition& mp2) { |
29 return mp2.first >= mp1.first && mp2.first <= mp1.second; | 29 return mp2.first >= mp1.first && mp2.first <= mp1.second; |
30 } | 30 } |
31 | 31 |
32 // Coalesces match positions in |matches| after index that intersect the match | 32 // Coalesces match positions in |matches| after index that intersect the match |
33 // position at |index|. | 33 // position at |index|. |
34 void CoalesceMatchesFrom(size_t index, Snippet::MatchPositions* matches) { | 34 void CoalesceMatchesFrom(size_t index, Snippet::MatchPositions* matches) { |
35 Snippet::MatchPosition& mp = (*matches)[index]; | 35 Snippet::MatchPosition& mp = (*matches)[index]; |
36 for (Snippet::MatchPositions::iterator i = matches->begin() + index + 1; | 36 for (Snippet::MatchPositions::iterator i = matches->begin() + index + 1; |
37 i != matches->end(); ) { | 37 i != matches->end(); ) { |
38 if (SnippetIntersects(mp, *i)) { | 38 if (SnippetIntersects(mp, *i)) { |
39 mp.second = i->second; | 39 mp.first = std::min(mp.first, i->first); |
sky
2012/10/15 23:32:34
I get the need for std::max on 40, bug 39 shouldn'
mrossetti
2012/10/16 16:38:05
Makes sense. Thanks.
| |
40 mp.second = std::max(mp.second, i->second); | |
40 i = matches->erase(i); | 41 i = matches->erase(i); |
41 } else { | 42 } else { |
42 return; | 43 return; |
43 } | 44 } |
44 } | 45 } |
45 } | 46 } |
46 | 47 |
47 // Sorts the match positions in |matches| by their first index, then coalesces | 48 // Sorts the match positions in |matches| by their first index, then coalesces |
48 // any match positions that intersect each other. | 49 // any match positions that intersect each other. |
49 void CoalseAndSortMatchPositions(Snippet::MatchPositions* matches) { | 50 void CoalseAndSortMatchPositions(Snippet::MatchPositions* matches) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 | 119 |
119 bool QueryNodeWord::Matches(const string16& word, bool exact) const { | 120 bool QueryNodeWord::Matches(const string16& word, bool exact) const { |
120 if (exact || !QueryParser::IsWordLongEnoughForPrefixSearch(word_)) | 121 if (exact || !QueryParser::IsWordLongEnoughForPrefixSearch(word_)) |
121 return word == word_; | 122 return word == word_; |
122 return word.size() >= word_.size() && | 123 return word.size() >= word_.size() && |
123 (word_.compare(0, word_.size(), word, 0, word_.size()) == 0); | 124 (word_.compare(0, word_.size(), word, 0, word_.size()) == 0); |
124 } | 125 } |
125 | 126 |
126 bool QueryNodeWord::HasMatchIn(const std::vector<QueryWord>& words, | 127 bool QueryNodeWord::HasMatchIn(const std::vector<QueryWord>& words, |
127 Snippet::MatchPositions* match_positions) const { | 128 Snippet::MatchPositions* match_positions) const { |
129 bool matched = false; | |
128 for (size_t i = 0; i < words.size(); ++i) { | 130 for (size_t i = 0; i < words.size(); ++i) { |
129 if (Matches(words[i].word, false)) { | 131 if (Matches(words[i].word, false)) { |
130 size_t match_start = words[i].position; | 132 size_t match_start = words[i].position; |
131 match_positions->push_back( | 133 match_positions->push_back( |
132 Snippet::MatchPosition(match_start, | 134 Snippet::MatchPosition(match_start, |
133 match_start + static_cast<int>(word_.size()))); | 135 match_start + static_cast<int>(word_.size()))); |
134 return true; | 136 matched = true; |
135 } | 137 } |
136 } | 138 } |
137 return false; | 139 return matched; |
138 } | 140 } |
139 | 141 |
140 void QueryNodeWord::AppendWords(std::vector<string16>* words) const { | 142 void QueryNodeWord::AppendWords(std::vector<string16>* words) const { |
141 words->push_back(word_); | 143 words->push_back(word_); |
142 } | 144 } |
143 | 145 |
144 // A QueryNodeList has a collection of QueryNodes which are deleted in the end. | 146 // A QueryNodeList has a collection of QueryNodes which are deleted in the end. |
145 class QueryNodeList : public QueryNode { | 147 class QueryNodeList : public QueryNode { |
146 public: | 148 public: |
147 typedef std::vector<QueryNode*> QueryNodeVector; | 149 typedef std::vector<QueryNode*> QueryNodeVector; |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
407 if (iter.IsWord()) { | 409 if (iter.IsWord()) { |
408 string16 word = iter.GetString(); | 410 string16 word = iter.GetString(); |
409 if (!word.empty()) { | 411 if (!word.empty()) { |
410 words->push_back(QueryWord()); | 412 words->push_back(QueryWord()); |
411 words->back().word = word; | 413 words->back().word = word; |
412 words->back().position = iter.prev(); | 414 words->back().position = iter.prev(); |
413 } | 415 } |
414 } | 416 } |
415 } | 417 } |
416 } | 418 } |
OLD | NEW |