![]() |
MySQL 9.2.0
Source Code Documentation
|
Owned, non-contiguous, growable memory buffer. More...
#include <managed_buffer_sequence.h>
Public Member Functions | |
Managed_buffer_sequence (const Grow_calculator_t &grow_calculator=Grow_calculator_t(), const Memory_resource_t &memory_resource=Memory_resource_t(), const Size_t default_buffer_count=16) | |
Construct a new, empty object. More... | |
Managed_buffer_sequence (Managed_buffer_sequence &)=delete | |
Managed_buffer_sequence (Managed_buffer_sequence &&)=delete | |
Managed_buffer_sequence & | operator= (Managed_buffer_sequence &)=delete |
Managed_buffer_sequence & | operator= (Managed_buffer_sequence &&)=delete |
~Managed_buffer_sequence () override | |
Grow_status | reserve_write_size (Size_t requested_write_size) |
Ensure the write part has at least the given size. More... | |
Grow_status | reserve_total_size (Size_t requested_total_size) |
Ensure the total capacity - the sum of sizes of read part and write part - is at least the given number. More... | |
void | reset (Size_t keep_buffer_count=1, Size_t keep_container_capacity=16) |
Reset the read part and the write part to size 0. More... | |
const Grow_calculator_t & | get_grow_calculator () const |
Return a const reference to the grow calculator. More... | |
void | set_grow_calculator (const Grow_calculator_t &grow_calculator) |
Set the grow calculator. More... | |
Grow_status | write (const Char_t *data, Size_t size) |
Append the given data. More... | |
std::string | debug_string (bool show_contents, int indent) const override |
In debug mode, return a string that describes the internal structure of this object, to use for debugging. More... | |
std::string | debug_string (bool show_contents=false) const |
In debug mode, return a string that describes the internal structure of this object, to use for debugging. More... | |
![]() | |
Rw_buffer_sequence (Iterator_t begin_arg, Iterator_t end_arg) | |
Construct a new Rw_buffer_sequence from given endpoint iterators, with position 0. More... | |
Rw_buffer_sequence (Rw_buffer_sequence &)=delete | |
Rw_buffer_sequence (Rw_buffer_sequence &&)=delete | |
Rw_buffer_sequence & | operator= (Rw_buffer_sequence &)=delete |
Rw_buffer_sequence & | operator= (Rw_buffer_sequence &&)=delete |
virtual | ~Rw_buffer_sequence ()=default |
void | set_position (Size_t new_position) |
Set the specified absolute position. More... | |
void | increase_position (Size_t delta) |
Move the position right, relative to the current position. More... | |
void | move_position (Difference_t delta) |
Move the position left or right, relative to the current position. More... | |
Size_t | capacity () const |
Return the current size, i.e., total size of all buffers. More... | |
const Buffer_sequence_view_t & | read_part () const |
Return a const reference to the read part. More... | |
Buffer_sequence_view_t & | read_part () |
Return a non-const reference to the read part. More... | |
const Buffer_sequence_view_t & | write_part () const |
Return a const reference to the write part. More... | |
Buffer_sequence_view_t & | write_part () |
Return a non-const reference to the write part. More... | |
std::string | debug_string (bool show_contents=false) const |
In debug mode, return a string that describes the internal structure of this object, to use for debugging. More... | |
Protected Types | |
using | List_t = typename std::list< Buffer_view_t, Buffer_allocator_t > |
using | List_iterator_t = typename List_t::iterator |
using | Vector_t = typename std::vector< Buffer_view_t, Buffer_allocator_t > |
using | Vector_iterator_t = typename Vector_t::iterator |
Protected Member Functions | |
Managed_buffer_sequence (Container_t buffers, const Grow_calculator_t &grow_calculator, const Memory_resource_t &memory_resource) | |
Construct a new object from a given container, where both the read part and the write part are size zero. More... | |
bool | allocate_and_add_buffer (Size_t size) |
Allocate and add a new buffer. More... | |
bool | add_buffer (Char_t *buffer_data, Size_t buffer_size) |
Insert the given buffer in the container, appending it to the write part. More... | |
Static Protected Member Functions | |
static void | reset_container (Vector_t &container, Size_t keep_container_capacity) |
std::vector -specific function to reset the container. More... | |
static void | reset_container (List_t &container, Size_t keep_container_capacity) |
std::list -specific function to reset the container. More... | |
![]() | |
static void | set_position (Size_t new_position, Buffer_sequence_view_t &left, Buffer_sequence_view_t &right) |
Move the position to the given, absolute position. More... | |
static Size_t | merge_if_split (Buffer_sequence_view_t &left, Buffer_sequence_view_t &right) |
If a buffer is split between the read and write parts, glue the pieces together again and include them in the read part. More... | |
static Size_t | move_position_one_buffer_left (Buffer_sequence_view_t &left, Buffer_sequence_view_t &right) |
Move the position exactly one buffer left, assuming no buffer is split. More... | |
static Size_t | move_position_at_most_one_buffer_right (Buffer_sequence_view_t &left, Buffer_sequence_view_t &right, Size_t limit) |
Move the position right by whatever is smaller: the given number, or one buffer; splits the buffer if the number is smaller than the buffer. More... | |
static std::tuple< Iterator_t, Iterator_t, Size_t > | get_boundaries (Buffer_sequence_view_t &buffer_sequence_view) |
Return the beginning, end, and size of the read and write parts. More... | |
Private Attributes | |
Grow_calculator_t | m_grow_calculator |
Determines how much memory to allocate when new memory is needed. More... | |
Char_allocator_t | m_char_allocator |
Allocator to allocate buffer data (characters). More... | |
Container_t | m_buffers |
Container of buffers. More... | |
Friends | |
template<class T > | |
class | managed_buffer_sequence::unittest::Accessor |
Open the class internals to any class named Accessor<T>, for some T. More... | |
Owned, non-contiguous, growable memory buffer.
This class never moves buffer data, but is non-contiguous. It is implemented as a container of Buffer objects.
Objects have a growable size, a movable position, and two buffer_sequence_view objects called the read part and the write part, which are accessible through the member functions read_part
and write_part
. The read part is everything preceding the position, and the write part is everything following the position. API clients acting as producers should write to the write part and then move the position forward as many bytes as it wrote. API clients acting as consumers should read the read part.
Generally, std::ostringstream or std::vector<char> are safer and simpler interfaces for buffers and should be preferred when possible. However they do not fit all use cases:
The main drawbacks of Managed_buffer_sequence are that it is non-standard, has a minimal feature set, and is non-contiguous.
This class never throws any exception.
Char_tp | the type of elements stored in the buffer: typically unsigned char. |
Container_tp | The type of container to hold the buffers. This defaults to std::vector, but std::list is also possible. |
using mysql::containers::buffers::Managed_buffer_sequence< Char_tp, Container_tp >::Buffer_allocator_t = typename Buffer_sequence_view_t::Buffer_allocator_t |
using mysql::containers::buffers::Managed_buffer_sequence< Char_tp, Container_tp >::Buffer_sequence_view_t = Buffer_sequence_view<Char_tp, Container_tp> |
using mysql::containers::buffers::Rw_buffer_sequence< Char_tp, Container_tp >::Buffer_view_t = typename Buffer_sequence_view_t::Buffer_view_t |
using mysql::containers::buffers::Managed_buffer_sequence< Char_tp, Container_tp >::Char_allocator_t = mysql::allocators::Allocator<Char_t> |
using mysql::containers::buffers::Rw_buffer_sequence< Char_tp, Container_tp >::Char_t = typename Buffer_sequence_view_t::Char_t |
using mysql::containers::buffers::Rw_buffer_sequence< Char_tp, Container_tp >::Const_iterator_t = typename Buffer_sequence_view_t::Const_iterator_t |
using mysql::containers::buffers::Rw_buffer_sequence< Char_tp, Container_tp >::Container_t = typename Buffer_sequence_view_t::Container_t |
using mysql::containers::buffers::Managed_buffer_sequence< Char_tp, Container_tp >::Grow_calculator_t = Grow_calculator |
using mysql::containers::buffers::Rw_buffer_sequence< Char_tp, Container_tp >::Iterator_t = typename Buffer_sequence_view_t::Iterator_t |
|
protected |
|
protected |
using mysql::containers::buffers::Managed_buffer_sequence< Char_tp, Container_tp >::Memory_resource_t = mysql::allocators::Memory_resource |
using mysql::containers::buffers::Managed_buffer_sequence< Char_tp, Container_tp >::Rw_buffer_sequence_t = Rw_buffer_sequence<Char_tp, Container_tp> |
using mysql::containers::buffers::Rw_buffer_sequence< Char_tp, Container_tp >::Size_t = typename Buffer_sequence_view_t::Size_t |
|
protected |
|
protected |
|
inlineexplicit |
Construct a new, empty object.
grow_calculator | the policy to determine how much memory to allocate, when new memory is needed |
memory_resource | The memory_resource used to allocate new memory, both for the container and for the buffers. |
default_buffer_count | The initial size of the container. This preallocates the container but not the buffers contained in it. |
|
delete |
|
delete |
|
inlineoverride |
|
inlineprotected |
Construct a new object from a given container, where both the read part and the write part are size zero.
The container will be moved. All elements in the container must be null buffers.
buffers | Container of buffers. This must have at least one element. All elements must be null buffers. |
grow_calculator | determines how much memory to allocate when new memory is needed. |
memory_resource | The memory_resource used to allocate new memory, both for the container and for the buffers. |
|
inlineprotected |
Insert the given buffer in the container, appending it to the write part.
buffer_data | The buffer. |
buffer_size | The buffer size. |
false | Success. |
true | An out of memory error occurred when growing the container. |
|
inlineprotected |
Allocate and add a new buffer.
size | The size of the new buffer that should be allocated. |
true | An out of memory condition occurred, and the function did not produce any side effects. |
false | The operation succeeded, and the object now has at least the requested size. |
|
inlineoverridevirtual |
In debug mode, return a string that describes the internal structure of this object, to use for debugging.
show_contents | If true, includes the buffer contents. Otherwise, just pointers and sizes. |
indent | If 0, put all info on one line. Otherwise, put each field on its own line and indent the given number of two-space levels. |
Reimplemented from mysql::containers::buffers::Rw_buffer_sequence< unsigned char, std::vector >.
|
inline |
In debug mode, return a string that describes the internal structure of this object, to use for debugging.
show_contents | If true, includes the buffer contents. Otherwise, just pointers and sizes. |
|
inline |
Return a const reference to the grow calculator.
|
delete |
|
delete |
|
inline |
Ensure the total capacity - the sum of sizes of read part and write part - is at least the given number.
This may add a new buffer if needed. When the previous size is less than the default size, this may even add two buffers: the default buffer and one more. Therefore, the caller should not assume that all the added size resides within one buffer.
Existing buffer data will not move. The container of buffers may grow, which may move the Buffer objects which hold pointers to the data. Therefore, all iterators are invalidated by this.
requested_total_size | The requested total size of all read and write buffers. |
success | The object now has at least the requested total size. The object may have been resized. |
exceeds_max_size | The existing size or the requested size exceeds either the maximum size. The object is unchanged. |
out_of_memory | The request could only be fulfilled by allocating more memory, but memory allocation failed. The object is unchanged. |
|
inline |
Ensure the write part has at least the given size.
This is only a convenience wrapper around reserve_total_size
.
requested_write_size | The requested size of the write part. |
success | The write part now has at least the requested size. The object may have been resized, following the rules of the Grow_calculator. |
exceeds_max_size | Either size() or read_part.size() + requested_write_size exceeds the max size configured in the Grow_calculator. The object is unchanged. |
out_of_memory | The request could only be fulfilled by allocating more memory, but memory allocation failed. The object is unchanged. |
|
inline |
Reset the read part and the write part to size 0.
This optionally keeps a given number of allocated buffers in the write part, as well as a given amount of container capacity.
keep_buffer_count | The number of existing buffers to keep. Using a nonzero value for this reduces container allocations when this object is reused. If the container has fewer buffers, the existing buffers will be kept and no more will be allocated. If the container has more buffers, the excess buffers will be deallocated. |
keep_container_capacity | The amount of container capacity to keep. Using a small nonzero value for this reduces container allocations when this object is reused. This must be at least the number of kept buffers plus two; otherwise it is modified to that number. If the underlying container type is a vector, it will only shrink if it would reduce the number of elements by half. |
|
inlinestaticprotected |
std::list
-specific function to reset the container.
This shrinks the list to keep_container_capacity
if it is bigger than keep_container_capacity
.
[in,out] | container | Reference to the list to be reset. |
keep_container_capacity | Keep this number of elements in the list, in order to save future allocations of list nodes. |
|
inlinestaticprotected |
std::vector
-specific function to reset the container.
This shrinks the vector to keep_container_capacity if it is bigger than twice keep_container_capacity.
[in,out] | container | Reference to the vector to be reset. |
keep_container_capacity | Keep a number of elements in the vector, to save on future vector resize operations. If the number of elements is at least twice this number, the vector size is reduced to this number. |
|
inline |
Set the grow calculator.
|
inline |
Append the given data.
This will grow the buffer if needed. Then it writes the data to the write part, and moves the position so that the written becomes part of the read part instead of the write part.
data | The data to write |
size | The number of bytes to write. |
success | The buffer already had enough capacity, or could be grown without error. The data has been appended and the position has been advanced size bytes. |
out_of_memory | An out of memory condition occurred when allocating memory for the buffer. This object is unchanged. |
exceeds_max_size | The required size would exceed the maximum specified by the Grow_calculator. This object is unchanged. |
|
friend |
Open the class internals to any class named Accessor<T>, for some T.
This may be used by unit tests that need access to internals.
For example, if unittest SomeTest needs access to member int m
, define the helper class:
|
private |
Container of buffers.
|
private |
Allocator to allocate buffer data (characters).
|
private |
Determines how much memory to allocate when new memory is needed.