OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/common/thumbnail_score.h" | 5 #include "chrome/common/thumbnail_score.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stringprintf.h" |
8 | 9 |
9 using base::Time; | 10 using base::Time; |
10 using base::TimeDelta; | 11 using base::TimeDelta; |
11 | 12 |
12 const TimeDelta ThumbnailScore::kUpdateThumbnailTime = TimeDelta::FromDays(1); | 13 const TimeDelta ThumbnailScore::kUpdateThumbnailTime = TimeDelta::FromDays(1); |
13 const double ThumbnailScore::kThumbnailMaximumBoringness = 0.94; | 14 const double ThumbnailScore::kThumbnailMaximumBoringness = 0.94; |
| 15 // Per crbug.com/65936#c4, 91.83% of thumbnail scores are less than 0.70. |
| 16 const double ThumbnailScore::kThumbnailInterestingEnoughBoringness = 0.70; |
14 const double ThumbnailScore::kThumbnailDegradePerHour = 0.01; | 17 const double ThumbnailScore::kThumbnailDegradePerHour = 0.01; |
15 | 18 |
16 // Calculates a numeric score from traits about where a snapshot was | 19 // Calculates a numeric score from traits about where a snapshot was |
17 // taken. We store the raw components in the database because I'm sure | 20 // taken. We store the raw components in the database because I'm sure |
18 // this will evolve and I don't want to break databases. | 21 // this will evolve and I don't want to break databases. |
19 static int GetThumbnailType(bool good_clipping, bool at_top) { | 22 static int GetThumbnailType(bool good_clipping, bool at_top) { |
20 if (good_clipping && at_top) { | 23 if (good_clipping && at_top) { |
21 return 0; | 24 return 0; |
22 } else if (good_clipping && !at_top) { | 25 } else if (good_clipping && !at_top) { |
23 return 1; | 26 return 1; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 // When testing equality we use ToTimeT() because that's the value | 66 // When testing equality we use ToTimeT() because that's the value |
64 // stuck in the SQL database, so we need to test equivalence with | 67 // stuck in the SQL database, so we need to test equivalence with |
65 // that lower resolution. | 68 // that lower resolution. |
66 return boring_score == rhs.boring_score && | 69 return boring_score == rhs.boring_score && |
67 good_clipping == rhs.good_clipping && | 70 good_clipping == rhs.good_clipping && |
68 at_top == rhs.at_top && | 71 at_top == rhs.at_top && |
69 time_at_snapshot.ToTimeT() == rhs.time_at_snapshot.ToTimeT() && | 72 time_at_snapshot.ToTimeT() == rhs.time_at_snapshot.ToTimeT() && |
70 redirect_hops_from_dest == rhs.redirect_hops_from_dest; | 73 redirect_hops_from_dest == rhs.redirect_hops_from_dest; |
71 } | 74 } |
72 | 75 |
| 76 std::string ThumbnailScore::ToString() const { |
| 77 return StringPrintf("boring_score: %f, at_top %d, good_clipping %d, " |
| 78 "time_at_snapshot: %f, redirect_hops_from_dest: %d", |
| 79 boring_score, |
| 80 at_top, |
| 81 good_clipping, |
| 82 time_at_snapshot.ToDoubleT(), |
| 83 redirect_hops_from_dest); |
| 84 } |
| 85 |
73 bool ShouldReplaceThumbnailWith(const ThumbnailScore& current, | 86 bool ShouldReplaceThumbnailWith(const ThumbnailScore& current, |
74 const ThumbnailScore& replacement) { | 87 const ThumbnailScore& replacement) { |
75 int current_type = GetThumbnailType(current.good_clipping, current.at_top); | 88 int current_type = GetThumbnailType(current.good_clipping, current.at_top); |
76 int replacement_type = GetThumbnailType(replacement.good_clipping, | 89 int replacement_type = GetThumbnailType(replacement.good_clipping, |
77 replacement.at_top); | 90 replacement.at_top); |
78 if (replacement_type < current_type) { | 91 if (replacement_type < current_type) { |
79 // If we have a better class of thumbnail, add it if it meets | 92 // If we have a better class of thumbnail, add it if it meets |
80 // certain minimum boringness. | 93 // certain minimum boringness. |
81 return replacement.boring_score < | 94 return replacement.boring_score < |
82 ThumbnailScore::kThumbnailMaximumBoringness; | 95 ThumbnailScore::kThumbnailMaximumBoringness; |
(...skipping 26 matching lines...) Expand all Loading... |
109 if (replacement_interesting_score > current_interesting_score) | 122 if (replacement_interesting_score > current_interesting_score) |
110 return true; | 123 return true; |
111 } | 124 } |
112 | 125 |
113 // If the current thumbnail doesn't meet basic boringness | 126 // If the current thumbnail doesn't meet basic boringness |
114 // requirements, but the replacement does, always replace the | 127 // requirements, but the replacement does, always replace the |
115 // current one even if we're using a worse thumbnail type. | 128 // current one even if we're using a worse thumbnail type. |
116 return current.boring_score >= ThumbnailScore::kThumbnailMaximumBoringness && | 129 return current.boring_score >= ThumbnailScore::kThumbnailMaximumBoringness && |
117 replacement.boring_score < ThumbnailScore::kThumbnailMaximumBoringness; | 130 replacement.boring_score < ThumbnailScore::kThumbnailMaximumBoringness; |
118 } | 131 } |
| 132 |
| 133 bool ThumbnailScore::ShouldConsiderUpdating() { |
| 134 const TimeDelta time_elapsed = Time::Now() - time_at_snapshot; |
| 135 // Consider the current thumbnail to be new and interesting enough if |
| 136 // the following critera are met. |
| 137 const bool new_and_interesting_enough = |
| 138 (time_elapsed < kUpdateThumbnailTime && |
| 139 good_clipping && at_top && |
| 140 boring_score < kThumbnailInterestingEnoughBoringness); |
| 141 // We want to generate a new thumbnail when the current thumbnail is |
| 142 // sufficiently old or uninteresting. |
| 143 return !new_and_interesting_enough; |
| 144 } |
OLD | NEW |