| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/contextual_search/browser/ctr_aggregator.h" |
| |
| #include "base/numerics/safe_conversions.h" |
| #include "base/time/time.h" |
| |
| namespace { |
| |
| const double kSecondsPerWeek = |
| base::Time::kMicrosecondsPerWeek / base::Time::kMicrosecondsPerSecond; |
| // Used for validation in debug build. Week numbers are > 2300 as of year 2016. |
| const int kReasonableMinWeek = 2000; |
| |
| } // namespace |
| |
| namespace contextual_search { |
| |
| CtrAggregator::CtrAggregator(WeeklyActivityStorage& storage) |
| : storage_(storage) { |
| base::Time now = base::Time::NowFromSystemTime(); |
| double now_in_seconds = now.ToDoubleT(); |
| week_number_ = now_in_seconds / kSecondsPerWeek; |
| DCHECK(week_number_ >= kReasonableMinWeek); |
| // NOTE: This initialization may callback into the storage implementation so |
| // that needs to be fully initialized when constructing this aggregator. |
| storage_.AdvanceToWeek(week_number_); |
| } |
| |
| // Testing only |
| CtrAggregator::CtrAggregator(WeeklyActivityStorage& storage, int week_number) |
| : storage_(storage), week_number_(week_number) { |
| storage_.AdvanceToWeek(week_number_); |
| } |
| |
| CtrAggregator::~CtrAggregator() {} |
| |
| void CtrAggregator::RecordImpression(bool did_click) { |
| storage_.WriteImpressions(week_number_, |
| 1 + storage_.ReadImpressions(week_number_)); |
| if (did_click) |
| storage_.WriteClicks(week_number_, 1 + storage_.ReadClicks(week_number_)); |
| } |
| |
| int CtrAggregator::GetCurrentWeekNumber() { |
| return week_number_; |
| } |
| |
| bool CtrAggregator::HasPreviousWeekData() { |
| return storage_.HasData(week_number_ - 1); |
| } |
| |
| int CtrAggregator::GetPreviousWeekImpressions() { |
| return storage_.ReadImpressions(week_number_ - 1); |
| } |
| |
| float CtrAggregator::GetPreviousWeekCtr() { |
| if (!HasPreviousWeekData()) |
| return NAN; |
| |
| int clicks = GetPreviousWeekClicks(); |
| int impressions = GetPreviousWeekImpressions(); |
| if (impressions == 0) |
| return 0.0; |
| return base::saturated_cast<float>(clicks) / impressions; |
| } |
| |
| bool CtrAggregator::HasPrevious28DayData() { |
| for (int previous = 1; previous <= kNumWeeksNeededFor28DayData; previous++) { |
| if (!storage_.HasData(week_number_ - previous)) |
| return false; |
| } |
| return true; |
| } |
| |
| float CtrAggregator::GetPrevious28DayCtr() { |
| if (!HasPrevious28DayData()) |
| return NAN; |
| |
| int clicks = GetPrevious28DayClicks(); |
| int impressions = GetPrevious28DayImpressions(); |
| if (impressions == 0) |
| return 0.0; |
| return base::saturated_cast<float>(clicks) / impressions; |
| } |
| |
| int CtrAggregator::GetPrevious28DayImpressions() { |
| int impressions = 0; |
| for (int previous = 1; previous <= kNumWeeksNeededFor28DayData; previous++) { |
| impressions += storage_.ReadImpressions(week_number_ - previous); |
| } |
| return impressions; |
| } |
| |
| // private |
| |
| int CtrAggregator::GetPreviousWeekClicks() { |
| return storage_.ReadClicks(week_number_ - 1); |
| } |
| |
| int CtrAggregator::GetPrevious28DayClicks() { |
| int clicks = 0; |
| for (int previous = 1; previous <= kNumWeeksNeededFor28DayData; previous++) { |
| clicks += storage_.ReadClicks(week_number_ - previous); |
| } |
| return clicks; |
| } |
| |
| // Testing only |
| |
| void CtrAggregator::IncrementWeek(int weeks) { |
| week_number_ += weeks; |
| storage_.AdvanceToWeek(week_number_); |
| } |
| |
| } // namespace contextual_search |