MySQL 9.4.0
Source Code Documentation
allocator.h
Go to the documentation of this file.
1/* Copyright (c) 2016, 2025, Oracle and/or its affiliates.
2
3This program is free software; you can redistribute it and/or modify it under
4the terms of the GNU General Public License, version 2.0, as published by the
5Free Software Foundation.
6
7This program is designed to work with certain software (including
8but not limited to OpenSSL) that is licensed under separate terms,
9as designated in a particular file or component or in included license
10documentation. The authors of MySQL hereby grant you an additional
11permission to link the program and your derivative works with the
12separately licensed software that they have either included with
13the program or referenced in the documentation.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
18for more details.
19
20You should have received a copy of the GNU General Public License along with
21this program; if not, write to the Free Software Foundation, Inc.,
2251 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24/** @file storage/temptable/include/temptable/allocator.h
25TempTable custom allocator. */
26
27#ifndef TEMPTABLE_ALLOCATOR_H
28#define TEMPTABLE_ALLOCATOR_H
29
30#include <algorithm> // std::max
31#include <atomic> // std::atomic
32#include <cstddef> // size_t
33#include <limits> // std::numeric_limits
34#include <memory> // std::shared_ptr
35#include <new> // new
36#include <utility> // std::forward
37
38#include "my_dbug.h"
39#include "my_sys.h"
40#include "sql/current_thd.h" // current_thd
41#include "sql/mysqld.h" // temptable_max_ram, temptable_max_mmap
42#include "sql/sql_class.h" // current_thd
47
48namespace temptable {
49extern std::atomic_uint64_t count_hit_max_ram;
50
51/* Thin abstraction which enables logging of memory operations.
52 *
53 * Used by the Allocator to implement switching from RAM to MMAP-backed
54 * allocations and vice-versa. E.g. Allocator will switch to MMAP-backed
55 * allocation strategy once temptable RAM-consumption threshold, which is
56 * defined by temptable_max_ram user-modifiable variable, is reached.
57 **/
59 struct RAM {
60 /** Log increments of heap-memory consumption.
61 *
62 * [in] Number of bytes.
63 * @return Heap-memory consumption after increase. */
64 static size_t increase(size_t bytes) {
65 assert(ram <= std::numeric_limits<decltype(bytes)>::max() - bytes);
66 return ram.fetch_add(bytes) + bytes;
67 }
68 /** Log decrements of heap-memory consumption.
69 *
70 * [in] Number of bytes.
71 * @return Heap-memory consumption after decrease. */
72 static size_t decrease(size_t bytes) {
73 assert(ram >= bytes);
74 return ram.fetch_sub(bytes) - bytes;
75 }
76 /** Get heap-memory threshold level. Level is defined by this Allocator.
77 *
78 * @return Heap-memory threshold. */
79 static size_t threshold() { return temptable_max_ram; }
80 /** Get current level of heap-memory consumption.
81 *
82 * @return Current level of heap-memory consumption (in bytes). */
83 static size_t consumption() { return ram; }
84 };
85
86 struct MMAP {
87 /** Log increments of MMAP-backed memory consumption.
88 *
89 * [in] Number of bytes.
90 * @return MMAP-memory consumption after increase. */
91 static size_t increase(size_t bytes) {
92 assert(mmap <= std::numeric_limits<decltype(bytes)>::max() - bytes);
93 return mmap.fetch_add(bytes) + bytes;
94 }
95 /** Log decrements of MMAP-backed memory consumption.
96 *
97 * [in] Number of bytes.
98 * @return MMAP-memory consumption after decrease. */
99 static size_t decrease(size_t bytes) {
100 assert(mmap >= bytes);
101 return mmap.fetch_sub(bytes) - bytes;
102 }
103 /** Get MMAP-backed memory threshold level. Level is defined by this
104 * Allocator.
105 *
106 * @return MMAP-memory threshold. */
107 static size_t threshold() { return temptable_max_mmap; }
108 /** Get current level of MMAP-backed memory consumption.
109 *
110 * @return Current level of MMAP-backed memory consumption (in bytes). */
111 static size_t consumption() { return mmap; }
112 };
113
114 private:
115 /** Total bytes allocated so far by all threads in RAM/MMAP. */
116 static std::atomic<size_t> ram;
117 static std::atomic<size_t> mmap;
118};
119
120/* Thin abstraction which enables logging of how much resources have been
121 * consumed at the per-table level. Each temptable::Table will be composed
122 * of this type so that the temptable::Allocator through its policies can
123 * monitor its memory consumption and act appropriately when threshold
124 * is reached.
125 **/
127 public:
130
131 size_t increase(size_t bytes) {
132 assert(m_total_bytes <=
133 std::numeric_limits<decltype(bytes)>::max() - bytes);
134 m_total_bytes += bytes;
135 return m_total_bytes;
136 }
137 size_t decrease(size_t bytes) {
138 assert(m_total_bytes >= bytes);
139 m_total_bytes -= bytes;
140 return m_total_bytes;
141 }
142 size_t threshold() { return m_threshold; }
143 size_t consumption() { return m_total_bytes; }
144
145 private:
148};
149
150/* Allocation scheme, a type which controls allocation patterns in TempTable
151 * allocator.
152 *
153 * In particular, allocation scheme can define the behavior of TempTable
154 * allocator allocations with respect to the following:
155 * 1. Where each consecutive Block of memory is going to be allocated from
156 * (e.g. RAM vs MMAP vs etc.)
157 * 2. How big each consecutive Block of memory is going to be
158 * (e.g. monotonic growth, exponential growth, no growth, etc.)
159 *
160 * Concrete implementations of previous points must be provided through
161 * customization points, namely Block_size_policy and Block_source_policy,
162 * template type parameters. Whatever these types are, they must provide
163 * conforming interface implementations.
164 *
165 * Block_size_policy customization point must provide concrete implementation
166 * with the following signature:
167 * static size_t block_size(size_t, size_t);
168 * Similarly, concrete implementations of Block_source_policy must provide:
169 * static Source block_source(size_t);
170 *
171 * That allows us to build different concrete allocation schemes by simply
172 * composing different customization points. For example:
173 *
174 * using Monotonic_growth_RAM_only =
175 * Allocation_scheme<Monotonic_policy, RAM_only_policy>;
176 *
177 * using Exponential_growth_RAM_only =
178 * Allocation_scheme<Exponential_policy, RAM_only_policy>;
179 *
180 * using Exponential_growth_preferring_RAM_over_MMAP =
181 * Allocation_scheme<Exponential_policy, Prefer_RAM_over_MMAP_policy>;
182 *
183 * using No_growth_RAM_only =
184 * Allocation_scheme<No_growth_policy, RAM_only_policy>;
185 *
186 * etc. etc.
187 *
188 */
189template <typename Block_size_policy, typename Block_source_policy>
192 return Block_source_policy::block_source(block_size);
193 }
194 static size_t block_size(size_t number_of_blocks, size_t n_bytes_requested) {
195 return Block_size_policy::block_size(number_of_blocks, n_bytes_requested);
196 }
197 static void block_freed(uint32_t block_size, Source block_source) {
198 Block_source_policy::block_freed(block_size, block_source);
199 }
200};
201
202/* Concrete implementation of Block_source_policy, a type which controls where
203 * TempTable allocator is going to be allocating next Block of memory from.
204 *
205 * In particular, this policy will make TempTable allocator:
206 * 1. Use RAM as long as temptable_max_ram threshold is not reached.
207 * 2. Start using MMAP when temptable_max_ram threshold is reached.
208 * 3. Go back using RAM as soon as RAM consumption drops below the
209 * temptable_max_ram threshold and there is enough space to accommodate the
210 * new block given the size.
211 * 4. Not take into account per-table memory limits defined through
212 * tmp_table_size SYSVAR.
213 * */
215 static Source block_source(uint32_t block_size) {
217 if (MemoryMonitor::RAM::increase(block_size) <=
219 return Source::RAM;
220 } else {
222 }
223 }
224
225 /* Track through the global status variable,
226 * if table exceeded the specified memory limit
227 */
229
231 if (MemoryMonitor::MMAP::increase(block_size) <=
233 return Source::MMAP_FILE;
234 } else {
236 }
237 }
239 }
240
241 static void block_freed(uint32_t block_size, Source block_source) {
242 if (block_source == Source::RAM) {
244 } else {
246 }
247 }
248};
249
250/* Concrete implementation of Block_size_policy, a type which controls how big
251 * next Block of memory is going to be allocated by TempTable allocator.
252 *
253 * In particular, this policy will make TempTable allocator to grow the
254 * block-size at exponential rate with upper limit of ALLOCATOR_MAX_BLOCK_BYTES,
255 * which is 2 ^ ALLOCATOR_MAX_BLOCK_MB_EXP.
256 *
257 * E.g. allocation pattern may look like the following:
258 * 1 MiB,
259 * 2 MiB,
260 * 4 MiB,
261 * 8 MiB,
262 * 16 MiB,
263 * 32 MiB,
264 * ...,
265 * ALLOCATOR_MAX_BLOCK_BYTES,
266 * ALLOCATOR_MAX_BLOCK_BYTES
267 *
268 * In cases when block size that is being requested is bigger than the one which
269 * is calculated by this policy, requested block size will be returned (even if
270 * it grows beyond ALLOCATOR_MAX_BLOCK_BYTES).
271 * */
273 /** Given the current number of allocated blocks by the allocator, and number
274 * of bytes actually requested by the client code, calculate the new block
275 * size.
276 *
277 * [in] Current number of allocated blocks.
278 * [in] Number of bytes requested by the client code.
279 * @return New block size. */
280 static size_t block_size(size_t number_of_blocks, size_t n_bytes_requested) {
281 size_t block_size_hint;
282 if (number_of_blocks < ALLOCATOR_MAX_BLOCK_MB_EXP) {
283 block_size_hint = (1ULL << number_of_blocks) * 1_MiB;
284 } else {
285 block_size_hint = ALLOCATOR_MAX_BLOCK_BYTES;
286 }
287 return std::max(block_size_hint, Block::size_hint(n_bytes_requested));
288 }
289};
290
291/* This is a concrete allocation scheme which is going to be default one for
292 * TempTable allocator.
293 *
294 * It uses exponential growth policy and policy which prefers RAM allocations
295 * over MMAP allocations.
296 */
299
300/**
301 Shared state between all instances of a given allocator.
302
303 STL allocators can (since C++11) carry state; however, that state should
304 never be mutable, as the allocator can be copy-constructed and rebound
305 without further notice, so e.g. deallocating memory in one allocator could
306 mean freeing a block that an earlier copy of the allocator still thinks is
307 valid.
308
309 Usually, mutable state will be external to the allocator (e.g.
310 Mem_root_allocator will point to a MEM_ROOT, but it won't own the MEM_ROOT);
311 however, TempTable was never written this way, and doesn't have a natural
312 place to stick the allocator state. Thus, we need a kludge where the
313 allocator's state is held in a shared_ptr, owned by all the instances
314 together. This is suboptimal for performance, and also is against the style
315 guide's recommendation to have clear ownership of objects, but at least it
316 avoids the use-after-free.
317 */
318template <class AllocationScheme>
320 public:
321 /**
322 * Destroys the state, deallocate the current_block if it was left empty.
323 */
324 ~AllocatorState() noexcept {
325 if (!current_block.is_empty()) {
327 }
328 /* User must deallocate all data from all blocks, otherwise the memory will
329 * be leaked.
330 */
331 assert(number_of_blocks == 0);
332 }
333
334 /**
335 * Gets a Block from which a new allocation of the specified size should be
336 * performed. It will use the current Block or create a new one if it is too
337 * small.
338 * [in] Number of bytes that will be allocated from the returned block.
339 */
340 Block *get_block_for_new_allocation(size_t n_bytes_requested) {
341 if (current_block.is_empty() ||
342 !current_block.can_accommodate(n_bytes_requested)) {
343 /* The current_block may have been left empty during some deallocate()
344 * call. It is the last opportunity to free it before we lose reference to
345 * it.
346 */
347 if (!current_block.is_empty() &&
350 }
351
352 const size_t block_size =
353 AllocationScheme::block_size(number_of_blocks, n_bytes_requested);
355 Block(block_size, AllocationScheme::block_source(block_size));
357 }
358 return &current_block;
359 }
360
361 /**
362 * Informs the state object of a block that has no data allocated inside of it
363 * anymore for garbage collection.
364 * [in] The empty block to manage and possibly free.
365 */
366 void block_is_not_used_anymore(Block block) noexcept {
367 if (block == current_block) {
368 /* Do nothing. Keep the last block alive. Some queries are repeatedly
369 * allocating one Row and freeing it, leading to constant allocation and
370 * deallocation of 1MB of memory for the current_block. Let's keep this
371 * block empty ready for a future use.
372 */
373 } else {
374 free_block(block);
375 }
376 }
377
378 private:
379 /**
380 * Frees the specified block and takes care of all accounting.
381 * [in] The empty block to free.
382 */
383 void free_block(Block &block) noexcept {
384 AllocationScheme::block_freed(block.size(), block.type());
385 block.destroy();
387 }
388
389 /** Current not-yet-full block to feed allocations from. */
391
392 /**
393 * Number of created blocks so far (by this Allocator object).
394 * We use this number only as a hint as to how big block to create when a
395 * new block needs to be created.
396 */
398};
399
400/** Custom memory allocator. All dynamic memory used by the TempTable engine
401 * is allocated through this allocator.
402 *
403 * The purpose of this allocator is to minimize the number of calls to the OS
404 * for allocating new memory (e.g. malloc()) and to improve the spatial
405 * locality of reference. It is able to do so quite easily thanks to the
406 * Block/Chunk entities it is implemented in terms of. Due to the design of
407 * these entities, it is also able to feed allocations and deallocations in
408 * (amortized) constant-time and keep being CPU memory-access friendly because
409 * of the internal self-adjustment to word-size memory alignment. To learn even
410 * more about specifics and more properties please have a look at the respective
411 * header files of Header/Block/Chunk class declarations.
412 *
413 * The most common use case, for which it is optimized,
414 * is to have the following performed by a single thread:
415 * - allocate many times (creation of a temp table and inserting data into it).
416 * - use the allocated memory (selects on the temp table).
417 * - free all the pieces (drop of the temp table).
418 *
419 * The allocator allocates memory from the OS in large blocks (e.g. a few MiB)
420 * whose size also increases progressively by the increasing number of
421 * allocation requests. Exact block-size increase progress is defined by the
422 * block allocation scheme which, by default, is set to
423 * AllocationScheme::Exponential.
424 *
425 * Allocator does not store a list of all allocated blocks but only keeps track
426 * of the current block which has not yet been entirely filled up and the
427 * overall number of allocated blocks. When current block gets filled up, new
428 * one is created and immediately made current.
429 *
430 * Furthermore, it always keeps the last block alive. It cannot be deallocated
431 * by the user. Last block is automatically deallocated at the thread exit.
432 *
433 * Allocator will also keep track of RAM-consumption and in case it reaches the
434 * threshold defined by temptable_max_ram, it will switch to MMAP-backed block
435 * allocations. It will switch back once RAM consumption is again below the
436 * threshold. */
437template <class T,
438 class AllocationScheme = Exponential_growth_preferring_RAM_over_MMAP>
440 static_assert(alignof(T) <= Block::ALIGN_TO,
441 "T's with alignment-requirement larger than "
442 "Block::ALIGN_TO are not supported.");
443 static_assert(sizeof(T) > 0, "Zero sized objects are not supported");
444
445 public:
446 typedef T *pointer;
447 typedef const T *const_pointer;
448 typedef T &reference;
449 typedef const T &const_reference;
450 typedef T value_type;
451 typedef size_t size_type;
452 typedef ptrdiff_t difference_type;
453
454 template <class U>
455 struct rebind {
457 };
458
459 /** Constructor. */
460 Allocator(Block *shared_block, TableResourceMonitor &table_resource_monitor);
461
462 /** Constructor from allocator of another type. The state is copied into the
463 * new object. */
464 template <class U>
465 Allocator(
466 /** [in] Source Allocator object. */
467 const Allocator<U> &other);
468
469 /** Move constructor from allocator of another type. */
470 template <class U>
471 Allocator(
472 /** [in,out] Source Allocator object. */
473 Allocator<U> &&other) noexcept;
474
475 /** Destructor. */
477
478 Allocator(const Allocator &) = default;
479
480 /** Assignment operator, not used, thus disabled. */
481 template <class U>
482 void operator=(const Allocator<U> &) = delete;
483
484 /** Move operator, not used, thus disabled. */
485 template <class U>
486 void operator=(const Allocator<U> &&) = delete;
487
488 /** Equality operator.
489 * @return true if equal */
490 template <class U>
491 bool operator==(
492 /** [in] Object to compare with. */
493 const Allocator<U> &rhs) const;
494
495 /** Inequality operator.
496 * @return true if not equal */
497 template <class U>
498 bool operator!=(
499 /** [in] Object to compare with. */
500 const Allocator<U> &rhs) const;
501
502 /** Allocate memory for storing `n_elements` number of elements. */
503 T *allocate(
504 /** [in] Number of elements that must be allocated. */
505 size_t n_elements);
506
507 /** Free a memory allocated by allocate(). */
508 void deallocate(
509 /** [in,out] Pointer to memory to free. */
510 T *ptr,
511 /** [in] Number of elements allocated. */
512 size_t n_elements);
513
514 /** Construct one object of type `U` on an already allocated chunk of memory,
515 * which must be large enough to store it. */
516 template <class U, class... Args>
517 void construct(
518 /** [in] Memory where to create the object. */
519 U *mem,
520 /** Arguments to pass to U's constructor. */
521 Args &&...args);
522
523 /** Destroy an object of type `U`. The memory is not returned to the OS, this
524 * is the counterpart of `construct()`. */
525 template <class U>
526 void destroy(
527 /** [in, out] Object to destroy. */
528 U *p);
529
530 /** Initialize necessary structures. Called once in the OS process lifetime,
531 * before other methods. */
532 static void init();
533
534 /**
535 Shared state between all the copies and rebinds of this allocator.
536 See AllocatorState for details.
537 */
538 std::shared_ptr<AllocatorState<AllocationScheme>> m_state;
539
540 /** A block of memory which is a state external to this allocator and can be
541 * shared among different instances of the allocator (not simultaneously). In
542 * order to speed up its operations, allocator may decide to consume the
543 * memory of this shared block.
544 */
546 /** Table resource monitor control mechanism that limits the amount of
547 * resources that can be consumed at the per-table level.
548 */
550};
551
552/* Implementation of inlined methods. */
553
554template <class T, class AllocationScheme>
556 Block *shared_block, TableResourceMonitor &table_resource_monitor)
557 : m_state(std::make_shared<AllocatorState<AllocationScheme>>()),
558 m_shared_block(shared_block),
559 m_table_resource_monitor(table_resource_monitor) {}
560
561template <class T, class AllocationScheme>
562template <class U>
564 : m_state(other.m_state),
565 m_shared_block(other.m_shared_block),
566 m_table_resource_monitor(other.m_table_resource_monitor) {}
567
568template <class T, class AllocationScheme>
569template <class U>
571 : m_state(std::move(other.m_state)),
572 m_shared_block(other.m_shared_block),
573 m_table_resource_monitor(other.m_table_resource_monitor) {}
574
575template <class T, class AllocationScheme>
577
578template <class T, class AllocationScheme>
579template <class U>
581 const Allocator<U> &) const {
582 return true;
583}
584
585template <class T, class AllocationScheme>
586template <class U>
588 const Allocator<U> &rhs) const {
589 return !(*this == rhs);
590}
591
592template <class T, class AllocationScheme>
593inline T *Allocator<T, AllocationScheme>::allocate(size_t n_elements) {
594 assert(n_elements <= std::numeric_limits<size_type>::max() / sizeof(T));
595 DBUG_EXECUTE_IF("temptable_allocator_oom", throw Result::OUT_OF_MEM;);
596 DBUG_EXECUTE_IF("temptable_allocator_record_file_full",
598
599 const size_t n_bytes_requested = n_elements * sizeof(T);
600 if (n_bytes_requested == 0) {
601 return nullptr;
602 }
603
604 Block *block;
605
606 if (m_shared_block && m_shared_block->is_empty()) {
607 const size_t block_size =
608 AllocationScheme::block_size(0, n_bytes_requested);
609 *m_shared_block =
610 Block(block_size, AllocationScheme::block_source(block_size));
611 block = m_shared_block;
612 } else if (m_shared_block &&
613 m_shared_block->can_accommodate(n_bytes_requested)) {
614 block = m_shared_block;
615 } else {
616 block = m_state->get_block_for_new_allocation(n_bytes_requested);
617 }
618
619 /* temptable::Table is allowed to fit no more data than the given threshold
620 * controlled through TableResourceMonitor abstraction. TableResourceMonitor
621 * is a simple abstraction which is in its part an alias for tmp_table_size, a
622 * system variable that end MySQL users will be using to control this
623 * threshold.
624 *
625 * Updating the tmp_table_size threshold can only be done through the separate
626 * SET statement which implies that the tmp_table_size threshold cannot be
627 * updated during the duration of some query which is running within the same
628 * session. Separate sessions can still of course change this value to their
629 * liking.
630 */
631 if (m_table_resource_monitor.consumption() + n_bytes_requested >
632 m_table_resource_monitor.threshold()) {
633 if (current_thd) {
634 /* Track through the status variable, if table
635 * size exceeded the tmp_table_size in user session
636 */
638 }
640 }
641 m_table_resource_monitor.increase(n_bytes_requested);
642
643 T *chunk_data =
644 reinterpret_cast<T *>(block->allocate(n_bytes_requested).data());
645 assert(reinterpret_cast<uintptr_t>(chunk_data) % alignof(T) == 0);
646 return chunk_data;
647}
648
649template <class T, class AllocationScheme>
651 size_t n_elements) {
652 assert(reinterpret_cast<uintptr_t>(chunk_data) % alignof(T) == 0);
653
654 if (chunk_data == nullptr) {
655 return;
656 }
657
658 const size_t n_bytes_requested = n_elements * sizeof(T);
659
660 Block block = Block(Chunk(chunk_data));
661 const auto remaining_chunks =
662 block.deallocate(Chunk(chunk_data), n_bytes_requested);
663 if (remaining_chunks == 0) {
664 if (m_shared_block && (block == *m_shared_block)) {
665 // Do nothing. Keep the last block alive.
666 } else {
667 m_state->block_is_not_used_anymore(block);
668 }
669 }
670 m_table_resource_monitor.decrease(n_bytes_requested);
671}
672
673template <class T, class AllocationScheme>
674template <class U, class... Args>
675inline void Allocator<T, AllocationScheme>::construct(U *mem, Args &&...args) {
676 new (mem) U(std::forward<Args>(args)...);
677}
678
679template <class T, class AllocationScheme>
680template <class U>
682 p->~U();
683}
684
685template <class T, class AllocationScheme>
688}
689
690} /* namespace temptable */
691
692#endif /* TEMPTABLE_ALLOCATOR_H */
Block abstraction for temptable-allocator.
Chunk abstraction for temptable Block allocator.
void inc_status_count_hit_tmp_table_size()
Definition: sql_class.cc:2500
Shared state between all instances of a given allocator.
Definition: allocator.h:319
Block * get_block_for_new_allocation(size_t n_bytes_requested)
Gets a Block from which a new allocation of the specified size should be performed.
Definition: allocator.h:340
void block_is_not_used_anymore(Block block) noexcept
Informs the state object of a block that has no data allocated inside of it anymore for garbage colle...
Definition: allocator.h:366
size_t number_of_blocks
Number of created blocks so far (by this Allocator object).
Definition: allocator.h:397
Block current_block
Current not-yet-full block to feed allocations from.
Definition: allocator.h:390
void free_block(Block &block) noexcept
Frees the specified block and takes care of all accounting.
Definition: allocator.h:383
~AllocatorState() noexcept
Destroys the state, deallocate the current_block if it was left empty.
Definition: allocator.h:324
Custom memory allocator.
Definition: allocator.h:439
Block * m_shared_block
A block of memory which is a state external to this allocator and can be shared among different insta...
Definition: allocator.h:545
void construct(U *mem, Args &&...args)
Construct one object of type U on an already allocated chunk of memory, which must be large enough to...
Definition: allocator.h:675
T & reference
Definition: allocator.h:448
const T * const_pointer
Definition: allocator.h:447
void deallocate(T *ptr, size_t n_elements)
Free a memory allocated by allocate().
Definition: allocator.h:650
const T & const_reference
Definition: allocator.h:449
void operator=(const Allocator< U > &&)=delete
Move operator, not used, thus disabled.
Allocator(const Allocator &)=default
~Allocator()
Destructor.
Allocator(Block *shared_block, TableResourceMonitor &table_resource_monitor)
Constructor.
Definition: allocator.h:555
T * pointer
Definition: allocator.h:442
T * allocate(size_t n_elements)
Allocate memory for storing n_elements number of elements.
Definition: allocator.h:593
size_t size_type
Definition: allocator.h:451
void destroy(U *p)
Destroy an object of type U.
Definition: allocator.h:681
static void init()
Initialize necessary structures.
Definition: allocator.h:686
bool operator!=(const Allocator< U > &rhs) const
Inequality operator.
Definition: allocator.h:587
TableResourceMonitor & m_table_resource_monitor
Table resource monitor control mechanism that limits the amount of resources that can be consumed at ...
Definition: allocator.h:549
bool operator==(const Allocator< U > &rhs) const
Equality operator.
Definition: allocator.h:580
ptrdiff_t difference_type
Definition: allocator.h:452
std::shared_ptr< AllocatorState< AllocationScheme > > m_state
Shared state between all the copies and rebinds of this allocator.
Definition: allocator.h:538
T value_type
Definition: allocator.h:450
void operator=(const Allocator< U > &)=delete
Assignment operator, not used, thus disabled.
Memory-block abstraction whose purpose is to serve as a building block for custom memory-allocator im...
Definition: block.h:163
bool is_empty() const
Check if Block is empty (not holding any data).
Definition: block.h:399
bool can_accommodate(size_t chunk_size) const
Check if Block can fit (allocate) a Chunk of given size.
Definition: block.h:403
size_t number_of_used_chunks() const
Get current number of Chunks allocated by the Block.
Definition: block.h:427
static constexpr size_t ALIGN_TO
Block will self-adjust all requested allocation-sizes to the multiple of this value.
Definition: block.h:167
Chunk allocate(size_t chunk_size) noexcept
Allocate a Chunk from a Block.
Definition: block.h:351
static size_t size_hint(size_t n_bytes)
For given size, how much memory will Block with single Chunk actually occupy.
Definition: block.h:448
Chunk is an abstraction with the purpose of representing a smallest logical memory-unit within the Bl...
Definition: chunk.h:68
uint8_t * data() const
Get the pointer to the data section which will be provided to the end-user.
Definition: chunk.h:158
Definition: allocator.h:126
TableResourceMonitor(size_t threshold)
Definition: allocator.h:128
size_t m_total_bytes
Definition: allocator.h:147
size_t increase(size_t bytes)
Definition: allocator.h:131
size_t decrease(size_t bytes)
Definition: allocator.h:137
size_t m_threshold
Definition: allocator.h:146
size_t threshold()
Definition: allocator.h:142
size_t consumption()
Definition: allocator.h:143
const char * p
Definition: ctype-mb.cc:1227
#define U
Definition: ctype-tis620.cc:73
thread_local THD * current_thd
Definition: current_thd.cc:26
#define T
Definition: jit_executor_value.cc:373
Memory utilities for temptable-allocator.
#define DBUG_EXECUTE_IF(keyword, a1)
Definition: my_dbug.h:171
Common header for many mysys elements.
ulonglong temptable_max_ram
Definition: mysqld.cc:1200
ulonglong temptable_max_mmap
Definition: mysqld.cc:1201
ValueType max(X &&first)
Definition: gtid.h:103
Definition: gcs_xcom_synode.h:64
Definition: allocator.h:48
constexpr size_t ALLOCATOR_MAX_BLOCK_MB_EXP
log2(allocator max block size in MiB).
Definition: constants.h:60
void Block_PSI_init()
Initialize the PSI memory engine.
Definition: block.cc:74
std::atomic_uint64_t count_hit_max_ram
Status variable that counts the memory limit breaches.
Definition: plugin.cc:56
constexpr size_t ALLOCATOR_MAX_BLOCK_BYTES
Limit on the size of a block created by Allocator (in bytes).
Definition: constants.h:65
Source
Type of memory allocated.
Definition: memutils.h:68
@ MMAP_FILE
Memory is allocated on disk, using mmap()'ed file.
@ RAM
Memory is allocated from RAM, using malloc() for example.
std::enable_if_t<!std::is_array< T >::value, std::shared_ptr< T > > make_shared(Args &&...args)
Dynamically allocates storage for an object of type T.
Definition: ut0new.h:2592
static MEM_ROOT mem
Definition: sql_servers.cc:100
TempTable constants.
Definition: allocator.h:190
static size_t block_size(size_t number_of_blocks, size_t n_bytes_requested)
Definition: allocator.h:194
static Source block_source(size_t block_size)
Definition: allocator.h:191
static void block_freed(uint32_t block_size, Source block_source)
Definition: allocator.h:197
Definition: allocator.h:455
Allocator< U, AllocationScheme > other
Definition: allocator.h:456
Definition: allocator.h:272
static size_t block_size(size_t number_of_blocks, size_t n_bytes_requested)
Given the current number of allocated blocks by the allocator, and number of bytes actually requested...
Definition: allocator.h:280
Definition: allocator.h:86
static size_t increase(size_t bytes)
Log increments of MMAP-backed memory consumption.
Definition: allocator.h:91
static size_t threshold()
Get MMAP-backed memory threshold level.
Definition: allocator.h:107
static size_t decrease(size_t bytes)
Log decrements of MMAP-backed memory consumption.
Definition: allocator.h:99
static size_t consumption()
Get current level of MMAP-backed memory consumption.
Definition: allocator.h:111
Definition: allocator.h:59
static size_t consumption()
Get current level of heap-memory consumption.
Definition: allocator.h:83
static size_t decrease(size_t bytes)
Log decrements of heap-memory consumption.
Definition: allocator.h:72
static size_t increase(size_t bytes)
Log increments of heap-memory consumption.
Definition: allocator.h:64
static size_t threshold()
Get heap-memory threshold level.
Definition: allocator.h:79
Definition: allocator.h:58
static std::atomic< size_t > mmap
Definition: allocator.h:117
static std::atomic< size_t > ram
Total bytes allocated so far by all threads in RAM/MMAP.
Definition: allocator.h:116
Definition: allocator.h:214
static Source block_source(uint32_t block_size)
Definition: allocator.h:215
static void block_freed(uint32_t block_size, Source block_source)
Definition: allocator.h:241
Definition: dtoa.cc:595