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

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

Issue 1164713004: Store network quality samples so we can compute percentiles. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed mmenke comments Created 5 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
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 #include "net/base/network_quality_estimator.h" 5 #include "net/base/network_quality_estimator.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "net/base/net_util.h" 11 #include "net/base/net_util.h"
12 #include "net/base/network_quality.h" 12 #include "net/base/network_quality.h"
13 #include "net/url_request/url_request.h" 13 #include "net/url_request/url_request.h"
14 #include "url/gurl.h" 14 #include "url/gurl.h"
15 15
16 namespace net { 16 namespace net {
17 17
18 // Maximum number of samples to hold in the SampleRingBuffer.
19 const size_t NetworkQualityEstimator::SampleRingBuffer::kMaximumSamples = 500;
20
18 NetworkQualityEstimator::NetworkQualityEstimator() 21 NetworkQualityEstimator::NetworkQualityEstimator()
19 : NetworkQualityEstimator(false) { 22 : NetworkQualityEstimator(false) {
20 } 23 }
21 24
22 NetworkQualityEstimator::NetworkQualityEstimator( 25 NetworkQualityEstimator::NetworkQualityEstimator(
23 bool allow_local_host_requests_for_tests) 26 bool allow_local_host_requests_for_tests)
24 : allow_localhost_requests_(allow_local_host_requests_for_tests), 27 : allow_localhost_requests_(allow_local_host_requests_for_tests),
25 last_connection_change_(base::TimeTicks::Now()), 28 last_connection_change_(base::TimeTicks::Now()),
26 current_connection_type_(NetworkChangeNotifier::GetConnectionType()), 29 current_connection_type_(NetworkChangeNotifier::GetConnectionType()),
27 bytes_read_since_last_connection_change_(false), 30 bytes_read_since_last_connection_change_(false),
28 peak_kbps_since_last_connection_change_(0) { 31 peak_kbps_since_last_connection_change_(0) {
29 static_assert(kMinRequestDurationMicroseconds > 0, 32 static_assert(kMinRequestDurationMicroseconds > 0,
30 "Minimum request duration must be > 0"); 33 "Minimum request duration must be > 0");
31 NetworkChangeNotifier::AddConnectionTypeObserver(this); 34 NetworkChangeNotifier::AddConnectionTypeObserver(this);
32 } 35 }
33 36
34 NetworkQualityEstimator::~NetworkQualityEstimator() { 37 NetworkQualityEstimator::~NetworkQualityEstimator() {
35 DCHECK(thread_checker_.CalledOnValidThread()); 38 DCHECK(thread_checker_.CalledOnValidThread());
36 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 39 NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
37 } 40 }
38 41
39 void NetworkQualityEstimator::NotifyDataReceived(const URLRequest& request, 42 void NetworkQualityEstimator::NotifyDataReceived(
40 int64_t prefilter_bytes_read) { 43 const URLRequest& request,
44 int64_t cummulative_prefilter_bytes_read,
45 int64_t prefiltered_bytes_read) {
41 DCHECK(thread_checker_.CalledOnValidThread()); 46 DCHECK(thread_checker_.CalledOnValidThread());
42 DCHECK_GT(prefilter_bytes_read, 0); 47 DCHECK_GT(cummulative_prefilter_bytes_read, 0);
48 DCHECK_GT(prefiltered_bytes_read, 0);
43 49
44 if (!request.url().is_valid() || 50 if (!request.url().is_valid() ||
45 (!allow_localhost_requests_ && IsLocalhost(request.url().host())) || 51 (!allow_localhost_requests_ && IsLocalhost(request.url().host())) ||
46 !request.url().SchemeIsHTTPOrHTTPS() || 52 !request.url().SchemeIsHTTPOrHTTPS() ||
47 // Verify that response headers are received, so it can be ensured that 53 // Verify that response headers are received, so it can be ensured that
48 // response is not cached. 54 // response is not cached.
49 request.response_info().response_time.is_null() || request.was_cached() || 55 request.response_info().response_time.is_null() || request.was_cached() ||
50 request.creation_time() < last_connection_change_) { 56 request.creation_time() < last_connection_change_) {
51 return; 57 return;
52 } 58 }
53 59
54 base::TimeTicks now = base::TimeTicks::Now(); 60 base::TimeTicks now = base::TimeTicks::Now();
55 base::TimeDelta request_duration = now - request.creation_time(); 61 base::TimeDelta request_duration = now - request.creation_time();
56 DCHECK_GE(request_duration, base::TimeDelta()); 62 DCHECK_GE(request_duration, base::TimeDelta());
57 if (!bytes_read_since_last_connection_change_) 63 if (!bytes_read_since_last_connection_change_)
58 fastest_RTT_since_last_connection_change_ = request_duration; 64 fastest_RTT_since_last_connection_change_ = request_duration;
59 65
60 bytes_read_since_last_connection_change_ = true; 66 bytes_read_since_last_connection_change_ = true;
61 if (request_duration < fastest_RTT_since_last_connection_change_) 67 if (request_duration < fastest_RTT_since_last_connection_change_)
62 fastest_RTT_since_last_connection_change_ = request_duration; 68 fastest_RTT_since_last_connection_change_ = request_duration;
63 69
70 // Only add RTT sample if this is the first read for this response.
71 if (cummulative_prefilter_bytes_read == prefiltered_bytes_read)
72 rtt_msec_samples_.AddSample(request_duration.InMilliseconds());
73
64 // Ignore tiny transfers which will not produce accurate rates. 74 // Ignore tiny transfers which will not produce accurate rates.
65 // Ignore short duration transfers. 75 // Ignore short duration transfers.
66 if (prefilter_bytes_read >= kMinTransferSizeInBytes && 76 if (cummulative_prefilter_bytes_read >= kMinTransferSizeInBytes &&
67 request_duration >= 77 request_duration >=
68 base::TimeDelta::FromMicroseconds(kMinRequestDurationMicroseconds)) { 78 base::TimeDelta::FromMicroseconds(kMinRequestDurationMicroseconds)) {
69 uint64_t kbps = static_cast<uint64_t>(prefilter_bytes_read * 8 * 1000 / 79 uint64_t kbps =
70 request_duration.InMicroseconds()); 80 static_cast<uint64_t>(cummulative_prefilter_bytes_read * 8 * 1000 /
81 request_duration.InMicroseconds());
71 if (kbps > peak_kbps_since_last_connection_change_) 82 if (kbps > peak_kbps_since_last_connection_change_)
72 peak_kbps_since_last_connection_change_ = kbps; 83 peak_kbps_since_last_connection_change_ = kbps;
84
85 kbps_samples_.AddSample(kbps);
73 } 86 }
74 } 87 }
75 88
76 void NetworkQualityEstimator::OnConnectionTypeChanged( 89 void NetworkQualityEstimator::OnConnectionTypeChanged(
77 NetworkChangeNotifier::ConnectionType type) { 90 NetworkChangeNotifier::ConnectionType type) {
78 DCHECK(thread_checker_.CalledOnValidThread()); 91 DCHECK(thread_checker_.CalledOnValidThread());
79 if (bytes_read_since_last_connection_change_) { 92 if (bytes_read_since_last_connection_change_) {
80 switch (current_connection_type_) { 93 switch (current_connection_type_) {
81 case NetworkChangeNotifier::CONNECTION_UNKNOWN: 94 case NetworkChangeNotifier::CONNECTION_UNKNOWN:
82 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", 95 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown",
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 break; 168 break;
156 } 169 }
157 } 170 }
158 171
159 last_connection_change_ = base::TimeTicks::Now(); 172 last_connection_change_ = base::TimeTicks::Now();
160 bytes_read_since_last_connection_change_ = false; 173 bytes_read_since_last_connection_change_ = false;
161 peak_kbps_since_last_connection_change_ = 0; 174 peak_kbps_since_last_connection_change_ = 0;
162 current_connection_type_ = type; 175 current_connection_type_ = type;
163 } 176 }
164 177
165 NetworkQuality NetworkQualityEstimator::GetEstimate() const { 178 NetworkQuality NetworkQualityEstimator::GetPeakEstimate() const {
166 DCHECK(thread_checker_.CalledOnValidThread()); 179 DCHECK(thread_checker_.CalledOnValidThread());
167 180
168 if (!bytes_read_since_last_connection_change_) { 181 if (!bytes_read_since_last_connection_change_) {
169 return NetworkQuality(fastest_RTT_since_last_connection_change_, 0, 182 return NetworkQuality(base::TimeDelta(), 0.0, 0, 0.0);
170 peak_kbps_since_last_connection_change_, 0);
171 } 183 }
172 if (!peak_kbps_since_last_connection_change_) { 184 if (!peak_kbps_since_last_connection_change_) {
173 return NetworkQuality(fastest_RTT_since_last_connection_change_, 0.1, 185 return NetworkQuality(fastest_RTT_since_last_connection_change_, 0.0, 0,
174 peak_kbps_since_last_connection_change_, 0); 186 0.0);
175 } 187 }
176 return NetworkQuality(fastest_RTT_since_last_connection_change_, 0.1, 188 return NetworkQuality(fastest_RTT_since_last_connection_change_, 0.0,
177 peak_kbps_since_last_connection_change_, 0.1); 189 peak_kbps_since_last_connection_change_, 0.0);
190 }
191
192 NetworkQualityEstimator::Sample::Sample(int value, base::TimeTicks timestamp)
193 : value(value), timestamp(timestamp) {
194 DCHECK_GE(value, 0);
195 }
196
197 NetworkQualityEstimator::Sample::~Sample() {
198 }
199
200 NetworkQualityEstimator::SampleRingBuffer::SampleRingBuffer() {
201 static_assert(kMaximumSamples > 0U,
202 "Minimum size of sample buffer must be > 0");
203 }
204
205 NetworkQualityEstimator::SampleRingBuffer::~SampleRingBuffer() {
206 }
207
208 void NetworkQualityEstimator::SampleRingBuffer::AddSample(int value) {
209 DCHECK_LE(samples_.size(), kMaximumSamples);
210 // Pop the oldest element if the buffer is already full.
211 if (samples_.size() == kMaximumSamples)
212 samples_.pop_front();
213
214 samples_.push_back(Sample(value, base::TimeTicks::Now()));
215 DCHECK_LE(samples_.size(), kMaximumSamples);
178 } 216 }
179 217
180 } // namespace net 218 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698