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