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

Side by Side Diff: net/base/network_quality_estimator.h

Issue 1144163008: Add in-memory caching of network quality estimates across network changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Not use scoped_ptr Created 5 years, 5 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
« no previous file with comments | « no previous file | net/base/network_quality_estimator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #ifndef NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_ 5 #ifndef NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_
6 #define NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_ 6 #define NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_
7 7
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <deque> 10 #include <deque>
11 #include <map> 11 #include <map>
12 #include <string>
12 13
13 #include "base/gtest_prod_util.h" 14 #include "base/gtest_prod_util.h"
14 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/scoped_ptr.h"
15 #include "base/threading/thread_checker.h" 17 #include "base/threading/thread_checker.h"
16 #include "base/time/time.h" 18 #include "base/time/time.h"
17 #include "net/base/net_export.h" 19 #include "net/base/net_export.h"
18 #include "net/base/network_change_notifier.h" 20 #include "net/base/network_change_notifier.h"
19 #include "net/base/network_quality.h" 21 #include "net/base/network_quality.h"
20 22
21 namespace net { 23 namespace net {
22 24
23 // NetworkQualityEstimator provides network quality estimates (quality of the 25 // NetworkQualityEstimator provides network quality estimates (quality of the
24 // full paths to all origins that have been connected to). 26 // full paths to all origins that have been connected to).
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 // Notifies NetworkQualityEstimator that a response has been received. 58 // Notifies NetworkQualityEstimator that a response has been received.
57 // |cumulative_prefilter_bytes_read| is the count of the bytes received prior 59 // |cumulative_prefilter_bytes_read| is the count of the bytes received prior
58 // to applying filters (e.g. decompression, SDCH) from request creation time 60 // to applying filters (e.g. decompression, SDCH) from request creation time
59 // until now. 61 // until now.
60 // |prefiltered_bytes_read| is the count of the bytes received prior 62 // |prefiltered_bytes_read| is the count of the bytes received prior
61 // to applying filters in the most recent read. 63 // to applying filters in the most recent read.
62 void NotifyDataReceived(const URLRequest& request, 64 void NotifyDataReceived(const URLRequest& request,
63 int64_t cumulative_prefilter_bytes_read, 65 int64_t cumulative_prefilter_bytes_read,
64 int64_t prefiltered_bytes_read); 66 int64_t prefiltered_bytes_read);
65 67
68 protected:
69 // NetworkID is used to uniquely identify a network.
70 // For the purpose of network quality estimation and caching, a network is
71 // uniquely identified by a combination of |type| and
72 // |id|. This approach is unable to distinguish networks with
73 // same name (e.g., different Wi-Fi networks with same SSID).
74 // This is a protected member to expose it to tests.
75 struct NET_EXPORT_PRIVATE NetworkID {
76 NetworkID(NetworkChangeNotifier::ConnectionType type, const std::string& id)
77 : type(type), id(id) {}
78 NetworkID(const NetworkID& other) : type(other.type), id(other.id) {}
79 ~NetworkID() {}
80
81 NetworkID& operator=(const NetworkID& other) {
82 type = other.type;
83 id = other.id;
84 return *this;
85 }
86
87 // Overloaded because NetworkID is used as key in a map.
88 bool operator<(const NetworkID& other) const {
89 return type < other.type || (type == other.type && id < other.id);
90 }
91
92 // Connection type of the network.
93 NetworkChangeNotifier::ConnectionType type;
94
95 // Name of this network. This is set to:
96 // - Wi-Fi SSID if the device is connected to a Wi-Fi access point and the
97 // SSID name is available, or
98 // - MCC/MNC code of the cellular carrier if the device is connected to a
99 // cellular network, or
100 // - "Ethernet" in case the device is connected to ethernet.
101 // - An empty string in all other cases or if the network name is not
102 // exposed by platform APIs.
103 std::string id;
104 };
105
106 // Construct a NetworkQualityEstimator instance allowing for test
107 // configuration. Registers for network type change notifications so estimates
108 // can be kept network specific.
109 // |variation_params| is the map containing all field trial parameters for the
110 // network quality estimator field trial.
111 // |allow_local_host_requests_for_tests| should only be true when testing
112 // against local HTTP server and allows the requests to local host to be
113 // used for network quality estimation.
114 // |allow_smaller_responses_for_tests| should only be true when testing.
115 // Allows the responses smaller than |kMinTransferSizeInBytes| or shorter than
116 // |kMinRequestDurationMicroseconds| to be used for network quality
117 // estimation.
118 NetworkQualityEstimator(
119 const std::map<std::string, std::string>& variation_params,
120 bool allow_local_host_requests_for_tests,
121 bool allow_smaller_responses_for_tests);
122
123 // Returns true if the cached network quality estimate was successfully read.
124 bool ReadCachedNetworkQualityEstimate();
125
126 // NetworkChangeNotifier::ConnectionTypeObserver implementation.
127 void OnConnectionTypeChanged(
128 NetworkChangeNotifier::ConnectionType type) override;
129
66 private: 130 private:
67 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, StoreObservations); 131 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, StoreObservations);
68 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestKbpsRTTUpdates); 132 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestKbpsRTTUpdates);
69 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestAddObservation); 133 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestAddObservation);
70 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ObtainOperatingParams); 134 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ObtainOperatingParams);
71 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, HalfLifeParam); 135 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, HalfLifeParam);
72 FRIEND_TEST_ALL_PREFIXES(URLRequestTestHTTP, NetworkQualityEstimator); 136 FRIEND_TEST_ALL_PREFIXES(URLRequestTestHTTP, NetworkQualityEstimator);
73 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, 137 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
74 PercentileSameTimestamps); 138 PercentileSameTimestamps);
75 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, 139 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
76 PercentileDifferentTimestamps); 140 PercentileDifferentTimestamps);
77 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ComputedPercentiles); 141 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ComputedPercentiles);
142 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestCaching);
143 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
144 TestLRUCacheMaximumSize);
145
146 // CachedNetworkQuality stores the quality of a previously seen network.
147 class NET_EXPORT_PRIVATE CachedNetworkQuality {
148 public:
149 explicit CachedNetworkQuality(const NetworkQuality& network_quality);
150 CachedNetworkQuality(const CachedNetworkQuality& other);
151 ~CachedNetworkQuality();
152
153 // Returns the network quality associated with this cached entry.
154 const NetworkQuality network_quality() const { return network_quality_; }
155
156 // Returns true if this cache entry was updated before
157 // |cached_network_quality|.
158 bool OlderThan(const CachedNetworkQuality& cached_network_quality) const;
159
160 // Time when this cache entry was last updated.
161 const base::TimeTicks last_update_time_;
162
163 // Quality of this cached network.
164 const NetworkQuality network_quality_;
165
166 private:
167 DISALLOW_ASSIGN(CachedNetworkQuality);
168 };
78 169
79 // Records the round trip time or throughput observation, along with the time 170 // Records the round trip time or throughput observation, along with the time
80 // the observation was made. 171 // the observation was made.
81 struct NET_EXPORT_PRIVATE Observation { 172 struct NET_EXPORT_PRIVATE Observation {
82 Observation(int32_t value, base::TimeTicks timestamp); 173 Observation(int32_t value, base::TimeTicks timestamp);
83
84 ~Observation(); 174 ~Observation();
85 175
86 // Value of the observation. 176 // Value of the observation.
87 const int32_t value; 177 const int32_t value;
88 178
89 // Time when the observation was taken. 179 // Time when the observation was taken.
90 const base::TimeTicks timestamp; 180 const base::TimeTicks timestamp;
91 }; 181 };
92 182
93 // Holds an observation and its weight. 183 // Holds an observation and its weight.
94 struct WeightedObservation { 184 struct NET_EXPORT_PRIVATE WeightedObservation {
95 WeightedObservation(int32_t value, double weight) 185 WeightedObservation(int32_t value, double weight)
96 : value(value), weight(weight) {} 186 : value(value), weight(weight) {}
97 WeightedObservation(const WeightedObservation& other) 187 WeightedObservation(const WeightedObservation& other)
98 : WeightedObservation(other.value, other.weight) {} 188 : WeightedObservation(other.value, other.weight) {}
99 189
100 WeightedObservation& operator=(const WeightedObservation& other) { 190 WeightedObservation& operator=(const WeightedObservation& other) {
101 value = other.value; 191 value = other.value;
102 weight = other.weight; 192 weight = other.weight;
103 return *this; 193 return *this;
104 } 194 }
105 195
106 // Required for sorting the samples in the ascending order of values. 196 // Required for sorting the samples in the ascending order of values.
107 bool operator<(const WeightedObservation& other) const { 197 bool operator<(const WeightedObservation& other) const {
108 return (value < other.value); 198 return (value < other.value);
109 } 199 }
110 200
111 // Value of the sample. 201 // Value of the sample.
112 int32_t value; 202 int32_t value;
113 203
114 // Weight of the sample. This is computed based on how much time has passed 204 // Weight of the sample. This is computed based on how much time has passed
115 // since the sample was taken. 205 // since the sample was taken.
116 double weight; 206 double weight;
117 }; 207 };
118 208
119 // Stores observations sorted by time. 209 // Stores observations sorted by time.
120 class NET_EXPORT_PRIVATE ObservationBuffer { 210 class NET_EXPORT_PRIVATE ObservationBuffer {
121 public: 211 public:
122 explicit ObservationBuffer(double weight_multiplier_per_second); 212 explicit ObservationBuffer(double weight_multiplier_per_second);
123
124 ~ObservationBuffer(); 213 ~ObservationBuffer();
125 214
126 // Adds |observation| to the buffer. The oldest observation in the buffer 215 // Adds |observation| to the buffer. The oldest observation in the buffer
127 // will be evicted to make room if the buffer is already full. 216 // will be evicted to make room if the buffer is already full.
128 void AddObservation(const Observation& observation); 217 void AddObservation(const Observation& observation);
129 218
130 // Returns the number of observations in this buffer. 219 // Returns the number of observations in this buffer.
131 size_t Size() const; 220 size_t Size() const;
132 221
133 // Clears the observations stored in this buffer. 222 // Clears the observations stored in this buffer.
(...skipping 23 matching lines...) Expand all
157 // The factor by which the weight of an observation reduces every second. 246 // The factor by which the weight of an observation reduces every second.
158 // For example, if an observation is 6 seconds old, its weight would be: 247 // For example, if an observation is 6 seconds old, its weight would be:
159 // weight_multiplier_per_second_ ^ 6 248 // weight_multiplier_per_second_ ^ 6
160 // Calculated from |kHalfLifeSeconds| by solving the following equation: 249 // Calculated from |kHalfLifeSeconds| by solving the following equation:
161 // weight_multiplier_per_second_ ^ kHalfLifeSeconds = 0.5 250 // weight_multiplier_per_second_ ^ kHalfLifeSeconds = 0.5
162 const double weight_multiplier_per_second_; 251 const double weight_multiplier_per_second_;
163 252
164 DISALLOW_COPY_AND_ASSIGN(ObservationBuffer); 253 DISALLOW_COPY_AND_ASSIGN(ObservationBuffer);
165 }; 254 };
166 255
256 // This does not use a unordered_map or hash_map for code simplicity (key just
257 // implements operator<, rather than hash and equality) and because the map is
258 // tiny.
259 typedef std::map<NetworkID, CachedNetworkQuality> CachedNetworkQualities;
260
167 // Tiny transfer sizes may give inaccurate throughput results. 261 // Tiny transfer sizes may give inaccurate throughput results.
168 // Minimum size of the transfer over which the throughput is computed. 262 // Minimum size of the transfer over which the throughput is computed.
169 static const int kMinTransferSizeInBytes = 10000; 263 static const int kMinTransferSizeInBytes = 10000;
170 264
171 // Minimum duration (in microseconds) of the transfer over which the 265 // Minimum duration (in microseconds) of the transfer over which the
172 // throughput is computed. 266 // throughput is computed.
173 static const int kMinRequestDurationMicroseconds = 1000; 267 static const int kMinRequestDurationMicroseconds = 1000;
174 268
175 // Minimum valid value of the variation parameter that holds RTT (in 269 // Minimum valid value of the variation parameter that holds RTT (in
176 // milliseconds) values. 270 // milliseconds) values.
177 static const int kMinimumRTTVariationParameterMsec = 1; 271 static const int kMinimumRTTVariationParameterMsec = 1;
178 272
179 // Minimum valid value of the variation parameter that holds throughput (in 273 // Minimum valid value of the variation parameter that holds throughput (in
180 // kbps) values. 274 // kbps) values.
181 static const int kMinimumThroughputVariationParameterKbps = 1; 275 static const int kMinimumThroughputVariationParameterKbps = 1;
182 276
183 // Construct a NetworkQualityEstimator instance allowing for test 277 // Maximum size of the cache that holds network quality estimates.
184 // configuration. Registers for network type change notifications so estimates 278 // Smaller size may reduce the cache hit rate due to frequent evictions.
185 // can be kept network specific. 279 // Larger size may affect performance.
186 // |variation_params| is the map containing all field trial parameters for the 280 static const size_t kMaximumNetworkQualityCacheSize = 10;
187 // network quality estimator field trial. 281
188 // |allow_local_host_requests_for_tests| should only be true when testing 282 // Maximum number of observations that can be held in the ObservationBuffer.
189 // against local HTTP server and allows the requests to local host to be 283 static const size_t kMaximumObservationsBufferSize = 300;
190 // used for network quality estimation.
191 // |allow_smaller_responses_for_tests| should only be true when testing
192 // against local HTTP server and allows the responses smaller than
193 // |kMinTransferSizeInBytes| or shorter than |kMinRequestDurationMicroseconds|
194 // to be used for network quality estimation.
195 NetworkQualityEstimator(
196 const std::map<std::string, std::string>& variation_params,
197 bool allow_local_host_requests_for_tests,
198 bool allow_smaller_responses_for_tests);
199 284
200 // Obtains operating parameters from the field trial parameters. 285 // Obtains operating parameters from the field trial parameters.
201 void ObtainOperatingParams( 286 void ObtainOperatingParams(
202 const std::map<std::string, std::string>& variation_params); 287 const std::map<std::string, std::string>& variation_params);
203 288
204 // Adds the default median RTT and downstream throughput estimate for the 289 // Adds the default median RTT and downstream throughput estimate for the
205 // current connection type to the observation buffer. 290 // current connection type to the observation buffer.
206 void AddDefaultEstimates(); 291 void AddDefaultEstimates();
207 292
208 // Returns the maximum size of the observation buffer.
209 // Used for testing.
210 size_t GetMaximumObservationBufferSizeForTests() const;
211
212 // Returns true if the size of all observation buffers is equal to the
213 // |expected_size|. Used for testing.
214 bool VerifyBufferSizeForTests(size_t expected_size) const;
215
216 // NetworkChangeNotifier::ConnectionTypeObserver implementation.
217 void OnConnectionTypeChanged(
218 NetworkChangeNotifier::ConnectionType type) override;
219
220 // Returns an estimate of network quality at the specified |percentile|. 293 // Returns an estimate of network quality at the specified |percentile|.
221 // |percentile| must be between 0 and 100 (both inclusive) with higher 294 // |percentile| must be between 0 and 100 (both inclusive) with higher
222 // percentiles indicating less performant networks. For example, if 295 // percentiles indicating less performant networks. For example, if
223 // |percentile| is 90, then the network is expected to be faster than the 296 // |percentile| is 90, then the network is expected to be faster than the
224 // returned estimate with 0.9 probability. Similarly, network is expected to 297 // returned estimate with 0.9 probability. Similarly, network is expected to
225 // be slower than the returned estimate with 0.1 probability. 298 // be slower than the returned estimate with 0.1 probability.
226 NetworkQuality GetEstimate(int percentile) const; 299 NetworkQuality GetEstimate(int percentile) const;
227 300
301 // Returns the current network ID checking by calling the platform APIs.
302 // Virtualized for testing.
303 virtual NetworkID GetCurrentNetworkID() const;
304
305 // Writes the estimated quality of the current network to the cache.
306 void CacheNetworkQualityEstimate();
307
228 // Records the UMA related to RTT. 308 // Records the UMA related to RTT.
229 void RecordRTTUMA(int32_t estimated_value_msec, 309 void RecordRTTUMA(int32_t estimated_value_msec,
230 int32_t actual_value_msec) const; 310 int32_t actual_value_msec) const;
231 311
232 // Determines if the requests to local host can be used in estimating the 312 // Determines if the requests to local host can be used in estimating the
233 // network quality. Set to true only for tests. 313 // network quality. Set to true only for tests.
234 const bool allow_localhost_requests_; 314 const bool allow_localhost_requests_;
235 315
236 // Determines if the responses smaller than |kMinTransferSizeInBytes| 316 // Determines if the responses smaller than |kMinTransferSizeInBytes|
237 // or shorter than |kMinTransferSizeInBytes| can be used in estimating the 317 // or shorter than |kMinTransferSizeInBytes| can be used in estimating the
238 // network quality. Set to true only for tests. 318 // network quality. Set to true only for tests.
239 const bool allow_small_responses_; 319 const bool allow_small_responses_;
240 320
241 // Time when last connection change was observed. 321 // Time when last connection change was observed.
242 base::TimeTicks last_connection_change_; 322 base::TimeTicks last_connection_change_;
243 323
244 // Last value passed to |OnConnectionTypeChanged|. This indicates the 324 // ID of the current network.
245 // current connection type. 325 NetworkID current_network_id_;
246 NetworkChangeNotifier::ConnectionType current_connection_type_;
247 326
248 // Fastest round-trip-time (RTT) since last connectivity change. RTT measured 327 // Peak network quality (fastest round-trip-time (RTT) and highest
249 // from URLRequest creation until first byte received. 328 // downstream throughput) measured since last connectivity change. RTT is
250 base::TimeDelta fastest_rtt_since_last_connection_change_; 329 // measured from time the request is sent until the first byte received.
330 // The accuracy is decreased by ignoring these factors:
331 // 1) Multiple URLRequests can occur concurrently.
332 // 2) Includes server processing time.
333 NetworkQuality peak_network_quality_;
251 334
252 // Rough measurement of downstream peak Kbps witnessed since last connectivity 335 // Cache that stores quality of previously seen networks.
253 // change. The accuracy is decreased by ignoring these factors: 336 CachedNetworkQualities cached_network_qualities_;
254 // 1) Multiple URLRequests can occur concurrently.
255 // 2) The transfer time includes at least one RTT while no bytes are read.
256 int32_t peak_kbps_since_last_connection_change_;
257 337
258 // Buffer that holds Kbps observations sorted by timestamp. 338 // Buffer that holds Kbps observations sorted by timestamp.
259 ObservationBuffer kbps_observations_; 339 ObservationBuffer kbps_observations_;
260 340
261 // Buffer that holds RTT (in milliseconds) observations sorted by timestamp. 341 // Buffer that holds RTT (in milliseconds) observations sorted by timestamp.
262 ObservationBuffer rtt_msec_observations_; 342 ObservationBuffer rtt_msec_observations_;
263 343
264 // Default network quality observations obtained from the network quality 344 // Default network quality observations obtained from the network quality
265 // estimator field trial parameters. The observations are indexed by 345 // estimator field trial parameters. The observations are indexed by
266 // ConnectionType. 346 // ConnectionType.
267 NetworkQuality 347 NetworkQuality
268 default_observations_[NetworkChangeNotifier::CONNECTION_LAST + 1]; 348 default_observations_[NetworkChangeNotifier::CONNECTION_LAST + 1];
269 349
270 // Estimated network quality. Updated on mainframe requests. 350 // Estimated network quality. Updated on mainframe requests.
271 NetworkQuality estimated_median_network_quality_; 351 NetworkQuality estimated_median_network_quality_;
272 352
273 base::ThreadChecker thread_checker_; 353 base::ThreadChecker thread_checker_;
274 354
275 DISALLOW_COPY_AND_ASSIGN(NetworkQualityEstimator); 355 DISALLOW_COPY_AND_ASSIGN(NetworkQualityEstimator);
276 }; 356 };
277 357
278 } // namespace net 358 } // namespace net
279 359
280 #endif // NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_ 360 #endif // NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_
OLDNEW
« no previous file with comments | « no previous file | net/base/network_quality_estimator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698