Index: net/quic/core/congestion_control/simulation/queue.cc |
diff --git a/net/quic/core/congestion_control/simulation/queue.cc b/net/quic/core/congestion_control/simulation/queue.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1b85d6b20325a8408cc6b642d00425517c8eb26a |
--- /dev/null |
+++ b/net/quic/core/congestion_control/simulation/queue.cc |
@@ -0,0 +1,59 @@ |
+#include "net/quic/core/congestion_control/simulation/queue.h" |
+ |
+namespace net { |
+namespace simulation { |
+ |
+Queue::ListenerInterface::~ListenerInterface() {} |
+ |
+Queue::Queue(Simulator* simulator, std::string name, QuicByteCount capacity) |
+ : Actor(simulator, name), |
+ capacity_(capacity), |
+ bytes_queued_(0), |
+ listener_(nullptr) {} |
+ |
+void Queue::set_tx_port(ConstrainedPortInterface* port) { |
+ tx_port_ = port; |
+} |
+ |
+void Queue::AcceptPacket(std::unique_ptr<Packet> packet) { |
+ if (packet->size + bytes_queued_ > capacity_) { |
+ DVLOG(1) << "Queue [" << name() << "] has received a packet from [" |
+ << packet->source << "] to [" << packet->destination |
+ << "] which is over capacity. Dropping it."; |
+ DVLOG(1) << "Queue size: " << bytes_queued_ << " out of " << capacity_ |
+ << ". Packet size: " << packet->size; |
+ return; |
+ } |
+ |
+ bytes_queued_ += packet->size; |
+ queue_.emplace(std::move(packet)); |
+ ScheduleNextPacketDequeue(); |
+} |
+ |
+void Queue::Act() { |
+ DCHECK(!queue_.empty()); |
+ if (tx_port_->TimeUntilAvailable().IsZero()) { |
+ DCHECK(bytes_queued_ >= queue_.front()->size); |
+ bytes_queued_ -= queue_.front()->size; |
+ |
+ tx_port_->AcceptPacket(std::move(queue_.front())); |
+ queue_.pop(); |
+ if (listener_ != nullptr) { |
+ listener_->OnPacketDequeued(); |
+ } |
+ } |
+ |
+ ScheduleNextPacketDequeue(); |
+} |
+ |
+void Queue::ScheduleNextPacketDequeue() { |
+ if (queue_.empty()) { |
+ DCHECK_EQ(bytes_queued_, 0); |
+ return; |
+ } |
+ |
+ Schedule(clock_->Now() + tx_port_->TimeUntilAvailable()); |
+} |
+ |
+} // namespace simulation |
+} // namespace net |