MySQL 9.4.0
Source Code Documentation
buffer_sequence_view.h
Go to the documentation of this file.
1/* Copyright (c) 2023, 2025, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24/// @file
25///
26/// Container class that provides a sequence of buffers to the caller.
27/// This is intended for capturing the output from compressors.
28
29#ifndef MYSQL_CONTAINERS_BUFFERS_BUFFER_SEQUENCE_VIEW_H
30#define MYSQL_CONTAINERS_BUFFERS_BUFFER_SEQUENCE_VIEW_H
31
32#include <algorithm> // std::min
33#include <cassert> // assert
34#include <cstring> // std::memcpy
35#include <limits> // std::numeric_limits
36#include <memory> // std::allocator
37#include <type_traits> // std::conditional
38#include <vector> // std::vector
39#include "mysql/allocators/allocator.h" // mysql::allocators::Allocator
40
41#include "mysql/containers/buffers/buffer_view.h" // Buffer_view
42#include "mysql/containers/buffers/grow_calculator.h" // Grow_calculator
43#include "mysql/containers/buffers/grow_status.h" // Grow_status
44
45#include "mysql/binlog/event/wrapper_functions.h" // BAPI_TRACE
46
47/// @addtogroup GroupLibsMysqlContainers
48/// @{
49
51
52/// Sequence of memory buffers.
53///
54/// This is a minimal class with just a sequence of buffers. It does
55/// not have a read/write position (@see Rw_buffer_sequence). It does
56/// not have methods to grow the buffer sequence (@see
57/// Managed_buffer_sequence).
58///
59/// @tparam Char_tp The type of elements stored in the buffer:
60/// typically unsigned char.
61///
62/// @tparam Container_tp The type of container to hold the buffers.
63/// This defaults to std::vector, but std::list is also possible.
64///
65/// @tparam const_tp If true, use const iterators instead of non-const
66/// iterators to represent the beginning and end of the container.
67template <class Char_tp = unsigned char,
68 template <class Element_tp, class Allocator_tp> class Container_tp =
70 bool const_tp = false>
72 public:
73 using Char_t = Char_tp;
74 using Size_t = std::size_t;
77 using Container_t = Container_tp<Buffer_view_t, Buffer_allocator_t>;
78 using Const_iterator_t = typename Container_t::const_iterator;
79 using Iterator_t =
80 typename std::conditional<const_tp, Const_iterator_t,
81 typename Container_t::iterator>::type;
82
83 private:
84 /// Indicates that @c m_size has not yet been computed.
85 static constexpr Size_t uninitialized_size =
87
88 public:
89 /// Construct a Buffer_sequence_view with buffers in the range given by
90 /// the iterators.
91 ///
92 /// This copies only the iterators; the underlying container and the
93 /// buffers contained in the container are not copied.
94 ///
95 /// @param begin_arg Iterator to the first buffer.
96 ///
97 /// @param end_arg Iterator to one-past-the-last buffer.
98 ///
99 /// @param size_arg The total size of all buffers from begin_arg to
100 /// end_arg. This is an optimization only: if the parameter is
101 /// omitted, it will be computed the next time it is needed.
103 Size_t size_arg = uninitialized_size)
104 : m_begin(begin_arg), m_end(end_arg), m_size(size_arg) {}
105
106 // Disallow copy, implement move.
108 Buffer_sequence_view(Buffer_sequence_view &&other) noexcept = default;
111
112 virtual ~Buffer_sequence_view() = default;
113
114 /// Iterator to the first buffer.
116
117 /// Iterator to the last buffer.
118 Iterator_t end() { return m_end; }
119
120 /// Iterator to the first buffer.
121 Const_iterator_t begin() const { return m_begin; }
122
123 /// Iterator to the last buffer.
124 Const_iterator_t end() const { return m_end; }
125
126 /// Const iterator pointing to the first buffer.
127 Const_iterator_t cbegin() const { return m_begin; }
128
129 /// Const iterator pointing to the last buffer.
130 Const_iterator_t cend() const { return m_end; }
131
132 /// Copy all data to the given, contiguous output buffer.
133 ///
134 /// The caller is responsible for providing a buffer of at
135 /// least @c size() bytes.
136 ///
137 /// @param destination The target buffer.
138 template <class Destination_char_t>
139 void copy(Destination_char_t *destination) const {
141 Size_t position = 0;
142 for (const auto &buffer : *this) {
143 std::memcpy(destination + position, buffer.data(), buffer.size());
144 position += buffer.size();
145 }
146 }
147
148 /// Return a copy of all the data in this object, as a `std::string`
149 /// object.
150 template <class Str_char_t = char,
151 class Str_traits_t = std::char_traits<Str_char_t>,
152 class Str_allocator_t = std::allocator<Str_char_t>>
153 std::basic_string<Str_char_t, Str_traits_t, Str_allocator_t> str(
154 const Str_allocator_t &allocator = Str_allocator_t()) {
155 std::basic_string<Str_char_t, Str_traits_t, Str_allocator_t> ret(
156 this->size(), '\0', allocator);
157 copy(ret.data());
158 return ret;
159 }
160
161 /// Return the total size of all buffers.
162 Size_t size() const {
163 if (m_size == uninitialized_size) {
164 Size_t size = 0;
165 for (const auto &buffer : *this) size += buffer.size();
166 m_size = size;
167 }
168 return m_size;
169 }
170
171 /// In debug mode, return a string that describes the internal
172 /// structure of this object, to use for debugging.
173 ///
174 /// @param show_contents If true, includes the buffer contents.
175 /// Otherwise, just pointers and sizes.
176 ///
177 /// @param indent If 0, put all info on one line. Otherwise, put
178 /// each field on its own line and indent the given number of
179 /// two-space levels.
180 ///
181 /// @return String that describes the internal structure of this
182 /// Buffer_sequence_view.
183 std::string debug_string([[maybe_unused]] bool show_contents = false,
184 [[maybe_unused]] int indent = 0) const {
185#ifdef NDEBUG
186 return "";
187#else
189 // whitespace following the comma: newline + indentation, or just space
190 std::string ws;
191 if (indent != 0)
192 ws = std::string("\n") +
193 std::string(static_cast<std::string::size_type>(indent * 2), ' ');
194 else
195 ws = " ";
196 // separator = comma + whitespace
197 std::string sep = "," + ws;
198 // whitespace / separator with one level deeper indentation
199 std::string ws2 = (indent != 0) ? (ws + " ") : ws;
200 std::string sep2 = (indent != 0) ? (sep + " ") : sep;
201 // clang-format off
202 ss << "Buffer_sequence_view(ptr=" << (const void *)this
203 << sep << "size=" << size()
204 << sep << "buffers.ptr=" << (const void *)&*this->begin()
205 << sep << "buffers=[";
206 // clang-format on
207 bool first = true;
208 for (auto &buffer : *this) {
209 if (first) {
210 if (indent != 0) ss << ws2;
211 first = false;
212 } else {
213 ss << sep2;
214 }
215 ss << buffer.debug_string(show_contents);
216 }
217 ss << "])";
218 return ss.str();
219#endif
220 }
221
222 private:
223 /// Iterator to beginning of buffer.
225
226 /// Iterator to end of buffer.
228
229 /// Total size of all buffers, cached.
230 mutable Size_t m_size;
231};
232
233} // namespace mysql::containers::buffers
234
235/// @}
236
237#endif // MYSQL_CONTAINERS_BUFFERS_BUFFER_SEQUENCE_VIEW_H
Class that groups a pointer+size as one object, without managing the memory for it.
Allocator using a Memory_resource to do the allocator.
Definition: allocator.h:54
Sequence of memory buffers.
Definition: buffer_sequence_view.h:71
Iterator_t begin()
Iterator to the first buffer.
Definition: buffer_sequence_view.h:115
typename std::conditional< const_tp, Const_iterator_t, typename Container_t::iterator >::type Iterator_t
Definition: buffer_sequence_view.h:81
Char_tp Char_t
Definition: buffer_sequence_view.h:73
Iterator_t end()
Iterator to the last buffer.
Definition: buffer_sequence_view.h:118
Buffer_sequence_view(Buffer_sequence_view &)=delete
Buffer_sequence_view(Buffer_sequence_view &&other) noexcept=default
Size_t size() const
Return the total size of all buffers.
Definition: buffer_sequence_view.h:162
std::string debug_string(bool show_contents=false, int indent=0) const
In debug mode, return a string that describes the internal structure of this object,...
Definition: buffer_sequence_view.h:183
Const_iterator_t end() const
Iterator to the last buffer.
Definition: buffer_sequence_view.h:124
Buffer_sequence_view(Iterator_t begin_arg, Iterator_t end_arg, Size_t size_arg=uninitialized_size)
Construct a Buffer_sequence_view with buffers in the range given by the iterators.
Definition: buffer_sequence_view.h:102
Container_tp< Buffer_view_t, Buffer_allocator_t > Container_t
Definition: buffer_sequence_view.h:77
static constexpr Size_t uninitialized_size
Indicates that m_size has not yet been computed.
Definition: buffer_sequence_view.h:85
Iterator_t m_begin
Iterator to beginning of buffer.
Definition: buffer_sequence_view.h:224
std::size_t Size_t
Definition: buffer_sequence_view.h:74
typename Container_t::const_iterator Const_iterator_t
Definition: buffer_sequence_view.h:78
void copy(Destination_char_t *destination) const
Copy all data to the given, contiguous output buffer.
Definition: buffer_sequence_view.h:139
Buffer_sequence_view & operator=(Buffer_sequence_view &&) noexcept=default
Buffer_sequence_view & operator=(Buffer_sequence_view &)=delete
Iterator_t m_end
Iterator to end of buffer.
Definition: buffer_sequence_view.h:227
Const_iterator_t cend() const
Const iterator pointing to the last buffer.
Definition: buffer_sequence_view.h:130
Size_t m_size
Total size of all buffers, cached.
Definition: buffer_sequence_view.h:230
Const_iterator_t begin() const
Iterator to the first buffer.
Definition: buffer_sequence_view.h:121
Const_iterator_t cbegin() const
Const iterator pointing to the first buffer.
Definition: buffer_sequence_view.h:127
std::basic_string< Str_char_t, Str_traits_t, Str_allocator_t > str(const Str_allocator_t &allocator=Str_allocator_t())
Return a copy of all the data in this object, as a std::string object.
Definition: buffer_sequence_view.h:153
void * data() const noexcept
Definition: buffer.h:119
size_t size() const noexcept
Definition: buffer.h:120
Allocator class that uses a polymorphic Memory_resource to allocate memory.
ValueType max(X &&first)
Definition: gtid.h:103
Definition: buffer_sequence_view.h:50
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut::allocator.
Definition: ut0new.h:2872
std::vector< T, ut::allocator< T > > vector
Specialization of vector which uses allocator.
Definition: ut0new.h:2876
required string type
Definition: replication_group_member_actions.proto:34
static task_arg end_arg()
Definition: task.h:207
Contains wrapper functions for memory allocation and deallocation.
#define BAPI_TRACE
Definition: wrapper_functions.h:65