MySQL 9.6.0
Source Code Documentation
allocator.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/// @brief Allocator class that uses a polymorphic Memory_resource to
27/// allocate memory.
28
29#ifndef MYSQL_ALLOCATORS_ALLOCATOR_H
30#define MYSQL_ALLOCATORS_ALLOCATOR_H
31
32#include <cassert> // assert
33#include <limits> // std::numeric_limits
34#include "mysql/allocators/memory_resource.h" // Memory_resource
35
36/// @addtogroup GroupLibsMysqlAllocators
37/// @{
38
40
41/// @brief Allocator using a Memory_resource to do the allocation.
42///
43/// A library that allocates memory should allow the user to pass a
44/// Memory_resource object which defaults to a default-constructed instance,
45/// Memory_resource(). Internally it should create the Allocator<T> classes it
46/// needs (possibly several, for different classes T), using the given
47/// Memory_resource object. Users of the library *outside* the server should
48/// just use the default Memory_resource. Users of the library *inside* the
49/// server should setup a PSI key and pass the result from
50/// @c psi_memory_resource(Key) to the library.
51template <class T>
52class Allocator {
53 public:
54 using value_type = T;
55 using size_type = std::size_t;
56 using difference_type = std::ptrdiff_t;
57
58 /// On move-assignment for containers using this allocator, make the target
59 /// container inherit the allocator and reuse the memory from the source
60 /// container.
62
63 /// On copy-assignment for containers using this allocator, make the target
64 /// container preserve its existing allocator and reuse its own memory if
65 /// possible.
67
68 /// Construct a new Allocator using the given Memory_resource.
69 ///
70 /// @param memory_resource The memory resource. By default, this
71 /// uses a default-constructed Memory_resource, so it uses
72 /// std::malloc and std::free for allocations.
73 explicit Allocator(
74 Memory_resource memory_resource = Memory_resource()) noexcept
75 : m_memory_resource(std::move(memory_resource)) {}
76
77 /// Implicit conversion from other instance.
78 ///
79 /// This is required to exist and be implicit by the Windows implementation of
80 /// @c std::vector.
81 template <class U>
82 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
83 constexpr Allocator(const Allocator<U> &other) noexcept
84 : m_memory_resource(other.get_memory_resource()) {}
85
86 // Declare all copy/move as noexcept, and copy the Memory_resource on moves.
87 //
88 // Allocators are required to not change when being moved-from
89 // (https://timsong-cpp.github.io/cppwp/allocator.requirements.general#67).
90 // The default move constructor would violate that by moving from the
91 // std::function members of Memory_resource. Therefore, we override and copy
92 // Memory_resource instead.
93 //
94 // It is also required that both move/copy do not throw. The copy operator for
95 // `std::function` may throw `bad_alloc`. Therefore we declare the functions
96 // as `noexcept`, so that it will instead call `std::terminate` on
97 // out-of-memory conditions. This is a reasonable action in such cases (and in
98 // practice may never occur, because of the small buffer optimization for
99 // std::function).
100 constexpr Allocator(const Allocator &other) noexcept = default;
101 constexpr Allocator &operator=(const Allocator &other) noexcept = default;
102 constexpr Allocator(Allocator &&other) noexcept
103 // Copy in move constructor is intentional (see above).
104 // NOLINTNEXTLINE(cert-oop11-cpp,performance-move-constructor-init)
105 : m_memory_resource(other.m_memory_resource) {}
106 constexpr Allocator &operator=(Allocator &&other) noexcept {
107 m_memory_resource = other.m_memory_resource;
108 return *this;
109 }
110 ~Allocator() noexcept = default;
111
112 /// Use the Memory_resource to allocate the given number of elements
113 /// of type T.
114 ///
115 /// @param n The number of elements.
116 ///
117 /// @return The new pointer.
118 ///
119 /// @throws std::bad_alloc on out of memory conditions.
120 [[nodiscard]] constexpr T *allocate(size_type n) {
121 T *p = static_cast<T *>(m_memory_resource.allocate(n * sizeof(value_type)));
122 if (p == nullptr) throw std::bad_alloc();
123 return p;
124 }
125
126 /// Use the Memory_resource to deallocate the given pointer.
127 ///
128 /// @param p The pointer to deallocate.
129 ///
130 /// @param size Unused.
131 constexpr void deallocate(T *p, [[maybe_unused]] size_type size) {
133 }
134
135 /// Return a Deleter function for objects allocated by this class.
136 ///
137 /// Such a Deleter must be specified when constructing a smart
138 /// pointer to an object created by this Allocator, for example:
139 ///
140 /// @code
141 /// Allocator<T> allocator(some_memory_resource);
142 /// T *obj = allocator.allocate(1);
143 /// std::shared_ptr<T> ptr(obj, allocator.get_deleter());
144 /// @endcode
145 ///
146 /// @retval Deleter function that takes a `T*` as argument and
147 /// uses the Memory_resource to deallocate it.
148 [[nodiscard]] std::function<void(T *)> get_deleter() {
149 auto deallocator = m_memory_resource.get_deallocator();
150 // Capture by value so we get a self-contained object that may
151 // outlive this Allocator and the Memory_resource if needed.
152 return [=](T *p) {
153 p->~T();
154 deallocator(p);
155 };
156 }
157
158 /// Return a reference to the underlying Memory_resource object.
159 [[nodiscard]] const Memory_resource &get_memory_resource() const {
160 return m_memory_resource;
161 }
162
163 private:
164 /// The underlying Memory_resource object.
166}; // class Allocator
167
168/// Compare two Allocator objects for equality.
169template <class T>
170[[nodiscard]] bool operator==([[maybe_unused]] const Allocator<T> &a1,
171 [[maybe_unused]] const Allocator<T> &a2) {
172 return true;
173}
174
175/// Compare two Allocator objects for inequality.
176template <class T>
177[[nodiscard]] bool operator!=([[maybe_unused]] const Allocator<T> &a1,
178 [[maybe_unused]] const Allocator<T> &a2) {
179 return true;
180}
181
182} // namespace mysql::allocators
183
184/// @}
185
186#endif // MYSQL_ALLOCATORS_ALLOCATOR_H
Allocator using a Memory_resource to do the allocation.
Definition: allocator.h:52
constexpr Allocator & operator=(Allocator &&other) noexcept
Definition: allocator.h:106
std::false_type propagate_on_container_copy_assignment
On copy-assignment for containers using this allocator, make the target container preserve its existi...
Definition: allocator.h:66
std::true_type propagate_on_container_move_assignment
On move-assignment for containers using this allocator, make the target container inherit the allocat...
Definition: allocator.h:61
constexpr void deallocate(T *p, size_type size)
Use the Memory_resource to deallocate the given pointer.
Definition: allocator.h:131
T value_type
Definition: allocator.h:54
std::function< void(T *)> get_deleter()
Return a Deleter function for objects allocated by this class.
Definition: allocator.h:148
const Memory_resource & get_memory_resource() const
Return a reference to the underlying Memory_resource object.
Definition: allocator.h:159
constexpr Allocator & operator=(const Allocator &other) noexcept=default
constexpr Allocator(Allocator &&other) noexcept
Definition: allocator.h:102
std::ptrdiff_t difference_type
Definition: allocator.h:56
std::size_t size_type
Definition: allocator.h:55
~Allocator() noexcept=default
Allocator(Memory_resource memory_resource=Memory_resource()) noexcept
Construct a new Allocator using the given Memory_resource.
Definition: allocator.h:73
constexpr Allocator(const Allocator &other) noexcept=default
Memory_resource m_memory_resource
The underlying Memory_resource object.
Definition: allocator.h:165
constexpr T * allocate(size_type n)
Use the Memory_resource to allocate the given number of elements of type T.
Definition: allocator.h:120
constexpr Allocator(const Allocator< U > &other) noexcept
Implicit conversion from other instance.
Definition: allocator.h:83
Polymorphism-free memory resource class with custom allocator and deallocator functions.
Definition: memory_resource.h:88
void * allocate(Size_t n) const
Allocate memory using the provided allocator.
Definition: memory_resource.h:113
void deallocate(Ptr_t p) const
Deallocate memory using the provided deallocator.
Definition: memory_resource.h:118
Deallocator_t get_deallocator() const
Return the deallocator.
Definition: memory_resource.h:121
const char * p
Definition: ctype-mb.cc:1227
#define T
Definition: jit_executor_value.cc:373
Class that wraps resources in a polymorphic manner.
Definition: allocator.h:39
bool operator!=(const Allocator< T > &a1, const Allocator< T > &a2)
Compare two Allocator objects for inequality.
Definition: allocator.h:177
bool operator==(const Allocator< T > &a1, const Allocator< T > &a2)
Compare two Allocator objects for equality.
Definition: allocator.h:170
noexcept
The return type for any call_and_catch(f, args...) call where f(args...) returns Type.
Definition: call_and_catch.h:76
size_t size(const char *const c)
Definition: base64.h:46
Define std::hash<Gtid>.
Definition: gtid.h:355
int n
Definition: xcom_base.cc:509