MySQL 8.0.37
Source Code Documentation
grow_constraint.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/// @addtogroup Replication
25/// @{
26/// @file grow_constraint.h
27
28#ifndef MYSQL_BUFFER_GROW_CONSTRAINT_H_
29#define MYSQL_BUFFER_GROW_CONSTRAINT_H_
30
31#include "libbinlogevents/include/nodiscard.h" // NODISCARD
32
33#include <algorithm> // std::min
34#include <limits> // std::numeric_limits
35#include <string> // std::string
36#ifndef NDEBUG
37#include <sstream> // std::stringstream
38#endif
39
40namespace mysqlns::buffer {
41
42/// Description of a heuristic to determine how much memory to allocate.
43///
44/// This may be used in diverse contexts such as growing a memory
45/// buffer, or growing a pool of objects.
46///
47/// This encapsulates several common heuristics for growth:
48///
49/// - The growth rate can be exponential. This is useful for cases
50/// such as contiguous memory buffers, where each size increment may
51/// copy all the existing data, e.g., using 'realloc'. Or, more
52/// generally, any data structure where size growth has a cost that
53/// is linear in the total size. In such cases an exponential
54/// growth rate ensures that execution time is not quadratic in the
55/// number of grow operations.
56///
57/// - The growth rate can be linear. This is useful for cases such as
58/// linked lists, where each size increment is linear in the
59/// increment size.
60///
61/// - There can be an upper bound on the size. This is useful
62/// e.g. when there are configurable memory limits.
63///
64/// - The size can be specified to be a multiple of a given number.
65/// This can potentially be useful if there is a way to align
66/// allocated objects to page sizes, or similar.
68 public:
69 using Size_t = std::size_t;
70 /// Return type for compute_new_size.
71 using Result_t = std::pair<bool, Size_t>;
72 /// Maximum allowed value for the application max size.
73 static constexpr Size_t machine_max_size = std::numeric_limits<Size_t>::max();
74
75 Grow_constraint() = default;
76 Grow_constraint(const Grow_constraint &other) = default;
77 Grow_constraint(Grow_constraint &&other) = default;
78 Grow_constraint &operator=(const Grow_constraint &other) = default;
80 virtual ~Grow_constraint() = default;
81
82 /// Set the maximum size.
83 ///
84 /// Whenever more than this is requested, the response should be to
85 /// fail. This is an inclusive upper bound, so requests for exactly
86 /// this size are allowed.
87 void set_max_size(Size_t max_size);
88
89 /// @return the maximum size.
90 Size_t get_max_size() const;
91
92 /// Set the grow factor.
93 ///
94 /// Whenever the size needs to increase, it should increase it by at
95 /// least this factor.
96 ///
97 /// Using a value > 1 ensures that successive calls to reserve()
98 /// with sizes increasing up to N take amortized linear time in N; a
99 /// value equal to 1 may result in execution time that is quadratic
100 /// in N.
101 void set_grow_factor(double grow_factor);
102
103 /// @return the grow factor.
104 double get_grow_factor() const;
105
106 /// Set the grow increment.
107 ///
108 /// Whenever the size needs to increase, it should increase by
109 /// at least this amount.
110 void set_grow_increment(Size_t grow_increment);
111
112 /// @return the grow increment.
114
115 /// Set the block size.
116 ///
117 /// The size should be kept to a multiple of this number.
118 void set_block_size(Size_t block_size);
119
120 /// @return the block size.
121 Size_t get_block_size() const;
122
123 /// In debug mode, return a string that describes the internal
124 /// structure of this object, to use for debugging.
125 std::string debug_string() const {
126#ifdef NDEBUG
127 return "";
128#else
130 // clang-format off
131 ss << "Grow_constraint(ptr=" << (const void *)this
132 << ", max_size=" << m_max_size
133 << ", grow_factor=" << m_grow_factor
134 << ", grow_increment=" << m_grow_increment
135 << ", block_size=" << m_block_size
136 << ")";
137 // clang-format on
138 return ss.str();
139#endif
140 }
141
142 /// Combine the constraints of this object with another
143 /// Grow_constraint or Grow_calculator object.
144 ///
145 /// This will return a new object of the same type as the argument.
146 /// The returned object will have the smallest max_size among `this`
147 /// and `other`, and the largest `grow_factor`, `grow_increment`, and
148 /// `block_size`.
149 template <class T>
150 [[NODISCARD]] T combine_with(const T &other) const {
151 T ret;
152 ret.set_max_size(std::min(get_max_size(), other.get_max_size()));
153 ret.set_grow_factor(std::max(get_grow_factor(), other.get_grow_factor()));
154 ret.set_grow_increment(
155 std::max(get_grow_increment(), other.get_grow_increment()));
156 ret.set_block_size(std::max(get_block_size(), other.get_block_size()));
157 return ret;
158 }
159
160 private:
161 /// Size must not exceed this number.
163
164 /// By default, don't constrain the grow factor.
165 static constexpr double default_grow_factor = 1.0;
166
167 /// By default, don't constrain the grow increment.
168 static constexpr Size_t default_grow_increment = 0;
169
170 /// By default, don't constrain the block size.
171 static constexpr Size_t default_block_size = 1;
172
173 // Size should grow by at least this factor.
175
176 // Size should grow by at least this number of bytes.
178
179 // Size should be rounded up to a multiple of at least this number of bytes.
181};
182
183} // namespace mysqlns::buffer
184
185/// @} (end of group Replication)
186
187#endif /* MYSQL_BUFFER_GROW_CONSTRAINT_H_ */
Description of a heuristic to determine how much memory to allocate.
Definition: grow_constraint.h:67
Grow_constraint(const Grow_constraint &other)=default
Size_t get_max_size() const
Definition: grow_constraint.cpp:32
static constexpr double default_grow_factor
By default, don't constrain the grow factor.
Definition: grow_constraint.h:165
static constexpr Size_t machine_max_size
Maximum allowed value for the application max size.
Definition: grow_constraint.h:73
Grow_constraint(Grow_constraint &&other)=default
virtual ~Grow_constraint()=default
void set_grow_increment(Size_t grow_increment)
Set the grow increment.
Definition: grow_constraint.cpp:43
void set_grow_factor(double grow_factor)
Set the grow factor.
Definition: grow_constraint.cpp:36
Size_t get_block_size() const
Definition: grow_constraint.cpp:56
double m_grow_factor
Definition: grow_constraint.h:174
Size_t get_grow_increment() const
Definition: grow_constraint.cpp:48
Size_t m_block_size
Definition: grow_constraint.h:180
std::size_t Size_t
Definition: grow_constraint.h:69
T combine_with(const T &other) const
Combine the constraints of this object with another Grow_constraint or Grow_calculator object.
Definition: grow_constraint.h:150
void set_max_size(Size_t max_size)
Set the maximum size.
Definition: grow_constraint.cpp:30
static constexpr Size_t default_grow_increment
By default, don't constrain the grow increment.
Definition: grow_constraint.h:168
Grow_constraint & operator=(Grow_constraint &&other)=default
double get_grow_factor() const
Definition: grow_constraint.cpp:41
static constexpr Size_t default_block_size
By default, don't constrain the block size.
Definition: grow_constraint.h:171
Size_t m_max_size
Size must not exceed this number.
Definition: grow_constraint.h:162
std::string debug_string() const
In debug mode, return a string that describes the internal structure of this object,...
Definition: grow_constraint.h:125
Grow_constraint & operator=(const Grow_constraint &other)=default
Size_t m_grow_increment
Definition: grow_constraint.h:177
void set_block_size(Size_t block_size)
Set the block size.
Definition: grow_constraint.cpp:52
std::pair< bool, Size_t > Result_t
Return type for compute_new_size.
Definition: grow_constraint.h:71
Definition: buffer_sequence_view.h:51
std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut::allocator.
Definition: ut0new.h:2870
#define NODISCARD
The function attribute [[NODISCARD]] is a replacement for [[nodiscard]] to workaround a gcc bug.
Definition: nodiscard.h:47