Internal QUICHE change

PiperOrigin-RevId: 282443752
Change-Id: Ifd6e39c3080ef3f6c477d9ae5b9750b4b2588166
diff --git a/quic/core/congestion_control/bandwidth_sampler.cc b/quic/core/congestion_control/bandwidth_sampler.cc
index 2555e0f..cc90cb0 100644
--- a/quic/core/congestion_control/bandwidth_sampler.cc
+++ b/quic/core/congestion_control/bandwidth_sampler.cc
@@ -21,6 +21,7 @@
   if (aggregation_epoch_start_time_ == QuicTime::Zero()) {
     aggregation_epoch_bytes_ = bytes_acked;
     aggregation_epoch_start_time_ = ack_time;
+    ++num_ack_aggregation_epochs_;
     return 0;
   }
 
@@ -36,6 +37,7 @@
     // Reset to start measuring a new aggregation epoch.
     aggregation_epoch_bytes_ = bytes_acked;
     aggregation_epoch_start_time_ = ack_time;
+    ++num_ack_aggregation_epochs_;
     return 0;
   }
 
diff --git a/quic/core/congestion_control/bandwidth_sampler.h b/quic/core/congestion_control/bandwidth_sampler.h
index b27e3a1..51f5e87 100644
--- a/quic/core/congestion_control/bandwidth_sampler.h
+++ b/quic/core/congestion_control/bandwidth_sampler.h
@@ -100,6 +100,10 @@
     max_ack_height_filter_.Reset(new_height, new_time);
   }
 
+  uint64_t num_ack_aggregation_epochs() const {
+    return num_ack_aggregation_epochs_;
+  }
+
  private:
   // Tracks the maximum number of bytes acked faster than the estimated
   // bandwidth.
@@ -113,6 +117,9 @@
   // The time this aggregation started and the number of bytes acked during it.
   QuicTime aggregation_epoch_start_time_ = QuicTime::Zero();
   QuicByteCount aggregation_epoch_bytes_ = 0;
+  // The number of ack aggregation epochs ever started, including the ongoing
+  // one. Stats only.
+  uint64_t num_ack_aggregation_epochs_ = 0;
 };
 
 // An interface common to any class that can provide bandwidth samples from the
@@ -273,6 +280,10 @@
 
   QuicByteCount max_ack_height() const { return max_ack_height_tracker_.Get(); }
 
+  uint64_t num_ack_aggregation_epochs() const {
+    return max_ack_height_tracker_.num_ack_aggregation_epochs();
+  }
+
   void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount length) {
     max_ack_height_tracker_.SetFilterWindowLength(length);
   }
diff --git a/quic/core/congestion_control/bandwidth_sampler_test.cc b/quic/core/congestion_control/bandwidth_sampler_test.cc
index 558971a..59318a9 100644
--- a/quic/core/congestion_control/bandwidth_sampler_test.cc
+++ b/quic/core/congestion_control/bandwidth_sampler_test.cc
@@ -551,6 +551,7 @@
 
   AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
                      1200, false);
+  EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
 }
 
 TEST_F(MaxAckHeightTrackerTest, VeryAggregatedSmallAcks) {
@@ -562,6 +563,7 @@
 
   AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6), 300,
                      false);
+  EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
 }
 
 TEST_F(MaxAckHeightTrackerTest, SomewhatAggregatedLargeAck) {
@@ -573,6 +575,7 @@
 
   AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
                      1000, false);
+  EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
 }
 
 TEST_F(MaxAckHeightTrackerTest, SomewhatAggregatedSmallAcks) {
@@ -584,11 +587,13 @@
 
   AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
                      false);
+  EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
 }
 
 TEST_F(MaxAckHeightTrackerTest, NotAggregated) {
   AggregationEpisode(bandwidth_, QuicTime::Delta::FromMilliseconds(100), 100,
                      true);
+  EXPECT_LT(2u, tracker_.num_ack_aggregation_epochs());
 }
 
 }  // namespace test
diff --git a/quic/core/congestion_control/bbr2_misc.h b/quic/core/congestion_control/bbr2_misc.h
index 139b120..8f08a58 100644
--- a/quic/core/congestion_control/bbr2_misc.h
+++ b/quic/core/congestion_control/bbr2_misc.h
@@ -331,6 +331,10 @@
     return bandwidth_sampler_.max_ack_height();
   }
 
+  uint64_t num_ack_aggregation_epochs() const {
+    return bandwidth_sampler_.num_ack_aggregation_epochs();
+  }
+
   bool MaybeExpireMinRtt(const Bbr2CongestionEvent& congestion_event);
 
   QuicBandwidth BandwidthEstimate() const {
diff --git a/quic/core/congestion_control/bbr2_sender.cc b/quic/core/congestion_control/bbr2_sender.cc
index 73787a2..31bf299 100644
--- a/quic/core/congestion_control/bbr2_sender.cc
+++ b/quic/core/congestion_control/bbr2_sender.cc
@@ -311,6 +311,10 @@
                 << ", CWND: " << GetCongestionWindow();
 }
 
+void Bbr2Sender::PopulateConnectionStats(QuicConnectionStats* stats) const {
+  stats->num_ack_aggregation_epochs = model_.num_ack_aggregation_epochs();
+}
+
 bool Bbr2Sender::ShouldSendProbingPacket() const {
   // TODO(wub): Implement ShouldSendProbingPacket properly.
   if (!BBR2_MODE_DISPATCH(IsProbingForBandwidth())) {
diff --git a/quic/core/congestion_control/bbr2_sender.h b/quic/core/congestion_control/bbr2_sender.h
index f0a3b5f..4cfd34c 100644
--- a/quic/core/congestion_control/bbr2_sender.h
+++ b/quic/core/congestion_control/bbr2_sender.h
@@ -87,6 +87,8 @@
   std::string GetDebugState() const override;
 
   void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
+
+  void PopulateConnectionStats(QuicConnectionStats* stats) const override;
   // End implementation of SendAlgorithmInterface.
 
   const Bbr2Params& Params() const { return params_; }
diff --git a/quic/core/congestion_control/bbr_sender.cc b/quic/core/congestion_control/bbr_sender.cc
index 4217048..0096ca5 100644
--- a/quic/core/congestion_control/bbr_sender.cc
+++ b/quic/core/congestion_control/bbr_sender.cc
@@ -905,6 +905,10 @@
                 << last_sent_packet_ << ", CWND: " << GetCongestionWindow();
 }
 
+void BbrSender::PopulateConnectionStats(QuicConnectionStats* stats) const {
+  stats->num_ack_aggregation_epochs = sampler_.num_ack_aggregation_epochs();
+}
+
 BbrSender::DebugState BbrSender::ExportDebugState() const {
   return DebugState(*this);
 }
diff --git a/quic/core/congestion_control/bbr_sender.h b/quic/core/congestion_control/bbr_sender.h
index 8c07a40..dc512cf 100644
--- a/quic/core/congestion_control/bbr_sender.h
+++ b/quic/core/congestion_control/bbr_sender.h
@@ -128,6 +128,7 @@
   CongestionControlType GetCongestionControlType() const override;
   std::string GetDebugState() const override;
   void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
+  void PopulateConnectionStats(QuicConnectionStats* stats) const override;
   // End implementation of SendAlgorithmInterface.
 
   // Gets the number of RTTs BBR remains in STARTUP phase.
diff --git a/quic/core/congestion_control/send_algorithm_interface.h b/quic/core/congestion_control/send_algorithm_interface.h
index 2c183f1..628e0d6 100644
--- a/quic/core/congestion_control/send_algorithm_interface.h
+++ b/quic/core/congestion_control/send_algorithm_interface.h
@@ -168,6 +168,9 @@
   // such cases, it should use the internal state it uses for congestion control
   // for that.
   virtual void OnApplicationLimited(QuicByteCount bytes_in_flight) = 0;
+
+  // Called before connection close to collect stats.
+  virtual void PopulateConnectionStats(QuicConnectionStats* stats) const = 0;
 };
 
 }  // namespace quic
diff --git a/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/quic/core/congestion_control/tcp_cubic_sender_bytes.h
index 8e89eaa..9144b8a 100644
--- a/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ b/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -73,6 +73,7 @@
   bool ShouldSendProbingPacket() const override;
   std::string GetDebugState() const override;
   void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
+  void PopulateConnectionStats(QuicConnectionStats* /*stats*/) const override {}
   // End implementation of SendAlgorithmInterface.
 
   QuicByteCount min_congestion_window() const { return min_congestion_window_; }