const uint64 kCubeFactor = (GG_UINT64_C(1) << kCubeScale) /
kCubeCongestionWindowScale;
-const uint32 kNumConnections = 2;
+const uint32 kDefaultNumConnections = 2;
const float kBeta = 0.7f; // Default Cubic backoff factor.
// Additional backoff factor when loss occurs in the concave part of the Cubic
// curve. This additional backoff factor is expected to give up bandwidth to
// new concurrent flows and speed up convergence.
const float kBetaLastMax = 0.85f;
-// kNConnectionBeta is the backoff factor after loss for our N-connection
-// emulation, which emulates the effective backoff of an ensemble of N TCP-Reno
-// connections on a single loss event. The effective multiplier is computed as:
-const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
-
-// TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that
-// kBeta here is a cwnd multiplier, and is equal to 1-beta from the CUBIC paper.
-// We derive the equivalent kNConnectionAlpha for an N-connection emulation as:
-const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
- (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
-// TODO(jri): Compute kNConnectionBeta and kNConnectionAlpha from
-// number of active streams.
-
} // namespace
Cubic::Cubic(const QuicClock* clock, QuicConnectionStats* stats)
: clock_(clock),
+ num_connections_(kDefaultNumConnections),
epoch_(QuicTime::Zero()),
last_update_time_(QuicTime::Zero()),
stats_(stats) {
Reset();
}
+void Cubic::SetNumConnections(int num_connections) {
+ num_connections_ = num_connections;
+}
+
+float Cubic::Alpha() const {
+ // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that
+ // beta here is a cwnd multiplier, and is equal to 1-beta from the paper.
+ // We derive the equivalent alpha for an N-connection emulation as:
+ const float beta = Beta();
+ return 3 * num_connections_ * num_connections_ * (1 - beta) / (1 + beta);
+}
+
+float Cubic::Beta() const {
+ // kNConnectionBeta is the backoff factor after loss for our N-connection
+ // emulation, which emulates the effective backoff of an ensemble of N
+ // TCP-Reno connections on a single loss event. The effective multiplier is
+ // computed as:
+ return (num_connections_ - 1 + kBeta) / num_connections_;
+}
+
void Cubic::Reset() {
epoch_ = QuicTime::Zero(); // Reset time.
last_update_time_ = QuicTime::Zero(); // Reset time.
last_target_congestion_window_ = 0;
}
-void Cubic::UpdateCongestionControlStats(
- QuicTcpCongestionWindow new_cubic_mode_cwnd,
- QuicTcpCongestionWindow new_reno_mode_cwnd) {
+void Cubic::UpdateCongestionControlStats(QuicPacketCount new_cubic_mode_cwnd,
+ QuicPacketCount new_reno_mode_cwnd) {
- QuicTcpCongestionWindow highest_new_cwnd = std::max(new_cubic_mode_cwnd,
- new_reno_mode_cwnd);
+ QuicPacketCount highest_new_cwnd = max(new_cubic_mode_cwnd,
+ new_reno_mode_cwnd);
if (last_congestion_window_ < highest_new_cwnd) {
// cwnd will increase to highest_new_cwnd.
stats_->cwnd_increase_congestion_avoidance +=
}
}
-QuicTcpCongestionWindow Cubic::CongestionWindowAfterPacketLoss(
- QuicTcpCongestionWindow current_congestion_window) {
+QuicPacketCount Cubic::CongestionWindowAfterPacketLoss(
+ QuicPacketCount current_congestion_window) {
if (current_congestion_window < last_max_congestion_window_) {
// We never reached the old max, so assume we are competing with another
// flow. Use our extra back off factor to allow the other flow to go up.
last_max_congestion_window_ = current_congestion_window;
}
epoch_ = QuicTime::Zero(); // Reset time.
- return static_cast<int>(current_congestion_window * kNConnectionBeta);
+ return static_cast<int>(current_congestion_window * Beta());
}
-QuicTcpCongestionWindow Cubic::CongestionWindowAfterAck(
- QuicTcpCongestionWindow current_congestion_window,
+QuicPacketCount Cubic::CongestionWindowAfterAck(
+ QuicPacketCount current_congestion_window,
QuicTime::Delta delay_min) {
acked_packets_count_ += 1; // Packets acked.
QuicTime current_time = clock_->ApproximateNow();
base::Time::kMicrosecondsPerSecond;
int64 offset = time_to_origin_point_ - elapsed_time;
- QuicTcpCongestionWindow delta_congestion_window = (kCubeCongestionWindowScale
+ QuicPacketCount delta_congestion_window = (kCubeCongestionWindowScale
* offset * offset * offset) >> kCubeScale;
- QuicTcpCongestionWindow target_congestion_window =
+ QuicPacketCount target_congestion_window =
origin_point_congestion_window_ - delta_congestion_window;
DCHECK_LT(0u, estimated_tcp_congestion_window_);
while (true) {
// Update estimated TCP congestion_window.
uint32 required_ack_count =
- estimated_tcp_congestion_window_ / kNConnectionAlpha;
+ estimated_tcp_congestion_window_ / Alpha();
if (acked_packets_count_ < required_ack_count) {
break;
}