| // Copyright (c) 2019 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_ | |
| #define QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_ | |
| #include <cstdint> | |
| #include <map> | |
| #include <set> | |
| #include "net/third_party/quiche/src/quic/core/quic_types.h" | |
| #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" | |
| #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" | |
| namespace quic { | |
| // Class to keep track of blocked streams and blocking dynamic table entries: | |
| // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-decoding | |
| // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-insertion | |
| class QUIC_EXPORT_PRIVATE QpackBlockingManager { | |
| public: | |
| using IndexSet = std::multiset<uint64_t>; | |
| QpackBlockingManager(); | |
| // Called when a Header Acknowledgement instruction is received on the decoder | |
| // stream. Returns false if there are no outstanding header blocks to be | |
| // acknowledged on |stream_id|. | |
| bool OnHeaderAcknowledgement(QuicStreamId stream_id); | |
| // Called when a Stream Cancellation instruction is received on the decoder | |
| // stream. | |
| void OnStreamCancellation(QuicStreamId stream_id); | |
| // Called when an Insert Count Increment instruction is received on the | |
| // decoder stream. | |
| void OnInsertCountIncrement(uint64_t increment); | |
| // Called when sending a header block containing references to dynamic table | |
| // entries with |indices|. |indices| must not be empty. | |
| void OnHeaderBlockSent(QuicStreamId stream_id, IndexSet indices); | |
| // Called when sending Insert With Name Reference or Duplicate instruction on | |
| // encoder stream, inserting entry |inserted_index| referring to | |
| // |referred_index|. | |
| void OnReferenceSentOnEncoderStream(uint64_t inserted_index, | |
| uint64_t referred_index); | |
| // Returns the number of blocked streams. | |
| uint64_t blocked_stream_count() const; | |
| // Returns the index of the blocking entry with the smallest index, | |
| // or std::numeric_limits<uint64_t>::max() if there are no blocking entries. | |
| uint64_t smallest_blocking_index() const; | |
| // Returns the Known Received Count as defined at | |
| // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#known-received-count. | |
| uint64_t known_received_count() const { return known_received_count_; } | |
| // Required Insert Count for set of indices. | |
| static uint64_t RequiredInsertCount(const IndexSet& indices); | |
| private: | |
| // A stream typically has only one header block, except for the rare cases of | |
| // 1xx responses, trailers, or push promises. Even if there are multiple | |
| // header blocks sent on a single stream, they might not be blocked at the | |
| // same time. Use std::list instead of QuicDeque because it has lower memory | |
| // footprint when holding few elements. | |
| using HeaderBlocksForStream = std::list<IndexSet>; | |
| using HeaderBlocks = QuicUnorderedMap<QuicStreamId, HeaderBlocksForStream>; | |
| // Increases |known_received_count_| to |new_known_received_count|, which must | |
| // me larger than |known_received_count_|. Removes acknowledged references | |
| // from |unacked_encoder_stream_references_|. | |
| void IncreaseKnownReceivedCountTo(uint64_t new_known_received_count); | |
| // Increase or decrease the reference count for each index in |indices|. | |
| void IncreaseReferenceCounts(const IndexSet& indices); | |
| void DecreaseReferenceCounts(const IndexSet& indices); | |
| // Multiset of indices in each header block for each stream. | |
| // Must not contain a stream id with an empty queue. | |
| HeaderBlocks header_blocks_; | |
| // Unacknowledged references on the encoder stream. | |
| // The key is the absolute index of the inserted entry, | |
| // the mapped value is the absolute index of the entry referred. | |
| std::map<uint64_t, uint64_t> unacked_encoder_stream_references_; | |
| // Number of references in |header_blocks_| and | |
| // |unacked_encoder_stream_references_| for each entry index. | |
| std::map<uint64_t, uint64_t> entry_reference_counts_; | |
| uint64_t known_received_count_; | |
| }; | |
| } // namespace quic | |
| #endif // QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_ |