Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Side by Side Diff: chrome/installer/util/experiment.cc

Issue 2889323004: Win 10 Inactive toast experiment metrics and storage modifications. (Closed)
Patch Set: Apply review comments Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 "chrome/installer/util/experiment.h"
6
7 #include <algorithm>
8 #include <cmath>
9
10 #include "base/logging.h"
11
12 namespace installer {
13
14 namespace {
15 // Returns closest integer of logarithm of |x| with base |b|.
grt (UTC plus 2) 2017/06/02 11:30:46 nit: blank line before comment
nikunjb 2017/06/02 22:49:48 Done.
16 double LogFloor(double x, double b) {
17 return std::round(std::log(x) / std::log(b));
18 }
19
20 // Returns the base to use for exponential buckets so that buckets
21 // 0,1,.. 2^|bits|-1 cover range [0, max_val]. If this function return b
22 // then Bucket value i will store values from [b^i, b^(i+1)]
23 double ExpBucketBase(int max_val, int bits) {
24 return std::exp(std::log(max_val + 1) / ((1 << bits) - 1));
25 }
26
27 // Invert bucket to the approximate value that the bucket may correspond to.
28 int BucketToValue(int bucket, double bucket_base) {
grt (UTC plus 2) 2017/06/02 11:30:45 unused
nikunjb 2017/06/02 22:49:48 Done.
29 return static_cast<int>(std::round(std::pow(bucket_base, bucket) - 1));
30 }
31
32 } // namespace
33
34 Experiment::Experiment() = default;
35 Experiment::Experiment(Experiment&&) = default;
36 Experiment::Experiment(const Experiment&) = default;
37 Experiment::~Experiment() = default;
38
39 void Experiment::InitializeFromMetrics(const ExperimentMetrics& metrics) {
40 *this = Experiment();
41 DCHECK_NE(ExperimentMetrics::kUninitialized, metrics.state);
42 DCHECK(metrics.InInitialState() ||
43 metrics.state == ExperimentMetrics::kGroupAssigned);
44 metrics_ = metrics;
45 state_ = metrics.state;
46 group_ = metrics.group;
47 }
48
49 void Experiment::SetState(ExperimentMetrics::State state) {
50 DCHECK_NE(ExperimentMetrics::kUninitialized, state);
51 state_ = state;
52 metrics_.state = state;
53 }
54
55 void Experiment::AssignGroup(int group) {
56 DCHECK_GE(group, 0);
57 DCHECK_LT(group, ExperimentMetrics::kNumGroups);
58 DCHECK(metrics_.InInitialState());
59
60 group_ = group;
61 metrics_.group = group;
62 SetState(ExperimentMetrics::kGroupAssigned);
63 }
64
65 void Experiment::SetToastLocation(ExperimentMetrics::ToastLocation location) {
66 DCHECK(!metrics_.InTerminalState());
67 DCHECK(!metrics_.InInitialState());
68 toast_location_ = location;
69 metrics_.toast_location = location;
70 }
71
72 void Experiment::SetInactiveDays(int days) {
73 DCHECK(!metrics_.InTerminalState());
74 DCHECK(!metrics_.InInitialState());
75 DCHECK_GE(days, 0);
76 inactive_days_ = days;
77 double log_base = ExpBucketBase(ExperimentMetrics::kMaxLastUsed,
78 ExperimentMetrics::kLastUsedBucketBits);
79 metrics_.last_used_bucket =
80 LogFloor(1 + std::min(days, ExperimentMetrics::kMaxLastUsed), log_base);
81 }
82
83 void Experiment::SetToastCount(int count) {
84 DCHECK(!metrics_.InTerminalState());
85 DCHECK(!metrics_.InInitialState());
86 toast_count_ = count;
87 metrics_.toast_count = std::min(count, ExperimentMetrics::kMaxToastCount);
88 }
89
90 void Experiment::SetDisplayTime(base::Time time) {
91 DCHECK(!metrics_.InTerminalState());
92 DCHECK(!metrics_.InInitialState());
93 if (metrics_.first_toast_offset == 0) {
94 // This is the first time toast is shown so add user to today's cohort.
95 first_display_time_ = time;
96 metrics_.first_toast_offset =
97 (time - base::Time::UnixEpoch() -
98 base::TimeDelta::FromSeconds(
99 ExperimentMetrics::kExperimentStartSeconds))
100 .InDays();
101 // If display time is outside the experiment range (possible due to
102 // invalid local time), then set it to be kMaxFirstToastOffset.
103 metrics_.first_toast_offset = std::min(
grt (UTC plus 2) 2017/06/02 11:30:45 nit: reverse these since the std::min isn't needed
nikunjb 2017/06/02 22:49:48 Done.
104 metrics_.first_toast_offset, ExperimentMetrics::kMaxFirstToastOffset);
105 if (metrics_.first_toast_offset < 0) {
106 metrics_.first_toast_offset = ExperimentMetrics::kMaxFirstToastOffset;
107 }
108 metrics_.toast_hour = (time - time.LocalMidnight()).InHours();
grt (UTC plus 2) 2017/06/02 11:30:46 do we want this only for the first toast rather th
nikunjb 2017/06/02 22:49:48 I was actually not sure, My reasoning for only doi
109 }
110 latest_display_time_ = time;
111 DCHECK_LE(metrics_.toast_hour, 24);
112 DCHECK_GE(metrics_.toast_hour, 0);
113 }
114
115 void Experiment::SetUserSessionUptime(base::TimeDelta time_delta) {
116 DCHECK(!metrics_.InTerminalState());
117 DCHECK(!metrics_.InInitialState());
118 user_session_uptime_ = time_delta;
119 double log_base = ExpBucketBase(ExperimentMetrics::kMaxSessionLength,
120 ExperimentMetrics::kSessionLengthBucketBits);
121 metrics_.session_length_bucket = LogFloor(
122 1 + std::min(time_delta, base::TimeDelta::FromMinutes(
123 ExperimentMetrics::kMaxSessionLength))
124 .InMinutes(),
125 log_base);
126 }
127
128 void Experiment::SetActionDelay(base::TimeDelta time_delta) {
129 DCHECK(!metrics_.InTerminalState());
130 DCHECK(!metrics_.InInitialState());
131 action_delay_ = time_delta;
132 double log_base = ExpBucketBase(ExperimentMetrics::kMaxActionDelay,
133 ExperimentMetrics::kActionDelayBucketBits);
134 metrics_.action_delay_bucket =
135 LogFloor(1 + std::min(time_delta, base::TimeDelta::FromSeconds(
136 ExperimentMetrics::kMaxActionDelay))
137 .InSeconds(),
138 log_base);
139 }
140
141 } // namespace installer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698