Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/contextual_search/browser/ctr_aggregator.h" | |
| 6 | |
| 7 #include <unordered_map> | |
| 8 | |
| 9 #include "base/lazy_instance.h" | |
| 10 #include "base/time/time.h" | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 // Keys for ChromePreferenceManager storage of first and last week written. | |
| 15 const char kFirstWeekWrittenKey[] = "contextual_search_first_week"; | |
| 16 const char kLastWeekWrittenKey[] = "contextual_search_last_week"; | |
| 17 // Number of weeks of data to record. | |
| 18 const int kNumWeeksToRecord = 5; | |
| 19 // Prefixes for ChromePreferenceManager storage keyed by week. | |
| 20 const char kClicksWeekKeyPrefix[] = "contextual_search_clicks_week_"; | |
| 21 const char kImpressionsWeekKeyPrefix[] = "contextual_search_impressions_week_"; | |
| 22 | |
| 23 const double kSecondsPerWeek = | |
| 24 base::Time::kMicrosecondsPerWeek / base::Time::kMicrosecondsPerSecond; | |
| 25 // Used for validation in debug build. | |
| 26 const int kReasonableMinWeek = 2000; | |
|
Theresa
2016/08/26 23:32:08
Why 2000?
Donn Denman
2016/08/29 22:58:06
Updated the comment: // Used for validation in deb
Theresa
2016/08/29 23:57:34
Acknowledged.
| |
| 27 | |
| 28 } // namespace | |
| 29 | |
| 30 namespace contextual_search { | |
| 31 | |
| 32 CTRAggregator::CTRAggregator(NativeIntStorage& storage) : storage_(storage) { | |
| 33 base::Time now = base::Time::NowFromSystemTime(); | |
| 34 double now_in_seconds = now.ToDoubleT(); | |
| 35 week_number_ = now_in_seconds / kSecondsPerWeek; | |
| 36 DCHECK(week_number_ >= kReasonableMinWeek); | |
| 37 } | |
| 38 | |
| 39 CTRAggregator::CTRAggregator(NativeIntStorage& storage, int week_number) | |
| 40 : storage_(storage), week_number_(week_number) { | |
| 41 storage_.WriteInt(kFirstWeekWrittenKey, week_number_); | |
|
Theresa
2016/08/26 23:32:08
Does this line need to get included in the 1-param
Donn Denman
2016/08/29 22:58:05
It's problematic to put it into the constructor si
| |
| 42 } | |
| 43 | |
| 44 CTRAggregator::~CTRAggregator() {} | |
| 45 | |
| 46 void CTRAggregator::RecordImpression(bool did_click) { | |
| 47 UpdateStorageToCurrentWeek(); | |
| 48 Increment(GetWeekImpressionsKey(week_number_)); | |
| 49 if (did_click) | |
| 50 Increment(GetWeekClicksKey(week_number_)); | |
| 51 } | |
| 52 | |
| 53 bool CTRAggregator::HasPreviousWeekData() { | |
| 54 EnsureFirstWeekRecorded(); | |
| 55 int first_week_written = storage_.ReadInt(kFirstWeekWrittenKey); | |
| 56 return (week_number_ - first_week_written >= 1); | |
| 57 } | |
| 58 | |
| 59 int CTRAggregator::GetPreviousWeekImpressions() { | |
| 60 UpdateStorageToCurrentWeek(); | |
| 61 std::string key_impressions = GetWeekImpressionsKey(week_number_ - 1); | |
| 62 return storage_.ReadInt(key_impressions); | |
| 63 } | |
| 64 | |
| 65 float CTRAggregator::GetPreviousWeekCTR() { | |
| 66 if (!HasPreviousWeekData()) | |
| 67 return NAN; | |
| 68 | |
| 69 UpdateStorageToCurrentWeek(); | |
| 70 int clicks = GetPreviousWeekClicks(); | |
| 71 int impressions = GetPreviousWeekImpressions(); | |
| 72 if (impressions == 0) | |
| 73 return 0.0; | |
| 74 return (float)clicks / impressions; | |
| 75 } | |
| 76 | |
| 77 bool CTRAggregator::HasPrevious28DayData() { | |
| 78 EnsureFirstWeekRecorded(); | |
| 79 int first_week_written = storage_.ReadInt(kFirstWeekWrittenKey); | |
| 80 return (week_number_ - first_week_written >= 4); | |
|
Theresa
2016/08/26 23:32:08
use > kNumWeeksToRecord instead of 4?
Donn Denman
2016/08/29 22:58:06
Done: made a const kNumWeeksNeededFor28DayData = 4
Theresa
2016/08/29 23:57:34
Done.
Theresa
2016/08/29 23:57:57
Err.. Acknowledged.
| |
| 81 } | |
| 82 | |
| 83 float CTRAggregator::GetPrevious28DayCTR() { | |
| 84 if (!HasPrevious28DayData()) | |
| 85 return NAN; | |
| 86 | |
| 87 UpdateStorageToCurrentWeek(); | |
| 88 int clicks = GetPrevious28DayClicks(); | |
| 89 int impressions = GetPrevious28DayImpressions(); | |
| 90 if (impressions == 0) | |
| 91 return 0.0; | |
| 92 return (float)clicks / impressions; | |
| 93 } | |
| 94 | |
| 95 int CTRAggregator::GetPrevious28DayImpressions() { | |
| 96 UpdateStorageToCurrentWeek(); | |
| 97 int impressions = 0; | |
| 98 for (int week = 1; week <= 4; week++) { | |
|
Theresa
2016/08/26 23:32:08
week < kNumWeeksToRecord?
Donn Denman
2016/08/29 22:58:06
Done: seems better to use the new kNumWeeksNeededF
| |
| 99 std::string key_impressions = GetWeekImpressionsKey(week_number_ - week); | |
| 100 impressions += storage_.ReadInt(key_impressions); | |
| 101 } | |
| 102 return impressions; | |
| 103 } | |
| 104 | |
| 105 // private | |
| 106 | |
| 107 int CTRAggregator::GetStorageIndex(int which_week) { | |
|
Theresa
2016/08/26 23:32:08
Is this called anywhere other than GetWeekKey? If
Donn Denman
2016/08/29 22:58:05
Done.
| |
| 108 DCHECK(which_week > kReasonableMinWeek); | |
| 109 return which_week % kNumWeeksToRecord; | |
| 110 } | |
| 111 | |
| 112 std::string CTRAggregator::GetWeekKey(int which_week) { | |
| 113 return std::to_string(GetStorageIndex(which_week)); | |
| 114 } | |
| 115 | |
| 116 std::string CTRAggregator::GetWeekImpressionsKey(int which_week) { | |
| 117 return kImpressionsWeekKeyPrefix + GetWeekKey(which_week); | |
| 118 } | |
| 119 | |
| 120 std::string CTRAggregator::GetWeekClicksKey(int which_week) { | |
| 121 return kClicksWeekKeyPrefix + GetWeekKey(which_week); | |
| 122 } | |
| 123 | |
| 124 int CTRAggregator::GetPreviousWeekClicks() { | |
| 125 std::string key_clicks = GetWeekClicksKey(week_number_ - 1); | |
| 126 return storage_.ReadInt(key_clicks); | |
| 127 } | |
| 128 | |
| 129 int CTRAggregator::GetPrevious28DayClicks() { | |
| 130 int clicks = 0; | |
| 131 for (int week = 1; week <= 4; week++) { | |
| 132 std::string key_clicks = GetWeekClicksKey(week_number_ - week); | |
| 133 clicks += storage_.ReadInt(key_clicks); | |
| 134 } | |
| 135 return clicks; | |
| 136 } | |
| 137 | |
| 138 void CTRAggregator::Increment(std::string key) { | |
| 139 int cur_value = storage_.ReadInt(key); | |
| 140 cur_value++; | |
| 141 storage_.WriteInt(key, cur_value); | |
| 142 } | |
| 143 | |
| 144 void CTRAggregator::EnsureFirstWeekRecorded() { | |
| 145 int first_week_written = storage_.ReadInt(kFirstWeekWrittenKey); | |
| 146 if (first_week_written == 0) | |
| 147 storage_.WriteInt(kFirstWeekWrittenKey, week_number_); | |
| 148 } | |
| 149 | |
| 150 void CTRAggregator::UpdateStorageToCurrentWeek() { | |
| 151 // If still on the same week we're done! | |
| 152 int last_week_written = storage_.ReadInt(kLastWeekWrittenKey); | |
| 153 if (last_week_written == week_number_) | |
| 154 return; | |
| 155 | |
| 156 EnsureFirstWeekRecorded(); | |
| 157 storage_.WriteInt(kLastWeekWrittenKey, week_number_); | |
| 158 if (last_week_written == 0) | |
| 159 return; | |
| 160 | |
| 161 // Moved to a new week. Since we recycle storage we must clear the new week | |
| 162 // and all that we may have skipped since our last write. | |
| 163 int weeks_to_clear = | |
| 164 std::min(week_number_ - last_week_written, kNumWeeksToRecord); | |
| 165 int week = week_number_; | |
| 166 while (weeks_to_clear > 0) { | |
| 167 storage_.WriteInt(GetWeekImpressionsKey(week), 0); | |
| 168 storage_.WriteInt(GetWeekClicksKey(week), 0); | |
| 169 week--; | |
| 170 weeks_to_clear--; | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 // Storage | |
| 175 | |
| 176 typedef std::unordered_map<std::string, int> IntMap; | |
| 177 static base::LazyInstance<IntMap> s_storage_cache_ = LAZY_INSTANCE_INITIALIZER; | |
| 178 | |
| 179 int CTRAggregator::ReadInt(std::string storage_key) { | |
| 180 if (s_storage_cache_.Get().count(storage_key) != 0) | |
| 181 return s_storage_cache_.Get().at(storage_key); | |
| 182 | |
| 183 int value = storage_.ReadInt(storage_key); | |
| 184 s_storage_cache_.Get().emplace(storage_key, value); | |
| 185 return value; | |
| 186 } | |
| 187 | |
| 188 void CTRAggregator::WriteInt(std::string storage_key, int value) { | |
|
Theresa
2016/08/26 23:32:08
What's calling this?
Donn Denman
2016/08/29 22:58:06
Oops -- thanks for catching this!
I added cachin
| |
| 189 storage_.WriteInt(storage_key, value); | |
| 190 s_storage_cache_.Get().emplace(storage_key, value); | |
| 191 } | |
| 192 | |
| 193 // Testing only | |
| 194 | |
| 195 void CTRAggregator::IncrementWeek(int weeks) { | |
| 196 week_number_ += weeks; | |
| 197 } | |
| 198 | |
| 199 } // namespace contextual_search | |
| OLD | NEW |