// Copyright (c) 2015 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_QUIC_STREAM_SEQUENCER_BUFFER_H_ #define QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_ // QuicStreamSequencerBuffer is a circular stream buffer with random write and // in-sequence read. It consists of a vector of pointers pointing // to memory blocks created as needed and an interval set recording received // data. // - Data are written in with offset indicating where it should be in the // stream, and the buffer grown as needed (up to the maximum buffer capacity), // without expensive copying (extra blocks are allocated). // - Data can be read from the buffer if there is no gap before it, // and the buffer shrinks as the data are consumed. // - An upper limit on the number of blocks in the buffer provides an upper // bound on memory use. // // This class is thread-unsafe. // // QuicStreamSequencerBuffer maintains a concept of the readable region, which // contains all written data that has not been read. // It promises stability of the underlying memory addresses in the readable // region, so pointers into it can be maintained, and the offset of a pointer // from the start of the read region can be calculated. // // Expected Use: // QuicStreamSequencerBuffer buffer(2.5 * 8 * 1024); // std::string source(1024, 'a'); // absl::string_view string_piece(source.data(), source.size()); // size_t written = 0; // buffer.OnStreamData(800, string_piece, GetEpollClockNow(), &written); // source = std::string{800, 'b'}; // absl::string_view string_piece1(source.data(), 800); // // Try to write to [1, 801), but should fail due to overlapping, // // res should be QUIC_INVALID_STREAM_DATA // auto res = buffer.OnStreamData(1, string_piece1, &written)); // // write to [0, 800), res should be QUIC_NO_ERROR // auto res = buffer.OnStreamData(0, string_piece1, GetEpollClockNow(), // &written); // // // Read into a iovec array with total capacity of 120 bytes. // char dest[120]; // iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40}, // iovec{dest + 80, 40}}; // size_t read = buffer.Readv(iovecs, 3); // // // Get single readable region. // iovec iov; // buffer.GetReadableRegion(iov); // // // Get readable regions from [256, 1024) and consume some of it. // iovec iovs[2]; // int iov_count = buffer.GetReadableRegions(iovs, 2); // // Consume some bytes in iovs, returning number of bytes having been // consumed. // size_t consumed = consume_iovs(iovs, iov_count); // buffer.MarkConsumed(consumed); #include <cstddef> #include <functional> #include <list> #include <memory> #include <string> #include "absl/strings/string_view.h" #include "quiche/quic/core/quic_interval_set.h" #include "quiche/quic/core/quic_packets.h" #include "quiche/quic/core/quic_types.h" #include "quiche/quic/platform/api/quic_export.h" #include "quiche/common/platform/api/quiche_iovec.h" namespace quic { namespace test { class QuicStreamSequencerBufferPeer; } // namespace test class QUICHE_EXPORT QuicStreamSequencerBuffer { … }; } // namespace quic #endif // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_