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

Side by Side Diff: chrome/browser/autocomplete/history_contents_provider.cc

Issue 7607007: Add confidence to AutocompleteMatch. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 4 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) 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/autocomplete/history_contents_provider.h" 5 #include "chrome/browser/autocomplete/history_contents_provider.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/autocomplete/autocomplete_match.h" 11 #include "chrome/browser/autocomplete/autocomplete_match.h"
12 #include "chrome/browser/bookmarks/bookmark_model.h" 12 #include "chrome/browser/bookmarks/bookmark_model.h"
13 #include "chrome/browser/bookmarks/bookmark_utils.h" 13 #include "chrome/browser/bookmarks/bookmark_utils.h"
14 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/url_constants.h" 15 #include "chrome/common/url_constants.h"
16 #include "googleurl/src/url_util.h" 16 #include "googleurl/src/url_util.h"
17 #include "net/base/net_util.h" 17 #include "net/base/net_util.h"
18 18
19 using base::TimeTicks; 19 using base::TimeTicks;
20 20
21 namespace { 21 namespace {
22 22
23 // Number of days to search for full text results. The longer this is, the more 23 // Number of days to search for full text results. The longer this is, the more
24 // time it will take. 24 // time it will take.
25 const int kDaysToSearch = 30; 25 const int kDaysToSearch = 30;
26 26
27 } // end namespace
28
27 // When processing the results from the history query, this structure points to 29 // When processing the results from the history query, this structure points to
28 // a single result. It allows the results to be sorted and processed without 30 // a single result. It allows the results to be sorted and processed without
29 // modifying the larger and slower results structure. 31 // modifying the larger and slower results structure.
30 struct MatchReference { 32 struct MatchReference {
31 MatchReference(const history::URLResult* result, int relevance) 33 MatchReference(const history::URLResult* result,
34 int relevance,
35 float confidence)
32 : result(result), 36 : result(result),
33 relevance(relevance) { 37 relevance(relevance),
38 confidence(confidence) {
34 } 39 }
35 40
36 const history::URLResult* result; 41 const history::URLResult* result;
37 int relevance; // Score of relevance computed by CalculateRelevance. 42 int relevance; // Score of relevance computed by CalculateRelevance.
43 float confidence; // Confidence computed by CalculateConfidence.
38 }; 44 };
39 45
46 namespace {
Peter Kasting 2011/08/09 20:53:00 Nit: Don't split the anonymous namespace into two
dominich 2011/08/09 21:43:43 Done.
47
40 // This is a > operator for MatchReference. 48 // This is a > operator for MatchReference.
41 bool CompareMatchRelevance(const MatchReference& a, const MatchReference& b) { 49 bool CompareMatchRelevance(const MatchReference& a, const MatchReference& b) {
42 if (a.relevance != b.relevance) 50 if (a.relevance != b.relevance)
43 return a.relevance > b.relevance; 51 return a.relevance > b.relevance;
44 52
45 // Want results in reverse-chronological order all else being equal. 53 // Want results in reverse-chronological order all else being equal.
46 return a.result->last_visit() > b.result->last_visit(); 54 return a.result->last_visit() > b.result->last_visit();
47 } 55 }
48 56
49 } // namespace 57 } // end namespace
50 58
51 using history::HistoryDatabase; 59 using history::HistoryDatabase;
52 60
53 HistoryContentsProvider::HistoryContentsProvider(ACProviderListener* listener, 61 HistoryContentsProvider::HistoryContentsProvider(ACProviderListener* listener,
54 Profile* profile, 62 Profile* profile,
55 bool body_only) 63 bool body_only)
56 : HistoryProvider(listener, profile, "HistoryContents"), 64 : HistoryProvider(listener, profile, "HistoryContents"),
57 star_title_count_(0), 65 star_title_count_(0),
58 star_contents_count_(0), 66 star_contents_count_(0),
59 title_count_(0), 67 title_count_(0),
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 188
181 // Make the result references and score the results. 189 // Make the result references and score the results.
182 std::vector<MatchReference> result_refs; 190 std::vector<MatchReference> result_refs;
183 result_refs.reserve(results_.size()); 191 result_refs.reserve(results_.size());
184 192
185 // Results are sorted in decreasing order so we run the loop backwards so that 193 // Results are sorted in decreasing order so we run the loop backwards so that
186 // the relevance increment favors the higher ranked results. 194 // the relevance increment favors the higher ranked results.
187 for (std::vector<history::URLResult*>::const_reverse_iterator i = 195 for (std::vector<history::URLResult*>::const_reverse_iterator i =
188 results_.rbegin(); i != results_.rend(); ++i) { 196 results_.rbegin(); i != results_.rend(); ++i) {
189 history::URLResult* result = *i; 197 history::URLResult* result = *i;
190 MatchReference ref(result, CalculateRelevance(*result)); 198 MatchReference ref(result, CalculateRelevance(*result),
199 CalculateConfidence(*result, results_));
191 result_refs.push_back(ref); 200 result_refs.push_back(ref);
192 } 201 }
193 202
194 // Get the top matches and add them. 203 // Get the top matches and add them.
195 size_t max_for_provider = std::min(kMaxMatches, result_refs.size()); 204 size_t max_for_provider = std::min(kMaxMatches, result_refs.size());
196 std::partial_sort(result_refs.begin(), result_refs.begin() + max_for_provider, 205 std::partial_sort(result_refs.begin(), result_refs.begin() + max_for_provider,
197 result_refs.end(), &CompareMatchRelevance); 206 result_refs.end(), &CompareMatchRelevance);
198 matches_.clear(); 207 matches_.clear();
199 for (size_t i = 0; i < max_for_provider; i++) { 208 for (size_t i = 0; i < max_for_provider; i++) {
200 matches_.push_back(ResultToMatch(*result_refs[i].result, 209 AutocompleteMatch match = ResultToMatch(result_refs[i]);
Peter Kasting 2011/08/09 20:53:00 Nit: I prefer constructor form to assignment form
dominich 2011/08/09 21:43:43 Done.
201 result_refs[i].relevance)); 210 UMA_HISTOGRAM_COUNTS_100("Autocomplete.Confidence_HistoryContents",
211 match.confidence * 100);
212 matches_.push_back(match);
202 } 213 }
203 } 214 }
204 215
205 // TODO(mrossetti): Remove MatchInTitle once body_only_ becomes permanent. 216 // TODO(mrossetti): Remove MatchInTitle once body_only_ becomes permanent.
206 bool HistoryContentsProvider::MatchInTitle(const history::URLResult& result) { 217 bool HistoryContentsProvider::MatchInTitle(const history::URLResult& result) {
207 return !body_only_ && !result.title_match_positions().empty(); 218 return !body_only_ && !result.title_match_positions().empty();
208 } 219 }
209 220
210 AutocompleteMatch HistoryContentsProvider::ResultToMatch( 221 AutocompleteMatch HistoryContentsProvider::ResultToMatch(
211 const history::URLResult& result, 222 const MatchReference& match_reference) {
212 int score) { 223 const history::URLResult& result = *match_reference.result;
213 AutocompleteMatch match(this, score, true, MatchInTitle(result) ? 224 AutocompleteMatch match(this, match_reference.relevance,
Peter Kasting 2011/08/09 20:53:00 Nit: This wrapping would be OK: AutocompleteMat
dominich 2011/08/09 21:43:43 Done.
214 AutocompleteMatch::HISTORY_TITLE : AutocompleteMatch::HISTORY_BODY); 225 match_reference.confidence, true,
226 MatchInTitle(result) ?
227 AutocompleteMatch::HISTORY_TITLE :
228 AutocompleteMatch::HISTORY_BODY);
215 match.contents = StringForURLDisplay(result.url(), true, trim_http_); 229 match.contents = StringForURLDisplay(result.url(), true, trim_http_);
216 match.fill_into_edit = 230 match.fill_into_edit =
217 AutocompleteInput::FormattedStringWithEquivalentMeaning(result.url(), 231 AutocompleteInput::FormattedStringWithEquivalentMeaning(result.url(),
218 match.contents); 232 match.contents);
219 match.destination_url = result.url(); 233 match.destination_url = result.url();
220 match.contents_class.push_back( 234 match.contents_class.push_back(
221 ACMatchClassification(0, ACMatchClassification::URL)); 235 ACMatchClassification(0, ACMatchClassification::URL));
222 match.description = result.title(); 236 match.description = result.title();
223 match.starred = 237 match.starred =
224 (profile_->GetBookmarkModel() && 238 (profile_->GetBookmarkModel() &&
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 int HistoryContentsProvider::CalculateRelevance( 270 int HistoryContentsProvider::CalculateRelevance(
257 const history::URLResult& result) { 271 const history::URLResult& result) {
258 const bool in_title = MatchInTitle(result); 272 const bool in_title = MatchInTitle(result);
259 if (!profile_->GetBookmarkModel() || 273 if (!profile_->GetBookmarkModel() ||
260 !profile_->GetBookmarkModel()->IsBookmarked(result.url())) 274 !profile_->GetBookmarkModel()->IsBookmarked(result.url()))
261 return in_title ? (700 + title_count_++) : (500 + contents_count_++); 275 return in_title ? (700 + title_count_++) : (500 + contents_count_++);
262 return in_title ? 276 return in_title ?
263 (1000 + star_title_count_++) : (550 + star_contents_count_++); 277 (1000 + star_title_count_++) : (550 + star_contents_count_++);
264 } 278 }
265 279
280 float HistoryContentsProvider::CalculateConfidence(
281 const history::URLResult& result,
282 const history::QueryResults& results) const {
283 // Calculate a score of [0, 0.5] based on visit count.
284 // TODO(dominic): Include typed count?
Peter Kasting 2011/08/09 20:53:00 If you're only going to use one, prefer typed_coun
dominich 2011/08/09 21:43:43 Done.
285 float numerator = result.visit_count();
286 float denominator = 0.0f;
287 for (std::vector<history::URLResult*>::const_iterator it = results.begin();
288 it != results.end(); ++it) {
289 denominator += (*it)->visit_count();
290 }
291 // It should only be equal to 0 if the result is not in the results vector.
292 DCHECK(denominator > 0);
293 float score = 0.5f * (numerator / denominator);
294
295 // Add 0.5 if the URL is bookmarked to get a final range of [0, 1].
Peter Kasting 2011/08/09 20:53:00 I think this gives far too much weight to bookmark
dominich 2011/08/09 21:43:43 Done.
296 if (profile_->GetBookmarkModel() &&
297 profile_->GetBookmarkModel()->IsBookmarked(result.url())) {
298 score += 0.5f;
299 }
300
301 return score;
302 }
303
266 void HistoryContentsProvider::QueryBookmarks(const AutocompleteInput& input) { 304 void HistoryContentsProvider::QueryBookmarks(const AutocompleteInput& input) {
267 BookmarkModel* bookmark_model = profile_->GetBookmarkModel(); 305 BookmarkModel* bookmark_model = profile_->GetBookmarkModel();
268 if (!bookmark_model) 306 if (!bookmark_model)
269 return; 307 return;
270 308
271 DCHECK(results_.empty()); 309 DCHECK(results_.empty());
272 310
273 TimeTicks start_time = TimeTicks::Now(); 311 TimeTicks start_time = TimeTicks::Now();
274 std::vector<bookmark_utils::TitleMatch> matches; 312 std::vector<bookmark_utils::TitleMatch> matches;
275 bookmark_model->GetBookmarksWithTitlesMatching(input.text(), 313 bookmark_model->GetBookmarksWithTitlesMatching(input.text(),
276 kMaxMatches, &matches); 314 kMaxMatches, &matches);
277 for (size_t i = 0; i < matches.size(); ++i) 315 for (size_t i = 0; i < matches.size(); ++i)
278 AddBookmarkTitleMatchToResults(matches[i]); 316 AddBookmarkTitleMatchToResults(matches[i]);
279 UMA_HISTOGRAM_TIMES("Omnibox.QueryBookmarksTime", 317 UMA_HISTOGRAM_TIMES("Omnibox.QueryBookmarksTime",
280 TimeTicks::Now() - start_time); 318 TimeTicks::Now() - start_time);
281 } 319 }
282 320
283 void HistoryContentsProvider::AddBookmarkTitleMatchToResults( 321 void HistoryContentsProvider::AddBookmarkTitleMatchToResults(
284 const bookmark_utils::TitleMatch& match) { 322 const bookmark_utils::TitleMatch& match) {
285 history::URLResult url_result(match.node->url(), match.match_positions); 323 history::URLResult url_result(match.node->url(), match.match_positions);
286 url_result.set_title(match.node->GetTitle()); 324 url_result.set_title(match.node->GetTitle());
287 results_.AppendURLBySwapping(&url_result); 325 results_.AppendURLBySwapping(&url_result);
288 } 326 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698