2
0
mirror of https://github.com/boostorg/mysql.git synced 2026-02-15 13:12:21 +00:00

New read_buffer

This commit is contained in:
Ruben Perez
2022-07-18 18:18:48 +02:00
parent cd6b0dc65f
commit 17567dec89

View File

@@ -25,64 +25,54 @@ namespace detail {
// - Dead area: these bytes have already been consumed, but won't disappear until a call to relocate().
// Optimized the case where we read several entire messages in a single read_some() call, preventing
// several memcpy()'s.
// - Reserved area: we already processed these bytes, but the client component hasn't consumed them yet.
// - Processing area: we have read these bytes but haven't processed them yet.
// - Processing area: we have read these bytes and the client hasn't consumed them yet.
// - Free area: free space for more bytes to be read.
class read_buffer
{
bytestring buffer_;
std::size_t reserved_offset_;
std::size_t processing_offset_;
std::size_t free_offset_;
public:
read_buffer(std::size_t size):
buffer_(size, std::uint8_t(0)),
reserved_offset_(0),
processing_offset_(0),
free_offset_(0)
{
buffer_.resize(buffer_.capacity());
}
std::uint8_t* reserved_first() noexcept { return &buffer_[reserved_offset_]; }
std::uint8_t* processing_first() noexcept { return &buffer_[processing_offset_]; }
std::uint8_t* free_first() noexcept { return &buffer_[free_offset_]; }
std::size_t reserved_size() const noexcept { return processing_offset_ - reserved_offset_; }
std::size_t dead_size() const noexcept { return processing_offset_; }
std::size_t processing_size() const noexcept { return free_offset_ - processing_offset_; }
std::size_t free_size() const noexcept { return buffer_.size() - free_offset_; }
boost::asio::mutable_buffer reserved_area() noexcept { return boost::asio::buffer(reserved_first(), reserved_size()); }
boost::asio::mutable_buffer free_area() noexcept { return boost::asio::buffer(free_first(), free_size()); }
// Removes n bytes from the reserved area
void remove_from_reserved(std::size_t n) noexcept
// Removes length bytes from the processing area, at a certain offset
void remove_from_processing(std::size_t offset, std::size_t length) noexcept
{
assert(n <= reserved_size());
reserved_offset_ += n;
}
// Removes n bytes from the read area, without touching the reserved area
void remove_from_processing_front(std::size_t n) noexcept
{
assert(n <= processing_size());
if (reserved_size())
assert(offset >= processing_offset_);
assert(length <= processing_size());
if (offset == 0) // remove from front, just extend the dead area
{
// Move the reserved bytes to the front
std::memmove(reserved_first() + n, reserved_first(), n);
processing_offset_ += length;
}
reserved_offset_ += n;
processing_offset_ += n;
else
{
// Move remaining bytes backwards
std::memmove(
&buffer_[processing_offset_ + offset],
&buffer_[processing_offset_ + offset + length],
processing_size() - length
);
free_offset_ -= length;
}
}
// Moves n bytes from the processing area to the reserved area
void move_to_reserved(std::size_t n) noexcept
{
assert(n <= processing_size());
processing_offset_ += n;
}
// Moves n bytes from the free area to the processing area
// Moves n bytes from the free to the processing area (e.g. they've been read)
void move_to_processing(std::size_t n) noexcept
{
assert(n <= free_size());
@@ -92,12 +82,25 @@ public:
// Removes the dead area, to make space
void relocate() noexcept
{
if (reserved_offset_ > 0)
if (dead_size() > 0)
{
std::memmove(&buffer_[0], reserved_first(), free_offset_ - reserved_offset_);
processing_offset_ -= reserved_offset_;
free_offset_ -= reserved_offset_;
reserved_offset_ = 0;
std::memmove(&buffer_[0], processing_first(), processing_size());
free_offset_ -= dead_size();
processing_offset_ = 0;
}
}
// Makes sure the free size is at least n bytes long; resizes the buffer if required
void grow_to_fit(std::size_t n)
{
if (free_size() < n)
{
relocate();
}
if (free_size() < n)
{
buffer_.resize(free_size() - n);
buffer_.resize(buffer_.capacity());
}
}