Index: net/quic/congestion_control/send_algorithm_simulator.h |
diff --git a/net/quic/congestion_control/send_algorithm_simulator.h b/net/quic/congestion_control/send_algorithm_simulator.h |
index 691b0c82dbd9fe04b35eaa50df9d0cf8b6f41083..4941f35665dd03a4e688a1f309b7f6d5dc4cf45d 100644 |
--- a/net/quic/congestion_control/send_algorithm_simulator.h |
+++ b/net/quic/congestion_control/send_algorithm_simulator.h |
@@ -8,6 +8,7 @@ |
#define NET_QUIC_CONGESTION_CONTROL_SEND_ALGORITHM_SIMULATOR_H_ |
#include <algorithm> |
+#include <vector> |
#include "base/basictypes.h" |
#include "net/quic/congestion_control/send_algorithm_interface.h" |
@@ -20,26 +21,79 @@ namespace net { |
class SendAlgorithmSimulator { |
public: |
+ struct Sender { |
+ Sender(SendAlgorithmInterface* send_algorithm, RttStats* rtt_stats); |
+ |
+ void RecordStats() { |
+ QuicByteCount cwnd = send_algorithm->GetCongestionWindow(); |
+ max_cwnd = std::max(max_cwnd, cwnd); |
+ min_cwnd = std::min(min_cwnd, cwnd); |
+ if (last_cwnd > cwnd) { |
+ max_cwnd_drop = std::max(max_cwnd_drop, last_cwnd - cwnd); |
+ } |
+ last_cwnd = cwnd; |
+ } |
+ |
+ SendAlgorithmInterface* send_algorithm; |
+ RttStats* rtt_stats; |
+ |
+ // Last sequence number the sender sent. |
+ QuicPacketSequenceNumber last_sent; |
+ // Last packet sequence number acked. |
+ QuicPacketSequenceNumber last_acked; |
+ // Packet sequence number to ack up to. |
+ QuicPacketSequenceNumber next_acked; |
+ |
+ // Stats collected for understanding the congestion control. |
+ QuicByteCount max_cwnd; |
+ QuicByteCount min_cwnd; |
+ QuicByteCount max_cwnd_drop; |
+ QuicByteCount last_cwnd; |
+ |
+ QuicBandwidth last_transfer_bandwidth; |
+ }; |
+ |
+ struct Transfer { |
+ Transfer(Sender* sender, QuicByteCount num_bytes, QuicTime start_time) |
+ : sender(sender), |
+ num_bytes(num_bytes), |
+ bytes_acked(0), |
+ bytes_in_flight(0), |
+ start_time(start_time) {} |
+ |
+ Sender* sender; |
+ QuicByteCount num_bytes; |
+ QuicByteCount bytes_acked; |
+ QuicByteCount bytes_in_flight; |
+ QuicTime start_time; |
+ }; |
+ |
struct SentPacket { |
SentPacket(QuicPacketSequenceNumber sequence_number, |
QuicTime send_time, |
- QuicTime ack_time) |
+ QuicTime ack_time, |
+ Transfer* transfer) |
: sequence_number(sequence_number), |
send_time(send_time), |
- ack_time(ack_time) {} |
+ ack_time(ack_time), |
+ transfer(transfer) {} |
+ |
QuicPacketSequenceNumber sequence_number; |
QuicTime send_time; |
QuicTime ack_time; |
+ Transfer* transfer; |
}; |
// |rtt_stats| should be the same RttStats used by the |send_algorithm|. |
- SendAlgorithmSimulator(SendAlgorithmInterface* send_algorithm, |
- MockClock* clock_, |
- RttStats* rtt_stats, |
+ SendAlgorithmSimulator(MockClock* clock_, |
QuicBandwidth bandwidth, |
QuicTime::Delta rtt); |
~SendAlgorithmSimulator(); |
+ void set_bandwidth(QuicBandwidth bandwidth) { |
+ bandwidth_ = bandwidth; |
+ } |
+ |
void set_forward_loss_rate(float loss_rate) { |
DCHECK_LT(loss_rate, 1.0f); |
forward_loss_rate_ = loss_rate; |
@@ -59,54 +113,58 @@ class SendAlgorithmSimulator { |
buffer_size_ = buffer_size_bytes; |
} |
- // Sends the specified number of bytes as quickly as possible and returns the |
- // average bandwidth in bytes per second. The time elapsed is based on |
- // waiting for all acks to arrive. |
- QuicBandwidth SendBytes(size_t num_bytes); |
+ // Advance the time by |delta| without sending anything. |
+ void AdvanceTime(QuicTime::Delta delta); |
+ |
+ // Adds a pending sender. The send will run when TransferBytes is called. |
+ // Adding two transfers with the same sender is unsupported. |
+ void AddTransfer(Sender* sender, size_t num_bytes); |
- const RttStats* rtt_stats() const { return rtt_stats_; } |
+ // Adds a pending sending to start at the specified time. |
+ void AddTransfer(Sender* sender, size_t num_bytes, QuicTime start_time); |
- QuicByteCount max_cwnd() const { return max_cwnd_; } |
- QuicByteCount min_cwnd() const { return min_cwnd_; } |
- QuicByteCount max_cwnd_drop() const { return max_cwnd_drop_; } |
- QuicByteCount last_cwnd() const { return last_cwnd_; } |
+ // Convenience method to transfer all bytes. |
+ void TransferBytes(); |
+ |
+ // Transfers bytes through the connection until |max_bytes| are reached, |
+ // |max_time| is reached, or all senders have finished sending. If max_bytes |
+ // is 0, it does not apply, and if |max_time| is Zero, no time limit applies. |
+ void TransferBytes(QuicByteCount max_bytes, QuicTime::Delta max_time); |
private: |
+ // A pending packet event, either a send or an ack. |
+ struct PacketEvent { |
+ PacketEvent(QuicTime::Delta time_delta, Transfer* transfer) |
+ : time_delta(time_delta), |
+ transfer(transfer) {} |
+ |
+ QuicTime::Delta time_delta; |
+ Transfer* transfer; |
+ }; |
+ |
+ // NextSendTime returns the next time any of the pending transfers send, |
+ // and populates transfer if the send time is not infinite. |
+ PacketEvent NextSendEvent(); |
+ |
// NextAckTime takes into account packet loss in both forward and reverse |
// direction, as well as delayed ack behavior. |
- QuicTime::Delta NextAckDelta(); |
- |
- // Whether all packets in sent_packets_ are lost. |
- bool AllPacketsLost(); |
+ PacketEvent NextAckEvent(); |
// Sets the next acked. |
- void FindNextAcked(); |
+ QuicTime::Delta FindNextAcked(Transfer* transfer); |
// Process all the acks that should have arrived by the current time, and |
// lose any packets that are missing. Returns the number of bytes acked. |
- int HandlePendingAck(); |
+ void HandlePendingAck(Transfer* transfer); |
- void SendDataNow(); |
- void RecordStats(); |
+ void SendDataNow(Transfer* transfer); |
- // Advance the time by |delta| without sending anything. |
- void AdvanceTime(QuicTime::Delta delta); |
+ // List of all pending transfers waiting to use the connection. |
+ std::vector<Transfer> pending_transfers_; |
- // Elapsed time from the start of the connection. |
- QuicTime ElapsedTime(); |
- |
- SendAlgorithmInterface* send_algorithm_; |
MockClock* clock_; |
- RttStats* rtt_stats_; |
- // Next packet sequence number to send. |
- QuicPacketSequenceNumber next_sent_; |
- // Last packet sequence number acked. |
- QuicPacketSequenceNumber last_acked_; |
- // Packet sequence number to ack up to. |
- QuicPacketSequenceNumber next_acked_; |
// Whether the next ack should be lost. |
bool lose_next_ack_; |
- QuicByteCount bytes_in_flight_; |
// The times acks are expected, assuming acks are not lost and every packet |
// is acked. |
std::list<SentPacket> sent_packets_; |
@@ -119,12 +177,6 @@ class SendAlgorithmSimulator { |
QuicTime::Delta rtt_; |
size_t buffer_size_; // In bytes. |
- // Stats collected for understanding the congestion control. |
- QuicByteCount max_cwnd_; |
- QuicByteCount min_cwnd_; |
- QuicByteCount max_cwnd_drop_; |
- QuicByteCount last_cwnd_; |
- |
DISALLOW_COPY_AND_ASSIGN(SendAlgorithmSimulator); |
}; |