Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/autocomplete/search_provider.h" | 5 #include "chrome/browser/autocomplete/search_provider.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 match.allowed_to_be_default_match = true; | 239 match.allowed_to_be_default_match = true; |
| 240 matches_.push_back(match); | 240 matches_.push_back(match); |
| 241 } | 241 } |
| 242 Stop(true); | 242 Stop(true); |
| 243 return; | 243 return; |
| 244 } | 244 } |
| 245 | 245 |
| 246 input_ = input; | 246 input_ = input; |
| 247 | 247 |
| 248 DoHistoryQuery(minimal_changes); | 248 DoHistoryQuery(minimal_changes); |
| 249 DoAnswersQuery(input); | 249 // Answers needs the scored history results before any suggest query has been |
|
Mark P
2014/09/05 22:18:16
nit: omit "the"
groby-ooo-7-16
2014/09/10 23:21:32
Done.
| |
| 250 // started. | |
|
Mark P
2014/09/05 22:18:15
Please explain why, either here or elsewhere if th
groby-ooo-7-16
2014/09/10 23:21:37
Done.
| |
| 251 if (OmniboxFieldTrial::EnableAnswersInSuggest()) { | |
|
groby-ooo-7-16
2014/08/28 21:36:08
We could _always_ do the scoring after DoHistoryQu
Mark P
2014/09/05 22:18:16
I like your approach in this changelist.
groby-ooo-7-16
2014/09/10 23:21:32
Acknowledged.
| |
| 252 ScoreHistoryResultsMultiWord( | |
| 253 default_history_results_, false, &scored_default_history_results_); | |
| 254 ScoreHistoryResultsMultiWord( | |
| 255 keyword_history_results_, true, &scored_keyword_history_results_); | |
| 256 | |
| 257 prefetch_data_ = FindAnswersPrefetchData(input.text()); | |
| 258 } | |
|
Mark P
2014/09/05 22:18:15
Consider:
else { clear all relevant data }
groby-ooo-7-16
2014/09/10 23:21:33
Done.
| |
| 259 | |
| 250 StartOrStopSuggestQuery(minimal_changes); | 260 StartOrStopSuggestQuery(minimal_changes); |
| 251 UpdateMatches(); | 261 UpdateMatches(); |
| 252 } | 262 } |
| 253 | 263 |
| 254 void SearchProvider::Stop(bool clear_cached_results) { | 264 void SearchProvider::Stop(bool clear_cached_results) { |
| 255 StopSuggest(); | 265 StopSuggest(); |
| 256 done_ = true; | 266 done_ = true; |
| 257 | 267 |
| 258 if (clear_cached_results) | 268 if (clear_cached_results) |
| 259 ClearAllResults(); | 269 ClearAllResults(); |
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 874 } | 884 } |
| 875 | 885 |
| 876 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, | 886 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, |
| 877 bool is_keyword, | 887 bool is_keyword, |
| 878 int did_not_accept_suggestion, | 888 int did_not_accept_suggestion, |
| 879 MatchMap* map) { | 889 MatchMap* map) { |
| 880 if (results.empty()) | 890 if (results.empty()) |
| 881 return; | 891 return; |
| 882 | 892 |
| 883 base::TimeTicks start_time(base::TimeTicks::Now()); | 893 base::TimeTicks start_time(base::TimeTicks::Now()); |
| 884 bool prevent_inline_autocomplete = input_.prevent_inline_autocomplete() || | |
| 885 (input_.type() == metrics::OmniboxInputType::URL); | |
| 886 const base::string16& input_text = | |
| 887 is_keyword ? keyword_input_.text() : input_.text(); | |
| 888 bool input_multiple_words = HasMultipleWords(input_text); | |
| 889 | 894 |
| 890 SearchSuggestionParser::SuggestResults scored_results; | 895 // Until Answers becomes default, scoring of history results will still happen |
| 891 if (!prevent_inline_autocomplete && input_multiple_words) { | 896 // here for non-Answers Chrome, to prevent any impact on timing measurements. |
|
Mark P
2014/09/05 22:18:16
The reason for this is not "to prevent any impact
groby-ooo-7-16
2014/09/10 23:21:33
Done.
| |
| 892 // ScoreHistoryResults() allows autocompletion of multi-word, 1-visit | 897 // Answers FieldTrials will instead use scoring results obtained previously. |
|
Mark P
2014/09/05 22:18:16
nit: "Answers FieldTrials" is awkward. Consider r
groby-ooo-7-16
2014/09/10 23:21:38
Done.
| |
| 893 // queries if the input also has multiple words. But if we were already | 898 SearchSuggestionParser::SuggestResults local_scored_results; |
| 894 // scoring a multi-word, multi-visit query aggressively, and the current | 899 const SearchSuggestionParser::SuggestResults* scored_results = NULL; |
| 895 // input is still a prefix of it, then changing the suggestion suddenly | 900 if (!OmniboxFieldTrial::EnableAnswersInSuggest()) { |
|
groby-ooo-7-16
2014/08/28 21:36:08
Another repost: Do we want to run unit tests both
Mark P
2014/09/05 22:18:16
It's up to you.
My typical strategy when I add a
groby-ooo-7-16
2014/09/10 23:21:33
They _shouldn't_ behave differently except for Ans
| |
| 896 // feels wrong. To detect this case, first score as if only one word has | 901 ScoreHistoryResultsMultiWord(results, is_keyword, &local_scored_results); |
| 897 // been typed, then check if the best result came from aggressive search | 902 scored_results = &local_scored_results; |
| 898 // history scoring. If it did, then just keep that score set. This | 903 } else { |
| 899 // 1200 the lowest possible score in CalculateRelevanceForHistory()'s | 904 // TODO(groby): Once answers is on by default, just pass in scored results. |
| 900 // aggressive-scoring curve. | 905 scored_results = is_keyword ? &scored_keyword_history_results_ |
| 901 scored_results = ScoreHistoryResults(results, prevent_inline_autocomplete, | 906 : &scored_default_history_results_; |
| 902 false, input_text, is_keyword); | |
| 903 if ((scored_results.front().relevance() < 1200) || | |
| 904 !HasMultipleWords(scored_results.front().suggestion())) | |
| 905 scored_results.clear(); // Didn't detect the case above, score normally. | |
| 906 } | 907 } |
| 907 if (scored_results.empty()) | 908 DCHECK(scored_results); |
| 908 scored_results = ScoreHistoryResults(results, prevent_inline_autocomplete, | 909 AddScoredHistoryResultsToMap(*scored_results, did_not_accept_suggestion, map); |
| 909 input_multiple_words, input_text, | |
| 910 is_keyword); | |
| 911 for (SearchSuggestionParser::SuggestResults::const_iterator i( | |
| 912 scored_results.begin()); i != scored_results.end(); ++i) { | |
| 913 AddMatchToMap(*i, std::string(), did_not_accept_suggestion, true, | |
| 914 providers_.GetKeywordProviderURL() != NULL, map); | |
| 915 } | |
| 916 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.AddHistoryResultsTime", | 910 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.AddHistoryResultsTime", |
| 917 base::TimeTicks::Now() - start_time); | 911 base::TimeTicks::Now() - start_time); |
| 918 } | 912 } |
| 919 | 913 |
| 914 // TODO(groby): Can this be merged with AddSuggestResultsToMap? | |
|
groby-ooo-7-16
2014/08/28 21:36:08
I don't think it can because AddSuggestResults bec
Mark P
2014/09/05 22:18:15
You're reading this wrong. It sets |mark_as_delet
groby-ooo-7-16
2014/09/10 23:21:37
Skipping the merging, then.
| |
| 915 void SearchProvider::AddScoredHistoryResultsToMap( | |
| 916 const SearchSuggestionParser::SuggestResults& results, | |
| 917 int did_not_accept_suggestion, | |
| 918 MatchMap* map) { | |
| 919 if (results.empty()) | |
|
Mark P
2014/09/05 22:18:16
I'm not sure the results.empty() short-circuit is
groby-ooo-7-16
2014/09/10 23:21:37
Done.
| |
| 920 return; | |
| 921 | |
| 922 for (SearchSuggestionParser::SuggestResults::const_iterator i( | |
| 923 results.begin()); i != results.end(); ++i) { | |
| 924 AddMatchToMap(*i, std::string(), did_not_accept_suggestion, true, | |
| 925 providers_.GetKeywordProviderURL() != NULL, map); | |
| 926 } | |
| 927 } | |
| 928 | |
| 920 SearchSuggestionParser::SuggestResults SearchProvider::ScoreHistoryResults( | 929 SearchSuggestionParser::SuggestResults SearchProvider::ScoreHistoryResults( |
| 921 const HistoryResults& results, | 930 const HistoryResults& results, |
| 922 bool base_prevent_inline_autocomplete, | 931 bool base_prevent_inline_autocomplete, |
| 923 bool input_multiple_words, | 932 bool input_multiple_words, |
| 924 const base::string16& input_text, | 933 const base::string16& input_text, |
| 925 bool is_keyword) { | 934 bool is_keyword) { |
| 926 SearchSuggestionParser::SuggestResults scored_results; | 935 SearchSuggestionParser::SuggestResults scored_results; |
| 927 // True if the user has asked this exact query previously. | 936 // True if the user has asked this exact query previously. |
| 928 bool found_what_you_typed_match = false; | 937 bool found_what_you_typed_match = false; |
| 929 const bool prevent_search_history_inlining = | 938 const bool prevent_search_history_inlining = |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1022 for (SearchSuggestionParser::SuggestResults::iterator i( | 1031 for (SearchSuggestionParser::SuggestResults::iterator i( |
| 1023 scored_results.begin()); i != scored_results.end(); ++i) { | 1032 scored_results.begin()); i != scored_results.end(); ++i) { |
| 1024 if ((last_relevance != 0) && (i->relevance() >= last_relevance)) | 1033 if ((last_relevance != 0) && (i->relevance() >= last_relevance)) |
| 1025 i->set_relevance(last_relevance - 1); | 1034 i->set_relevance(last_relevance - 1); |
| 1026 last_relevance = i->relevance(); | 1035 last_relevance = i->relevance(); |
| 1027 } | 1036 } |
| 1028 | 1037 |
| 1029 return scored_results; | 1038 return scored_results; |
| 1030 } | 1039 } |
| 1031 | 1040 |
| 1041 void SearchProvider::ScoreHistoryResultsMultiWord( | |
| 1042 const HistoryResults& results, | |
| 1043 bool is_keyword, | |
| 1044 SearchSuggestionParser::SuggestResults* scored_results) { | |
| 1045 if (results.empty()) | |
|
Mark P
2014/09/05 22:18:16
Shouldn't we clear scored_results in this case?
groby-ooo-7-16
2014/09/10 23:21:33
Done.
| |
| 1046 return; | |
| 1047 | |
| 1048 bool prevent_inline_autocomplete = | |
| 1049 input_.prevent_inline_autocomplete() || | |
|
Mark P
2014/09/05 22:18:16
nit: can't this go on the previous line?
groby-ooo-7-16
2014/09/10 23:21:37
It can. I blame git cl format.
| |
| 1050 (input_.type() == metrics::OmniboxInputType::URL); | |
| 1051 const base::string16& input_text = | |
| 1052 is_keyword ? keyword_input_.text() : input_.text(); | |
|
Mark P
2014/09/05 22:18:15
Consider GetInput(is_keyword).text()
groby-ooo-7-16
2014/09/10 23:21:38
Done.
| |
| 1053 bool input_multiple_words = HasMultipleWords(input_text); | |
| 1054 | |
| 1055 if (!prevent_inline_autocomplete && input_multiple_words) { | |
| 1056 // ScoreHistoryResults() allows autocompletion of multi-word, 1-visit | |
| 1057 // queries if the input also has multiple words. But if we were already | |
| 1058 // scoring a multi-word, multi-visit query aggressively, and the current | |
| 1059 // input is still a prefix of it, then changing the suggestion suddenly | |
| 1060 // feels wrong. To detect this case, first score as if only one word has | |
| 1061 // been typed, then check if the best result came from aggressive search | |
| 1062 // history scoring. If it did, then just keep that score set. This | |
| 1063 // 1200 the lowest possible score in CalculateRelevanceForHistory()'s | |
| 1064 // aggressive-scoring curve. | |
| 1065 *scored_results = ScoreHistoryResults( | |
| 1066 results, prevent_inline_autocomplete, false, input_text, is_keyword); | |
| 1067 if ((scored_results->front().relevance() < 1200) || | |
| 1068 !HasMultipleWords(scored_results->front().suggestion())) | |
| 1069 scored_results->clear(); // Didn't detect the case above, score normally. | |
| 1070 } | |
| 1071 if (scored_results->empty()) | |
|
Mark P
2014/09/05 22:18:15
nit: { }
groby-ooo-7-16
2014/09/10 23:21:33
Done.
| |
| 1072 *scored_results = ScoreHistoryResults(results, prevent_inline_autocomplete, | |
| 1073 input_multiple_words, input_text, | |
| 1074 is_keyword); | |
| 1075 } | |
| 1076 | |
| 1032 void SearchProvider::AddSuggestResultsToMap( | 1077 void SearchProvider::AddSuggestResultsToMap( |
| 1033 const SearchSuggestionParser::SuggestResults& results, | 1078 const SearchSuggestionParser::SuggestResults& results, |
| 1034 const std::string& metadata, | 1079 const std::string& metadata, |
| 1035 MatchMap* map) { | 1080 MatchMap* map) { |
| 1036 for (size_t i = 0; i < results.size(); ++i) { | 1081 for (size_t i = 0; i < results.size(); ++i) { |
| 1037 AddMatchToMap(results[i], metadata, i, false, | 1082 AddMatchToMap(results[i], metadata, i, false, |
| 1038 providers_.GetKeywordProviderURL() != NULL, map); | 1083 providers_.GetKeywordProviderURL() != NULL, map); |
| 1039 } | 1084 } |
| 1040 } | 1085 } |
| 1041 | 1086 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1260 if (match->answer_contents.empty() && result.size() > 1) | 1305 if (match->answer_contents.empty() && result.size() > 1) |
| 1261 ++match; | 1306 ++match; |
| 1262 if (match->answer_contents.empty() || match->answer_type.empty() || | 1307 if (match->answer_contents.empty() || match->answer_type.empty() || |
| 1263 match->fill_into_edit.empty()) | 1308 match->fill_into_edit.empty()) |
| 1264 return; | 1309 return; |
| 1265 | 1310 |
| 1266 // Valid answer encountered, cache it for further queries. | 1311 // Valid answer encountered, cache it for further queries. |
| 1267 answers_cache_.UpdateRecentAnswers(match->fill_into_edit, match->answer_type); | 1312 answers_cache_.UpdateRecentAnswers(match->fill_into_edit, match->answer_type); |
| 1268 } | 1313 } |
| 1269 | 1314 |
| 1270 void SearchProvider::DoAnswersQuery(const AutocompleteInput& input) { | 1315 AnswersQueryData SearchProvider::FindAnswersPrefetchData( |
| 1271 prefetch_data_ = answers_cache_.GetTopAnswerEntry(input.text()); | 1316 const base::string16& input) { |
| 1317 // Retrieve the top entry from scored history results. | |
| 1318 | |
| 1319 // TODO(groby): This seems a bit of a waste. Figure out if we can either | |
| 1320 // re-use a partially populated map, or if we should just scan through the | |
| 1321 // results, duplicates be damned. | |
|
groby-ooo-7-16
2014/08/28 21:36:08
Re-use of the partial map extends the state the Se
Mark P
2014/09/05 22:18:16
I'm not sure I follow your proposal here.
Note th
groby-ooo-7-16
2014/09/10 23:21:35
We're building the MatchMap twice - once here, onc
Mark P
2014/09/16 22:24:55
Acknowledged.
| |
| 1322 MatchMap map; | |
| 1323 // TODO(groby): Can I just default to marking suggestions as "not accepted"? | |
| 1324 // This seems to only matter for AQS.... | |
|
groby-ooo-7-16
2014/08/28 21:36:08
See question above.
If I share state, I'll obviou
groby-ooo-7-16
2014/08/28 21:36:08
See question above.
This might also be relevant
Mark P
2014/09/05 22:18:15
No. In fact, the value of did_not_accept_suggesti
Mark P
2014/09/05 22:18:16
ditto: I'm not sure I follow your proposal here.
groby-ooo-7-16
2014/09/10 23:21:33
Shorter: Does it matter that AddTransformed...() i
groby-ooo-7-16
2014/09/10 23:21:33
Acknowledged.
| |
| 1325 AddScoredHistoryResultsToMap(scored_keyword_history_results_, false, &map); | |
|
Mark P
2014/09/05 22:18:16
Please do not pass false for an int without an exp
groby-ooo-7-16
2014/09/10 23:21:33
It is indeed - thanks for catching this. I read th
| |
| 1326 AddScoredHistoryResultsToMap(scored_default_history_results_, false, &map); | |
| 1327 | |
| 1328 ACMatches matches; | |
| 1329 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) | |
| 1330 matches.push_back(i->second); | |
| 1331 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant); | |
| 1332 | |
| 1333 // If there is a top scoring entry, find the corresponding answer. | |
| 1334 if (!matches.empty()) | |
| 1335 return answers_cache_.GetTopAnswerEntry(matches[0].contents); | |
| 1336 | |
| 1337 return AnswersQueryData(); | |
| 1272 } | 1338 } |
| OLD | NEW |