MySQL 9.1.0
Source Code Documentation
buffer_sequence_view.h
Go to the documentation of this file.
1/* Copyright (c) 2023, 2024, 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#include "mysql/utils/nodiscard.h" // NODISCARD
45
46#include "mysql/binlog/event/wrapper_functions.h" // BAPI_TRACE
47
48/// @addtogroup GroupLibsMysqlContainers
49/// @{
50
52
53/// Sequence of memory buffers.
54///
55/// This is a minimal class with just a sequence of buffers. It does
56/// not have a read/write position (@see Rw_buffer_sequence). It does
57/// not have methods to grow the buffer sequence (@see
58/// Managed_buffer_sequence).
59///
60/// @tparam Char_tp The type of elements stored in the buffer:
61/// typically unsigned char.
62///
63/// @tparam Container_tp The type of container to hold the buffers.
64/// This defaults to std::vector, but std::list is also possible.
65///
66/// @tparam const_tp If true, use const iterators instead of non-const
67/// iterators to represent the beginning and end of the container.
68template <class Char_tp = unsigned char,
69 template <class Element_tp, class Allocator_tp> class Container_tp =
71 bool const_tp = false>
73 public:
74 using Char_t = Char_tp;
75 using Size_t = std::size_t;
78 using Container_t = Container_tp<Buffer_view_t, Buffer_allocator_t>;
79 using Const_iterator_t = typename Container_t::const_iterator;
80 using Iterator_t =
81 typename std::conditional<const_tp, Const_iterator_t,
82 typename Container_t::iterator>::type;
83
84 private:
85 /// Indicates that @c m_size has not yet been computed.
86 static constexpr Size_t uninitialized_size =
87 std::numeric_limits<Size_t>::max();
88
89 public:
90 /// Construct a Buffer_sequence_view with buffers in the range given by
91 /// the iterators.
92 ///
93 /// This copies only the iterators; the underlying container and the
94 /// buffers contained in the container are not copied.
95 ///
96 /// @param begin_arg Iterator to the first buffer.
97 ///
98 /// @param end_arg Iterator to one-past-the-last buffer.
99 ///
100 /// @param size_arg The total size of all buffers from begin_arg to
101 /// end_arg. This is an optimization only: if the parameter is
102 /// omitted, it will be computed the next time it is needed.
104 Size_t size_arg = uninitialized_size)
105 : m_begin(begin_arg), m_end(end_arg), m_size(size_arg) {}
106
107 // Disallow copy, implement move.
109 Buffer_sequence_view(Buffer_sequence_view &&other) noexcept = default;
112
113 virtual ~Buffer_sequence_view() = default;
114
115 /// Iterator to the first buffer.
117
118 /// Iterator to the last buffer.
119 Iterator_t end() { return m_end; }
120
121 /// Iterator to the first buffer.
122 Const_iterator_t begin() const { return m_begin; }
123
124 /// Iterator to the last buffer.
125 Const_iterator_t end() const { return m_end; }
126
127 /// Const iterator pointing to the first buffer.
128 Const_iterator_t cbegin() const { return m_begin; }
129
130 /// Const iterator pointing to the last buffer.
131 Const_iterator_t cend() const { return m_end; }
132
133 /// Copy all data to the given, contiguous output buffer.
134 ///
135 /// The caller is responsible for providing a buffer of at
136 /// least @c size() bytes.
137 ///
138 /// @param destination The target buffer.
139 template <class Destination_char_t>
140 void copy(Destination_char_t *destination) const {
142 Size_t position = 0;
143 for (const auto &buffer : *this) {
144 std::memcpy(destination + position, buffer.data(), buffer.size());
145 position += buffer.size();
146 }
147 }
148
149 /// Return a copy of all the data in this object, as a `std::string`
150 /// object.
151 template <class Str_char_t = char,
152 class Str_traits_t = std::char_traits<Str_char_t>,
153 class Str_allocator_t = std::allocator<Str_char_t>>
154 std::basic_string<Str_char_t, Str_traits_t, Str_allocator_t> str(
155 const Str_allocator_t &allocator = Str_allocator_t()) {
156 std::basic_string<Str_char_t, Str_traits_t, Str_allocator_t> ret(
157 this->size(), '\0', allocator);
158 copy(ret.data());
159 return ret;
160 }
161
162 /// Return the total size of all buffers.
163 Size_t size() const {
164 if (m_size == uninitialized_size) {
165 Size_t size = 0;
166 for (const auto &buffer : *this) size += buffer.size();
167 m_size = size;
168 }
169 return m_size;
170 }
171
172 /// In debug mode, return a string that describes the internal
173 /// structure of this object, to use for debugging.
174 ///
175 /// @param show_contents If true, includes the buffer contents.
176 /// Otherwise, just pointers and sizes.
177 ///
178 /// @param indent If 0, put all info on one line. Otherwise, put
179 /// each field on its own line and indent the given number of
180 /// two-space levels.
181 ///
182 /// @return String that describes the internal structure of this
183 /// Buffer_sequence_view.
184 std::string debug_string([[maybe_unused]] bool show_contents = false,
185 [[maybe_unused]] int indent = 0) const {
186#ifdef NDEBUG
187 return "";
188#else
190 // whitespace following the comma: newline + indentation, or just space
191 std::string ws;
192 if (indent != 0)
193 ws = std::string("\n") +
194 std::string(static_cast<std::string::size_type>(indent * 2), ' ');
195 else
196 ws = " ";
197 // separator = comma + whitespace
198 std::string sep = "," + ws;
199 // whitespace / separator with one level deeper indentation
200 std::string ws2 = (indent != 0) ? (ws + " ") : ws;
201 std::string sep2 = (indent != 0) ? (sep + " ") : sep;
202 // clang-format off
203 ss << "Buffer_sequence_view(ptr=" << (const void *)this
204 << sep << "size=" << size()
205 << sep << "buffers.ptr=" << (const void *)&*this->begin()
206 << sep << "buffers=[";
207 // clang-format on
208 bool first = true;
209 for (auto &buffer : *this) {
210 if (first) {
211 if (indent != 0) ss << ws2;
212 first = false;
213 } else {
214 ss << sep2;
215 }
216 ss << buffer.debug_string(show_contents);
217 }
218 ss << "])";
219 return ss.str();
220#endif
221 }
222
223 private:
224 /// Iterator to beginning of buffer.
226
227 /// Iterator to end of buffer.
229
230 /// Total size of all buffers, cached.
231 mutable Size_t m_size;
232};
233
234} // namespace mysql::containers::buffers
235
236/// @}
237
238#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:72
Iterator_t begin()
Iterator to the first buffer.
Definition: buffer_sequence_view.h:116
typename std::conditional< const_tp, Const_iterator_t, typename Container_t::iterator >::type Iterator_t
Definition: buffer_sequence_view.h:82
Char_tp Char_t
Definition: buffer_sequence_view.h:74
Iterator_t end()
Iterator to the last buffer.
Definition: buffer_sequence_view.h:119
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:163
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:184
Const_iterator_t end() const
Iterator to the last buffer.
Definition: buffer_sequence_view.h:125
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:103
Container_tp< Buffer_view_t, Buffer_allocator_t > Container_t
Definition: buffer_sequence_view.h:78
static constexpr Size_t uninitialized_size
Indicates that m_size has not yet been computed.
Definition: buffer_sequence_view.h:86
Iterator_t m_begin
Iterator to beginning of buffer.
Definition: buffer_sequence_view.h:225
std::size_t Size_t
Definition: buffer_sequence_view.h:75
typename Container_t::const_iterator Const_iterator_t
Definition: buffer_sequence_view.h:79
void copy(Destination_char_t *destination) const
Copy all data to the given, contiguous output buffer.
Definition: buffer_sequence_view.h:140
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:228
Const_iterator_t cend() const
Const iterator pointing to the last buffer.
Definition: buffer_sequence_view.h:131
Size_t m_size
Total size of all buffers, cached.
Definition: buffer_sequence_view.h:231
Const_iterator_t begin() const
Iterator to the first buffer.
Definition: buffer_sequence_view.h:122
Const_iterator_t cbegin() const
Const iterator pointing to the first buffer.
Definition: buffer_sequence_view.h:128
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:154
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.
Definition: buffer_sequence_view.h:51
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