This source file includes following definitions.
- unacked_data_
- GetEstimate
- OnPacketSent
- OnAcknowledgedPacket
- OnRetransmissionTimeout
- GetAvailableCongestionWindow
- OnIncomingFeedback
#include "net/quic/congestion_control/inter_arrival_probe.h"
#include <algorithm>
#include "base/basictypes.h"
#include "base/logging.h"
using std::max;
namespace net {
namespace {
const int kProbeSizePackets = 10;
const QuicByteCount kMinPacketSize = 500;
const int64 kDefaultBytesPerSecond = 40000;
const float kUncertainScaleFactor = 0.5;
}
InterArrivalProbe::InterArrivalProbe(QuicByteCount max_segment_size)
: max_segment_size_(max_segment_size),
estimate_available_(false),
available_channel_estimate_(QuicBandwidth::Zero()),
unacked_data_(0) {
}
InterArrivalProbe::~InterArrivalProbe() {
}
bool InterArrivalProbe::GetEstimate(QuicBandwidth* available_channel_estimate) {
if (!estimate_available_) {
return false;
}
*available_channel_estimate = available_channel_estimate_;
return true;
}
void InterArrivalProbe::OnPacketSent(QuicByteCount bytes) {
if (!estimate_available_) {
unacked_data_ += bytes;
}
}
void InterArrivalProbe::OnAcknowledgedPacket(QuicByteCount bytes) {
if (!estimate_available_) {
DCHECK_LE(bytes, unacked_data_);
unacked_data_ -= bytes;
}
}
void InterArrivalProbe::OnRetransmissionTimeout() {
if (!estimate_available_) {
unacked_data_ = 0;
}
}
QuicByteCount InterArrivalProbe::GetAvailableCongestionWindow() {
if (estimate_available_) {
return 0;
}
return (kProbeSizePackets * max_segment_size_) - unacked_data_;
}
void InterArrivalProbe::OnIncomingFeedback(
QuicPacketSequenceNumber sequence_number,
QuicByteCount bytes_sent,
QuicTime time_sent,
QuicTime time_received) {
if (estimate_available_) {
return;
}
if (available_channel_estimator_.get() == NULL) {
if (bytes_sent < kMinPacketSize) {
return;
}
first_sequence_number_ = sequence_number;
available_channel_estimator_.reset(new AvailableChannelEstimator(
sequence_number, time_sent, time_received));
return;
}
available_channel_estimator_->OnIncomingFeedback(sequence_number,
bytes_sent,
time_sent,
time_received);
if (sequence_number < kProbeSizePackets - 1 + first_sequence_number_) {
return;
}
QuicBandwidth available_channel_estimate = QuicBandwidth::Zero();
AvailableChannelEstimateState available_channel_estimate_state =
available_channel_estimator_->GetAvailableChannelEstimate(
&available_channel_estimate);
switch (available_channel_estimate_state) {
case kAvailableChannelEstimateUnknown:
available_channel_estimate_ =
QuicBandwidth::FromBytesPerSecond(kDefaultBytesPerSecond);
break;
case kAvailableChannelEstimateUncertain:
available_channel_estimate_ =
available_channel_estimate.Scale(kUncertainScaleFactor);
break;
case kAvailableChannelEstimateGood:
available_channel_estimate_ = available_channel_estimate;
break;
case kAvailableChannelEstimateSenderLimited:
available_channel_estimate_ =
max(available_channel_estimate,
QuicBandwidth::FromBytesPerSecond(kDefaultBytesPerSecond));
break;
}
estimate_available_ = true;
available_channel_estimator_.reset(NULL);
DVLOG(1) << "Probe estimate:"
<< available_channel_estimate_.ToKBitsPerSecond()
<< " Kbits/s";
}
}