MySQL 9.1.0
Source Code Documentation
mysql::containers::buffers::Managed_buffer< Char_tp > Class Template Reference

Owned, growable, contiguous memory buffer. More...

#include <managed_buffer.h>

Inheritance diagram for mysql::containers::buffers::Managed_buffer< Char_tp >:
[legend]

Public Types

using Char_t = Char_tp
 
using Buffer_view_t = Buffer_view< Char_t >
 
using Rw_buffer_t = Rw_buffer< Char_t >
 
using Memory_resource_t = mysql::allocators::Memory_resource
 
using Char_allocator_t = mysql::allocators::Allocator< Char_t >
 
using Grow_calculator_t = Grow_calculator
 
using Const_iterator_t = const Char_t *
 
using Iterator_t = Char_t *
 
using Size_t = std::size_t
 
- Public Types inherited from mysql::containers::buffers::Rw_buffer< unsigned char >
using Char_t = unsigned char
 
using Size_t = std::size_t
 
using Difference_t = std::ptrdiff_t
 
using Iterator_t = Char_t *
 
using Const_iterator_t = const Char_t *
 
using Buffer_view_t = mysql::containers::buffers::Buffer_view< Char_t >
 

Public Member Functions

 Managed_buffer (const Memory_resource_t &memory_resource=Memory_resource_t())
 Construct a new object without a default buffer. More...
 
 Managed_buffer (Size_t default_capacity, const Memory_resource_t &memory_resource=Memory_resource_t())
 Construct a new object that owns a default buffer. More...
 
 Managed_buffer (Buffer_view_t default_buffer, const Memory_resource_t &memory_resource=Memory_resource_t())
 Construct a new object that uses the given default buffer. More...
 
 Managed_buffer (Managed_buffer &other)=delete
 
 Managed_buffer (Managed_buffer &&other) noexcept=default
 
Managed_bufferoperator= (Managed_buffer &other)=delete
 
Managed_bufferoperator= (Managed_buffer &&other) noexcept=default
 
 ~Managed_buffer () override
 
Grow_status reserve_total_size (Size_t requested_size)
 Reserve space so that the total buffer size is at least the given number. More...
 
Grow_status reserve_write_size (Size_t requested_write_size)
 Reserve space so that the write size is at least the given number. More...
 
void reset ()
 Reset the buffer. More...
 
void set_grow_calculator (const Grow_calculator_t &grow_calculator)
 Set the grow calculator. More...
 
const Grow_calculator_tget_grow_calculator () const
 Return a const reference to the grow calculator. More...
 
Size_t get_default_capacity ()
 Return the size of the default buffer. More...
 
- Public Member Functions inherited from mysql::containers::buffers::Rw_buffer< unsigned char >
 Rw_buffer ()=default
 
 Rw_buffer (Buffer_view_t buffer)
 Create a new Rw_buffer from the specified size and buffer. More...
 
 Rw_buffer (Rw_buffer &)=delete
 Deleted copy constructor. More...
 
 Rw_buffer (Rw_buffer &&) noexcept=default
 Default move constructor. More...
 
Rw_bufferoperator= (Rw_buffer &)=delete
 Deleted copy assignment operator. More...
 
Rw_bufferoperator= (Rw_buffer &&) noexcept=default
 Default move assignment operator. More...
 
virtual ~Rw_buffer ()=default
 Default delete operator. More...
 
const Buffer_view_tread_part () const
 Return the read part. More...
 
Buffer_view_tread_part ()
 Return the read part. More...
 
const Buffer_view_twrite_part () const
 Return the write part. More...
 
Buffer_view_twrite_part ()
 Return the write part. More...
 
Size_t capacity () const
 Return the total size of the read part and the write part. More...
 
void set_position (Size_t new_position)
 Set the position to a fixed number. More...
 
void increase_position (Size_t increment)
 Increase the position right, relative to the currrent position. More...
 
void move_position (Difference_t delta)
 Move the position left or right, relative to the current position. More...
 

Private Member Functions

Char_tallocate_buffer (Size_t new_size)
 Allocate a new buffer and return it. More...
 
void replace_buffer (Char_t *new_buffer, Size_t new_size)
 Replace the underlying data buffer by the given one. More...
 

Private Attributes

Grow_calculator_t m_grow_calculator
 Calculator for growing the buffer. More...
 
Char_allocator_t m_char_allocator
 Allocator to grow the buffer. More...
 
Char_tm_default_buffer
 User-provided, user-owned buffer. More...
 
Size_t m_default_capacity
 Size of user-provided, user-owned buffer. More...
 
bool m_owns_default_buffer
 If true, the default buffer will be deallocated by the destructor. More...
 

Additional Inherited Members

- Protected Attributes inherited from mysql::containers::buffers::Rw_buffer< unsigned char >
Buffer_view_t m_read_part
 
Buffer_view_t m_write_part
 

Detailed Description

template<class Char_tp = unsigned char>
class mysql::containers::buffers::Managed_buffer< Char_tp >

Owned, growable, contiguous memory buffer.

This class provides a single contiguous buffer. Therefore, it may have to move data when it grows. It is implemented as a Buffer that is resized using realloc.

The caller can provide a user-defined, pre-allocated buffer, which will then be used as long as it suffices; a new buffer will be allocated if not. This can be used to remove the need for allocation in use cases where the object is small.

Objects have a growable total capacity, which is split into two parts; the read part and the write part, each represented as a Buffer_view. The intended use case is where the user interacts with an API that produces data into a user-provided buffer. The user can then: (1) grow the buffer before invoking the API; (2) invoke the API to write data to the write part; (3) tell the Managed_buffer to move the written bytes to the read part.

Generally, std::stringstream 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:

  • std::stringstream is preferrable and more convenient when appending existing data to the stream. But it is not suitable for interaction with C-like APIs that produce data in a char* given by the caller. The user would need to allocate a buffer outside the stringsteam and then append the buffer to the stringstream, which would imply unnecessary memory and cpu overheads.
  • When using a C-like API that produces data in a char* given by the caller, std::vector is often good. The user can reserve as much memory as needed and then pass the underlying data array to the API. However, the following properties are sometimes advantageous for Managed_buffer:
    • Vector has no practical way to put an exact bound on the memory usage. Managed_buffer uses a Grow_calculator which allows exact control on memory usage, including a maximum capacity.
    • Even for small buffer sizes, vector needs at least one heap allocation. Managed_buffer allows the use of a default buffer of fixed size, for example allocated on the stack. This can reduce the need for heap allocation in use patterns where the required buffer capacity is usually small.

The main drawback of Managed_buffer is that it is non-standard and has a minimal feature set.

The main difference between Buffer_sequence and Managed_buffer, is that Managed_buffer keeps data in a contiguous buffer, whereas Buffer_sequence never copies data.

This class never throws any exception.

Template Parameters
Char_tpThe char type; usually char or unsigned char.

Member Typedef Documentation

◆ Buffer_view_t

template<class Char_tp = unsigned char>
using mysql::containers::buffers::Managed_buffer< Char_tp >::Buffer_view_t = Buffer_view<Char_t>

◆ Char_allocator_t

template<class Char_tp = unsigned char>
using mysql::containers::buffers::Managed_buffer< Char_tp >::Char_allocator_t = mysql::allocators::Allocator<Char_t>

◆ Char_t

template<class Char_tp = unsigned char>
using mysql::containers::buffers::Managed_buffer< Char_tp >::Char_t = Char_tp

◆ Const_iterator_t

template<class Char_tp = unsigned char>
using mysql::containers::buffers::Rw_buffer< Char_tp >::Const_iterator_t = const Char_t *

◆ Grow_calculator_t

template<class Char_tp = unsigned char>
using mysql::containers::buffers::Managed_buffer< Char_tp >::Grow_calculator_t = Grow_calculator

◆ Iterator_t

template<class Char_tp = unsigned char>
using mysql::containers::buffers::Rw_buffer< Char_tp >::Iterator_t = Char_t *

◆ Memory_resource_t

template<class Char_tp = unsigned char>
using mysql::containers::buffers::Managed_buffer< Char_tp >::Memory_resource_t = mysql::allocators::Memory_resource

◆ Rw_buffer_t

template<class Char_tp = unsigned char>
using mysql::containers::buffers::Managed_buffer< Char_tp >::Rw_buffer_t = Rw_buffer<Char_t>

◆ Size_t

template<class Char_tp = unsigned char>
using mysql::containers::buffers::Rw_buffer< Char_tp >::Size_t = std::size_t

Constructor & Destructor Documentation

◆ Managed_buffer() [1/5]

template<class Char_tp = unsigned char>
mysql::containers::buffers::Managed_buffer< Char_tp >::Managed_buffer ( const Memory_resource_t memory_resource = Memory_resource_t())
inlineexplicit

Construct a new object without a default buffer.

◆ Managed_buffer() [2/5]

template<class Char_tp = unsigned char>
mysql::containers::buffers::Managed_buffer< Char_tp >::Managed_buffer ( Size_t  default_capacity,
const Memory_resource_t memory_resource = Memory_resource_t() 
)
inlineexplicit

Construct a new object that owns a default buffer.

The default buffer is created when needed. Once created, it survives calls to reset and will only be deleted when the Managed_buffer is deleted.

Parameters
default_capacityThe capacity of the default buffer.
memory_resourceMemory_resource used to allocate memory.

◆ Managed_buffer() [3/5]

template<class Char_tp = unsigned char>
mysql::containers::buffers::Managed_buffer< Char_tp >::Managed_buffer ( Buffer_view_t  default_buffer,
const Memory_resource_t memory_resource = Memory_resource_t() 
)
inlineexplicit

Construct a new object that uses the given default buffer.

The default buffer is owned by the caller, so the caller must ensure that it outlives the Managed_buffer.

Parameters
default_bufferThe default buffer.
memory_resourceMemory_resource used to allocate memory.

◆ Managed_buffer() [4/5]

template<class Char_tp = unsigned char>
mysql::containers::buffers::Managed_buffer< Char_tp >::Managed_buffer ( Managed_buffer< Char_tp > &  other)
delete

◆ Managed_buffer() [5/5]

template<class Char_tp = unsigned char>
mysql::containers::buffers::Managed_buffer< Char_tp >::Managed_buffer ( Managed_buffer< Char_tp > &&  other)
defaultnoexcept

◆ ~Managed_buffer()

template<class Char_tp = unsigned char>
mysql::containers::buffers::Managed_buffer< Char_tp >::~Managed_buffer ( )
inlineoverride

Member Function Documentation

◆ allocate_buffer()

template<class Char_tp = unsigned char>
Char_t * mysql::containers::buffers::Managed_buffer< Char_tp >::allocate_buffer ( Size_t  new_size)
inlineprivate

Allocate a new buffer and return it.

This never throws; it returns nullptr on out of memory.

Parameters
new_sizeThe size of the buffer.
Returns
the new buffer on success, nullptr on out of memory.

◆ get_default_capacity()

template<class Char_tp = unsigned char>
Size_t mysql::containers::buffers::Managed_buffer< Char_tp >::get_default_capacity ( )
inline

Return the size of the default buffer.

◆ get_grow_calculator()

template<class Char_tp = unsigned char>
const Grow_calculator_t & mysql::containers::buffers::Managed_buffer< Char_tp >::get_grow_calculator ( ) const
inline

Return a const reference to the grow calculator.

◆ operator=() [1/2]

template<class Char_tp = unsigned char>
Managed_buffer & mysql::containers::buffers::Managed_buffer< Char_tp >::operator= ( Managed_buffer< Char_tp > &&  other)
defaultnoexcept

◆ operator=() [2/2]

template<class Char_tp = unsigned char>
Managed_buffer & mysql::containers::buffers::Managed_buffer< Char_tp >::operator= ( Managed_buffer< Char_tp > &  other)
delete

◆ replace_buffer()

template<class Char_tp = unsigned char>
void mysql::containers::buffers::Managed_buffer< Char_tp >::replace_buffer ( Char_t new_buffer,
Size_t  new_size 
)
inlineprivate

Replace the underlying data buffer by the given one.

Parameters
new_bufferThe new buffer. This must be different from the old buffer.
new_sizeThe size of the new buffer.

◆ reserve_total_size()

template<class Char_tp = unsigned char>
Grow_status mysql::containers::buffers::Managed_buffer< Char_tp >::reserve_total_size ( Size_t  requested_size)
inline

Reserve space so that the total buffer size is at least the given number.

The buffer will be resized if necessary. So, on successful return, the caller should call begin() to get the new buffer pointer.

Note
This may move existing data to a new address; consider any existing pointers into the buffer as invalid after this call.
Parameters
requested_sizeThe requested total size of the read part and the write part.
Return values
Grow_status::successThe object now has at least the given size; either it was successfully re-allocated, or it already had the requested size.
Grow_status::exceeds_max_sizeif requested_size exceeds the configured maximum size.
Grow_status::out_of_memoryMemory allocation failed.

◆ reserve_write_size()

template<class Char_tp = unsigned char>
Grow_status mysql::containers::buffers::Managed_buffer< Char_tp >::reserve_write_size ( Size_t  requested_write_size)
inline

Reserve space so that the write size is at least the given number.

Parameters
requested_write_sizeThe requested size of the write part.
Return values
Grow_status::successThe write part now has at least the given size; either it was successfully re-allocated, or it already had the requested size.
Grow_status::exceeds_max_sizeif the existing read size plus requested_write_size exceeds the max size configured in the Grow_calculator.
Grow_status::out_of_memoryMemory allocation failed.

◆ reset()

template<class Char_tp = unsigned char>
void mysql::containers::buffers::Managed_buffer< Char_tp >::reset ( )
inline

Reset the buffer.

This makes the read part empty. The write part will point to the default buffer if there is one; otherwise the write part will be empty.

◆ set_grow_calculator()

template<class Char_tp = unsigned char>
void mysql::containers::buffers::Managed_buffer< Char_tp >::set_grow_calculator ( const Grow_calculator_t grow_calculator)
inline

Set the grow calculator.

Details:

  • If the new Grow_calculator's maximum size is less than the current buffer size, it does not change the existing buffer, but subsequent calls to reserve will fail.
  • In case the new Grow_calculator's maximum size is less than the default capacity, this object will provide capacity equal to the default_size, exceeding the Grow_calculator's maximum size.

Member Data Documentation

◆ m_char_allocator

template<class Char_tp = unsigned char>
Char_allocator_t mysql::containers::buffers::Managed_buffer< Char_tp >::m_char_allocator
private

Allocator to grow the buffer.

◆ m_default_buffer

template<class Char_tp = unsigned char>
Char_t* mysql::containers::buffers::Managed_buffer< Char_tp >::m_default_buffer
private

User-provided, user-owned buffer.

◆ m_default_capacity

template<class Char_tp = unsigned char>
Size_t mysql::containers::buffers::Managed_buffer< Char_tp >::m_default_capacity
private

Size of user-provided, user-owned buffer.

◆ m_grow_calculator

template<class Char_tp = unsigned char>
Grow_calculator_t mysql::containers::buffers::Managed_buffer< Char_tp >::m_grow_calculator
private

Calculator for growing the buffer.

◆ m_owns_default_buffer

template<class Char_tp = unsigned char>
bool mysql::containers::buffers::Managed_buffer< Char_tp >::m_owns_default_buffer
private

If true, the default buffer will be deallocated by the destructor.


The documentation for this class was generated from the following file: