blob: 7acfd5abac1510b183c24fee4ae7399a948d18b6 [file] [log] [blame]
// 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_