Optimize QpackBlockingManager::blocking_allowed_on_stream().
Iterating through |header_blocks_| can be costly, so handle the presumably
common cases of zero and very large blocked stream limits first. Also,
do early return as soon as |blocked_stream_count| gets too large.
gfe-relnote: n/a, change to QUIC v99-only code. Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 271596962
Change-Id: I18ecea0ae7c631c52c8cb53badbff2ff3471b2c4
diff --git a/quic/core/qpack/qpack_blocking_manager.cc b/quic/core/qpack/qpack_blocking_manager.cc
index f121aa0..2243c90 100644
--- a/quic/core/qpack/qpack_blocking_manager.cc
+++ b/quic/core/qpack/qpack_blocking_manager.cc
@@ -74,6 +74,18 @@
bool QpackBlockingManager::blocking_allowed_on_stream(
QuicStreamId stream_id,
uint64_t maximum_blocked_streams) const {
+ // This should be the most common case: the limit is larger than the number of
+ // streams that have unacknowledged header blocks (regardless of whether they
+ // are blocked or not) plus one for stream |stream_id|.
+ if (header_blocks_.size() + 1 <= maximum_blocked_streams) {
+ return true;
+ }
+
+ // This should be another common case: no blocked stream allowed.
+ if (maximum_blocked_streams == 0) {
+ return false;
+ }
+
uint64_t blocked_stream_count = 0;
for (const auto& header_blocks_for_stream : header_blocks_) {
for (const IndexSet& indices : header_blocks_for_stream.second) {
@@ -84,14 +96,31 @@
return true;
}
++blocked_stream_count;
+ // If stream |stream_id| is already blocked, then it is not counted yet,
+ // therefore the number of blocked streams is at least
+ // |blocked_stream_count + 1|, which cannot be more than
+ // |maximum_blocked_streams| by API contract.
+ // If stream |stream_id| is not blocked, then blocking will increase the
+ // blocked stream count to at least |blocked_stream_count + 1|. If that
+ // is larger than |maximum_blocked_streams|, then blocking is not
+ // allowed on stream |stream_id|.
+ if (blocked_stream_count + 1 > maximum_blocked_streams) {
+ return false;
+ }
break;
}
}
}
- // Stream |stream_id| is not blocked, therefore sending blocking references on
- // it would increase the blocked stream count by one.
- return blocked_stream_count + 1 <= maximum_blocked_streams;
+ // Stream |stream_id| is not blocked.
+ // If there are no blocked streams, then
+ // |blocked_stream_count + 1 <= maximum_blocked_streams| because
+ // |maximum_blocked_streams| is larger than zero.
+ // If there are are blocked streams, then
+ // |blocked_stream_count + 1 <= maximum_blocked_streams| otherwise the method
+ // would have returned false when |blocked_stream_count| was incremented.
+ // Therefore blocking on |stream_id| is allowed.
+ return true;
}
uint64_t QpackBlockingManager::smallest_blocking_index() const {