OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "ui/app_list/search/tokenized_string_match.h" | 5 #include "ui/app_list/search/tokenized_string_match.h" |
6 | 6 |
| 7 #include <cmath> |
| 8 |
7 #include "base/i18n/string_search.h" | 9 #include "base/i18n/string_search.h" |
8 #include "base/logging.h" | 10 #include "base/logging.h" |
9 #include "ui/app_list/search/tokenized_string_char_iterator.h" | 11 #include "ui/app_list/search/tokenized_string_char_iterator.h" |
10 | 12 |
11 namespace app_list { | 13 namespace app_list { |
12 | 14 |
13 namespace { | 15 namespace { |
14 | 16 |
15 // The factors below are applied when the current char of query matches | 17 // The factors below are applied when the current char of query matches |
16 // the current char of the text to be matched. Different factors are chosen | 18 // the current char of the text to be matched. Different factors are chosen |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 if (base::i18n::StringSearchIgnoringCaseAndAccents(query.text(), | 213 if (base::i18n::StringSearchIgnoringCaseAndAccents(query.text(), |
212 text.text(), | 214 text.text(), |
213 &substr_match_start, | 215 &substr_match_start, |
214 &substr_match_length)) { | 216 &substr_match_length)) { |
215 relevance_ = kIsSubstringMultiplier * substr_match_length; | 217 relevance_ = kIsSubstringMultiplier * substr_match_length; |
216 hits_.push_back(gfx::Range(substr_match_start, | 218 hits_.push_back(gfx::Range(substr_match_start, |
217 substr_match_start + substr_match_length)); | 219 substr_match_start + substr_match_length)); |
218 } | 220 } |
219 } | 221 } |
220 | 222 |
221 // Using length() for normalizing is not 100% correct but should be good | 223 // Temper the relevance score with an exponential curve. Each point of |
222 // enough compared with using real char count of the text. | 224 // relevance (roughly, each keystroke) is worth less than the last. This means |
223 if (text.text().length()) | 225 // that typing a few characters of a word is enough to promote matches very |
224 relevance_ /= text.text().length(); | 226 // high, with any subsequent characters being worth comparatively less. |
| 227 // TODO(mgiuca): This doesn't really play well with Omnibox results, since as |
| 228 // you type more characters, the app/omnibox results tend to jump over each |
| 229 // other. |
| 230 relevance_ = 1.0 - std::pow(0.5, relevance_); |
225 | 231 |
226 return relevance_ > kNoMatchScore; | 232 return relevance_ > kNoMatchScore; |
227 } | 233 } |
228 | 234 |
229 bool TokenizedStringMatch::Calculate(const base::string16& query, | 235 bool TokenizedStringMatch::Calculate(const base::string16& query, |
230 const base::string16& text) { | 236 const base::string16& text) { |
231 const TokenizedString tokenized_query(query); | 237 const TokenizedString tokenized_query(query); |
232 const TokenizedString tokenized_text(text); | 238 const TokenizedString tokenized_text(text); |
233 return Calculate(tokenized_query, tokenized_text); | 239 return Calculate(tokenized_query, tokenized_text); |
234 } | 240 } |
235 | 241 |
236 } // namespace app_list | 242 } // namespace app_list |
OLD | NEW |