gfe-relnote: Save the time the last inflight packet was sent instead of iterating through the deque.  Protected by gfe2_reloadable_flag_quic_simple_inflight_time.

PiperOrigin-RevId: 267115183
Change-Id: I98661c317b4009e182ecbec9e25c8fd368791758
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc
index 2eb606b..54e6444 100644
--- a/quic/core/quic_sent_packet_manager.cc
+++ b/quic/core/quic_sent_packet_manager.cc
@@ -645,7 +645,7 @@
     // Other crypto handshake packets won't be in flight, only the newest
     // transmission of a crypto packet is in flight at once.
     // TODO(ianswett): Instead of handling all crypto packets special,
-    // only handle nullptr encrypted packets in a special way.
+    // only handle null encrypted packets in a special way.
     const QuicTransmissionInfo& newest_transmission_info =
         unacked_packets_.GetTransmissionInfo(newest_transmission);
     unacked_packets_.NotifyFramesAcked(newest_transmission_info, ack_delay_time,
@@ -1021,7 +1021,8 @@
       // TODO(ianswett): When CWND is available, it would be preferable to
       // set the timer based on the earliest retransmittable packet.
       // Base the updated timer on the send time of the last packet.
-      const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime();
+      const QuicTime sent_time =
+          unacked_packets_.GetLastInFlightPacketSentTime();
       const QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
       // Ensure the TLP timer never gets set to a time in the past.
       return std::max(clock_->ApproximateNow(), tlp_time);
@@ -1029,15 +1030,16 @@
     case RTO_MODE: {
       DCHECK(!pto_enabled_);
       // The RTO is based on the first outstanding packet.
-      const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime();
+      const QuicTime sent_time =
+          unacked_packets_.GetLastInFlightPacketSentTime();
       QuicTime rto_time = sent_time + GetRetransmissionDelay();
       // Wait for TLP packets to be acked before an RTO fires.
-      QuicTime tlp_time =
-          unacked_packets_.GetLastPacketSentTime() + GetTailLossProbeDelay();
+      QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
       return std::max(tlp_time, rto_time);
     }
     case PTO_MODE: {
-      if (handshake_mode_disabled_ && !handshake_confirmed_ &&
+      if (!unacked_packets().simple_inflight_time() &&
+          handshake_mode_disabled_ && !handshake_confirmed_ &&
           !unacked_packets_.HasInFlightPackets()) {
         DCHECK_EQ(Perspective::IS_CLIENT, unacked_packets_.perspective());
         return std::max(clock_->ApproximateNow(),
@@ -1045,9 +1047,9 @@
                             GetProbeTimeoutDelay());
       }
       // Ensure PTO never gets set to a time in the past.
-      return std::max(
-          clock_->ApproximateNow(),
-          unacked_packets_.GetLastPacketSentTime() + GetProbeTimeoutDelay());
+      return std::max(clock_->ApproximateNow(),
+                      unacked_packets_.GetLastInFlightPacketSentTime() +
+                          GetProbeTimeoutDelay());
     }
   }
   DCHECK(false);
diff --git a/quic/core/quic_unacked_packet_map.cc b/quic/core/quic_unacked_packet_map.cc
index f07fd31..92f3171 100644
--- a/quic/core/quic_unacked_packet_map.cc
+++ b/quic/core/quic_unacked_packet_map.cc
@@ -29,10 +29,14 @@
       least_unacked_(FirstSendingPacketNumber()),
       bytes_in_flight_(0),
       pending_crypto_packet_count_(0),
+      last_inflight_packet_sent_time_(QuicTime::Zero()),
       last_crypto_packet_sent_time_(QuicTime::Zero()),
       session_notifier_(nullptr),
       session_decides_what_to_write_(false),
-      supports_multiple_packet_number_spaces_(false) {}
+      supports_multiple_packet_number_spaces_(false),
+      simple_inflight_time_(GetQuicReloadableFlag(quic_simple_inflight_time)) {
+  QUIC_RELOADABLE_FLAG_COUNT(quic_simple_inflight_time);
+}
 
 QuicUnackedPacketMap::~QuicUnackedPacketMap() {
   for (QuicTransmissionInfo& transmission_info : unacked_packets_) {
@@ -79,6 +83,9 @@
     info.in_flight = true;
     largest_sent_retransmittable_packets_[GetPacketNumberSpace(
         info.encryption_level)] = packet_number;
+    // TODO(ianswett): Should this field be per packet number space or should
+    // GetInFlightPacketSentTime() use largest_sent_retransmittable_packets_?
+    last_inflight_packet_sent_time_ = sent_time;
   }
   unacked_packets_.push_back(info);
   // Swap the retransmittable frames to avoid allocations.
@@ -321,7 +328,10 @@
   return &unacked_packets_[packet_number - least_unacked_];
 }
 
-QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const {
+QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime() const {
+  if (simple_inflight_time_) {
+    return last_inflight_packet_sent_time_;
+  }
   auto it = unacked_packets_.rbegin();
   while (it != unacked_packets_.rend()) {
     if (it->in_flight) {
diff --git a/quic/core/quic_unacked_packet_map.h b/quic/core/quic_unacked_packet_map.h
index 64d1da8..864e485 100644
--- a/quic/core/quic_unacked_packet_map.h
+++ b/quic/core/quic_unacked_packet_map.h
@@ -131,7 +131,7 @@
       QuicPacketNumber packet_number);
 
   // Returns the time that the last unacked packet was sent.
-  QuicTime GetLastPacketSentTime() const;
+  QuicTime GetLastInFlightPacketSentTime() const;
 
   // Returns the time that the last unacked crypto packet was sent.
   QuicTime GetLastCryptoPacketSentTime() const;
@@ -227,6 +227,8 @@
     return supports_multiple_packet_number_spaces_;
   }
 
+  bool simple_inflight_time() const { return simple_inflight_time_; }
+
  private:
   friend class test::QuicUnackedPacketMapPeer;
 
@@ -288,6 +290,9 @@
   // Number of retransmittable crypto handshake packets.
   size_t pending_crypto_packet_count_;
 
+  // Time that the last inflight packet was sent.
+  QuicTime last_inflight_packet_sent_time_;
+
   // Time that the last unacked crypto packet was sent.
   QuicTime last_crypto_packet_sent_time_;
 
@@ -303,6 +308,9 @@
 
   // If true, supports multiple packet number spaces.
   bool supports_multiple_packet_number_spaces_;
+
+  // Latched value of the quic_simple_inflight_time flag.
+  bool simple_inflight_time_;
 };
 
 }  // namespace quic