| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/history/scored_history_match.h" | 5 #include "chrome/browser/history/scored_history_match.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <iterator> | 9 #include <iterator> |
| 10 #include <numeric> | 10 #include <numeric> |
| 11 #include <set> | 11 #include <set> |
| 12 | 12 |
| 13 #include <math.h> | 13 #include <math.h> |
| 14 | 14 |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/i18n/case_conversion.h" | 16 #include "base/i18n/case_conversion.h" |
| 17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 18 #include "base/string_util.h" | 18 #include "base/string_util.h" |
| 19 #include "base/utf_string_conversions.h" | 19 #include "base/utf_string_conversions.h" |
| 20 #include "chrome/browser/api/bookmarks/bookmark_service.h" |
| 20 #include "chrome/browser/autocomplete/autocomplete_field_trial.h" | 21 #include "chrome/browser/autocomplete/autocomplete_field_trial.h" |
| 21 #include "chrome/browser/autocomplete/url_prefix.h" | 22 #include "chrome/browser/autocomplete/url_prefix.h" |
| 22 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
| 23 #include "content/public/browser/browser_thread.h" | 24 #include "content/public/browser/browser_thread.h" |
| 24 | 25 |
| 25 namespace history { | 26 namespace history { |
| 26 | 27 |
| 27 // The maximum score any candidate result can achieve. | 28 // The maximum score any candidate result can achieve. |
| 28 const int kMaxTotalScore = 1425; | 29 const int kMaxTotalScore = 1425; |
| 29 | 30 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 46 if (!initialized_) { | 47 if (!initialized_) { |
| 47 InitializeNewScoringField(); | 48 InitializeNewScoringField(); |
| 48 initialized_ = true; | 49 initialized_ = true; |
| 49 } | 50 } |
| 50 } | 51 } |
| 51 | 52 |
| 52 ScoredHistoryMatch::ScoredHistoryMatch(const URLRow& row, | 53 ScoredHistoryMatch::ScoredHistoryMatch(const URLRow& row, |
| 53 const string16& lower_string, | 54 const string16& lower_string, |
| 54 const String16Vector& terms, | 55 const String16Vector& terms, |
| 55 const RowWordStarts& word_starts, | 56 const RowWordStarts& word_starts, |
| 56 const base::Time now) | 57 const base::Time now, |
| 58 BookmarkService* bookmark_service) |
| 57 : HistoryMatch(row, 0, false, false), | 59 : HistoryMatch(row, 0, false, false), |
| 58 raw_score(0), | 60 raw_score(0), |
| 59 can_inline(false) { | 61 can_inline(false) { |
| 60 if (!initialized_) { | 62 if (!initialized_) { |
| 61 InitializeNewScoringField(); | 63 InitializeNewScoringField(); |
| 62 initialized_ = true; | 64 initialized_ = true; |
| 63 } | 65 } |
| 64 | 66 |
| 65 GURL gurl = row.url(); | 67 GURL gurl = row.url(); |
| 66 if (!gurl.is_valid()) | 68 if (!gurl.is_valid()) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 // 3) AND the search string does not end in whitespace (making it look to | 104 // 3) AND the search string does not end in whitespace (making it look to |
| 103 // the IMUI as though there is a single search term when actually there | 105 // the IMUI as though there is a single search term when actually there |
| 104 // is a second, empty term). | 106 // is a second, empty term). |
| 105 can_inline = !url_matches.empty() && | 107 can_inline = !url_matches.empty() && |
| 106 terms.size() == 1 && | 108 terms.size() == 1 && |
| 107 (url_matches[0].offset == 0 || | 109 (url_matches[0].offset == 0 || |
| 108 URLPrefix::IsURLPrefix(url.substr(0, url_matches[0].offset))) && | 110 URLPrefix::IsURLPrefix(url.substr(0, url_matches[0].offset))) && |
| 109 !IsWhitespace(*(lower_string.rbegin())); | 111 !IsWhitespace(*(lower_string.rbegin())); |
| 110 match_in_scheme = can_inline && url_matches[0].offset == 0; | 112 match_in_scheme = can_inline && url_matches[0].offset == 0; |
| 111 | 113 |
| 114 // Determine if the associated URLs is referenced by any bookmarks. |
| 115 float bookmark_boost = |
| 116 (bookmark_service && bookmark_service->IsBookmarked(gurl)) ? 10.0 : 0.0; |
| 117 |
| 112 if (use_new_scoring) { | 118 if (use_new_scoring) { |
| 113 const float topicality_score = GetTopicalityScore( | 119 const float topicality_score = GetTopicalityScore( |
| 114 terms.size(), url, url_matches, title_matches, word_starts); | 120 terms.size(), url, url_matches, title_matches, word_starts); |
| 115 const float recency_score = GetRecencyScore( | 121 const float recency_score = GetRecencyScore( |
| 116 (now - row.last_visit()).InDays()); | 122 (now - row.last_visit()).InDays()); |
| 117 const float popularity_score = GetPopularityScore( | 123 const float popularity_score = GetPopularityScore( |
| 118 row.typed_count(), row.visit_count()); | 124 row.typed_count() + bookmark_boost, row.visit_count()); |
| 119 | 125 |
| 120 // Combine recency, popularity, and topicality scores into one. | 126 // Combine recency, popularity, and topicality scores into one. |
| 121 // Example of how this functions: Suppose the omnibox has one | 127 // Example of how this functions: Suppose the omnibox has one |
| 122 // input term. Suppose we have a URL that has 30 typed visits with | 128 // input term. Suppose we have a URL that has 30 typed visits with |
| 123 // the most recent being within a day and the omnibox input term | 129 // the most recent being within a day and the omnibox input term |
| 124 // has a single URL hostname hit at a word boundary. Then this | 130 // has a single URL hostname hit at a word boundary. Then this |
| 125 // URL will score 1200 ( = 30 * 40.0). | 131 // URL will score 1200 ( = 30 * 40.0). |
| 126 raw_score = 40.0 * topicality_score * recency_score * popularity_score; | 132 raw_score = 40.0 * topicality_score * recency_score * popularity_score; |
| 127 raw_score = | 133 raw_score = |
| 128 (raw_score <= kint32max) ? static_cast<int>(raw_score) : kint32max; | 134 (raw_score <= kint32max) ? static_cast<int>(raw_score) : kint32max; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 143 return; | 149 return; |
| 144 | 150 |
| 145 // Determine scoring factors for the recency of visit, visit count and typed | 151 // Determine scoring factors for the recency of visit, visit count and typed |
| 146 // count attributes of the URLRow. | 152 // count attributes of the URLRow. |
| 147 const int kDaysAgoLevel[] = { 1, 10, 20, 30 }; | 153 const int kDaysAgoLevel[] = { 1, 10, 20, 30 }; |
| 148 int days_ago_value = ScoreForValue((base::Time::Now() - | 154 int days_ago_value = ScoreForValue((base::Time::Now() - |
| 149 row.last_visit()).InDays(), kDaysAgoLevel); | 155 row.last_visit()).InDays(), kDaysAgoLevel); |
| 150 const int kVisitCountLevel[] = { 50, 30, 10, 5 }; | 156 const int kVisitCountLevel[] = { 50, 30, 10, 5 }; |
| 151 int visit_count_value = ScoreForValue(row.visit_count(), kVisitCountLevel); | 157 int visit_count_value = ScoreForValue(row.visit_count(), kVisitCountLevel); |
| 152 const int kTypedCountLevel[] = { 50, 30, 10, 5 }; | 158 const int kTypedCountLevel[] = { 50, 30, 10, 5 }; |
| 153 int typed_count_value = ScoreForValue(row.typed_count(), kTypedCountLevel); | 159 int typed_count_value = ScoreForValue(row.typed_count() + bookmark_boost, |
| 160 kTypedCountLevel); |
| 154 | 161 |
| 155 // The final raw score is calculated by: | 162 // The final raw score is calculated by: |
| 156 // - multiplying each factor by a 'relevance' | 163 // - multiplying each factor by a 'relevance' |
| 157 // - calculating the average. | 164 // - calculating the average. |
| 158 // Note that visit_count is reduced by typed_count because both are bumped | 165 // Note that visit_count is reduced by typed_count because both are bumped |
| 159 // when a typed URL is recorded thus giving visit_count too much weight. | 166 // when a typed URL is recorded thus giving visit_count too much weight. |
| 160 const int kTermScoreRelevance = 4; | 167 const int kTermScoreRelevance = 4; |
| 161 const int kDaysAgoRelevance = 2; | 168 const int kDaysAgoRelevance = 2; |
| 162 const int kVisitCountRelevance = 2; | 169 const int kVisitCountRelevance = 2; |
| 163 const int kTypedCountRelevance = 5; | 170 const int kTypedCountRelevance = 5; |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 // Add a beacon to the logs that'll allow us to identify later what | 531 // Add a beacon to the logs that'll allow us to identify later what |
| 525 // new scoring state a user is in. Do this by incrementing a bucket in | 532 // new scoring state a user is in. Do this by incrementing a bucket in |
| 526 // a histogram, where the bucket represents the user's new scoring state. | 533 // a histogram, where the bucket represents the user's new scoring state. |
| 527 UMA_HISTOGRAM_ENUMERATION( | 534 UMA_HISTOGRAM_ENUMERATION( |
| 528 "Omnibox.HistoryQuickProviderNewScoringFieldTrialBeacon", | 535 "Omnibox.HistoryQuickProviderNewScoringFieldTrialBeacon", |
| 529 new_scoring_option, NUM_OPTIONS); | 536 new_scoring_option, NUM_OPTIONS); |
| 530 | 537 |
| 531 } | 538 } |
| 532 | 539 |
| 533 } // namespace history | 540 } // namespace history |
| OLD | NEW |