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> |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 // makes it inlineable may be empty. | 145 // makes it inlineable may be empty. |
146 DCHECK(best_inlineable_prefix != NULL); | 146 DCHECK(best_inlineable_prefix != NULL); |
147 const int num_components_in_best_inlineable_prefix = | 147 const int num_components_in_best_inlineable_prefix = |
148 best_inlineable_prefix->num_components; | 148 best_inlineable_prefix->num_components; |
149 innermost_match = (num_components_in_best_inlineable_prefix == | 149 innermost_match = (num_components_in_best_inlineable_prefix == |
150 num_components_in_best_prefix); | 150 num_components_in_best_prefix); |
151 } | 151 } |
152 | 152 |
153 const float topicality_score = GetTopicalityScore( | 153 const float topicality_score = GetTopicalityScore( |
154 terms.size(), url, terms_to_word_starts_offsets, word_starts); | 154 terms.size(), url, terms_to_word_starts_offsets, word_starts); |
155 const float frecency_score = GetFrecency( | 155 const float frequency_score = GetFrequency( |
156 now, (bookmark_service && bookmark_service->IsBookmarked(gurl)), visits); | 156 now, (bookmark_service && bookmark_service->IsBookmarked(gurl)), visits); |
157 raw_score_ = GetFinalRelevancyScore(topicality_score, frecency_score); | 157 raw_score_ = GetFinalRelevancyScore(topicality_score, frequency_score); |
158 raw_score_ = | 158 raw_score_ = |
159 (raw_score_ <= kint32max) ? static_cast<int>(raw_score_) : kint32max; | 159 (raw_score_ <= kint32max) ? static_cast<int>(raw_score_) : kint32max; |
160 | 160 |
161 if (also_do_hup_like_scoring_ && can_inline_) { | 161 if (also_do_hup_like_scoring_ && can_inline_) { |
162 // HistoryURL-provider-like scoring gives any match that is | 162 // HistoryURL-provider-like scoring gives any match that is |
163 // capable of being inlined a certain minimum score. Some of these | 163 // capable of being inlined a certain minimum score. Some of these |
164 // are given a higher score that lets them be shown in inline. | 164 // are given a higher score that lets them be shown in inline. |
165 // This test here derives from the test in | 165 // This test here derives from the test in |
166 // HistoryURLProvider::PromoteMatchForInlineAutocomplete(). | 166 // HistoryURLProvider::PromoteMatchForInlineAutocomplete(). |
167 const bool promote_to_inline = (row.typed_count() > 1) || | 167 const bool promote_to_inline = (row.typed_count() > 1) || |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 } | 512 } |
513 days_ago_to_recency_score_[days_ago] = unnormalized_recency_score / 100.0; | 513 days_ago_to_recency_score_[days_ago] = unnormalized_recency_score / 100.0; |
514 if (days_ago > 0) { | 514 if (days_ago > 0) { |
515 DCHECK_LE(days_ago_to_recency_score_[days_ago], | 515 DCHECK_LE(days_ago_to_recency_score_[days_ago], |
516 days_ago_to_recency_score_[days_ago - 1]); | 516 days_ago_to_recency_score_[days_ago - 1]); |
517 } | 517 } |
518 } | 518 } |
519 } | 519 } |
520 | 520 |
521 // static | 521 // static |
522 float ScoredHistoryMatch::GetFrecency(const base::Time& now, | 522 float ScoredHistoryMatch::GetFrequency(const base::Time& now, |
523 const bool bookmarked, | 523 const bool bookmarked, |
524 const VisitInfoVector& visits) { | 524 const VisitInfoVector& visits) { |
525 // Compute the weighted average |value_of_transition| over the last at | 525 // Compute the weighted average |value_of_transition| over the last at |
526 // most kMaxVisitsToScore visits, where each visit is weighted using | 526 // most kMaxVisitsToScore visits, where each visit is weighted using |
527 // GetRecencyScore() based on how many days ago it happened. Use | 527 // GetRecencyScore() based on how many days ago it happened. Use |
528 // kMaxVisitsToScore as the denominator for the average regardless of | 528 // kMaxVisitsToScore as the denominator for the average regardless of |
529 // how many visits there were in order to penalize a match that has | 529 // how many visits there were in order to penalize a match that has |
530 // fewer visits than kMaxVisitsToScore. | 530 // fewer visits than kMaxVisitsToScore. |
531 float summed_visit_points = 0; | 531 float summed_visit_points = 0; |
532 for (size_t i = 0; i < std::min(visits.size(), kMaxVisitsToScore); ++i) { | 532 for (size_t i = 0; i < std::min(visits.size(), kMaxVisitsToScore); ++i) { |
533 int value_of_transition = | 533 int value_of_transition = |
534 (visits[i].second == content::PAGE_TRANSITION_TYPED) ? 20 : 1; | 534 (visits[i].second == content::PAGE_TRANSITION_TYPED) ? 20 : 1; |
535 if (bookmarked) | 535 if (bookmarked) |
536 value_of_transition = std::max(value_of_transition, bookmark_value_); | 536 value_of_transition = std::max(value_of_transition, bookmark_value_); |
537 const float bucket_weight = | 537 const float bucket_weight = |
538 GetRecencyScore((now - visits[i].first).InDays()); | 538 GetRecencyScore((now - visits[i].first).InDays()); |
539 summed_visit_points += (value_of_transition * bucket_weight); | 539 summed_visit_points += (value_of_transition * bucket_weight); |
540 } | 540 } |
541 return visits.size() * summed_visit_points / kMaxVisitsToScore; | 541 return visits.size() * summed_visit_points / kMaxVisitsToScore; |
542 } | 542 } |
543 | 543 |
544 // static | 544 // static |
545 float ScoredHistoryMatch::GetFinalRelevancyScore(float topicality_score, | 545 float ScoredHistoryMatch::GetFinalRelevancyScore(float topicality_score, |
546 float frecency_score) { | 546 float frequency_score) { |
547 if (topicality_score == 0) | 547 if (topicality_score == 0) |
548 return 0; | 548 return 0; |
549 // Here's how to interpret intermediate_score: Suppose the omnibox | 549 // Here's how to interpret intermediate_score: Suppose the omnibox |
550 // has one input term. Suppose we have a URL for which the omnibox | 550 // has one input term. Suppose we have a URL for which the omnibox |
551 // input term has a single URL hostname hit at a word boundary. (This | 551 // input term has a single URL hostname hit at a word boundary. (This |
552 // implies topicality_score = 1.0.). Then the intermediate_score for | 552 // implies topicality_score = 1.0.). Then the intermediate_score for |
553 // this URL will depend entirely on the frecency_score with | 553 // this URL will depend entirely on the frequency_score with |
554 // this interpretation: | 554 // this interpretation: |
555 // - a single typed visit more than three months ago, no other visits -> 0.2 | 555 // - a single typed visit more than three months ago, no other visits -> 0.2 |
556 // - a visit every three days, no typed visits -> 0.706 | 556 // - a visit every three days, no typed visits -> 0.706 |
557 // - a visit every day, no typed visits -> 0.916 | 557 // - a visit every day, no typed visits -> 0.916 |
558 // - a single typed visit yesterday, no other visits -> 2.0 | 558 // - a single typed visit yesterday, no other visits -> 2.0 |
559 // - a typed visit once a week -> 11.77 | 559 // - a typed visit once a week -> 11.77 |
560 // - a typed visit every three days -> 14.12 | 560 // - a typed visit every three days -> 14.12 |
561 // - at least ten typed visits today -> 20.0 (maximum score) | 561 // - at least ten typed visits today -> 20.0 (maximum score) |
562 const float intermediate_score = topicality_score * frecency_score; | 562 const float intermediate_score = topicality_score * frequency_score; |
563 // The below code maps intermediate_score to the range [0, 1399]. | 563 // The below code maps intermediate_score to the range [0, 1399]. |
564 // The score maxes out at 1400 (i.e., cannot beat a good inline result). | 564 // The score maxes out at 1400 (i.e., cannot beat a good inline result). |
565 if (intermediate_score <= 1) { | 565 if (intermediate_score <= 1) { |
566 // Linearly extrapolate between 0 and 1.5 so 0 has a score of 400 | 566 // Linearly extrapolate between 0 and 1.5 so 0 has a score of 400 |
567 // and 1.5 has a score of 600. | 567 // and 1.5 has a score of 600. |
568 const float slope = (600 - 400) / (1.5f - 0.0f); | 568 const float slope = (600 - 400) / (1.5f - 0.0f); |
569 return 400 + slope * intermediate_score; | 569 return 400 + slope * intermediate_score; |
570 } | 570 } |
571 if (intermediate_score <= 12.0) { | 571 if (intermediate_score <= 12.0) { |
572 // Linearly extrapolate up to 12 so 12 has a score of 1300. | 572 // Linearly extrapolate up to 12 so 12 has a score of 1300. |
(...skipping 26 matching lines...) Expand all Loading... |
599 max_assigned_score_for_non_inlineable_matches_ = | 599 max_assigned_score_for_non_inlineable_matches_ = |
600 HistoryURLProvider::kScoreForBestInlineableResult - 1; | 600 HistoryURLProvider::kScoreForBestInlineableResult - 1; |
601 } | 601 } |
602 bookmark_value_ = OmniboxFieldTrial::HQPBookmarkValue(); | 602 bookmark_value_ = OmniboxFieldTrial::HQPBookmarkValue(); |
603 allow_tld_matches_ = OmniboxFieldTrial::HQPAllowMatchInTLDValue(); | 603 allow_tld_matches_ = OmniboxFieldTrial::HQPAllowMatchInTLDValue(); |
604 allow_scheme_matches_ = OmniboxFieldTrial::HQPAllowMatchInSchemeValue(); | 604 allow_scheme_matches_ = OmniboxFieldTrial::HQPAllowMatchInSchemeValue(); |
605 initialized_ = true; | 605 initialized_ = true; |
606 } | 606 } |
607 | 607 |
608 } // namespace history | 608 } // namespace history |
OLD | NEW |