Let QuicBandwidth::FromBytesAndTimeDelta return 1 bit per second if the result is less than that but not zero.

Protected by FLAGS_quic_reloadable_flag_quic_round_up_tiny_bandwidth (Default True).

PiperOrigin-RevId: 341455235
Change-Id: I48c3bb613eb966f7dd0f93881715e434de84b6ff
diff --git a/quic/core/quic_bandwidth.h b/quic/core/quic_bandwidth.h
index e3e0cd1..97de22c 100644
--- a/quic/core/quic_bandwidth.h
+++ b/quic/core/quic_bandwidth.h
@@ -17,6 +17,7 @@
 #include "net/third_party/quiche/src/quic/core/quic_time.h"
 #include "net/third_party/quiche/src/quic/core/quic_types.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
 
 namespace quic {
 
@@ -54,8 +55,23 @@
   // Create a new QuicBandwidth based on the bytes per the elapsed delta.
   static inline QuicBandwidth FromBytesAndTimeDelta(QuicByteCount bytes,
                                                     QuicTime::Delta delta) {
-    return QuicBandwidth((8 * bytes * kNumMicrosPerSecond) /
-                         delta.ToMicroseconds());
+    if (!GetQuicReloadableFlag(quic_round_up_tiny_bandwidth)) {
+      return QuicBandwidth((8 * bytes * kNumMicrosPerSecond) /
+                           delta.ToMicroseconds());
+    }
+
+    if (bytes == 0) {
+      return QuicBandwidth(0);
+    }
+
+    // 1 bit is 1000000 micro bits.
+    int64_t num_micro_bits = 8 * bytes * kNumMicrosPerSecond;
+    if (num_micro_bits < delta.ToMicroseconds()) {
+      QUIC_RELOADABLE_FLAG_COUNT(quic_round_up_tiny_bandwidth);
+      return QuicBandwidth(1);
+    }
+
+    return QuicBandwidth(num_micro_bits / delta.ToMicroseconds());
   }
 
   inline int64_t ToBitsPerSecond() const { return bits_per_second_; }
diff --git a/quic/core/quic_bandwidth_test.cc b/quic/core/quic_bandwidth_test.cc
index 005eef0..0a32e4e 100644
--- a/quic/core/quic_bandwidth_test.cc
+++ b/quic/core/quic_bandwidth_test.cc
@@ -58,6 +58,18 @@
   EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(10),
             QuicBandwidth::FromBytesAndTimeDelta(
                 1000, QuicTime::Delta::FromMilliseconds(100)));
+
+  EXPECT_EQ(QuicBandwidth::Zero(), QuicBandwidth::FromBytesAndTimeDelta(
+                                       0, QuicTime::Delta::FromSeconds(9)));
+
+  if (GetQuicReloadableFlag(quic_round_up_tiny_bandwidth)) {
+    EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(1),
+              QuicBandwidth::FromBytesAndTimeDelta(
+                  1, QuicTime::Delta::FromSeconds(9)));
+  } else {
+    EXPECT_EQ(QuicBandwidth::Zero(), QuicBandwidth::FromBytesAndTimeDelta(
+                                         1, QuicTime::Delta::FromSeconds(9)));
+  }
 }
 
 TEST_F(QuicBandwidthTest, Scale) {
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 0662174..6c87293 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -63,6 +63,7 @@
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reject_spdy_frames, true)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reject_spdy_settings, true)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_round_up_tiny_bandwidth, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_goaway_with_connection_close, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_path_response, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_timestamps, false)