Index: net/base/network_quality_estimator.cc |
diff --git a/net/base/network_quality_estimator.cc b/net/base/network_quality_estimator.cc |
index 6415ee6e6d7eb36b47ab4fd568d3537283b27729..01e6c90b60e784a786d603151dbd9aa39a662d14 100644 |
--- a/net/base/network_quality_estimator.cc |
+++ b/net/base/network_quality_estimator.cc |
@@ -15,6 +15,9 @@ |
namespace net { |
+const size_t NetworkQualityEstimator::ObservationBuffer::kMaximumObservations = |
+ 500; |
+ |
NetworkQualityEstimator::NetworkQualityEstimator() |
: NetworkQualityEstimator(false) { |
} |
@@ -24,7 +27,7 @@ NetworkQualityEstimator::NetworkQualityEstimator( |
: allow_localhost_requests_(allow_local_host_requests_for_tests), |
last_connection_change_(base::TimeTicks::Now()), |
current_connection_type_(NetworkChangeNotifier::GetConnectionType()), |
- bytes_read_since_last_connection_change_(false), |
+ fastest_rtt_since_last_connection_change_(base::TimeDelta::Max()), |
peak_kbps_since_last_connection_change_(0) { |
static_assert(kMinRequestDurationMicroseconds > 0, |
"Minimum request duration must be > 0"); |
@@ -36,10 +39,13 @@ NetworkQualityEstimator::~NetworkQualityEstimator() { |
NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
} |
-void NetworkQualityEstimator::NotifyDataReceived(const URLRequest& request, |
- int64_t prefilter_bytes_read) { |
+void NetworkQualityEstimator::NotifyDataReceived( |
+ const URLRequest& request, |
+ int64_t cumulative_prefilter_bytes_read, |
+ int64_t prefiltered_bytes_read) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK_GT(prefilter_bytes_read, 0); |
+ DCHECK_GT(cumulative_prefilter_bytes_read, 0); |
+ DCHECK_GT(prefiltered_bytes_read, 0); |
if (!request.url().is_valid() || |
(!allow_localhost_requests_ && IsLocalhost(request.url().host())) || |
@@ -54,61 +60,77 @@ void NetworkQualityEstimator::NotifyDataReceived(const URLRequest& request, |
base::TimeTicks now = base::TimeTicks::Now(); |
base::TimeDelta request_duration = now - request.creation_time(); |
DCHECK_GE(request_duration, base::TimeDelta()); |
- if (!bytes_read_since_last_connection_change_) |
- fastest_RTT_since_last_connection_change_ = request_duration; |
- bytes_read_since_last_connection_change_ = true; |
- if (request_duration < fastest_RTT_since_last_connection_change_) |
- fastest_RTT_since_last_connection_change_ = request_duration; |
+ // Only add RTT observation if this is the first read for this response. |
+ if (cumulative_prefilter_bytes_read == prefiltered_bytes_read) { |
+ if (request_duration < fastest_rtt_since_last_connection_change_) |
+ fastest_rtt_since_last_connection_change_ = request_duration; |
+ |
+ rtt_msec_observations_.AddObservation( |
+ Observation(request_duration.InMilliseconds(), now)); |
+ } |
// Ignore tiny transfers which will not produce accurate rates. |
// Ignore short duration transfers. |
- if (prefilter_bytes_read >= kMinTransferSizeInBytes && |
+ if (cumulative_prefilter_bytes_read >= kMinTransferSizeInBytes && |
request_duration >= |
base::TimeDelta::FromMicroseconds(kMinRequestDurationMicroseconds)) { |
- uint64_t kbps = static_cast<uint64_t>(prefilter_bytes_read * 8 * 1000 / |
- request_duration.InMicroseconds()); |
- if (kbps > peak_kbps_since_last_connection_change_) |
- peak_kbps_since_last_connection_change_ = kbps; |
+ double kbpsF = (cumulative_prefilter_bytes_read * 8.0) / |
mmenke
2015/06/12 20:31:41
nit: kbps_f
tbansal1
2015/06/12 21:27:53
Done.
|
+ (1000.0 * request_duration.InSecondsF()); |
mmenke
2015/06/12 20:31:42
nit: I Think .... / 1000.0 / request_duration.InS
tbansal1
2015/06/12 21:27:53
Done.
|
+ DCHECK_GE(kbpsF, 0.0); |
+ |
+ // Check overflow errors. This may happen if the kbpsF is more than |
+ // 2 * 10^9 (= 2000 Gbps). |
+ if (kbpsF >= INT32_MAX) |
mmenke
2015/06/12 20:31:41
I think "std::numeric_limits<int32_t>::max()" is p
tbansal1
2015/06/12 21:27:53
Done.
|
+ kbpsF = INT32_MAX - 1; |
+ |
+ int32_t kbps = static_cast<int32_t>(kbpsF); |
+ |
+ if (kbps > 0) { |
+ if (kbps > peak_kbps_since_last_connection_change_) |
+ peak_kbps_since_last_connection_change_ = kbps; |
+ |
+ kbps_observations_.AddObservation(Observation(kbps, now)); |
+ } |
} |
} |
void NetworkQualityEstimator::OnConnectionTypeChanged( |
NetworkChangeNotifier::ConnectionType type) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- if (bytes_read_since_last_connection_change_) { |
+ if (fastest_rtt_since_last_connection_change_ != base::TimeDelta::Max()) { |
switch (current_connection_type_) { |
case NetworkChangeNotifier::CONNECTION_UNKNOWN: |
UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", |
- fastest_RTT_since_last_connection_change_); |
+ fastest_rtt_since_last_connection_change_); |
break; |
case NetworkChangeNotifier::CONNECTION_ETHERNET: |
UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Ethernet", |
- fastest_RTT_since_last_connection_change_); |
+ fastest_rtt_since_last_connection_change_); |
break; |
case NetworkChangeNotifier::CONNECTION_WIFI: |
UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Wifi", |
- fastest_RTT_since_last_connection_change_); |
+ fastest_rtt_since_last_connection_change_); |
break; |
case NetworkChangeNotifier::CONNECTION_2G: |
UMA_HISTOGRAM_TIMES("NQE.FastestRTT.2G", |
- fastest_RTT_since_last_connection_change_); |
+ fastest_rtt_since_last_connection_change_); |
break; |
case NetworkChangeNotifier::CONNECTION_3G: |
UMA_HISTOGRAM_TIMES("NQE.FastestRTT.3G", |
- fastest_RTT_since_last_connection_change_); |
+ fastest_rtt_since_last_connection_change_); |
break; |
case NetworkChangeNotifier::CONNECTION_4G: |
UMA_HISTOGRAM_TIMES("NQE.FastestRTT.4G", |
- fastest_RTT_since_last_connection_change_); |
+ fastest_rtt_since_last_connection_change_); |
break; |
case NetworkChangeNotifier::CONNECTION_NONE: |
UMA_HISTOGRAM_TIMES("NQE.FastestRTT.None", |
- fastest_RTT_since_last_connection_change_); |
+ fastest_rtt_since_last_connection_change_); |
break; |
case NetworkChangeNotifier::CONNECTION_BLUETOOTH: |
UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Bluetooth", |
- fastest_RTT_since_last_connection_change_); |
+ fastest_rtt_since_last_connection_change_); |
break; |
default: |
NOTREACHED(); |
@@ -157,24 +179,56 @@ void NetworkQualityEstimator::OnConnectionTypeChanged( |
} |
last_connection_change_ = base::TimeTicks::Now(); |
- bytes_read_since_last_connection_change_ = false; |
peak_kbps_since_last_connection_change_ = 0; |
+ fastest_rtt_since_last_connection_change_ = base::TimeDelta::Max(); |
+ kbps_observations_.Clear(); |
+ rtt_msec_observations_.Clear(); |
current_connection_type_ = type; |
} |
-NetworkQuality NetworkQualityEstimator::GetEstimate() const { |
+NetworkQuality NetworkQualityEstimator::GetPeakEstimate() const { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- if (!bytes_read_since_last_connection_change_) { |
- return NetworkQuality(fastest_RTT_since_last_connection_change_, 0, |
- peak_kbps_since_last_connection_change_, 0); |
- } |
- if (!peak_kbps_since_last_connection_change_) { |
- return NetworkQuality(fastest_RTT_since_last_connection_change_, 0.1, |
- peak_kbps_since_last_connection_change_, 0); |
- } |
- return NetworkQuality(fastest_RTT_since_last_connection_change_, 0.1, |
- peak_kbps_since_last_connection_change_, 0.1); |
+ return NetworkQuality(fastest_rtt_since_last_connection_change_, |
+ peak_kbps_since_last_connection_change_); |
+} |
+ |
+NetworkQualityEstimator::Observation::Observation(int32_t value, |
+ base::TimeTicks timestamp) |
+ : value(value), timestamp(timestamp) { |
+ DCHECK_GE(value, 0); |
+ DCHECK(!timestamp.is_null()); |
+} |
+ |
+NetworkQualityEstimator::Observation::~Observation() { |
+} |
+ |
+NetworkQualityEstimator::ObservationBuffer::ObservationBuffer() { |
+ static_assert(kMaximumObservations > 0U, |
+ "Minimum size of observation buffer must be > 0"); |
+} |
+ |
+NetworkQualityEstimator::ObservationBuffer::~ObservationBuffer() { |
+} |
+ |
+void NetworkQualityEstimator::ObservationBuffer::AddObservation( |
+ const Observation& observation) { |
+ DCHECK_LE(observations_.size(), kMaximumObservations); |
+ // Evict the oldest element if the buffer is already full. |
+ if (observations_.size() == kMaximumObservations) |
+ observations_.pop_front(); |
+ |
+ observations_.push_back(observation); |
+ DCHECK_LE(observations_.size(), kMaximumObservations); |
+} |
+ |
+size_t NetworkQualityEstimator::ObservationBuffer::Size() const { |
+ return observations_.size(); |
+} |
+ |
+void NetworkQualityEstimator::ObservationBuffer::Clear() { |
+ observations_.clear(); |
+ DCHECK(observations_.empty()); |
} |
} // namespace net |