MySQL 9.1.0
Source Code Documentation
grow_calculator.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#ifndef MYSQL_CONTAINERS_BUFFERS_GROW_CALCULATOR_H
27#define MYSQL_CONTAINERS_BUFFERS_GROW_CALCULATOR_H
28
29#include "mysql/containers/buffers/grow_constraint.h" // Grow_constraint
30
31#include <algorithm> // std::min
32#include <limits> // std::numeric_limits
33#include <string> // std::string
34#ifdef NDEBUG
35#include <sstream> // std::stringstream
36#endif
37
38/// @addtogroup GroupLibsMysqlContainers
39/// @{
40
42
43/// Description of a heuristic to determine how much memory to allocate.
44///
45/// This may be used in diverse contexts such as growing a memory
46/// buffer, or growing a pool of objects.
47///
48/// This encapsulates several common heuristics for growth:
49///
50/// - The growth rate can be exponential. This is useful for cases
51/// such as contiguous memory buffers, where each size increment may
52/// copy all the existing data, e.g., using 'realloc'. Or, more
53/// generally, any data structure where size growth has a cost that
54/// is linear in the total size. In such cases an exponential
55/// growth rate ensures that execution time is not quadratic in the
56/// number of grow operations.
57///
58/// - The growth rate can be linear. This is useful for cases such as
59/// linked lists, where each size increment is linear in the
60/// increment size.
61///
62/// - There can be an upper bound on the size. This is useful
63/// e.g. when there are configurable memory limits.
64///
65/// - The size can be specified to be a multiple of a given number.
66/// This can potentially be useful if there is a way to align
67/// allocated objects to page sizes, or similar.
69 public:
71 /// Return type for compute_new_size.
73 /// By default, limit memory to 1 GiB.
74 static constexpr Size_t default_max_size =
75 Size_t(1024) * Size_t(1024) * Size_t(1024);
76 /// By default, double the size in each allocation.
77 static constexpr double default_grow_factor = 2.0;
78 /// By default, allocate at least 1 KiB more in each call.
79 static constexpr Size_t default_grow_increment = 1024;
80 /// By default, allocate multiples of 1 KiB.
81 static constexpr Size_t default_block_size = 1024;
82
84
85 /// Compute the new size.
86 ///
87 /// This follows the following rules:
88 ///
89 /// - It returns exceeds_max_size if the requested size, or the
90 /// existing size, exceeds the configured max size.
91 ///
92 /// - It never shrinks. If the request is smaller than the existing
93 /// size, it just returns the existing size.
94 ///
95 /// - It multiplies the old size by the grow_factor, and if needed
96 /// increments the size further until it has grown by the
97 /// grow_increment, and then rounds up to the nearest multiple of
98 /// the block_size. If the result of these operations exceeds the
99 /// max size, the result is reduced to the max size.
100 ///
101 /// @param old_size The existing size.
102 ///
103 /// @param requested_size The total size needed.
104 ///
105 /// @retval A pair. The first component is `bool` and contains the
106 /// error status: `false` means success, i.e., the requested size
107 /// does not exceed the maximum size. It also counts as success if
108 /// the request is less than the existing size, or if the request is
109 /// zero. `true` means error, i.e., the requested size exceeds the
110 /// maximum size. The second component is the new size. If the
111 /// first component is `true` for error, the second component is
112 /// zero.
113 ///
114 /// @retval other value The new size.
115 Result_t compute_new_size(Size_t old_size, Size_t requested_size) const;
116};
117
118} // namespace mysql::containers::buffers
119
120/// @}
121
122#endif /* MYSQL_CONTAINERS_BUFFERS_GROW_CALCULATOR_H */
Description of a heuristic to determine how much memory to allocate.
Definition: grow_calculator.h:68
std::size_t Size_t
Definition: grow_constraint.h:68
static constexpr Size_t default_block_size
By default, allocate multiples of 1 KiB.
Definition: grow_calculator.h:81
static constexpr Size_t default_max_size
By default, limit memory to 1 GiB.
Definition: grow_calculator.h:74
Grow_calculator()
Definition: grow_calculator.cpp:32
static constexpr double default_grow_factor
By default, double the size in each allocation.
Definition: grow_calculator.h:77
Result_t compute_new_size(Size_t old_size, Size_t requested_size) const
Compute the new size.
Definition: grow_calculator.cpp:39
static constexpr Size_t default_grow_increment
By default, allocate at least 1 KiB more in each call.
Definition: grow_calculator.h:79
Description of a heuristic to determine how much memory to allocate.
Definition: grow_constraint.h:66
std::size_t Size_t
Definition: grow_constraint.h:68
std::pair< bool, Size_t > Result_t
Return type for compute_new_size.
Definition: grow_constraint.h:70
Definition: buffer_sequence_view.h:51