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:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user