Remove streams_waiting_for_acks_ in QuicSession because it stores duplicate information and only reduces minimal time complexity.

Session shouldn't care this much about streams' states.

Protected by gfe2_reloadable_flag_quic_remove_streams_waiting_for_acks

PiperOrigin-RevId: 321829178
Change-Id: I3589810eb553b1b743799b7ab51990fbd42e1008
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 5bfc517..a6286cc 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -99,8 +99,9 @@
       is_configured_(false),
       enable_round_robin_scheduling_(false),
       was_zero_rtt_rejected_(false),
-      fix_gquic_stream_type_(
-          GetQuicReloadableFlag(quic_fix_gquic_stream_type)) {
+      fix_gquic_stream_type_(GetQuicReloadableFlag(quic_fix_gquic_stream_type)),
+      remove_streams_waiting_for_acks_(
+          GetQuicReloadableFlag(quic_remove_streams_waiting_for_acks)) {
   closed_streams_clean_up_alarm_ =
       QuicWrapUnique<QuicAlarm>(connection_->alarm_factory()->CreateAlarm(
           new ClosedStreamsCleanUpDelegate(this)));
@@ -877,7 +878,11 @@
     zombie_streams_[stream_id] = std::move(it->second);
   } else {
     // Clean up the stream since it is no longer waiting for acks.
-    streams_waiting_for_acks_.erase(stream_id);
+    if (remove_streams_waiting_for_acks_) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_remove_streams_waiting_for_acks, 1, 4);
+    } else {
+      streams_waiting_for_acks_.erase(stream_id);
+    }
     closed_streams_.push_back(std::move(it->second));
     // Do not retransmit data of a closed stream.
     streams_with_pending_retransmission_.erase(stream_id);
@@ -2003,7 +2008,11 @@
 }
 
 void QuicSession::OnStreamDoneWaitingForAcks(QuicStreamId id) {
-  streams_waiting_for_acks_.erase(id);
+  if (remove_streams_waiting_for_acks_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_remove_streams_waiting_for_acks, 2, 4);
+  } else {
+    streams_waiting_for_acks_.erase(id);
+  }
 
   auto it = zombie_streams_.find(id);
   if (it == zombie_streams_.end()) {
@@ -2020,6 +2029,10 @@
 }
 
 void QuicSession::OnStreamWaitingForAcks(QuicStreamId id) {
+  if (remove_streams_waiting_for_acks_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_remove_streams_waiting_for_acks, 3, 4);
+    return;
+  }
   // Exclude crypto stream's status since it is counted in HasUnackedCryptoData.
   if (GetCryptoStream() != nullptr && id == GetCryptoStream()->id()) {
     return;
@@ -2181,7 +2194,19 @@
 }
 
 bool QuicSession::HasUnackedStreamData() const {
-  return !streams_waiting_for_acks_.empty();
+  if (!remove_streams_waiting_for_acks_) {
+    return !streams_waiting_for_acks_.empty();
+  }
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_remove_streams_waiting_for_acks, 4, 4);
+  if (!zombie_streams().empty()) {
+    return true;
+  }
+  for (const auto& it : stream_map_) {
+    if (it.second->IsWaitingForAcks()) {
+      return true;
+    }
+  }
+  return false;
 }
 
 HandshakeState QuicSession::GetHandshakeState() const {
diff --git a/quic/core/quic_session.h b/quic/core/quic_session.h
index 2d104a9..db8c55f 100644
--- a/quic/core/quic_session.h
+++ b/quic/core/quic_session.h
@@ -349,7 +349,8 @@
   // a stream is reset because of an error).
   void OnStreamDoneWaitingForAcks(QuicStreamId id);
 
-  // Called when stream |id| is newly waiting for acks.
+  // TODO(b/136274541): Remove this once quic_remove_streams_waiting_for_acks is
+  // deprecated. Called when stream |id| is newly waiting for acks.
   void OnStreamWaitingForAcks(QuicStreamId id);
 
   // Returns true if there is pending handshake data in the crypto stream.
@@ -755,7 +756,9 @@
   // which are waiting for the first byte of payload to arrive.
   PendingStreamMap pending_stream_map_;
 
-  // Set of stream ids that are waiting for acks excluding crypto stream id.
+  // TODO(b/136274541): Remove this once quic_remove_streams_waiting_for_acks is
+  // deprecated. Set of stream ids that are waiting for acks excluding crypto
+  // stream id.
   QuicHashSet<QuicStreamId> streams_waiting_for_acks_;
 
   // TODO(fayang): Consider moving LegacyQuicStreamIdManager into
@@ -831,6 +834,9 @@
 
   // Latched value of flag quic_fix_gquic_stream_type.
   const bool fix_gquic_stream_type_;
+
+  // Latched value of flag quic_remove_streams_waiting_for_acks.
+  const bool remove_streams_waiting_for_acks_;
 };
 
 }  // namespace quic
diff --git a/quic/core/quic_stream.h b/quic/core/quic_stream.h
index 41484a3..2a7d036 100644
--- a/quic/core/quic_stream.h
+++ b/quic/core/quic_stream.h
@@ -218,9 +218,6 @@
   size_t busy_counter() const { return busy_counter_; }
   void set_busy_counter(size_t busy_counter) { busy_counter_ = busy_counter; }
 
-  void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
-  void set_stream_error(QuicRstStreamErrorCode error) { stream_error_ = error; }
-
   // Adjust the flow control window according to new offset in |frame|.
   virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
 
@@ -408,6 +405,9 @@
   // empty.
   void SetFinSent();
 
+  void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
+  void set_stream_error(QuicRstStreamErrorCode error) { stream_error_ = error; }
+
   StreamDelegateInterface* stream_delegate() { return stream_delegate_; }
 
   bool fin_buffered() const { return fin_buffered_; }