xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_blocking_manager.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
6 #define QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
7 
8 #include <cstdint>
9 #include <map>
10 #include <set>
11 
12 #include "absl/container/flat_hash_map.h"
13 #include "quiche/quic/core/quic_types.h"
14 #include "quiche/quic/platform/api/quic_export.h"
15 
16 namespace quic {
17 
18 namespace test {
19 
20 class QpackBlockingManagerPeer;
21 
22 }  // namespace test
23 
24 // Class to keep track of blocked streams and blocking dynamic table entries:
25 // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-decoding
26 // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-insertion
27 class QUICHE_EXPORT QpackBlockingManager {
28  public:
29   using IndexSet = std::multiset<uint64_t>;
30 
31   QpackBlockingManager();
32 
33   // Called when a Header Acknowledgement instruction is received on the decoder
34   // stream.  Returns false if there are no outstanding header blocks to be
35   // acknowledged on |stream_id|.
36   bool OnHeaderAcknowledgement(QuicStreamId stream_id);
37 
38   // Called when a Stream Cancellation instruction is received on the decoder
39   // stream.
40   void OnStreamCancellation(QuicStreamId stream_id);
41 
42   // Called when an Insert Count Increment instruction is received on the
43   // decoder stream.  Returns true if Known Received Count is successfully
44   // updated.  Returns false on overflow.
45   bool OnInsertCountIncrement(uint64_t increment);
46 
47   // Called when sending a header block containing references to dynamic table
48   // entries with |indices|.  |indices| must not be empty.
49   void OnHeaderBlockSent(QuicStreamId stream_id, IndexSet indices);
50 
51   // Returns true if sending blocking references on stream |stream_id| would not
52   // increase the total number of blocked streams above
53   // |maximum_blocked_streams|.  Note that if |stream_id| is already blocked
54   // then it is always allowed to send more blocking references on it.
55   // Behavior is undefined if |maximum_blocked_streams| is smaller than number
56   // of currently blocked streams.
57   bool blocking_allowed_on_stream(QuicStreamId stream_id,
58                                   uint64_t maximum_blocked_streams) const;
59 
60   // Returns the index of the blocking entry with the smallest index,
61   // or std::numeric_limits<uint64_t>::max() if there are no blocking entries.
62   uint64_t smallest_blocking_index() const;
63 
64   // Returns the Known Received Count as defined at
65   // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#known-received-count.
known_received_count()66   uint64_t known_received_count() const { return known_received_count_; }
67 
68   // Required Insert Count for set of indices.
69   static uint64_t RequiredInsertCount(const IndexSet& indices);
70 
71  private:
72   friend test::QpackBlockingManagerPeer;
73 
74   // A stream typically has only one header block, except for the rare cases of
75   // 1xx responses and trailers. Even if there are multiple header blocks sent
76   // on a single stream, they might not be blocked at the same time. Use
77   // std::list instead of quiche::QuicheCircularDeque because it has lower
78   // memory footprint when holding few elements.
79   using HeaderBlocksForStream = std::list<IndexSet>;
80   using HeaderBlocks = absl::flat_hash_map<QuicStreamId, HeaderBlocksForStream>;
81 
82   // Increase or decrease the reference count for each index in |indices|.
83   void IncreaseReferenceCounts(const IndexSet& indices);
84   void DecreaseReferenceCounts(const IndexSet& indices);
85 
86   // Multiset of indices in each header block for each stream.
87   // Must not contain a stream id with an empty queue.
88   HeaderBlocks header_blocks_;
89 
90   // Number of references in |header_blocks_| for each entry index.
91   std::map<uint64_t, uint64_t> entry_reference_counts_;
92 
93   uint64_t known_received_count_;
94 };
95 
96 }  // namespace quic
97 
98 #endif  // QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
99